From 804169dd621a3ad3eec1a32ce30350de667fee80 Mon Sep 17 00:00:00 2001 From: aliaspider Date: Thu, 30 Oct 2014 00:23:30 +0100 Subject: apply a facelift --- source/65c816.h | 63 +- source/apu.c | 1284 +++++---- source/apu.h | 132 +- source/apumem.h | 282 +- source/c4.c | 226 +- source/c4.h | 28 +- source/c4emu.c | 1600 ++++++------ source/cheats.c | 629 ++--- source/cheats2.c | 335 +-- source/clip.c | 1299 +++++---- source/cpu.c | 240 +- source/cpuaddr.h | 390 +-- source/cpuexec.c | 1308 +++++----- source/cpuexec.h | 210 +- source/cpumacro.h | 1100 ++++---- source/cpuops.c | 4986 ++++++++++++++++++----------------- source/cpuops.h | 32 +- source/data.c | 1195 +++++---- source/display.h | 96 +- source/dma.c | 1833 ++++++------- source/dma.h | 36 +- source/dsp1.c | 2705 ++++++++++--------- source/dsp1.h | 63 +- source/dsp1emu.c | 1730 ++++++------ source/dsp2emu.c | 458 ++-- source/dsp4.h | 134 +- source/dsp4emu.c | 2302 ++++++++-------- source/font.h | 139 +- source/fxdbg.c | 588 ++--- source/fxemu.c | 1022 ++++---- source/fxemu.h | 59 +- source/fxinst.c | 4168 ++++++++++++++++++++--------- source/fxinst.h | 312 +-- source/getset.h | 1081 ++++---- source/gfx.c | 6343 ++++++++++++++++++++++---------------------- source/gfx.h | 293 ++- source/globals.c | 248 +- source/memmap.c | 7231 ++++++++++++++++++++++++++------------------------- source/memmap.h | 237 +- source/messages.h | 104 +- source/missing.h | 150 +- source/obc1.c | 204 +- source/obc1.h | 36 +- source/pixform.h | 96 +- source/port.h | 42 +- source/ppu.c | 5751 ++++++++++++++++++++-------------------- source/ppu.h | 447 ++-- source/sa1.c | 1575 ++++++----- source/sa1.h | 207 +- source/sa1cpu.c | 94 +- source/sar.h | 58 +- source/screenshot.c | 277 +- source/screenshot.h | 28 +- source/sdd1.c | 140 +- source/sdd1.h | 38 +- source/sdd1emu.c | 625 ++--- source/sdd1emu.h | 32 +- source/seta.c | 36 +- source/seta.h | 82 +- source/seta010.c | 1211 +++++---- source/seta011.c | 291 ++- source/seta018.c | 334 +-- source/snaporig.c | 703 ++--- source/snaporig.h | 532 ++-- source/snapshot.c | 2936 ++++++++++----------- source/snapshot.h | 42 +- source/snes9x.h | 441 ++-- source/soundux.c | 2845 ++++++++++---------- source/soundux.h | 250 +- source/spc700.c | 2989 ++++++++++----------- source/spc700.h | 59 +- source/spc7110.c | 3886 +++++++++++++-------------- source/spc7110.h | 154 +- source/srtc.c | 756 +++--- source/srtc.h | 60 +- source/tile.c | 1549 +++++------ source/tile.h | 300 +-- 77 files changed, 39335 insertions(+), 36442 deletions(-) (limited to 'source') diff --git a/source/65c816.h b/source/65c816.h index eee60b3..851939d 100644 --- a/source/65c816.h +++ b/source/65c816.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -147,24 +147,31 @@ typedef union { #ifdef LSB_FIRST - struct { uint8 l,h; } B; + struct + { + uint8 l, h; + } B; #else - struct { uint8 h,l; } B; + struct + { + uint8 h, l; + } B; #endif - uint16 W; + uint16 W; } pair; -typedef struct { - uint8 PB; - uint8 DB; - pair P; - pair A; - pair D; - pair S; - pair X; - pair Y; - uint16 PC; -}SRegisters; +typedef struct +{ + uint8 PB; + uint8 DB; + pair P; + pair A; + pair D; + pair S; + pair X; + pair Y; + uint16 PC; +} SRegisters; #endif diff --git a/source/apu.c b/source/apu.c index e117bd8..a63b42f 100644 --- a/source/apu.c +++ b/source/apu.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -101,675 +101,671 @@ /* For note-triggered SPC dump support */ #include "snapshot.h" -const char *S9xGetFilenameInc (const char *); +const char* S9xGetFilenameInc(const char*); -int spc_is_dumping=0; +int spc_is_dumping = 0; int spc_is_dumping_temp; -uint8 spc_dump_dsp[0x100]; +uint8 spc_dump_dsp[0x100]; extern int NoiseFreq [32]; -bool8 S9xInitAPU () +bool8 S9xInitAPU() { - IAPU.RAM = (uint8 *) malloc (0x10000); - - if (!IAPU.RAM) - { - S9xDeinitAPU (); - return (FALSE); - } - - memset(IAPU.RAM, 0, 0x10000); - - return (TRUE); + IAPU.RAM = (uint8*) malloc(0x10000); + + if (!IAPU.RAM) + { + S9xDeinitAPU(); + return (FALSE); + } + + memset(IAPU.RAM, 0, 0x10000); + + return (TRUE); } -void S9xDeinitAPU () +void S9xDeinitAPU() { - if (IAPU.RAM) - { - free ((char *) IAPU.RAM); - IAPU.RAM = NULL; - } + if (IAPU.RAM) + { + free((char*) IAPU.RAM); + IAPU.RAM = NULL; + } } uint8 APUROM [64]; -void S9xResetAPU () +void S9xResetAPU() { - int i,j; - - Settings.APUEnabled = Settings.NextAPUEnabled; - - ZeroMemory(spc_dump_dsp, 0x100); - ZeroMemory(IAPU.RAM, 0x100); - memset(IAPU.RAM+0x20, 0xFF, 0x20); - memset(IAPU.RAM+0x60, 0xFF, 0x20); - memset(IAPU.RAM+0xA0, 0xFF, 0x20); - memset(IAPU.RAM+0xE0, 0xFF, 0x20); - - for(i=1;i<256;i++) - { - memcpy(IAPU.RAM+(i<<8), IAPU.RAM, 0x100); - } - - ZeroMemory (APU.OutPorts, 4); - IAPU.DirectPage = IAPU.RAM; - // memmove converted: Different mallocs [Neb] - // DS2 DMA notes: The APU ROM is not 32-byte aligned [Neb] - memcpy (&IAPU.RAM [0xffc0], APUROM, sizeof (APUROM)); - // memmove converted: Different mallocs [Neb] - // DS2 DMA notes: The APU ROM is not 32-byte aligned [Neb] - memcpy (APU.ExtraRAM, APUROM, sizeof (APUROM)); - IAPU.PC = IAPU.RAM + IAPU.RAM [0xfffe] + (IAPU.RAM [0xffff] << 8); - APU.Cycles = 0; - IAPU.Registers.YA.W = 0; - IAPU.Registers.X = 0; - IAPU.Registers.S = 0xff; - IAPU.Registers.P = 0; - S9xAPUUnpackStatus (); - IAPU.Registers.PC = 0; - IAPU.APUExecuting = Settings.APUEnabled; + int i, j; + + Settings.APUEnabled = Settings.NextAPUEnabled; + + ZeroMemory(spc_dump_dsp, 0x100); + ZeroMemory(IAPU.RAM, 0x100); + memset(IAPU.RAM + 0x20, 0xFF, 0x20); + memset(IAPU.RAM + 0x60, 0xFF, 0x20); + memset(IAPU.RAM + 0xA0, 0xFF, 0x20); + memset(IAPU.RAM + 0xE0, 0xFF, 0x20); + + for (i = 1; i < 256; i++) + memcpy(IAPU.RAM + (i << 8), IAPU.RAM, 0x100); + + ZeroMemory(APU.OutPorts, 4); + IAPU.DirectPage = IAPU.RAM; + // memmove converted: Different mallocs [Neb] + // DS2 DMA notes: The APU ROM is not 32-byte aligned [Neb] + memcpy(&IAPU.RAM [0xffc0], APUROM, sizeof(APUROM)); + // memmove converted: Different mallocs [Neb] + // DS2 DMA notes: The APU ROM is not 32-byte aligned [Neb] + memcpy(APU.ExtraRAM, APUROM, sizeof(APUROM)); + IAPU.PC = IAPU.RAM + IAPU.RAM [0xfffe] + (IAPU.RAM [0xffff] << 8); + APU.Cycles = 0; + IAPU.Registers.YA.W = 0; + IAPU.Registers.X = 0; + IAPU.Registers.S = 0xff; + IAPU.Registers.P = 0; + S9xAPUUnpackStatus(); + IAPU.Registers.PC = 0; + IAPU.APUExecuting = Settings.APUEnabled; #ifdef SPC700_SHUTDOWN - IAPU.WaitAddress1 = NULL; - IAPU.WaitAddress2 = NULL; - IAPU.WaitCounter = 0; + IAPU.WaitAddress1 = NULL; + IAPU.WaitAddress2 = NULL; + IAPU.WaitCounter = 0; #endif - APU.ShowROM = TRUE; - IAPU.RAM [0xf1] = 0x80; - - for (i = 0; i < 3; i++) - { - APU.TimerEnabled [i] = FALSE; - APU.TimerValueWritten [i] = 0; - APU.TimerTarget [i] = 0; - APU.Timer [i] = 0; - } - for (j = 0; j < 0x80; j++) - APU.DSP [j] = 0; - - IAPU.TwoCycles = IAPU.OneCycle * 2; - - for (i = 0; i < 256; i++) - S9xAPUCycles [i] = S9xAPUCycleLengths [i] * IAPU.OneCycle; - - APU.DSP [APU_ENDX] = 0; - APU.DSP [APU_KOFF] = 0; - APU.DSP [APU_KON] = 0; - APU.DSP [APU_FLG] = APU_MUTE | APU_ECHO_DISABLED; - APU.KeyedChannels = 0; - - S9xResetSound (TRUE); - S9xSetEchoEnable (0); + APU.ShowROM = TRUE; + IAPU.RAM [0xf1] = 0x80; + + for (i = 0; i < 3; i++) + { + APU.TimerEnabled [i] = FALSE; + APU.TimerValueWritten [i] = 0; + APU.TimerTarget [i] = 0; + APU.Timer [i] = 0; + } + for (j = 0; j < 0x80; j++) + APU.DSP [j] = 0; + + IAPU.TwoCycles = IAPU.OneCycle * 2; + + for (i = 0; i < 256; i++) + S9xAPUCycles [i] = S9xAPUCycleLengths [i] * IAPU.OneCycle; + + APU.DSP [APU_ENDX] = 0; + APU.DSP [APU_KOFF] = 0; + APU.DSP [APU_KON] = 0; + APU.DSP [APU_FLG] = APU_MUTE | APU_ECHO_DISABLED; + APU.KeyedChannels = 0; + + S9xResetSound(TRUE); + S9xSetEchoEnable(0); } -void S9xSetAPUDSP (uint8 byte) +void S9xSetAPUDSP(uint8 byte) { - uint8 reg = IAPU.RAM [0xf2]; - static uint8 KeyOn; - static uint8 KeyOnPrev; - int i; - - spc_dump_dsp[reg] = byte; - - switch (reg) - { - case APU_FLG: - if (byte & APU_SOFT_RESET) - { - APU.DSP [reg] = APU_MUTE | APU_ECHO_DISABLED | (byte & 0x1f); - APU.DSP [APU_ENDX] = 0; - APU.DSP [APU_KOFF] = 0; - APU.DSP [APU_KON] = 0; - S9xSetEchoWriteEnable (FALSE); + uint8 reg = IAPU.RAM [0xf2]; + static uint8 KeyOn; + static uint8 KeyOnPrev; + int i; + + spc_dump_dsp[reg] = byte; + + switch (reg) + { + case APU_FLG: + if (byte & APU_SOFT_RESET) + { + APU.DSP [reg] = APU_MUTE | APU_ECHO_DISABLED | (byte & 0x1f); + APU.DSP [APU_ENDX] = 0; + APU.DSP [APU_KOFF] = 0; + APU.DSP [APU_KON] = 0; + S9xSetEchoWriteEnable(FALSE); // Kill sound - S9xResetSound (FALSE); - } - else - { - S9xSetEchoWriteEnable (!(byte & APU_ECHO_DISABLED)); - if (byte & APU_MUTE) - { - S9xSetSoundMute (TRUE); - } - else - S9xSetSoundMute (FALSE); - - SoundData.noise_hertz = NoiseFreq [byte & 0x1f]; - for (i = 0; i < 8; i++) - { - if (SoundData.channels [i].type == SOUND_NOISE) - S9xSetSoundFrequency (i, SoundData.noise_hertz); - } - } - break; - case APU_NON: - if (byte != APU.DSP [APU_NON]) - { - int c; - uint8 mask = 1; - for (c = 0; c < 8; c++, mask <<= 1) - { - int type; - - if (byte & mask) - type = SOUND_NOISE; - else - type = SOUND_SAMPLE; - - S9xSetSoundType (c, type); - } - } - break; - case APU_MVOL_LEFT: - if (byte != APU.DSP [APU_MVOL_LEFT]) - { - S9xSetMasterVolume ((signed char) byte, - (signed char) APU.DSP [APU_MVOL_RIGHT]); - } - break; - case APU_MVOL_RIGHT: - if (byte != APU.DSP [APU_MVOL_RIGHT]) - { - S9xSetMasterVolume ((signed char) APU.DSP [APU_MVOL_LEFT], - (signed char) byte); - } - break; - case APU_EVOL_LEFT: - if (byte != APU.DSP [APU_EVOL_LEFT]) - { - S9xSetEchoVolume ((signed char) byte, - (signed char) APU.DSP [APU_EVOL_RIGHT]); - } - break; - case APU_EVOL_RIGHT: - if (byte != APU.DSP [APU_EVOL_RIGHT]) - { - S9xSetEchoVolume ((signed char) APU.DSP [APU_EVOL_LEFT], - (signed char) byte); - } - break; - case APU_ENDX: - byte = 0; - break; - - case APU_KOFF: - // if (byte) - { + S9xResetSound(FALSE); + } + else + { + S9xSetEchoWriteEnable(!(byte & APU_ECHO_DISABLED)); + if (byte & APU_MUTE) + S9xSetSoundMute(TRUE); + else + S9xSetSoundMute(FALSE); + + SoundData.noise_hertz = NoiseFreq [byte & 0x1f]; + for (i = 0; i < 8; i++) + { + if (SoundData.channels [i].type == SOUND_NOISE) + S9xSetSoundFrequency(i, SoundData.noise_hertz); + } + } + break; + case APU_NON: + if (byte != APU.DSP [APU_NON]) + { int c; - uint8 mask = 1; + uint8 mask = 1; for (c = 0; c < 8; c++, mask <<= 1) - { - if ((byte & mask) != 0) - { - if (APU.KeyedChannels & mask) - { - { - KeyOnPrev&=~mask; - APU.KeyedChannels &= ~mask; - APU.DSP [APU_KON] &= ~mask; - //APU.DSP [APU_KOFF] |= mask; - S9xSetSoundKeyOff (c); - } - } - } - else if((KeyOnPrev&mask)!=0) - { - KeyOnPrev&=~mask; - APU.KeyedChannels |= mask; - //APU.DSP [APU_KON] |= mask; - APU.DSP [APU_KOFF] &= ~mask; - APU.DSP [APU_ENDX] &= ~mask; - S9xPlaySample (c); - } - } - } - //KeyOnPrev=0; - APU.DSP [APU_KOFF] = byte; - return; - case APU_KON: - if (spc_is_dumping) - { - if (byte & ~spc_is_dumping_temp) - { - IAPU.Registers.PC = IAPU.PC - IAPU.RAM; - S9xAPUPackStatus(); - S9xSPCDump (".spc"); - spc_is_dumping = 0; - } - } - if (byte) - { + { + int type; + + if (byte & mask) + type = SOUND_NOISE; + else + type = SOUND_SAMPLE; + + S9xSetSoundType(c, type); + } + } + break; + case APU_MVOL_LEFT: + if (byte != APU.DSP [APU_MVOL_LEFT]) + { + S9xSetMasterVolume((signed char) byte, + (signed char) APU.DSP [APU_MVOL_RIGHT]); + } + break; + case APU_MVOL_RIGHT: + if (byte != APU.DSP [APU_MVOL_RIGHT]) + { + S9xSetMasterVolume((signed char) APU.DSP [APU_MVOL_LEFT], + (signed char) byte); + } + break; + case APU_EVOL_LEFT: + if (byte != APU.DSP [APU_EVOL_LEFT]) + { + S9xSetEchoVolume((signed char) byte, + (signed char) APU.DSP [APU_EVOL_RIGHT]); + } + break; + case APU_EVOL_RIGHT: + if (byte != APU.DSP [APU_EVOL_RIGHT]) + { + S9xSetEchoVolume((signed char) APU.DSP [APU_EVOL_LEFT], + (signed char) byte); + } + break; + case APU_ENDX: + byte = 0; + break; + + case APU_KOFF: + // if (byte) + { + int c; + uint8 mask = 1; + for (c = 0; c < 8; c++, mask <<= 1) + { + if ((byte & mask) != 0) + { + if (APU.KeyedChannels & mask) + { + { + KeyOnPrev &= ~mask; + APU.KeyedChannels &= ~mask; + APU.DSP [APU_KON] &= ~mask; + //APU.DSP [APU_KOFF] |= mask; + S9xSetSoundKeyOff(c); + } + } + } + else if ((KeyOnPrev & mask) != 0) + { + KeyOnPrev &= ~mask; + APU.KeyedChannels |= mask; + //APU.DSP [APU_KON] |= mask; + APU.DSP [APU_KOFF] &= ~mask; + APU.DSP [APU_ENDX] &= ~mask; + S9xPlaySample(c); + } + } + } + //KeyOnPrev=0; + APU.DSP [APU_KOFF] = byte; + return; + case APU_KON: + if (spc_is_dumping) + { + if (byte & ~spc_is_dumping_temp) + { + IAPU.Registers.PC = IAPU.PC - IAPU.RAM; + S9xAPUPackStatus(); + S9xSPCDump(".spc"); + spc_is_dumping = 0; + } + } + if (byte) + { int c; - uint8 mask = 1; + uint8 mask = 1; for (c = 0; c < 8; c++, mask <<= 1) - { - if ((byte & mask) != 0) - { - // Pac-In-Time requires that channels can be key-on - // regardeless of their current state. - if((APU.DSP [APU_KOFF] & mask) ==0) - { - KeyOnPrev&=~mask; - APU.KeyedChannels |= mask; - //APU.DSP [APU_KON] |= mask; - //APU.DSP [APU_KOFF] &= ~mask; - APU.DSP [APU_ENDX] &= ~mask; - S9xPlaySample (c); - } - else KeyOn|=mask; - } - } - } - spc_is_dumping_temp = byte; - return; - - case APU_VOL_LEFT + 0x00: - case APU_VOL_LEFT + 0x10: - case APU_VOL_LEFT + 0x20: - case APU_VOL_LEFT + 0x30: - case APU_VOL_LEFT + 0x40: - case APU_VOL_LEFT + 0x50: - case APU_VOL_LEFT + 0x60: - case APU_VOL_LEFT + 0x70: - // At Shin Megami Tensei suggestion 6/11/00 - // if (byte != APU.DSP [reg]) - { - S9xSetSoundVolume (reg >> 4, (signed char) byte, - (signed char) APU.DSP [reg + 1]); - } - break; - case APU_VOL_RIGHT + 0x00: - case APU_VOL_RIGHT + 0x10: - case APU_VOL_RIGHT + 0x20: - case APU_VOL_RIGHT + 0x30: - case APU_VOL_RIGHT + 0x40: - case APU_VOL_RIGHT + 0x50: - case APU_VOL_RIGHT + 0x60: - case APU_VOL_RIGHT + 0x70: - // At Shin Megami Tensei suggestion 6/11/00 - // if (byte != APU.DSP [reg]) - { - S9xSetSoundVolume (reg >> 4, (signed char) APU.DSP [reg - 1], - (signed char) byte); - } - break; - - case APU_P_LOW + 0x00: - case APU_P_LOW + 0x10: - case APU_P_LOW + 0x20: - case APU_P_LOW + 0x30: - case APU_P_LOW + 0x40: - case APU_P_LOW + 0x50: - case APU_P_LOW + 0x60: - case APU_P_LOW + 0x70: - S9xSetSoundHertz (reg >> 4, ((byte + (APU.DSP [reg + 1] << 8)) & FREQUENCY_MASK) * 8); - break; - - case APU_P_HIGH + 0x00: - case APU_P_HIGH + 0x10: - case APU_P_HIGH + 0x20: - case APU_P_HIGH + 0x30: - case APU_P_HIGH + 0x40: - case APU_P_HIGH + 0x50: - case APU_P_HIGH + 0x60: - case APU_P_HIGH + 0x70: - S9xSetSoundHertz (reg >> 4, - (((byte << 8) + APU.DSP [reg - 1]) & FREQUENCY_MASK) * 8); - break; - - case APU_SRCN + 0x00: - case APU_SRCN + 0x10: - case APU_SRCN + 0x20: - case APU_SRCN + 0x30: - case APU_SRCN + 0x40: - case APU_SRCN + 0x50: - case APU_SRCN + 0x60: - case APU_SRCN + 0x70: - if (byte != APU.DSP [reg]) - { - S9xSetSoundSample (reg >> 4, byte); - } - break; - - case APU_ADSR1 + 0x00: - case APU_ADSR1 + 0x10: - case APU_ADSR1 + 0x20: - case APU_ADSR1 + 0x30: - case APU_ADSR1 + 0x40: - case APU_ADSR1 + 0x50: - case APU_ADSR1 + 0x60: - case APU_ADSR1 + 0x70: - if (byte != APU.DSP [reg]) - { - { - S9xFixEnvelope (reg >> 4, APU.DSP [reg + 2], byte, - APU.DSP [reg + 1]); - } - } - break; - - case APU_ADSR2 + 0x00: - case APU_ADSR2 + 0x10: - case APU_ADSR2 + 0x20: - case APU_ADSR2 + 0x30: - case APU_ADSR2 + 0x40: - case APU_ADSR2 + 0x50: - case APU_ADSR2 + 0x60: - case APU_ADSR2 + 0x70: - if (byte != APU.DSP [reg]) - { - { - S9xFixEnvelope (reg >> 4, APU.DSP [reg + 1], APU.DSP [reg - 1], - byte); - } - } - break; - - case APU_GAIN + 0x00: - case APU_GAIN + 0x10: - case APU_GAIN + 0x20: - case APU_GAIN + 0x30: - case APU_GAIN + 0x40: - case APU_GAIN + 0x50: - case APU_GAIN + 0x60: - case APU_GAIN + 0x70: - if (byte != APU.DSP [reg]) - { - { - S9xFixEnvelope (reg >> 4, byte, APU.DSP [reg - 2], - APU.DSP [reg - 1]); - } - } - break; - - case APU_ENVX + 0x00: - case APU_ENVX + 0x10: - case APU_ENVX + 0x20: - case APU_ENVX + 0x30: - case APU_ENVX + 0x40: - case APU_ENVX + 0x50: - case APU_ENVX + 0x60: - case APU_ENVX + 0x70: - break; - - case APU_OUTX + 0x00: - case APU_OUTX + 0x10: - case APU_OUTX + 0x20: - case APU_OUTX + 0x30: - case APU_OUTX + 0x40: - case APU_OUTX + 0x50: - case APU_OUTX + 0x60: - case APU_OUTX + 0x70: - break; - - case APU_DIR: - break; - - case APU_PMON: - if (byte != APU.DSP [APU_PMON]) - { - S9xSetFrequencyModulationEnable (byte); - } - break; - - case APU_EON: - if (byte != APU.DSP [APU_EON]) - { - S9xSetEchoEnable (byte); - } - break; - - case APU_EFB: - S9xSetEchoFeedback ((signed char) byte); - break; - - case APU_ESA: - break; - - case APU_EDL: - S9xSetEchoDelay (byte & 0xf); - break; - - case APU_C0: - case APU_C1: - case APU_C2: - case APU_C3: - case APU_C4: - case APU_C5: - case APU_C6: - case APU_C7: - S9xSetFilterCoefficient (reg >> 4, (signed char) byte); - break; - default: - // XXX - //printf ("Write %02x to unknown APU register %02x\n", byte, reg); - break; - } - - KeyOnPrev|=KeyOn; - KeyOn=0; - - if (reg < 0x80) - APU.DSP [reg] = byte; + { + if ((byte & mask) != 0) + { + // Pac-In-Time requires that channels can be key-on + // regardeless of their current state. + if ((APU.DSP [APU_KOFF] & mask) == 0) + { + KeyOnPrev &= ~mask; + APU.KeyedChannels |= mask; + //APU.DSP [APU_KON] |= mask; + //APU.DSP [APU_KOFF] &= ~mask; + APU.DSP [APU_ENDX] &= ~mask; + S9xPlaySample(c); + } + else KeyOn |= mask; + } + } + } + spc_is_dumping_temp = byte; + return; + + case APU_VOL_LEFT + 0x00: + case APU_VOL_LEFT + 0x10: + case APU_VOL_LEFT + 0x20: + case APU_VOL_LEFT + 0x30: + case APU_VOL_LEFT + 0x40: + case APU_VOL_LEFT + 0x50: + case APU_VOL_LEFT + 0x60: + case APU_VOL_LEFT + 0x70: + // At Shin Megami Tensei suggestion 6/11/00 + // if (byte != APU.DSP [reg]) + { + S9xSetSoundVolume(reg >> 4, (signed char) byte, + (signed char) APU.DSP [reg + 1]); + } + break; + case APU_VOL_RIGHT + 0x00: + case APU_VOL_RIGHT + 0x10: + case APU_VOL_RIGHT + 0x20: + case APU_VOL_RIGHT + 0x30: + case APU_VOL_RIGHT + 0x40: + case APU_VOL_RIGHT + 0x50: + case APU_VOL_RIGHT + 0x60: + case APU_VOL_RIGHT + 0x70: + // At Shin Megami Tensei suggestion 6/11/00 + // if (byte != APU.DSP [reg]) + { + S9xSetSoundVolume(reg >> 4, (signed char) APU.DSP [reg - 1], + (signed char) byte); + } + break; + + case APU_P_LOW + 0x00: + case APU_P_LOW + 0x10: + case APU_P_LOW + 0x20: + case APU_P_LOW + 0x30: + case APU_P_LOW + 0x40: + case APU_P_LOW + 0x50: + case APU_P_LOW + 0x60: + case APU_P_LOW + 0x70: + S9xSetSoundHertz(reg >> 4, + ((byte + (APU.DSP [reg + 1] << 8)) & FREQUENCY_MASK) * 8); + break; + + case APU_P_HIGH + 0x00: + case APU_P_HIGH + 0x10: + case APU_P_HIGH + 0x20: + case APU_P_HIGH + 0x30: + case APU_P_HIGH + 0x40: + case APU_P_HIGH + 0x50: + case APU_P_HIGH + 0x60: + case APU_P_HIGH + 0x70: + S9xSetSoundHertz(reg >> 4, + (((byte << 8) + APU.DSP [reg - 1]) & FREQUENCY_MASK) * 8); + break; + + case APU_SRCN + 0x00: + case APU_SRCN + 0x10: + case APU_SRCN + 0x20: + case APU_SRCN + 0x30: + case APU_SRCN + 0x40: + case APU_SRCN + 0x50: + case APU_SRCN + 0x60: + case APU_SRCN + 0x70: + if (byte != APU.DSP [reg]) + S9xSetSoundSample(reg >> 4, byte); + break; + + case APU_ADSR1 + 0x00: + case APU_ADSR1 + 0x10: + case APU_ADSR1 + 0x20: + case APU_ADSR1 + 0x30: + case APU_ADSR1 + 0x40: + case APU_ADSR1 + 0x50: + case APU_ADSR1 + 0x60: + case APU_ADSR1 + 0x70: + if (byte != APU.DSP [reg]) + { + { + S9xFixEnvelope(reg >> 4, APU.DSP [reg + 2], byte, + APU.DSP [reg + 1]); + } + } + break; + + case APU_ADSR2 + 0x00: + case APU_ADSR2 + 0x10: + case APU_ADSR2 + 0x20: + case APU_ADSR2 + 0x30: + case APU_ADSR2 + 0x40: + case APU_ADSR2 + 0x50: + case APU_ADSR2 + 0x60: + case APU_ADSR2 + 0x70: + if (byte != APU.DSP [reg]) + { + { + S9xFixEnvelope(reg >> 4, APU.DSP [reg + 1], APU.DSP [reg - 1], + byte); + } + } + break; + + case APU_GAIN + 0x00: + case APU_GAIN + 0x10: + case APU_GAIN + 0x20: + case APU_GAIN + 0x30: + case APU_GAIN + 0x40: + case APU_GAIN + 0x50: + case APU_GAIN + 0x60: + case APU_GAIN + 0x70: + if (byte != APU.DSP [reg]) + { + { + S9xFixEnvelope(reg >> 4, byte, APU.DSP [reg - 2], + APU.DSP [reg - 1]); + } + } + break; + + case APU_ENVX + 0x00: + case APU_ENVX + 0x10: + case APU_ENVX + 0x20: + case APU_ENVX + 0x30: + case APU_ENVX + 0x40: + case APU_ENVX + 0x50: + case APU_ENVX + 0x60: + case APU_ENVX + 0x70: + break; + + case APU_OUTX + 0x00: + case APU_OUTX + 0x10: + case APU_OUTX + 0x20: + case APU_OUTX + 0x30: + case APU_OUTX + 0x40: + case APU_OUTX + 0x50: + case APU_OUTX + 0x60: + case APU_OUTX + 0x70: + break; + + case APU_DIR: + break; + + case APU_PMON: + if (byte != APU.DSP [APU_PMON]) + S9xSetFrequencyModulationEnable(byte); + break; + + case APU_EON: + if (byte != APU.DSP [APU_EON]) + S9xSetEchoEnable(byte); + break; + + case APU_EFB: + S9xSetEchoFeedback((signed char) byte); + break; + + case APU_ESA: + break; + + case APU_EDL: + S9xSetEchoDelay(byte & 0xf); + break; + + case APU_C0: + case APU_C1: + case APU_C2: + case APU_C3: + case APU_C4: + case APU_C5: + case APU_C6: + case APU_C7: + S9xSetFilterCoefficient(reg >> 4, (signed char) byte); + break; + default: + // XXX + //printf ("Write %02x to unknown APU register %02x\n", byte, reg); + break; + } + + KeyOnPrev |= KeyOn; + KeyOn = 0; + + if (reg < 0x80) + APU.DSP [reg] = byte; } -void S9xFixEnvelope (int channel, uint8 gain, uint8 adsr1, uint8 adsr2) +void S9xFixEnvelope(int channel, uint8 gain, uint8 adsr1, uint8 adsr2) { - if (adsr1 & 0x80) - { - // ADSR mode - static unsigned long AttackRate [16] = { - 4100, 2600, 1500, 1000, 640, 380, 260, 160, - 96, 64, 40, 24, 16, 10, 6, 1 - }; - static unsigned long DecayRate [8] = { - 1200, 740, 440, 290, 180, 110, 74, 37 - }; - static unsigned long SustainRate [32] = { - ~0, 38000, 28000, 24000, 19000, 14000, 12000, 9400, - 7100, 5900, 4700, 3500, 2900, 2400, 1800, 1500, - 1200, 880, 740, 590, 440, 370, 290, 220, - 180, 150, 110, 92, 74, 55, 37, 18 - }; - // XXX: can DSP be switched to ADSR mode directly from GAIN/INCREASE/ - // DECREASE mode? And if so, what stage of the sequence does it start - // at? - if (S9xSetSoundMode (channel, MODE_ADSR)) - { - // Hack for ROMs that use a very short attack rate, key on a - // channel, then switch to decay mode. e.g. Final Fantasy II. - - int attack = AttackRate [adsr1 & 0xf]; - - if (attack == 1 && (!Settings.SoundSync + if (adsr1 & 0x80) + { + // ADSR mode + static unsigned long AttackRate [16] = + { + 4100, 2600, 1500, 1000, 640, 380, 260, 160, + 96, 64, 40, 24, 16, 10, 6, 1 + }; + static unsigned long DecayRate [8] = + { + 1200, 740, 440, 290, 180, 110, 74, 37 + }; + static unsigned long SustainRate [32] = + { + ~0, 38000, 28000, 24000, 19000, 14000, 12000, 9400, + 7100, 5900, 4700, 3500, 2900, 2400, 1800, 1500, + 1200, 880, 740, 590, 440, 370, 290, 220, + 180, 150, 110, 92, 74, 55, 37, 18 + }; + // XXX: can DSP be switched to ADSR mode directly from GAIN/INCREASE/ + // DECREASE mode? And if so, what stage of the sequence does it start + // at? + if (S9xSetSoundMode(channel, MODE_ADSR)) + { + // Hack for ROMs that use a very short attack rate, key on a + // channel, then switch to decay mode. e.g. Final Fantasy II. + + int attack = AttackRate [adsr1 & 0xf]; + + if (attack == 1 && (!Settings.SoundSync #ifdef __WIN32__ - || Settings.SoundDriver != WIN_SNES9X_DIRECT_SOUND_DRIVER + || Settings.SoundDriver != WIN_SNES9X_DIRECT_SOUND_DRIVER #endif - )) - attack = 0; - - S9xSetSoundADSR (channel, attack, - DecayRate [(adsr1 >> 4) & 7], - SustainRate [adsr2 & 0x1f], - (adsr2 >> 5) & 7, 8); - } - } - else - { - // Gain mode - if ((gain & 0x80) == 0) - { - if (S9xSetSoundMode (channel, MODE_GAIN)) - { - S9xSetEnvelopeRate (channel, 0, 0, gain & 0x7f); - S9xSetEnvelopeHeight (channel, gain & 0x7f); - } - } - else - { - static unsigned long IncreaseRate [32] = { - ~0, 4100, 3100, 2600, 2000, 1500, 1300, 1000, - 770, 640, 510, 380, 320, 260, 190, 160, - 130, 96, 80, 64, 48, 40, 32, 24, - 20, 16, 12, 10, 8, 6, 4, 2 - }; - static unsigned long DecreaseRateExp [32] = { - ~0, 38000, 28000, 24000, 19000, 14000, 12000, 9400, - 7100, 5900, 4700, 3500, 2900, 2400, 1800, 1500, - 1200, 880, 740, 590, 440, 370, 290, 220, - 180, 150, 110, 92, 74, 55, 37, 18 - }; - if (gain & 0x40) - { - // Increase mode - if (S9xSetSoundMode (channel, (gain & 0x20) ? -MODE_INCREASE_BENT_LINE : - MODE_INCREASE_LINEAR)) - { - S9xSetEnvelopeRate (channel, IncreaseRate [gain & 0x1f], - 1, 127); - } - } - else - { - uint32 rate = (gain & 0x20) ? DecreaseRateExp [gain & 0x1f] / 2 : - IncreaseRate [gain & 0x1f]; - int mode = (gain & 0x20) ? MODE_DECREASE_EXPONENTIAL - : MODE_DECREASE_LINEAR; - - if (S9xSetSoundMode (channel, mode)) - S9xSetEnvelopeRate (channel, rate, -1, 0); - } - } - } + )) + attack = 0; + + S9xSetSoundADSR(channel, attack, + DecayRate [(adsr1 >> 4) & 7], + SustainRate [adsr2 & 0x1f], + (adsr2 >> 5) & 7, 8); + } + } + else + { + // Gain mode + if ((gain & 0x80) == 0) + { + if (S9xSetSoundMode(channel, MODE_GAIN)) + { + S9xSetEnvelopeRate(channel, 0, 0, gain & 0x7f); + S9xSetEnvelopeHeight(channel, gain & 0x7f); + } + } + else + { + static unsigned long IncreaseRate [32] = + { + ~0, 4100, 3100, 2600, 2000, 1500, 1300, 1000, + 770, 640, 510, 380, 320, 260, 190, 160, + 130, 96, 80, 64, 48, 40, 32, 24, + 20, 16, 12, 10, 8, 6, 4, 2 + }; + static unsigned long DecreaseRateExp [32] = + { + ~0, 38000, 28000, 24000, 19000, 14000, 12000, 9400, + 7100, 5900, 4700, 3500, 2900, 2400, 1800, 1500, + 1200, 880, 740, 590, 440, 370, 290, 220, + 180, 150, 110, 92, 74, 55, 37, 18 + }; + if (gain & 0x40) + { + // Increase mode + if (S9xSetSoundMode(channel, (gain & 0x20) ? + MODE_INCREASE_BENT_LINE : + MODE_INCREASE_LINEAR)) + { + S9xSetEnvelopeRate(channel, IncreaseRate [gain & 0x1f], + 1, 127); + } + } + else + { + uint32 rate = (gain & 0x20) ? DecreaseRateExp [gain & 0x1f] / 2 : + IncreaseRate [gain & 0x1f]; + int mode = (gain & 0x20) ? MODE_DECREASE_EXPONENTIAL + : MODE_DECREASE_LINEAR; + + if (S9xSetSoundMode(channel, mode)) + S9xSetEnvelopeRate(channel, rate, -1, 0); + } + } + } } -void S9xSetAPUControl (uint8 byte) +void S9xSetAPUControl(uint8 byte) { - //if (byte & 0x40) - //printf ("*** Special SPC700 timing enabled\n"); - if ((byte & 1) != 0 && !APU.TimerEnabled [0]) - { - APU.Timer [0] = 0; - IAPU.RAM [0xfd] = 0; - if ((APU.TimerTarget [0] = IAPU.RAM [0xfa]) == 0) - APU.TimerTarget [0] = 0x100; - } - if ((byte & 2) != 0 && !APU.TimerEnabled [1]) - { - APU.Timer [1] = 0; - IAPU.RAM [0xfe] = 0; - if ((APU.TimerTarget [1] = IAPU.RAM [0xfb]) == 0) - APU.TimerTarget [1] = 0x100; - } - if ((byte & 4) != 0 && !APU.TimerEnabled [2]) - { - APU.Timer [2] = 0; - IAPU.RAM [0xff] = 0; - if ((APU.TimerTarget [2] = IAPU.RAM [0xfc]) == 0) - APU.TimerTarget [2] = 0x100; - } - APU.TimerEnabled [0] = byte & 1; - APU.TimerEnabled [1] = (byte & 2) >> 1; - APU.TimerEnabled [2] = (byte & 4) >> 2; - - if (byte & 0x10) - IAPU.RAM [0xF4] = IAPU.RAM [0xF5] = 0; - - if (byte & 0x20) - IAPU.RAM [0xF6] = IAPU.RAM [0xF7] = 0; - - if (byte & 0x80) - { - if (!APU.ShowROM) - { - // memmove converted: Different mallocs [Neb] - // DS2 DMA notes: The APU ROM is not 32-byte aligned [Neb] - memcpy (&IAPU.RAM [0xffc0], APUROM, sizeof (APUROM)); - APU.ShowROM = TRUE; - } - } - else - { - if (APU.ShowROM) - { - APU.ShowROM = FALSE; - // memmove converted: Different mallocs [Neb] - // DS2 DMA notes: The APU ROM is not 32-byte aligned [Neb] - memcpy (&IAPU.RAM [0xffc0], APU.ExtraRAM, sizeof (APUROM)); - } - } - IAPU.RAM [0xf1] = byte; + //if (byte & 0x40) + //printf ("*** Special SPC700 timing enabled\n"); + if ((byte & 1) != 0 && !APU.TimerEnabled [0]) + { + APU.Timer [0] = 0; + IAPU.RAM [0xfd] = 0; + if ((APU.TimerTarget [0] = IAPU.RAM [0xfa]) == 0) + APU.TimerTarget [0] = 0x100; + } + if ((byte & 2) != 0 && !APU.TimerEnabled [1]) + { + APU.Timer [1] = 0; + IAPU.RAM [0xfe] = 0; + if ((APU.TimerTarget [1] = IAPU.RAM [0xfb]) == 0) + APU.TimerTarget [1] = 0x100; + } + if ((byte & 4) != 0 && !APU.TimerEnabled [2]) + { + APU.Timer [2] = 0; + IAPU.RAM [0xff] = 0; + if ((APU.TimerTarget [2] = IAPU.RAM [0xfc]) == 0) + APU.TimerTarget [2] = 0x100; + } + APU.TimerEnabled [0] = byte & 1; + APU.TimerEnabled [1] = (byte & 2) >> 1; + APU.TimerEnabled [2] = (byte & 4) >> 2; + + if (byte & 0x10) + IAPU.RAM [0xF4] = IAPU.RAM [0xF5] = 0; + + if (byte & 0x20) + IAPU.RAM [0xF6] = IAPU.RAM [0xF7] = 0; + + if (byte & 0x80) + { + if (!APU.ShowROM) + { + // memmove converted: Different mallocs [Neb] + // DS2 DMA notes: The APU ROM is not 32-byte aligned [Neb] + memcpy(&IAPU.RAM [0xffc0], APUROM, sizeof(APUROM)); + APU.ShowROM = TRUE; + } + } + else + { + if (APU.ShowROM) + { + APU.ShowROM = FALSE; + // memmove converted: Different mallocs [Neb] + // DS2 DMA notes: The APU ROM is not 32-byte aligned [Neb] + memcpy(&IAPU.RAM [0xffc0], APU.ExtraRAM, sizeof(APUROM)); + } + } + IAPU.RAM [0xf1] = byte; } -void S9xSetAPUTimer (uint16 Address, uint8 byte) +void S9xSetAPUTimer(uint16 Address, uint8 byte) { - IAPU.RAM [Address] = byte; - - switch (Address) - { - case 0xfa: - if ((APU.TimerTarget [0] = IAPU.RAM [0xfa]) == 0) - APU.TimerTarget [0] = 0x100; - APU.TimerValueWritten [0] = TRUE; - break; - case 0xfb: - if ((APU.TimerTarget [1] = IAPU.RAM [0xfb]) == 0) - APU.TimerTarget [1] = 0x100; - APU.TimerValueWritten [1] = TRUE; - break; - case 0xfc: - if ((APU.TimerTarget [2] = IAPU.RAM [0xfc]) == 0) - APU.TimerTarget [2] = 0x100; - APU.TimerValueWritten [2] = TRUE; - break; - } + IAPU.RAM [Address] = byte; + + switch (Address) + { + case 0xfa: + if ((APU.TimerTarget [0] = IAPU.RAM [0xfa]) == 0) + APU.TimerTarget [0] = 0x100; + APU.TimerValueWritten [0] = TRUE; + break; + case 0xfb: + if ((APU.TimerTarget [1] = IAPU.RAM [0xfb]) == 0) + APU.TimerTarget [1] = 0x100; + APU.TimerValueWritten [1] = TRUE; + break; + case 0xfc: + if ((APU.TimerTarget [2] = IAPU.RAM [0xfc]) == 0) + APU.TimerTarget [2] = 0x100; + APU.TimerValueWritten [2] = TRUE; + break; + } } -uint8 S9xGetAPUDSP () +uint8 S9xGetAPUDSP() { - uint8 reg = IAPU.RAM [0xf2] & 0x7f; - uint8 byte = APU.DSP [reg]; - - switch (reg) - { - case APU_KON: - break; - case APU_KOFF: - break; - case APU_OUTX + 0x00: - case APU_OUTX + 0x10: - case APU_OUTX + 0x20: - case APU_OUTX + 0x30: - case APU_OUTX + 0x40: - case APU_OUTX + 0x50: - case APU_OUTX + 0x60: - case APU_OUTX + 0x70: - if (SoundData.channels [reg >> 4].state == SOUND_SILENT) - return (0); - return ((SoundData.channels [reg >> 4].sample >> 8) | - (SoundData.channels [reg >> 4].sample & 0xff)); - - case APU_ENVX + 0x00: - case APU_ENVX + 0x10: - case APU_ENVX + 0x20: - case APU_ENVX + 0x30: - case APU_ENVX + 0x40: - case APU_ENVX + 0x50: - case APU_ENVX + 0x60: - case APU_ENVX + 0x70: - return ((uint8) S9xGetEnvelopeHeight (reg >> 4)); - - case APU_ENDX: - // To fix speech in Magical Drop 2 6/11/00 - // APU.DSP [APU_ENDX] = 0; - break; - default: - break; - } - return (byte); + uint8 reg = IAPU.RAM [0xf2] & 0x7f; + uint8 byte = APU.DSP [reg]; + + switch (reg) + { + case APU_KON: + break; + case APU_KOFF: + break; + case APU_OUTX + 0x00: + case APU_OUTX + 0x10: + case APU_OUTX + 0x20: + case APU_OUTX + 0x30: + case APU_OUTX + 0x40: + case APU_OUTX + 0x50: + case APU_OUTX + 0x60: + case APU_OUTX + 0x70: + if (SoundData.channels [reg >> 4].state == SOUND_SILENT) + return (0); + return ((SoundData.channels [reg >> 4].sample >> 8) | + (SoundData.channels [reg >> 4].sample & 0xff)); + + case APU_ENVX + 0x00: + case APU_ENVX + 0x10: + case APU_ENVX + 0x20: + case APU_ENVX + 0x30: + case APU_ENVX + 0x40: + case APU_ENVX + 0x50: + case APU_ENVX + 0x60: + case APU_ENVX + 0x70: + return ((uint8) S9xGetEnvelopeHeight(reg >> 4)); + + case APU_ENDX: + // To fix speech in Magical Drop 2 6/11/00 + // APU.DSP [APU_ENDX] = 0; + break; + default: + break; + } + return (byte); } diff --git a/source/apu.h b/source/apu.h index 847a2a8..0311c7f 100644 --- a/source/apu.h +++ b/source/apu.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -94,39 +94,39 @@ typedef struct { - uint8 *PC; - SAPURegisters Registers; - uint8 *RAM; - uint8 *DirectPage; - bool8 APUExecuting; - uint8 Bit; - uint32 Address; - uint8 *WaitAddress1; - uint8 *WaitAddress2; - uint32 WaitCounter; - uint8 _Carry; - uint8 _Zero; - uint8 _Overflow; - uint32 TimerErrorCounter; - uint32 Scanline; - int32 OneCycle; - int32 TwoCycles; -}SIAPU; + uint8* PC; + SAPURegisters Registers; + uint8* RAM; + uint8* DirectPage; + bool8 APUExecuting; + uint8 Bit; + uint32 Address; + uint8* WaitAddress1; + uint8* WaitAddress2; + uint32 WaitCounter; + uint8 _Carry; + uint8 _Zero; + uint8 _Overflow; + uint32 TimerErrorCounter; + uint32 Scanline; + int32 OneCycle; + int32 TwoCycles; +} SIAPU; typedef struct { - int32 Cycles; - bool8 ShowROM; - uint8 Flags; - uint8 KeyedChannels; - uint8 OutPorts [4]; - uint8 DSP [0x80]; - uint8 ExtraRAM [64]; - uint16 Timer [3]; - uint16 TimerTarget [3]; - bool8 TimerEnabled [3]; - bool8 TimerValueWritten [3]; -}SAPU; + int32 Cycles; + bool8 ShowROM; + uint8 Flags; + uint8 KeyedChannels; + uint8 OutPorts [4]; + uint8 DSP [0x80]; + uint8 ExtraRAM [64]; + uint16 Timer [3]; + uint16 TimerTarget [3]; + bool8 TimerEnabled [3]; + bool8 TimerValueWritten [3]; +} SAPU; SAPU APU; SIAPU IAPU; @@ -135,34 +135,34 @@ extern int spc_is_dumping_temp; extern uint8 spc_dump_dsp[0x100]; STATIC inline void S9xAPUUnpackStatus() { - IAPU._Zero = ((IAPU.Registers.P & Zero) == 0) | (IAPU.Registers.P & Negative); - IAPU._Carry = (IAPU.Registers.P & Carry); - IAPU._Overflow = (IAPU.Registers.P & Overflow) >> 6; + IAPU._Zero = ((IAPU.Registers.P & Zero) == 0) | (IAPU.Registers.P & Negative); + IAPU._Carry = (IAPU.Registers.P & Carry); + IAPU._Overflow = (IAPU.Registers.P & Overflow) >> 6; } STATIC inline void S9xAPUPackStatus() { - IAPU.Registers.P &= ~(Zero | Negative | Carry | Overflow); - IAPU.Registers.P |= IAPU._Carry | ((IAPU._Zero == 0) << 1) | - (IAPU._Zero & 0x80) | (IAPU._Overflow << 6); + IAPU.Registers.P &= ~(Zero | Negative | Carry | Overflow); + IAPU.Registers.P |= IAPU._Carry | ((IAPU._Zero == 0) << 1) | + (IAPU._Zero & 0x80) | (IAPU._Overflow << 6); } -void S9xResetAPU (void); -bool8 S9xInitAPU (); -void S9xDeinitAPU (); -void S9xDecacheSamples (); -int S9xTraceAPU (); -int S9xAPUOPrint (char *buffer, uint16 Address); -void S9xSetAPUControl (uint8 byte); -void S9xSetAPUDSP (uint8 byte); -uint8 S9xGetAPUDSP (); -void S9xSetAPUTimer (uint16 Address, uint8 byte); -bool8 S9xInitSound (int quality, bool8 stereo, int buffer_size); -void S9xOpenCloseSoundTracingFile (bool8); -void S9xPrintAPUState (); -extern uint16 S9xAPUCycles [256]; // Scaled cycle lengths -extern uint16 S9xAPUCycleLengths [256]; // Raw data. -extern void (*S9xApuOpcodes [256]) (void); +void S9xResetAPU(void); +bool8 S9xInitAPU(); +void S9xDeinitAPU(); +void S9xDecacheSamples(); +int S9xTraceAPU(); +int S9xAPUOPrint(char* buffer, uint16 Address); +void S9xSetAPUControl(uint8 byte); +void S9xSetAPUDSP(uint8 byte); +uint8 S9xGetAPUDSP(); +void S9xSetAPUTimer(uint16 Address, uint8 byte); +bool8 S9xInitSound(int quality, bool8 stereo, int buffer_size); +void S9xOpenCloseSoundTracingFile(bool8); +void S9xPrintAPUState(); +extern uint16 S9xAPUCycles [256]; // Scaled cycle lengths +extern uint16 S9xAPUCycleLengths [256]; // Raw data. +extern void (*S9xApuOpcodes [256])(void); #define APU_VOL_LEFT 0x00 diff --git a/source/apumem.h b/source/apumem.h index 4d79cf6..686126c 100644 --- a/source/apumem.h +++ b/source/apumem.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -93,154 +93,146 @@ extern uint8 W4; extern uint8 APUROM[64]; -uint8 S9xAPUGetByteZ (uint8 Address) +uint8 S9xAPUGetByteZ(uint8 Address) { - if (Address >= 0xf0 && IAPU.DirectPage == IAPU.RAM) - { - if (Address >= 0xf4 && Address <= 0xf7) - { + if (Address >= 0xf0 && IAPU.DirectPage == IAPU.RAM) + { + if (Address >= 0xf4 && Address <= 0xf7) + { #ifdef SPC700_SHUTDOWN - IAPU.WaitAddress2 = IAPU.WaitAddress1; - IAPU.WaitAddress1 = IAPU.PC; -#endif - return (IAPU.RAM [Address]); - } - if (Address >= 0xfd) - { + IAPU.WaitAddress2 = IAPU.WaitAddress1; + IAPU.WaitAddress1 = IAPU.PC; +#endif + return (IAPU.RAM [Address]); + } + if (Address >= 0xfd) + { #ifdef SPC700_SHUTDOWN - IAPU.WaitAddress2 = IAPU.WaitAddress1; - IAPU.WaitAddress1 = IAPU.PC; -#endif - uint8 t = IAPU.RAM [Address]; - IAPU.RAM [Address] = 0; - return (t); - } - else - if (Address == 0xf3) - return (S9xGetAPUDSP ()); - - return (IAPU.RAM [Address]); - } - else - return (IAPU.DirectPage [Address]); + IAPU.WaitAddress2 = IAPU.WaitAddress1; + IAPU.WaitAddress1 = IAPU.PC; +#endif + uint8 t = IAPU.RAM [Address]; + IAPU.RAM [Address] = 0; + return (t); + } + else if (Address == 0xf3) + return (S9xGetAPUDSP()); + + return (IAPU.RAM [Address]); + } + else + return (IAPU.DirectPage [Address]); } -void S9xAPUSetByteZ (uint8 byte, uint8 Address) +void S9xAPUSetByteZ(uint8 byte, uint8 Address) { - if (Address >= 0xf0 && IAPU.DirectPage == IAPU.RAM) - { - if (Address == 0xf3) - S9xSetAPUDSP (byte); - else - if (Address >= 0xf4 && Address <= 0xf7) - APU.OutPorts [Address - 0xf4] = byte; - else - if (Address == 0xf1) - S9xSetAPUControl (byte); - else - if (Address < 0xfd) - { - IAPU.RAM [Address] = byte; - if (Address >= 0xfa) - { - if (byte == 0) - APU.TimerTarget [Address - 0xfa] = 0x100; - else - APU.TimerTarget [Address - 0xfa] = byte; - } - } - } - else - IAPU.DirectPage [Address] = byte; + if (Address >= 0xf0 && IAPU.DirectPage == IAPU.RAM) + { + if (Address == 0xf3) + S9xSetAPUDSP(byte); + else if (Address >= 0xf4 && Address <= 0xf7) + APU.OutPorts [Address - 0xf4] = byte; + else if (Address == 0xf1) + S9xSetAPUControl(byte); + else if (Address < 0xfd) + { + IAPU.RAM [Address] = byte; + if (Address >= 0xfa) + { + if (byte == 0) + APU.TimerTarget [Address - 0xfa] = 0x100; + else + APU.TimerTarget [Address - 0xfa] = byte; + } + } + } + else + IAPU.DirectPage [Address] = byte; } -uint8 S9xAPUGetByte (uint32 Address) +uint8 S9xAPUGetByte(uint32 Address) { - Address &= 0xffff; - - if (Address <= 0xff && Address >= 0xf0) - { - if (Address >= 0xf4 && Address <= 0xf7) - { + Address &= 0xffff; + + if (Address <= 0xff && Address >= 0xf0) + { + if (Address >= 0xf4 && Address <= 0xf7) + { #ifdef SPC700_SHUTDOWN - IAPU.WaitAddress2 = IAPU.WaitAddress1; - IAPU.WaitAddress1 = IAPU.PC; -#endif - return (IAPU.RAM [Address]); - } - else - if (Address == 0xf3) - return (S9xGetAPUDSP ()); - if (Address >= 0xfd) - { + IAPU.WaitAddress2 = IAPU.WaitAddress1; + IAPU.WaitAddress1 = IAPU.PC; +#endif + return (IAPU.RAM [Address]); + } + else if (Address == 0xf3) + return (S9xGetAPUDSP()); + if (Address >= 0xfd) + { #ifdef SPC700_SHUTDOWN - IAPU.WaitAddress2 = IAPU.WaitAddress1; - IAPU.WaitAddress1 = IAPU.PC; + IAPU.WaitAddress2 = IAPU.WaitAddress1; + IAPU.WaitAddress1 = IAPU.PC; #endif - uint8 t = IAPU.RAM [Address]; - IAPU.RAM [Address] = 0; - return (t); - } - return (IAPU.RAM [Address]); - } - else - return (IAPU.RAM [Address]); + uint8 t = IAPU.RAM [Address]; + IAPU.RAM [Address] = 0; + return (t); + } + return (IAPU.RAM [Address]); + } + else + return (IAPU.RAM [Address]); } -void S9xAPUSetByte (uint8 byte, uint32 Address) +void S9xAPUSetByte(uint8 byte, uint32 Address) { - Address &= 0xffff; - - if (Address <= 0xff && Address >= 0xf0) - { - if (Address == 0xf3) - S9xSetAPUDSP (byte); - else - if (Address >= 0xf4 && Address <= 0xf7) - APU.OutPorts [Address - 0xf4] = byte; - else - if (Address == 0xf1) - S9xSetAPUControl (byte); - else - if (Address < 0xfd) - { - IAPU.RAM [Address] = byte; - if (Address >= 0xfa) - { - if (byte == 0) - APU.TimerTarget [Address - 0xfa] = 0x100; - else - APU.TimerTarget [Address - 0xfa] = byte; - } - } - } - else - { + Address &= 0xffff; + + if (Address <= 0xff && Address >= 0xf0) + { + if (Address == 0xf3) + S9xSetAPUDSP(byte); + else if (Address >= 0xf4 && Address <= 0xf7) + APU.OutPorts [Address - 0xf4] = byte; + else if (Address == 0xf1) + S9xSetAPUControl(byte); + else if (Address < 0xfd) + { + IAPU.RAM [Address] = byte; + if (Address >= 0xfa) + { + if (byte == 0) + APU.TimerTarget [Address - 0xfa] = 0x100; + else + APU.TimerTarget [Address - 0xfa] = byte; + } + } + } + else + { #if 0 -if (Address >= 0x2500 && Address <= 0x2504) -printf ("%06d %04x <- %02x\n", ICPU.Scanline, Address, byte); -if (Address == 0x26c6) -{ - extern FILE *apu_trace; - extern FILE *trace; - APU.Flags |= TRACE_FLAG; - CPU.Flags |= TRACE_FLAG; - if (apu_trace == NULL) - apu_trace = fopen ("aputrace.log", "wb"); - if (trace == NULL) - trace = fopen ("trace.log", "wb"); - printf ("TRACING SWITCHED ON\n"); -} + if (Address >= 0x2500 && Address <= 0x2504) + printf("%06d %04x <- %02x\n", ICPU.Scanline, Address, byte); + if (Address == 0x26c6) + { + extern FILE* apu_trace; + extern FILE* trace; + APU.Flags |= TRACE_FLAG; + CPU.Flags |= TRACE_FLAG; + if (apu_trace == NULL) + apu_trace = fopen("aputrace.log", "wb"); + if (trace == NULL) + trace = fopen("trace.log", "wb"); + printf("TRACING SWITCHED ON\n"); + } #endif - if (Address < 0xffc0) - IAPU.RAM [Address] = byte; - else - { - APU.ExtraRAM [Address - 0xffc0] = byte; - if (!APU.ShowROM) - IAPU.RAM [Address] = byte; - } - } + if (Address < 0xffc0) + IAPU.RAM [Address] = byte; + else + { + APU.ExtraRAM [Address - 0xffc0] = byte; + if (!APU.ShowROM) + IAPU.RAM [Address] = byte; + } + } } #endif diff --git a/source/c4.c b/source/c4.c index cda3e11..0a48c0b 100644 --- a/source/c4.c +++ b/source/c4.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -104,85 +104,85 @@ static double tanval; static double c4x, c4y, c4z; static double c4x2, c4y2, c4z2; -void C4TransfWireFrame () +void C4TransfWireFrame() { - c4x = (double) C4WFXVal; - c4y = (double) C4WFYVal; - c4z = (double) C4WFZVal - 0x95; - - // Rotate X - tanval = -(double) C4WFX2Val * 3.14159265 * 2 / 128; - c4y2 = c4y * cos (tanval) - c4z * sin (tanval); - c4z2 = c4y * sin (tanval) + c4z * cos (tanval); - - // Rotate Y - tanval = -(double)C4WFY2Val*3.14159265*2/128; - c4x2 = c4x * cos (tanval) + c4z2 * sin (tanval); - c4z = c4x * - sin (tanval) + c4z2 * cos (tanval); - - // Rotate Z - tanval = -(double) C4WFDist * 3.14159265*2 / 128; - c4x = c4x2 * cos (tanval) - c4y2 * sin (tanval); - c4y = c4x2 * sin (tanval) + c4y2 * cos (tanval); - - // Scale - C4WFXVal = (short) (c4x*(double)C4WFScale/(0x90*(c4z+0x95))*0x95); - C4WFYVal = (short) (c4y*(double)C4WFScale/(0x90*(c4z+0x95))*0x95); + c4x = (double) C4WFXVal; + c4y = (double) C4WFYVal; + c4z = (double) C4WFZVal - 0x95; + + // Rotate X + tanval = -(double) C4WFX2Val * 3.14159265 * 2 / 128; + c4y2 = c4y * cos(tanval) - c4z * sin(tanval); + c4z2 = c4y * sin(tanval) + c4z * cos(tanval); + + // Rotate Y + tanval = -(double)C4WFY2Val * 3.14159265 * 2 / 128; + c4x2 = c4x * cos(tanval) + c4z2 * sin(tanval); + c4z = c4x * - sin(tanval) + c4z2 * cos(tanval); + + // Rotate Z + tanval = -(double) C4WFDist * 3.14159265 * 2 / 128; + c4x = c4x2 * cos(tanval) - c4y2 * sin(tanval); + c4y = c4x2 * sin(tanval) + c4y2 * cos(tanval); + + // Scale + C4WFXVal = (short)(c4x * (double)C4WFScale / (0x90 * (c4z + 0x95)) * 0x95); + C4WFYVal = (short)(c4y * (double)C4WFScale / (0x90 * (c4z + 0x95)) * 0x95); } -void C4TransfWireFrame2 () +void C4TransfWireFrame2() { - c4x = (double)C4WFXVal; - c4y = (double)C4WFYVal; - c4z = (double)C4WFZVal; - - // Rotate X - tanval = -(double) C4WFX2Val * 3.14159265 * 2 / 128; - c4y2 = c4y * cos (tanval) - c4z * sin (tanval); - c4z2 = c4y * sin (tanval) + c4z * cos (tanval); - - // Rotate Y - tanval = -(double) C4WFY2Val * 3.14159265 * 2 / 128; - c4x2 = c4x * cos (tanval) + c4z2 * sin (tanval); - c4z = c4x * -sin (tanval) + c4z2 * cos (tanval); - - // Rotate Z - tanval = -(double)C4WFDist * 3.14159265 * 2 / 128; - c4x = c4x2 * cos (tanval) - c4y2 * sin (tanval); - c4y = c4x2 * sin (tanval) + c4y2 * cos (tanval); - - // Scale - C4WFXVal =(short)(c4x * (double)C4WFScale / 0x100); - C4WFYVal =(short)(c4y * (double)C4WFScale / 0x100); + c4x = (double)C4WFXVal; + c4y = (double)C4WFYVal; + c4z = (double)C4WFZVal; + + // Rotate X + tanval = -(double) C4WFX2Val * 3.14159265 * 2 / 128; + c4y2 = c4y * cos(tanval) - c4z * sin(tanval); + c4z2 = c4y * sin(tanval) + c4z * cos(tanval); + + // Rotate Y + tanval = -(double) C4WFY2Val * 3.14159265 * 2 / 128; + c4x2 = c4x * cos(tanval) + c4z2 * sin(tanval); + c4z = c4x * -sin(tanval) + c4z2 * cos(tanval); + + // Rotate Z + tanval = -(double)C4WFDist * 3.14159265 * 2 / 128; + c4x = c4x2 * cos(tanval) - c4y2 * sin(tanval); + c4y = c4x2 * sin(tanval) + c4y2 * cos(tanval); + + // Scale + C4WFXVal = (short)(c4x * (double)C4WFScale / 0x100); + C4WFYVal = (short)(c4y * (double)C4WFScale / 0x100); } -void C4CalcWireFrame () +void C4CalcWireFrame() { - C4WFXVal = C4WFX2Val - C4WFXVal; - C4WFYVal = C4WFY2Val - C4WFYVal; - if (abs (C4WFXVal) > abs (C4WFYVal)) - { - C4WFDist = abs (C4WFXVal) + 1; - C4WFYVal = (short) (256 * (double) C4WFYVal / abs (C4WFXVal)); - if (C4WFXVal < 0) - C4WFXVal = -256; - else - C4WFXVal = 256; - } - else - { - if (C4WFYVal != 0) - { - C4WFDist = abs(C4WFYVal)+1; - C4WFXVal = (short) (256 * (double)C4WFXVal / abs (C4WFYVal)); - if (C4WFYVal < 0) - C4WFYVal = -256; - else - C4WFYVal = 256; - } - else - C4WFDist = 0; - } + C4WFXVal = C4WFX2Val - C4WFXVal; + C4WFYVal = C4WFY2Val - C4WFYVal; + if (abs(C4WFXVal) > abs(C4WFYVal)) + { + C4WFDist = abs(C4WFXVal) + 1; + C4WFYVal = (short)(256 * (double) C4WFYVal / abs(C4WFXVal)); + if (C4WFXVal < 0) + C4WFXVal = -256; + else + C4WFXVal = 256; + } + else + { + if (C4WFYVal != 0) + { + C4WFDist = abs(C4WFYVal) + 1; + C4WFXVal = (short)(256 * (double)C4WFXVal / abs(C4WFYVal)); + if (C4WFYVal < 0) + C4WFYVal = -256; + else + C4WFYVal = 256; + } + else + C4WFDist = 0; + } } short C41FXVal; @@ -191,46 +191,46 @@ short C41FAngleRes; short C41FDist; short C41FDistVal; -void C4Op1F () +void C4Op1F() { - if (C41FXVal == 0) - { - if (C41FYVal > 0) - C41FAngleRes = 0x80; - else - C41FAngleRes = 0x180; - } - else - { - tanval = (double) C41FYVal / C41FXVal; - C41FAngleRes = (short) (atan (tanval) / (3.141592675 * 2) * 512); - C41FAngleRes = C41FAngleRes; - if (C41FXVal< 0) - C41FAngleRes += 0x100; - C41FAngleRes &= 0x1FF; - } + if (C41FXVal == 0) + { + if (C41FYVal > 0) + C41FAngleRes = 0x80; + else + C41FAngleRes = 0x180; + } + else + { + tanval = (double) C41FYVal / C41FXVal; + C41FAngleRes = (short)(atan(tanval) / (3.141592675 * 2) * 512); + C41FAngleRes = C41FAngleRes; + if (C41FXVal < 0) + C41FAngleRes += 0x100; + C41FAngleRes &= 0x1FF; + } } void C4Op15() { - tanval = sqrt ((double) C41FYVal * C41FYVal + (double) C41FXVal * C41FXVal); - C41FDist = (short) tanval; + tanval = sqrt((double) C41FYVal * C41FYVal + (double) C41FXVal * C41FXVal); + C41FDist = (short) tanval; } void C4Op0D() { - tanval = sqrt ((double) C41FYVal * C41FYVal + (double) C41FXVal * C41FXVal); - tanval = C41FDistVal / tanval; - C41FYVal = (short) (C41FYVal * tanval * 0.99); - C41FXVal = (short) (C41FXVal * tanval * 0.98); + tanval = sqrt((double) C41FYVal * C41FYVal + (double) C41FXVal * C41FXVal); + tanval = C41FDistVal / tanval; + C41FYVal = (short)(C41FYVal * tanval * 0.99); + C41FXVal = (short)(C41FXVal * tanval * 0.98); } #ifdef ZSNES_C4 -void C4LoaDMem(char *C4RAM) +void C4LoaDMem(char* C4RAM) { - memmove(C4RAM+(READ_WORD(C4RAM+0x1f45)&0x1fff), - S9xGetMemPointer(READ_3WORD(C4RAM+0x1f40)), - READ_WORD(C4RAM+0x1f43)); + memmove(C4RAM + (READ_WORD(C4RAM + 0x1f45) & 0x1fff), + S9xGetMemPointer(READ_3WORD(C4RAM + 0x1f40)), + READ_WORD(C4RAM + 0x1f43)); } #endif diff --git a/source/c4.h b/source/c4.h index 4f73f13..ba67c84 100644 --- a/source/c4.h +++ b/source/c4.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ diff --git a/source/c4emu.c b/source/c4emu.c index ef37e9c..0b87bfe 100644 --- a/source/c4emu.c +++ b/source/c4emu.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,51 +43,51 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ #ifdef HAVE_CONFIG_H - #include +#include #endif #include #include "snes9x.h" @@ -96,807 +96,861 @@ #include "ppu.h" #include "c4.h" -void S9xInitC4 () +void S9xInitC4() { - // Stupid zsnes code, we can't do the logical thing without breaking - // savestates -// Memory.C4RAM = &Memory.FillRAM [0x6000]; - memset(Memory.C4RAM, 0, 0x2000); + // Stupid zsnes code, we can't do the logical thing without breaking + // savestates + // Memory.C4RAM = &Memory.FillRAM [0x6000]; + memset(Memory.C4RAM, 0, 0x2000); } -uint8 S9xGetC4 (uint16 Address) +uint8 S9xGetC4(uint16 Address) { - return (Memory.C4RAM [Address-0x6000]); + return (Memory.C4RAM [Address - 0x6000]); } static uint8 C4TestPattern [12 * 4] = { - 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0x00, 0xff, - 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, - 0x80, 0xff, 0xff, 0x7f, - 0x00, 0x80, 0x00, 0xff, - 0x7f, 0x00, 0xff, 0x7f, - 0xff, 0x7f, 0xff, 0xff, - 0x00, 0x00, 0x01, 0xff, - 0xff, 0xfe, 0x00, 0x01, - 0x00, 0xff, 0xfe, 0x00 + 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, + 0x80, 0xff, 0xff, 0x7f, + 0x00, 0x80, 0x00, 0xff, + 0x7f, 0x00, 0xff, 0x7f, + 0xff, 0x7f, 0xff, 0xff, + 0x00, 0x00, 0x01, 0xff, + 0xff, 0xfe, 0x00, 0x01, + 0x00, 0xff, 0xfe, 0x00 }; -static void C4ConvOAM(void){ - uint8 *i; - uint8 *OAMptr=Memory.C4RAM+(Memory.C4RAM[0x626]<<2); - for(i=Memory.C4RAM+0x1fd; i>OAMptr; i-=4){ - // Clear OAM-to-be - *i=0xe0; - } - - uint16 globalX, globalY; - uint8 *OAMptr2; - int16 SprX, SprY; - uint8 SprName, SprAttr; - uint8 SprCount; - - globalX=READ_WORD(Memory.C4RAM+0x0621); - globalY=READ_WORD(Memory.C4RAM+0x0623); - OAMptr2=Memory.C4RAM+0x200+(Memory.C4RAM[0x626]>>2); - - if(Memory.C4RAM[0x0620]!=0){ - int prio,i; - SprCount=128-Memory.C4RAM[0x626]; - uint8 offset=(Memory.C4RAM[0x626]&3)*2; - for(prio=0x30; prio>=0; prio-=0x10){ - uint8 *srcptr=Memory.C4RAM+0x220; - for(i=Memory.C4RAM[0x0620]; i>0 && SprCount>0; i--, srcptr+=16){ - if((srcptr[4]&0x30)!=prio) continue; - SprX=READ_WORD(srcptr)-globalX; - SprY=READ_WORD(srcptr+2)-globalY; - SprName=srcptr[5]; - SprAttr=srcptr[4] | srcptr[0x06]; // XXX: mask bits? - - uint8 *sprptr=S9xGetMemPointer(READ_3WORD(srcptr+7)); - if(*sprptr!=0){ - int SprCnt; - int16 X, Y; - for(SprCnt=*sprptr++; SprCnt>0 && SprCount>0; SprCnt--, sprptr+=4){ - X=(int8)sprptr[1]; - if(SprAttr&0x40){ // flip X - X=-X-((sprptr[0]&0x20)?16:8); - } - X+=SprX; - if(X>=-16 && X<=272){ - Y=(int8)sprptr[2]; - if(SprAttr&0x80){ - Y=-Y-((sprptr[0]&0x20)?16:8); - } - Y+=SprY; - if(Y>=-16 && Y<=224){ - OAMptr[0]=X&0xff; - OAMptr[1]=(uint8)Y; - OAMptr[2]=SprName+sprptr[3]; - OAMptr[3]=SprAttr^(sprptr[0]&0xc0); // XXX: Carry from SprName addition? - *OAMptr2 &= ~(3<0){ - OAMptr[0]=(uint8)SprX; - OAMptr[1]=(uint8)SprY; - OAMptr[2]=SprName; - OAMptr[3]=SprAttr; - *OAMptr2 &= ~(3< OAMptr; i -= 4) + { + // Clear OAM-to-be + *i = 0xe0; + } + + uint16 globalX, globalY; + uint8* OAMptr2; + int16 SprX, SprY; + uint8 SprName, SprAttr; + uint8 SprCount; + + globalX = READ_WORD(Memory.C4RAM + 0x0621); + globalY = READ_WORD(Memory.C4RAM + 0x0623); + OAMptr2 = Memory.C4RAM + 0x200 + (Memory.C4RAM[0x626] >> 2); + + if (Memory.C4RAM[0x0620] != 0) + { + int prio, i; + SprCount = 128 - Memory.C4RAM[0x626]; + uint8 offset = (Memory.C4RAM[0x626] & 3) * 2; + for (prio = 0x30; prio >= 0; prio -= 0x10) + { + uint8* srcptr = Memory.C4RAM + 0x220; + for (i = Memory.C4RAM[0x0620]; i > 0 && SprCount > 0; i--, srcptr += 16) + { + if ((srcptr[4] & 0x30) != prio) continue; + SprX = READ_WORD(srcptr) - globalX; + SprY = READ_WORD(srcptr + 2) - globalY; + SprName = srcptr[5]; + SprAttr = srcptr[4] | srcptr[0x06]; // XXX: mask bits? + + uint8* sprptr = S9xGetMemPointer(READ_3WORD(srcptr + 7)); + if (*sprptr != 0) + { + int SprCnt; + int16 X, Y; + for (SprCnt = *sprptr++; SprCnt > 0 && SprCount > 0; SprCnt--, sprptr += 4) + { + X = (int8)sprptr[1]; + if (SprAttr & 0x40) // flip X + X = -X - ((sprptr[0] & 0x20) ? 16 : 8); + X += SprX; + if (X >= -16 && X <= 272) + { + Y = (int8)sprptr[2]; + if (SprAttr & 0x80) + Y = -Y - ((sprptr[0] & 0x20) ? 16 : 8); + Y += SprY; + if (Y >= -16 && Y <= 224) + { + OAMptr[0] = X & 0xff; + OAMptr[1] = (uint8)Y; + OAMptr[2] = SprName + sprptr[3]; + OAMptr[3] = SprAttr ^ (sprptr[0] & 0xc0); // XXX: Carry from SprName addition? + *OAMptr2 &= ~(3 << offset); + if (X & 0x100) *OAMptr2 |= 1 << offset; + if (sprptr[0] & 0x20) *OAMptr2 |= 2 << offset; + OAMptr += 4; + SprCount--; + offset = (offset + 2) & 6; + if (offset == 0) OAMptr2++; + } + } + } } - } - } - // XXX: Copy to OAM? I doubt it. -} - -static void C4DoScaleRotate(int row_padding){ - int16 A, B, C, D; - - // Calculate matrix - int32 XScale=READ_WORD(Memory.C4RAM+0x1f8f); - if(XScale&0x8000) XScale=0x7fff; - int32 YScale=READ_WORD(Memory.C4RAM+0x1f92); - if(YScale&0x8000) YScale=0x7fff; - - if(READ_WORD(Memory.C4RAM+0x1f80)==0) - { // no rotation - // XXX: only do this for C and D? - // XXX: and then only when YScale is 0x1000? - A=(int16)XScale; - B=0; - C=0; - D=(int16)YScale; - } - else if(READ_WORD(Memory.C4RAM+0x1f80)==128){ // 90 degree rotation - // XXX: Really do this? - A=0; - B=(int16)(-YScale); - C=(int16)XScale; - D=0; - } else if(READ_WORD(Memory.C4RAM+0x1f80)==256){ // 180 degree rotation - // XXX: Really do this? - A=(int16)(-XScale); - B=0; - C=0; - D=(int16)(-YScale); - } else if(READ_WORD(Memory.C4RAM+0x1f80)==384){ // 270 degree rotation - // XXX: Really do this? - A=0; - B=(int16)YScale; - C=(int16)(-XScale); - D=0; - } else { - A=(int16)SAR16(C4CosTable[READ_WORD(Memory.C4RAM+0x1f80)&0x1ff]*XScale, 15); - B=(int16)(-SAR16(C4SinTable[READ_WORD(Memory.C4RAM+0x1f80)&0x1ff]*YScale, 15)); - C=(int16)SAR16(C4SinTable[READ_WORD(Memory.C4RAM+0x1f80)&0x1ff]*XScale, 15); - D=(int16)SAR16(C4CosTable[READ_WORD(Memory.C4RAM+0x1f80)&0x1ff]*YScale, 15); - } - - // Calculate Pixel Resolution - uint8 w=Memory.C4RAM[0x1f89]&~7; - uint8 h=Memory.C4RAM[0x1f8c]&~7; - -// printf("%dx%d XScale=%04x YScale=%04x angle=%03x\n", w, h, XScale, YScale, READ_WORD(Memory.C4RAM+0x1f80)&0x1ff); -// printf("Matrix: [%10g %10g] [%04x %04x]\n", A/4096.0, B/4096.0, A&0xffff, B&0xffff); -// printf(" [%10g %10g] [%04x %04x]\n", C/4096.0, D/4096.0, C&0xffff, D&0xffff); - - // Clear the output RAM - memset(Memory.C4RAM, 0, (w+row_padding/4)*h/2); - - int32 Cx=(int16)READ_WORD(Memory.C4RAM+0x1f83); - int32 Cy=(int16)READ_WORD(Memory.C4RAM+0x1f86); - - // Calculate start position (i.e. (Ox, Oy) = (0, 0)) - // The low 12 bits are fractional, so (Cx<<12) gives us the Cx we want in - // the function. We do Cx*A etc normally because the matrix parameters - // already have the fractional parts. - int32 LineX=(Cx<<12) - Cx*A - Cx*B; - int32 LineY=(Cy<<12) - Cy*C - Cy*D; - - // Start loop - uint32 X, Y; - uint8 byte; - int outidx=0; - int x,y; - uint8 bit=0x80; - for(y=0; y>12)>=w || (Y>>12)>=h){ - byte=0; - } else { - uint32 addr=(Y>>12)*w+(X>>12); - byte=Memory.C4RAM[0x600+(addr>>1)]; - if(addr&1) byte>>=4; + else if (SprCount > 0) + { + OAMptr[0] = (uint8)SprX; + OAMptr[1] = (uint8)SprY; + OAMptr[2] = SprName; + OAMptr[3] = SprAttr; + *OAMptr2 &= ~(3 << offset); + if (SprX & 0x100) *OAMptr2 |= 3 << offset; + else *OAMptr2 |= 2 << offset; + OAMptr += 4; + SprCount--; + offset = (offset + 2) & 6; + if (offset == 0) OAMptr2++; } + } + } + } + // XXX: Copy to OAM? I doubt it. +} - // De-bitplanify - if(byte&1) Memory.C4RAM[outidx]|=bit; - if(byte&2) Memory.C4RAM[outidx+1]|=bit; - if(byte&4) Memory.C4RAM[outidx+16]|=bit; - if(byte&8) Memory.C4RAM[outidx+17]|=bit; - - bit>>=1; - if(bit==0){ - bit=0x80; - outidx+=32; - } - - X+=A; // Add 1 to output x => add an A and a C - Y+=C; - } - outidx+=2+row_padding; - if(outidx&0x10){ - outidx&=~0x10; - } else { - outidx-=w*4+row_padding; - } - LineX+=B; // Add 1 to output y => add a B and a D - LineY+=D; - } +static void C4DoScaleRotate(int row_padding) +{ + int16 A, B, C, D; + + // Calculate matrix + int32 XScale = READ_WORD(Memory.C4RAM + 0x1f8f); + if (XScale & 0x8000) XScale = 0x7fff; + int32 YScale = READ_WORD(Memory.C4RAM + 0x1f92); + if (YScale & 0x8000) YScale = 0x7fff; + + if (READ_WORD(Memory.C4RAM + 0x1f80) == 0) + { + // no rotation + // XXX: only do this for C and D? + // XXX: and then only when YScale is 0x1000? + A = (int16)XScale; + B = 0; + C = 0; + D = (int16)YScale; + } + else if (READ_WORD(Memory.C4RAM + 0x1f80) == 128) // 90 degree rotation + { + // XXX: Really do this? + A = 0; + B = (int16)(-YScale); + C = (int16)XScale; + D = 0; + } + else if (READ_WORD(Memory.C4RAM + 0x1f80) == 256) // 180 degree rotation + { + // XXX: Really do this? + A = (int16)(-XScale); + B = 0; + C = 0; + D = (int16)(-YScale); + } + else if (READ_WORD(Memory.C4RAM + 0x1f80) == 384) // 270 degree rotation + { + // XXX: Really do this? + A = 0; + B = (int16)YScale; + C = (int16)(-XScale); + D = 0; + } + else + { + A = (int16)SAR16(C4CosTable[READ_WORD(Memory.C4RAM + 0x1f80) & 0x1ff] * XScale, + 15); + B = (int16)(-SAR16(C4SinTable[READ_WORD(Memory.C4RAM + 0x1f80) & 0x1ff] * + YScale, 15)); + C = (int16)SAR16(C4SinTable[READ_WORD(Memory.C4RAM + 0x1f80) & 0x1ff] * XScale, + 15); + D = (int16)SAR16(C4CosTable[READ_WORD(Memory.C4RAM + 0x1f80) & 0x1ff] * YScale, + 15); + } + + // Calculate Pixel Resolution + uint8 w = Memory.C4RAM[0x1f89] & ~7; + uint8 h = Memory.C4RAM[0x1f8c] & ~7; + + // printf("%dx%d XScale=%04x YScale=%04x angle=%03x\n", w, h, XScale, YScale, READ_WORD(Memory.C4RAM+0x1f80)&0x1ff); + // printf("Matrix: [%10g %10g] [%04x %04x]\n", A/4096.0, B/4096.0, A&0xffff, B&0xffff); + // printf(" [%10g %10g] [%04x %04x]\n", C/4096.0, D/4096.0, C&0xffff, D&0xffff); + + // Clear the output RAM + memset(Memory.C4RAM, 0, (w + row_padding / 4)*h / 2); + + int32 Cx = (int16)READ_WORD(Memory.C4RAM + 0x1f83); + int32 Cy = (int16)READ_WORD(Memory.C4RAM + 0x1f86); + + // Calculate start position (i.e. (Ox, Oy) = (0, 0)) + // The low 12 bits are fractional, so (Cx<<12) gives us the Cx we want in + // the function. We do Cx*A etc normally because the matrix parameters + // already have the fractional parts. + int32 LineX = (Cx << 12) - Cx * A - Cx * B; + int32 LineY = (Cy << 12) - Cy * C - Cy * D; + + // Start loop + uint32 X, Y; + uint8 byte; + int outidx = 0; + int x, y; + uint8 bit = 0x80; + for (y = 0; y < h; y++) + { + X = LineX; + Y = LineY; + for (x = 0; x < w; x++) + { + if ((X >> 12) >= w || (Y >> 12) >= h) + byte = 0; + else + { + uint32 addr = (Y >> 12) * w + (X >> 12); + byte = Memory.C4RAM[0x600 + (addr >> 1)]; + if (addr & 1) byte >>= 4; + } + + // De-bitplanify + if (byte & 1) Memory.C4RAM[outidx] |= bit; + if (byte & 2) Memory.C4RAM[outidx + 1] |= bit; + if (byte & 4) Memory.C4RAM[outidx + 16] |= bit; + if (byte & 8) Memory.C4RAM[outidx + 17] |= bit; + + bit >>= 1; + if (bit == 0) + { + bit = 0x80; + outidx += 32; + } + + X += A; // Add 1 to output x => add an A and a C + Y += C; + } + outidx += 2 + row_padding; + if (outidx & 0x10) + outidx &= ~0x10; + else + outidx -= w * 4 + row_padding; + LineX += B; // Add 1 to output y => add a B and a D + LineY += D; + } } static void C4DrawLine(int32 X1, int32 Y1, int16 Z1, - int32 X2, int32 Y2, int16 Z2, uint8 Color){ - // Transform coordinates - C4WFXVal=(short)X1; - C4WFYVal=(short)Y1; - C4WFZVal=Z1; - C4WFScale=Memory.C4RAM[0x1f90]; - C4WFX2Val=Memory.C4RAM[0x1f86]; - C4WFY2Val=Memory.C4RAM[0x1f87]; - C4WFDist=Memory.C4RAM[0x1f88]; - C4TransfWireFrame2(); - X1=(C4WFXVal+48)<<8; - Y1=(C4WFYVal+48)<<8; - - C4WFXVal=(short)X2; - C4WFYVal=(short)Y2; - C4WFZVal=Z2; - C4TransfWireFrame2(); - X2=(C4WFXVal+48)<<8; - Y2=(C4WFYVal+48)<<8; - - // get line info - C4WFXVal=(short)(X1>>8); - C4WFYVal=(short)(Y1>>8); - C4WFX2Val=(short)(X2>>8); - C4WFY2Val=(short)(Y2>>8); - C4CalcWireFrame(); - X2=(int16)C4WFXVal; - Y2=(int16)C4WFYVal; - - // render line - int i; - for(i=C4WFDist?C4WFDist:1; i>0; i--) - { //.loop - if(X1>0xff && Y1>0xff && X1<0x6000 && Y1<0x6000) - { - uint16 addr=((X1&~0x7ff) + (Y1&~0x7ff)*12 + (Y1&0x700))>>7; - addr=(((Y1>>8)>>3)<<8)-(((Y1>>8)>>3)<<6)+(((X1>>8)>>3)<<4)+((Y1>>8)&7)*2; - uint8 bit=0x80>>((X1>>8)&7); - Memory.C4RAM[addr+0x300]&=~bit; - Memory.C4RAM[addr+0x301]&=~bit; - if(Color&1) Memory.C4RAM[addr+0x300]|=bit; - if(Color&2) Memory.C4RAM[addr+0x301]|=bit; - } - X1+=X2; - Y1+=Y2; - } + int32 X2, int32 Y2, int16 Z2, uint8 Color) +{ + // Transform coordinates + C4WFXVal = (short)X1; + C4WFYVal = (short)Y1; + C4WFZVal = Z1; + C4WFScale = Memory.C4RAM[0x1f90]; + C4WFX2Val = Memory.C4RAM[0x1f86]; + C4WFY2Val = Memory.C4RAM[0x1f87]; + C4WFDist = Memory.C4RAM[0x1f88]; + C4TransfWireFrame2(); + X1 = (C4WFXVal + 48) << 8; + Y1 = (C4WFYVal + 48) << 8; + + C4WFXVal = (short)X2; + C4WFYVal = (short)Y2; + C4WFZVal = Z2; + C4TransfWireFrame2(); + X2 = (C4WFXVal + 48) << 8; + Y2 = (C4WFYVal + 48) << 8; + + // get line info + C4WFXVal = (short)(X1 >> 8); + C4WFYVal = (short)(Y1 >> 8); + C4WFX2Val = (short)(X2 >> 8); + C4WFY2Val = (short)(Y2 >> 8); + C4CalcWireFrame(); + X2 = (int16)C4WFXVal; + Y2 = (int16)C4WFYVal; + + // render line + int i; + for (i = C4WFDist ? C4WFDist : 1; i > 0; i--) + { + //.loop + if (X1 > 0xff && Y1 > 0xff && X1 < 0x6000 && Y1 < 0x6000) + { + uint16 addr = ((X1 & ~0x7ff) + (Y1 & ~0x7ff) * 12 + (Y1 & 0x700)) >> 7; + addr = (((Y1 >> 8) >> 3) << 8) - (((Y1 >> 8) >> 3) << 6) + ((( + X1 >> 8) >> 3) << 4) + ((Y1 >> 8) & 7) * 2; + uint8 bit = 0x80 >> ((X1 >> 8) & 7); + Memory.C4RAM[addr + 0x300] &= ~bit; + Memory.C4RAM[addr + 0x301] &= ~bit; + if (Color & 1) Memory.C4RAM[addr + 0x300] |= bit; + if (Color & 2) Memory.C4RAM[addr + 0x301] |= bit; + } + X1 += X2; + Y1 += Y2; + } } static void C4DrawWireFrame(void) { - uint8 *line=S9xGetMemPointer(READ_3WORD(Memory.C4RAM+0x1f80)); - uint8 *point1, *point2; - int16 X1, Y1, Z1; - int16 X2, Y2, Z2; - uint8 Color; - - int i; - for(i=Memory.C4RAM[0x0295]; i>0; i--, line+=5){ - if(line[0]==0xff && line[1]==0xff){ - uint8 *tmp=line-5; - while(line[2]==0xff && line[3]==0xff) tmp-=5; - point1=S9xGetMemPointer((Memory.C4RAM[0x1f82]<<16) | (tmp[2]<<8) | tmp[3]); - } else { - point1=S9xGetMemPointer((Memory.C4RAM[0x1f82]<<16) | (line[0]<<8) | line[1]); - } - point2=S9xGetMemPointer((Memory.C4RAM[0x1f82]<<16) | (line[2]<<8) | line[3]); - - X1=(point1[0]<<8) | point1[1]; - Y1=(point1[2]<<8) | point1[3]; - Z1=(point1[4]<<8) | point1[5]; - X2=(point2[0]<<8) | point2[1]; - Y2=(point2[2]<<8) | point2[3]; - Z2=(point2[4]<<8) | point2[5]; - Color=line[4]; - C4DrawLine(X1, Y1, Z1, X2, Y2, Z2, Color); - } + uint8* line = S9xGetMemPointer(READ_3WORD(Memory.C4RAM + 0x1f80)); + uint8* point1, *point2; + int16 X1, Y1, Z1; + int16 X2, Y2, Z2; + uint8 Color; + + int i; + for (i = Memory.C4RAM[0x0295]; i > 0; i--, line += 5) + { + if (line[0] == 0xff && line[1] == 0xff) + { + uint8* tmp = line - 5; + while (line[2] == 0xff && line[3] == 0xff) tmp -= 5; + point1 = S9xGetMemPointer((Memory.C4RAM[0x1f82] << 16) | + (tmp[2] << 8) | tmp[3]); + } + else + point1 = S9xGetMemPointer((Memory.C4RAM[0x1f82] << 16) | + (line[0] << 8) | line[1]); + point2 = S9xGetMemPointer((Memory.C4RAM[0x1f82] << 16) | + (line[2] << 8) | line[3]); + + X1 = (point1[0] << 8) | point1[1]; + Y1 = (point1[2] << 8) | point1[3]; + Z1 = (point1[4] << 8) | point1[5]; + X2 = (point2[0] << 8) | point2[1]; + Y2 = (point2[2] << 8) | point2[3]; + Z2 = (point2[4] << 8) | point2[5]; + Color = line[4]; + C4DrawLine(X1, Y1, Z1, X2, Y2, Z2, Color); + } } -static void C4TransformLines(void){ - C4WFX2Val=Memory.C4RAM[0x1f83]; - C4WFY2Val=Memory.C4RAM[0x1f86]; - C4WFDist=Memory.C4RAM[0x1f89]; - C4WFScale=Memory.C4RAM[0x1f8c]; - - int i; - - // transform vertices - uint8 *ptr=Memory.C4RAM; - { - for(i=READ_WORD(Memory.C4RAM+0x1f80); i>0; i--, ptr+=0x10) - { - C4WFXVal=READ_WORD(ptr+1); - C4WFYVal=READ_WORD(ptr+5); - C4WFZVal=READ_WORD(ptr+9); - C4TransfWireFrame(); - - // displace - WRITE_WORD(ptr+1, C4WFXVal+0x80); - WRITE_WORD(ptr+5, C4WFYVal+0x50); - } - } - WRITE_WORD(Memory.C4RAM+0x600, 23); - WRITE_WORD(Memory.C4RAM+0x602, 0x60); - WRITE_WORD(Memory.C4RAM+0x605, 0x40); - WRITE_WORD(Memory.C4RAM+0x600+8, 23); - WRITE_WORD(Memory.C4RAM+0x602+8, 0x60); - WRITE_WORD(Memory.C4RAM+0x605+8, 0x40); - - ptr=Memory.C4RAM+0xb02; - uint8 *ptr2=Memory.C4RAM; - { - int i; - for(i=READ_WORD(Memory.C4RAM+0xb00); i>0; i--, ptr+=2, ptr2+=8) - { - C4WFXVal=READ_WORD(Memory.C4RAM+(ptr[0]<<4)+1); - C4WFYVal=READ_WORD(Memory.C4RAM+(ptr[0]<<4)+5); - C4WFX2Val=READ_WORD(Memory.C4RAM+(ptr[1]<<4)+1); - C4WFY2Val=READ_WORD(Memory.C4RAM+(ptr[1]<<4)+5); - C4CalcWireFrame(); - WRITE_WORD(ptr2+0x600, C4WFDist?C4WFDist:1); - WRITE_WORD(ptr2+0x602, C4WFXVal); - WRITE_WORD(ptr2+0x605, C4WFYVal); - } - } +static void C4TransformLines(void) +{ + C4WFX2Val = Memory.C4RAM[0x1f83]; + C4WFY2Val = Memory.C4RAM[0x1f86]; + C4WFDist = Memory.C4RAM[0x1f89]; + C4WFScale = Memory.C4RAM[0x1f8c]; + + int i; + + // transform vertices + uint8* ptr = Memory.C4RAM; + { + for (i = READ_WORD(Memory.C4RAM + 0x1f80); i > 0; i--, ptr += 0x10) + { + C4WFXVal = READ_WORD(ptr + 1); + C4WFYVal = READ_WORD(ptr + 5); + C4WFZVal = READ_WORD(ptr + 9); + C4TransfWireFrame(); + + // displace + WRITE_WORD(ptr + 1, C4WFXVal + 0x80); + WRITE_WORD(ptr + 5, C4WFYVal + 0x50); + } + } + WRITE_WORD(Memory.C4RAM + 0x600, 23); + WRITE_WORD(Memory.C4RAM + 0x602, 0x60); + WRITE_WORD(Memory.C4RAM + 0x605, 0x40); + WRITE_WORD(Memory.C4RAM + 0x600 + 8, 23); + WRITE_WORD(Memory.C4RAM + 0x602 + 8, 0x60); + WRITE_WORD(Memory.C4RAM + 0x605 + 8, 0x40); + + ptr = Memory.C4RAM + 0xb02; + uint8* ptr2 = Memory.C4RAM; + { + int i; + for (i = READ_WORD(Memory.C4RAM + 0xb00); i > 0; i--, ptr += 2, ptr2 += 8) + { + C4WFXVal = READ_WORD(Memory.C4RAM + (ptr[0] << 4) + 1); + C4WFYVal = READ_WORD(Memory.C4RAM + (ptr[0] << 4) + 5); + C4WFX2Val = READ_WORD(Memory.C4RAM + (ptr[1] << 4) + 1); + C4WFY2Val = READ_WORD(Memory.C4RAM + (ptr[1] << 4) + 5); + C4CalcWireFrame(); + WRITE_WORD(ptr2 + 0x600, C4WFDist ? C4WFDist : 1); + WRITE_WORD(ptr2 + 0x602, C4WFXVal); + WRITE_WORD(ptr2 + 0x605, C4WFYVal); + } + } } -static void C4BitPlaneWave(){ - static uint16 bmpdata[]={ - 0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000A, 0x000C, 0x000E, - 0x0200, 0x0202, 0x0204, 0x0206, 0x0208, 0x020A, 0x020C, 0x020E, - 0x0400, 0x0402, 0x0404, 0x0406, 0x0408, 0x040A, 0x040C, 0x040E, - 0x0600, 0x0602, 0x0604, 0x0606, 0x0608, 0x060A, 0x060C, 0x060E, - 0x0800, 0x0802, 0x0804, 0x0806, 0x0808, 0x080A, 0x080C, 0x080E - }; - - uint8 *dst=Memory.C4RAM; - uint32 waveptr=Memory.C4RAM[0x1f83]; - uint16 mask1=0xc0c0; - uint16 mask2=0x3f3f; - - int i,j; - for(j=0; j<0x10; j++){ - do { - int16 height=-((int8)Memory.C4RAM[waveptr+0xb00])-16; - for(i=0; i<40; i++){ - uint16 tmp=READ_WORD(dst+bmpdata[i]) & mask2; - if(height>=0){ - if(height<8){ - tmp|=mask1&READ_WORD(Memory.C4RAM+0xa00+height*2); - } else { - tmp|=mask1&0xff00; - } - } - WRITE_WORD(dst+bmpdata[i], tmp); - height++; +static void C4BitPlaneWave() +{ + static uint16 bmpdata[] = + { + 0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000A, 0x000C, 0x000E, + 0x0200, 0x0202, 0x0204, 0x0206, 0x0208, 0x020A, 0x020C, 0x020E, + 0x0400, 0x0402, 0x0404, 0x0406, 0x0408, 0x040A, 0x040C, 0x040E, + 0x0600, 0x0602, 0x0604, 0x0606, 0x0608, 0x060A, 0x060C, 0x060E, + 0x0800, 0x0802, 0x0804, 0x0806, 0x0808, 0x080A, 0x080C, 0x080E + }; + + uint8* dst = Memory.C4RAM; + uint32 waveptr = Memory.C4RAM[0x1f83]; + uint16 mask1 = 0xc0c0; + uint16 mask2 = 0x3f3f; + + int i, j; + for (j = 0; j < 0x10; j++) + { + do + { + int16 height = -((int8)Memory.C4RAM[waveptr + 0xb00]) - 16; + for (i = 0; i < 40; i++) + { + uint16 tmp = READ_WORD(dst + bmpdata[i]) & mask2; + if (height >= 0) + { + if (height < 8) + tmp |= mask1 & READ_WORD(Memory.C4RAM + 0xa00 + height * 2); + else + tmp |= mask1 & 0xff00; } - waveptr=(waveptr+1)&0x7f; - mask1=(mask1>>2)|(mask1<<6); - mask2=(mask2>>2)|(mask2<<6); - } while(mask1!=0xc0c0); - dst+=16; + WRITE_WORD(dst + bmpdata[i], tmp); + height++; + } + waveptr = (waveptr + 1) & 0x7f; + mask1 = (mask1 >> 2) | (mask1 << 6); + mask2 = (mask2 >> 2) | (mask2 << 6); + } + while (mask1 != 0xc0c0); + dst += 16; - do { - int i; - int16 height=-((int8)Memory.C4RAM[waveptr+0xb00])-16; - for(i=0; i<40; i++){ - uint16 tmp=READ_WORD(dst+bmpdata[i]) & mask2; - if(height>=0){ - if(height<8){ - tmp|=mask1&READ_WORD(Memory.C4RAM+0xa10+height*2); - } else { - tmp|=mask1&0xff00; - } - } - WRITE_WORD(dst+bmpdata[i], tmp); - height++; + do + { + int i; + int16 height = -((int8)Memory.C4RAM[waveptr + 0xb00]) - 16; + for (i = 0; i < 40; i++) + { + uint16 tmp = READ_WORD(dst + bmpdata[i]) & mask2; + if (height >= 0) + { + if (height < 8) + tmp |= mask1 & READ_WORD(Memory.C4RAM + 0xa10 + height * 2); + else + tmp |= mask1 & 0xff00; } - waveptr=(waveptr+1)&0x7f; - mask1=(mask1>>2)|(mask1<<6); - mask2=(mask2>>2)|(mask2<<6); - } while(mask1!=0xc0c0); - dst+=16; - } + WRITE_WORD(dst + bmpdata[i], tmp); + height++; + } + waveptr = (waveptr + 1) & 0x7f; + mask1 = (mask1 >> 2) | (mask1 << 6); + mask2 = (mask2 >> 2) | (mask2 << 6); + } + while (mask1 != 0xc0c0); + dst += 16; + } } static void C4SprDisintegrate() { - uint8 width, height; - uint32 StartX, StartY; - uint8 *src; - int32 scaleX, scaleY; - int32 Cx, Cy; - - width=Memory.C4RAM[0x1f89]; - height=Memory.C4RAM[0x1f8c]; - Cx=(int16)READ_WORD(Memory.C4RAM+0x1f80); - Cy=(int16)READ_WORD(Memory.C4RAM+0x1f83); - - scaleX=(int16)READ_WORD(Memory.C4RAM+0x1f86); - scaleY=(int16)READ_WORD(Memory.C4RAM+0x1f8f); - StartX=-Cx*scaleX+(Cx<<8); - StartY=-Cy*scaleY+(Cy<<8); - src=Memory.C4RAM+0x600; - - memset(Memory.C4RAM, 0, width*height/2); - uint32 x,y,i,j; - for( y=StartY, i=0; i>8)>8)>8)*width+(x>>8)<0x2000) - { - uint8 pixel=(j&1)?(*src>>4):*src; - int idx=(y>>11)*width*4+(x>>11)*32+((y>>8)&7)*2; - uint8 mask=0x80>>((x>>8)&7); - if(pixel&1) Memory.C4RAM[idx]|=mask; - if(pixel&2) Memory.C4RAM[idx+1]|=mask; - if(pixel&4) Memory.C4RAM[idx+16]|=mask; - if(pixel&8) Memory.C4RAM[idx+17]|=mask; - } - if(j&1) src++; - } - } + uint8 width, height; + uint32 StartX, StartY; + uint8* src; + int32 scaleX, scaleY; + int32 Cx, Cy; + + width = Memory.C4RAM[0x1f89]; + height = Memory.C4RAM[0x1f8c]; + Cx = (int16)READ_WORD(Memory.C4RAM + 0x1f80); + Cy = (int16)READ_WORD(Memory.C4RAM + 0x1f83); + + scaleX = (int16)READ_WORD(Memory.C4RAM + 0x1f86); + scaleY = (int16)READ_WORD(Memory.C4RAM + 0x1f8f); + StartX = -Cx * scaleX + (Cx << 8); + StartY = -Cy * scaleY + (Cy << 8); + src = Memory.C4RAM + 0x600; + + memset(Memory.C4RAM, 0, width * height / 2); + uint32 x, y, i, j; + for (y = StartY, i = 0; i < height; i++, y += scaleY) + { + for (x = StartX, j = 0; j < width; j++, x += scaleX) + { + if ((x >> 8) < width && (y >> 8) < height && (y >> 8)*width + (x >> 8) < 0x2000) + { + uint8 pixel = (j & 1) ? (*src >> 4) : *src; + int idx = (y >> 11) * width * 4 + (x >> 11) * 32 + ((y >> 8) & 7) * 2; + uint8 mask = 0x80 >> ((x >> 8) & 7); + if (pixel & 1) Memory.C4RAM[idx] |= mask; + if (pixel & 2) Memory.C4RAM[idx + 1] |= mask; + if (pixel & 4) Memory.C4RAM[idx + 16] |= mask; + if (pixel & 8) Memory.C4RAM[idx + 17] |= mask; + } + if (j & 1) src++; + } + } } static void S9xC4ProcessSprites() { - switch(Memory.C4RAM[0x1f4d]) - { - case 0x00: // Build OAM - C4ConvOAM(); - break; - - case 0x03: // Scale/Rotate - C4DoScaleRotate(0); - break; - - case 0x05: // Transform Lines - C4TransformLines(); - break; - - case 0x07: // Scale/Rotate - C4DoScaleRotate(64); - break; - - case 0x08: // Draw wireframe - C4DrawWireFrame(); - break; - - case 0x0b: // Disintegrate - C4SprDisintegrate(); - break; - - case 0x0c: // Wave - C4BitPlaneWave(); - break; - - default: - break; - } + switch (Memory.C4RAM[0x1f4d]) + { + case 0x00: // Build OAM + C4ConvOAM(); + break; + + case 0x03: // Scale/Rotate + C4DoScaleRotate(0); + break; + + case 0x05: // Transform Lines + C4TransformLines(); + break; + + case 0x07: // Scale/Rotate + C4DoScaleRotate(64); + break; + + case 0x08: // Draw wireframe + C4DrawWireFrame(); + break; + + case 0x0b: // Disintegrate + C4SprDisintegrate(); + break; + + case 0x0c: // Wave + C4BitPlaneWave(); + break; + + default: + break; + } } -void S9xSetC4 (uint8 byte, uint16 Address) +void S9xSetC4(uint8 byte, uint16 Address) { - int i; - Memory.C4RAM [Address-0x6000] = byte; - if (Address == 0x7f4f) - { - if(Memory.C4RAM[0x1f4d]==0x0e && byte<0x40 && (byte&3)==0) + int i; + Memory.C4RAM [Address - 0x6000] = byte; + if (Address == 0x7f4f) + { + if (Memory.C4RAM[0x1f4d] == 0x0e && byte < 0x40 && (byte & 3) == 0) + Memory.C4RAM[0x1f80] = byte >> 2; + else { - Memory.C4RAM[0x1f80]=byte>>2; - } - else - { - switch (byte) - { - case 0x00: // Sprite - S9xC4ProcessSprites(); - break; - - case 0x01: // Draw wireframe - memset(Memory.C4RAM+0x300, 0, 16*12*3*4); - C4DrawWireFrame(); - break; - - case 0x05: // Propulsion (?) - { - int32 tmp=0x10000; - if(READ_WORD(Memory.C4RAM+0x1f83)){ - tmp=SAR32((tmp/READ_WORD(Memory.C4RAM+0x1f83))*READ_WORD(Memory.C4RAM+0x1f81), 8); - } - WRITE_WORD(Memory.C4RAM+0x1f80, (uint16)tmp); - } - break; - - case 0x0d: // Set vector length - C41FXVal=READ_WORD(Memory.C4RAM+0x1f80); - C41FYVal=READ_WORD(Memory.C4RAM+0x1f83); - C41FDistVal=READ_WORD(Memory.C4RAM+0x1f86); - C4Op0D(); - WRITE_WORD(Memory.C4RAM+0x1f89, C41FXVal); - WRITE_WORD(Memory.C4RAM+0x1f8c, C41FYVal); - break; - - case 0x10: // Polar to rectangluar - { - int32 tmp=SAR32((int32)READ_WORD(Memory.C4RAM+0x1f83)*C4CosTable[READ_WORD(Memory.C4RAM+0x1f80)&0x1ff]*2, 16); - WRITE_3WORD(Memory.C4RAM+0x1f86, tmp); - tmp=SAR32((int32)READ_WORD(Memory.C4RAM+0x1f83)*C4SinTable[READ_WORD(Memory.C4RAM+0x1f80)&0x1ff]*2, 16); - WRITE_3WORD(Memory.C4RAM+0x1f89, (tmp-SAR32(tmp, 6))); - } - break; - - case 0x13: // Polar to rectangluar - { - int32 tmp=SAR32((int32)READ_WORD(Memory.C4RAM+0x1f83)*C4CosTable[READ_WORD(Memory.C4RAM+0x1f80)&0x1ff]*2, 8); - WRITE_3WORD(Memory.C4RAM+0x1f86, tmp); - tmp=SAR32((int32)READ_WORD(Memory.C4RAM+0x1f83)*C4SinTable[READ_WORD(Memory.C4RAM+0x1f80)&0x1ff]*2, 8); - WRITE_3WORD(Memory.C4RAM+0x1f89, tmp); - } - break; - - case 0x15: // Pythagorean - C41FXVal=READ_WORD(Memory.C4RAM+0x1f80); - C41FYVal=READ_WORD(Memory.C4RAM+0x1f83); - C41FDist=(int16)sqrt((double)C41FXVal*C41FXVal + (double)C41FYVal*C41FYVal); - WRITE_WORD(Memory.C4RAM+0x1f80, C41FDist); - break; - - case 0x1f: // atan - C41FXVal=READ_WORD(Memory.C4RAM+0x1f80); - C41FYVal=READ_WORD(Memory.C4RAM+0x1f83); - C4Op1F(); - WRITE_WORD(Memory.C4RAM+0x1f86, C41FAngleRes); - break; - - case 0x22: // Trapezoid - { - int16 angle1=READ_WORD(Memory.C4RAM+0x1f8c)&0x1ff; - int16 angle2=READ_WORD(Memory.C4RAM+0x1f8f)&0x1ff; - int32 tan1=(C4CosTable[angle1]!=0)?((((int32)C4SinTable[angle1])<<16)/C4CosTable[angle1]):0x80000000; - int32 tan2=(C4CosTable[angle2]!=0)?((((int32)C4SinTable[angle2])<<16)/C4CosTable[angle2]):0x80000000; - int16 y = READ_WORD(Memory.C4RAM+0x1f83) - READ_WORD(Memory.C4RAM+0x1f89); - int16 left, right; - int j; - for(j=0; j<225; j++) - { - if(y>=0) - { - left = SAR32((int32)tan1*y, 16) - - READ_WORD(Memory.C4RAM+0x1f80) + - READ_WORD(Memory.C4RAM+0x1f86); - right = SAR32((int32)tan2*y, 16) - - READ_WORD(Memory.C4RAM+0x1f80) + - READ_WORD(Memory.C4RAM+0x1f86) + - READ_WORD(Memory.C4RAM+0x1f93); - - if(left<0 && right<0){ - left=1; - right=0; - } else if(left<0){ - left=0; - } else if(right<0){ - right=0; - } - if(left>255 && right>255){ - left=255; - right=254; - } else if(left>255){ - left=255; - } else if(right>255){ - right=255; - } - } - else - { - left=1; - right=0; - } - Memory.C4RAM[j+0x800] = (uint8)left; - Memory.C4RAM[j+0x900] = (uint8)right; - y++; - } - } - break; - - case 0x25: // Multiply - { - int32 foo=READ_3WORD(Memory.C4RAM+0x1f80); - int32 bar=READ_3WORD(Memory.C4RAM+0x1f83); - foo*=bar; - WRITE_3WORD(Memory.C4RAM+0x1f80, foo); - } - break; - - case 0x2d: // Transform Coords - C4WFXVal=READ_WORD(Memory.C4RAM+0x1f81); - C4WFYVal=READ_WORD(Memory.C4RAM+0x1f84); - C4WFZVal=READ_WORD(Memory.C4RAM+0x1f87); - C4WFX2Val=Memory.C4RAM[0x1f89]; - C4WFY2Val=Memory.C4RAM[0x1f8a]; - C4WFDist=Memory.C4RAM[0x1f8b]; - C4WFScale=READ_WORD(Memory.C4RAM+0x1f90); - C4TransfWireFrame2(); - WRITE_WORD(Memory.C4RAM+0x1f80, C4WFXVal); - WRITE_WORD(Memory.C4RAM+0x1f83, C4WFYVal); - break; - - case 0x40: // Sum - { - int i; - uint16 sum=0; - for(i=0; i<0x800; sum+=Memory.C4RAM[i++]); - WRITE_WORD(Memory.C4RAM+0x1f80, sum); - } - break; - - case 0x54: // Square - { - int64 a=SAR64((int64)READ_3WORD(Memory.C4RAM+0x1f80)<<40, 40); - // printf("%08X%08X\n", (uint32)(a>>32), (uint32)(a&0xFFFFFFFF)); - a*=a; - // printf("%08X%08X\n", (uint32)(a>>32), (uint32)(a&0xFFFFFFFF)); - WRITE_3WORD(Memory.C4RAM+0x1f83, a); - WRITE_3WORD(Memory.C4RAM+0x1f86, (a>>24)); - } - break; - - case 0x5c: // Immediate Reg - for (i = 0; i < 12 * 4; i++) - Memory.C4RAM [i] = C4TestPattern [i]; - break; - - case 0x89: // Immediate ROM - Memory.C4RAM [0x1f80] = 0x36; - Memory.C4RAM [0x1f81] = 0x43; - Memory.C4RAM [0x1f82] = 0x05; - break; - - default: - break; + switch (byte) + { + case 0x00: // Sprite + S9xC4ProcessSprites(); + break; + + case 0x01: // Draw wireframe + memset(Memory.C4RAM + 0x300, 0, 16 * 12 * 3 * 4); + C4DrawWireFrame(); + break; + + case 0x05: // Propulsion (?) + { + int32 tmp = 0x10000; + if (READ_WORD(Memory.C4RAM + 0x1f83)) + tmp = SAR32((tmp / READ_WORD(Memory.C4RAM + 0x1f83)) * READ_WORD( + Memory.C4RAM + 0x1f81), 8); + WRITE_WORD(Memory.C4RAM + 0x1f80, (uint16)tmp); + } + break; + + case 0x0d: // Set vector length + C41FXVal = READ_WORD(Memory.C4RAM + 0x1f80); + C41FYVal = READ_WORD(Memory.C4RAM + 0x1f83); + C41FDistVal = READ_WORD(Memory.C4RAM + 0x1f86); + C4Op0D(); + WRITE_WORD(Memory.C4RAM + 0x1f89, C41FXVal); + WRITE_WORD(Memory.C4RAM + 0x1f8c, C41FYVal); + break; + + case 0x10: // Polar to rectangluar + { + int32 tmp = SAR32((int32)READ_WORD(Memory.C4RAM + 0x1f83) * + C4CosTable[READ_WORD(Memory.C4RAM + 0x1f80) & 0x1ff] * 2, 16); + WRITE_3WORD(Memory.C4RAM + 0x1f86, tmp); + tmp = SAR32((int32)READ_WORD(Memory.C4RAM + 0x1f83) * C4SinTable[READ_WORD( + Memory.C4RAM + 0x1f80) & 0x1ff] * 2, 16); + WRITE_3WORD(Memory.C4RAM + 0x1f89, (tmp - SAR32(tmp, 6))); + } + break; + + case 0x13: // Polar to rectangluar + { + int32 tmp = SAR32((int32)READ_WORD(Memory.C4RAM + 0x1f83) * + C4CosTable[READ_WORD(Memory.C4RAM + 0x1f80) & 0x1ff] * 2, 8); + WRITE_3WORD(Memory.C4RAM + 0x1f86, tmp); + tmp = SAR32((int32)READ_WORD(Memory.C4RAM + 0x1f83) * C4SinTable[READ_WORD( + Memory.C4RAM + 0x1f80) & 0x1ff] * 2, 8); + WRITE_3WORD(Memory.C4RAM + 0x1f89, tmp); + } + break; + + case 0x15: // Pythagorean + C41FXVal = READ_WORD(Memory.C4RAM + 0x1f80); + C41FYVal = READ_WORD(Memory.C4RAM + 0x1f83); + C41FDist = (int16)sqrt((double)C41FXVal * C41FXVal + (double)C41FYVal * + C41FYVal); + WRITE_WORD(Memory.C4RAM + 0x1f80, C41FDist); + break; + + case 0x1f: // atan + C41FXVal = READ_WORD(Memory.C4RAM + 0x1f80); + C41FYVal = READ_WORD(Memory.C4RAM + 0x1f83); + C4Op1F(); + WRITE_WORD(Memory.C4RAM + 0x1f86, C41FAngleRes); + break; + + case 0x22: // Trapezoid + { + int16 angle1 = READ_WORD(Memory.C4RAM + 0x1f8c) & 0x1ff; + int16 angle2 = READ_WORD(Memory.C4RAM + 0x1f8f) & 0x1ff; + int32 tan1 = (C4CosTable[angle1] != 0) ? ((((int32)C4SinTable[angle1]) << 16) / + C4CosTable[angle1]) : 0x80000000; + int32 tan2 = (C4CosTable[angle2] != 0) ? ((((int32)C4SinTable[angle2]) << 16) / + C4CosTable[angle2]) : 0x80000000; + int16 y = READ_WORD(Memory.C4RAM + 0x1f83) - READ_WORD(Memory.C4RAM + 0x1f89); + int16 left, right; + int j; + for (j = 0; j < 225; j++) + { + if (y >= 0) + { + left = SAR32((int32)tan1 * y, 16) - + READ_WORD(Memory.C4RAM + 0x1f80) + + READ_WORD(Memory.C4RAM + 0x1f86); + right = SAR32((int32)tan2 * y, 16) - + READ_WORD(Memory.C4RAM + 0x1f80) + + READ_WORD(Memory.C4RAM + 0x1f86) + + READ_WORD(Memory.C4RAM + 0x1f93); + + if (left < 0 && right < 0) + { + left = 1; + right = 0; + } + else if (left < 0) + left = 0; + else if (right < 0) + right = 0; + if (left > 255 && right > 255) + { + left = 255; + right = 254; + } + else if (left > 255) + left = 255; + else if (right > 255) + right = 255; + } + else + { + left = 1; + right = 0; + } + Memory.C4RAM[j + 0x800] = (uint8)left; + Memory.C4RAM[j + 0x900] = (uint8)right; + y++; } - } - } else if (Address == 0x7f47) { - // memmove required: Can overlap arbitrarily [Neb] - memmove(Memory.C4RAM+(READ_WORD(Memory.C4RAM+0x1f45)&0x1fff), - S9xGetMemPointer(READ_3WORD(Memory.C4RAM+0x1f40)), - READ_WORD(Memory.C4RAM+0x1f43)); - } + } + break; + + case 0x25: // Multiply + { + int32 foo = READ_3WORD(Memory.C4RAM + 0x1f80); + int32 bar = READ_3WORD(Memory.C4RAM + 0x1f83); + foo *= bar; + WRITE_3WORD(Memory.C4RAM + 0x1f80, foo); + } + break; + + case 0x2d: // Transform Coords + C4WFXVal = READ_WORD(Memory.C4RAM + 0x1f81); + C4WFYVal = READ_WORD(Memory.C4RAM + 0x1f84); + C4WFZVal = READ_WORD(Memory.C4RAM + 0x1f87); + C4WFX2Val = Memory.C4RAM[0x1f89]; + C4WFY2Val = Memory.C4RAM[0x1f8a]; + C4WFDist = Memory.C4RAM[0x1f8b]; + C4WFScale = READ_WORD(Memory.C4RAM + 0x1f90); + C4TransfWireFrame2(); + WRITE_WORD(Memory.C4RAM + 0x1f80, C4WFXVal); + WRITE_WORD(Memory.C4RAM + 0x1f83, C4WFYVal); + break; + + case 0x40: // Sum + { + int i; + uint16 sum = 0; + for (i = 0; i < 0x800; sum += Memory.C4RAM[i++]); + WRITE_WORD(Memory.C4RAM + 0x1f80, sum); + } + break; + + case 0x54: // Square + { + int64 a = SAR64((int64)READ_3WORD(Memory.C4RAM + 0x1f80) << 40, 40); + // printf("%08X%08X\n", (uint32)(a>>32), (uint32)(a&0xFFFFFFFF)); + a *= a; + // printf("%08X%08X\n", (uint32)(a>>32), (uint32)(a&0xFFFFFFFF)); + WRITE_3WORD(Memory.C4RAM + 0x1f83, a); + WRITE_3WORD(Memory.C4RAM + 0x1f86, (a >> 24)); + } + break; + + case 0x5c: // Immediate Reg + for (i = 0; i < 12 * 4; i++) + Memory.C4RAM [i] = C4TestPattern [i]; + break; + + case 0x89: // Immediate ROM + Memory.C4RAM [0x1f80] = 0x36; + Memory.C4RAM [0x1f81] = 0x43; + Memory.C4RAM [0x1f82] = 0x05; + break; + + default: + break; + } + } + } + else if (Address == 0x7f47) + { + // memmove required: Can overlap arbitrarily [Neb] + memmove(Memory.C4RAM + (READ_WORD(Memory.C4RAM + 0x1f45) & 0x1fff), + S9xGetMemPointer(READ_3WORD(Memory.C4RAM + 0x1f40)), + READ_WORD(Memory.C4RAM + 0x1f43)); + } } -int16 C4SinTable[512] = { - 0, 402, 804, 1206, 1607, 2009, 2410, 2811, - 3211, 3611, 4011, 4409, 4808, 5205, 5602, 5997, - 6392, 6786, 7179, 7571, 7961, 8351, 8739, 9126, - 9512, 9896, 10278, 10659, 11039, 11416, 11793, 12167, - 12539, 12910, 13278, 13645, 14010, 14372, 14732, 15090, - 15446, 15800, 16151, 16499, 16846, 17189, 17530, 17869, - 18204, 18537, 18868, 19195, 19519, 19841, 20159, 20475, - 20787, 21097, 21403, 21706, 22005, 22301, 22594, 22884, - 23170, 23453, 23732, 24007, 24279, 24547, 24812, 25073, - 25330, 25583, 25832, 26077, 26319, 26557, 26790, 27020, - 27245, 27466, 27684, 27897, 28106, 28310, 28511, 28707, - 28898, 29086, 29269, 29447, 29621, 29791, 29956, 30117, - 30273, 30425, 30572, 30714, 30852, 30985, 31114, 31237, - 31357, 31471, 31581, 31685, 31785, 31881, 31971, 32057, - 32138, 32214, 32285, 32351, 32413, 32469, 32521, 32568, - 32610, 32647, 32679, 32706, 32728, 32745, 32758, 32765, - 32767, 32765, 32758, 32745, 32728, 32706, 32679, 32647, - 32610, 32568, 32521, 32469, 32413, 32351, 32285, 32214, - 32138, 32057, 31971, 31881, 31785, 31685, 31581, 31471, - 31357, 31237, 31114, 30985, 30852, 30714, 30572, 30425, - 30273, 30117, 29956, 29791, 29621, 29447, 29269, 29086, - 28898, 28707, 28511, 28310, 28106, 27897, 27684, 27466, - 27245, 27020, 26790, 26557, 26319, 26077, 25832, 25583, - 25330, 25073, 24812, 24547, 24279, 24007, 23732, 23453, - 23170, 22884, 22594, 22301, 22005, 21706, 21403, 21097, - 20787, 20475, 20159, 19841, 19519, 19195, 18868, 18537, - 18204, 17869, 17530, 17189, 16846, 16499, 16151, 15800, - 15446, 15090, 14732, 14372, 14010, 13645, 13278, 12910, - 12539, 12167, 11793, 11416, 11039, 10659, 10278, 9896, - 9512, 9126, 8739, 8351, 7961, 7571, 7179, 6786, - 6392, 5997, 5602, 5205, 4808, 4409, 4011, 3611, - 3211, 2811, 2410, 2009, 1607, 1206, 804, 402, - 0, -402, -804, -1206, -1607, -2009, -2410, -2811, - -3211, -3611, -4011, -4409, -4808, -5205, -5602, -5997, - -6392, -6786, -7179, -7571, -7961, -8351, -8739, -9126, - -9512, -9896, -10278, -10659, -11039, -11416, -11793, -12167, - -12539, -12910, -13278, -13645, -14010, -14372, -14732, -15090, - -15446, -15800, -16151, -16499, -16846, -17189, -17530, -17869, - -18204, -18537, -18868, -19195, -19519, -19841, -20159, -20475, - -20787, -21097, -21403, -21706, -22005, -22301, -22594, -22884, - -23170, -23453, -23732, -24007, -24279, -24547, -24812, -25073, - -25330, -25583, -25832, -26077, -26319, -26557, -26790, -27020, - -27245, -27466, -27684, -27897, -28106, -28310, -28511, -28707, - -28898, -29086, -29269, -29447, -29621, -29791, -29956, -30117, - -30273, -30425, -30572, -30714, -30852, -30985, -31114, -31237, - -31357, -31471, -31581, -31685, -31785, -31881, -31971, -32057, - -32138, -32214, -32285, -32351, -32413, -32469, -32521, -32568, - -32610, -32647, -32679, -32706, -32728, -32745, -32758, -32765, - -32767, -32765, -32758, -32745, -32728, -32706, -32679, -32647, - -32610, -32568, -32521, -32469, -32413, -32351, -32285, -32214, - -32138, -32057, -31971, -31881, -31785, -31685, -31581, -31471, - -31357, -31237, -31114, -30985, -30852, -30714, -30572, -30425, - -30273, -30117, -29956, -29791, -29621, -29447, -29269, -29086, - -28898, -28707, -28511, -28310, -28106, -27897, -27684, -27466, - -27245, -27020, -26790, -26557, -26319, -26077, -25832, -25583, - -25330, -25073, -24812, -24547, -24279, -24007, -23732, -23453, - -23170, -22884, -22594, -22301, -22005, -21706, -21403, -21097, - -20787, -20475, -20159, -19841, -19519, -19195, -18868, -18537, - -18204, -17869, -17530, -17189, -16846, -16499, -16151, -15800, - -15446, -15090, -14732, -14372, -14010, -13645, -13278, -12910, - -12539, -12167, -11793, -11416, -11039, -10659, -10278, -9896, - -9512, -9126, -8739, -8351, -7961, -7571, -7179, -6786, - -6392, -5997, -5602, -5205, -4808, -4409, -4011, -3611, - -3211, -2811, -2410, -2009, -1607, -1206, -804, -402 +int16 C4SinTable[512] = +{ + 0, 402, 804, 1206, 1607, 2009, 2410, 2811, + 3211, 3611, 4011, 4409, 4808, 5205, 5602, 5997, + 6392, 6786, 7179, 7571, 7961, 8351, 8739, 9126, + 9512, 9896, 10278, 10659, 11039, 11416, 11793, 12167, + 12539, 12910, 13278, 13645, 14010, 14372, 14732, 15090, + 15446, 15800, 16151, 16499, 16846, 17189, 17530, 17869, + 18204, 18537, 18868, 19195, 19519, 19841, 20159, 20475, + 20787, 21097, 21403, 21706, 22005, 22301, 22594, 22884, + 23170, 23453, 23732, 24007, 24279, 24547, 24812, 25073, + 25330, 25583, 25832, 26077, 26319, 26557, 26790, 27020, + 27245, 27466, 27684, 27897, 28106, 28310, 28511, 28707, + 28898, 29086, 29269, 29447, 29621, 29791, 29956, 30117, + 30273, 30425, 30572, 30714, 30852, 30985, 31114, 31237, + 31357, 31471, 31581, 31685, 31785, 31881, 31971, 32057, + 32138, 32214, 32285, 32351, 32413, 32469, 32521, 32568, + 32610, 32647, 32679, 32706, 32728, 32745, 32758, 32765, + 32767, 32765, 32758, 32745, 32728, 32706, 32679, 32647, + 32610, 32568, 32521, 32469, 32413, 32351, 32285, 32214, + 32138, 32057, 31971, 31881, 31785, 31685, 31581, 31471, + 31357, 31237, 31114, 30985, 30852, 30714, 30572, 30425, + 30273, 30117, 29956, 29791, 29621, 29447, 29269, 29086, + 28898, 28707, 28511, 28310, 28106, 27897, 27684, 27466, + 27245, 27020, 26790, 26557, 26319, 26077, 25832, 25583, + 25330, 25073, 24812, 24547, 24279, 24007, 23732, 23453, + 23170, 22884, 22594, 22301, 22005, 21706, 21403, 21097, + 20787, 20475, 20159, 19841, 19519, 19195, 18868, 18537, + 18204, 17869, 17530, 17189, 16846, 16499, 16151, 15800, + 15446, 15090, 14732, 14372, 14010, 13645, 13278, 12910, + 12539, 12167, 11793, 11416, 11039, 10659, 10278, 9896, + 9512, 9126, 8739, 8351, 7961, 7571, 7179, 6786, + 6392, 5997, 5602, 5205, 4808, 4409, 4011, 3611, + 3211, 2811, 2410, 2009, 1607, 1206, 804, 402, + 0, -402, -804, -1206, -1607, -2009, -2410, -2811, + -3211, -3611, -4011, -4409, -4808, -5205, -5602, -5997, + -6392, -6786, -7179, -7571, -7961, -8351, -8739, -9126, + -9512, -9896, -10278, -10659, -11039, -11416, -11793, -12167, + -12539, -12910, -13278, -13645, -14010, -14372, -14732, -15090, + -15446, -15800, -16151, -16499, -16846, -17189, -17530, -17869, + -18204, -18537, -18868, -19195, -19519, -19841, -20159, -20475, + -20787, -21097, -21403, -21706, -22005, -22301, -22594, -22884, + -23170, -23453, -23732, -24007, -24279, -24547, -24812, -25073, + -25330, -25583, -25832, -26077, -26319, -26557, -26790, -27020, + -27245, -27466, -27684, -27897, -28106, -28310, -28511, -28707, + -28898, -29086, -29269, -29447, -29621, -29791, -29956, -30117, + -30273, -30425, -30572, -30714, -30852, -30985, -31114, -31237, + -31357, -31471, -31581, -31685, -31785, -31881, -31971, -32057, + -32138, -32214, -32285, -32351, -32413, -32469, -32521, -32568, + -32610, -32647, -32679, -32706, -32728, -32745, -32758, -32765, + -32767, -32765, -32758, -32745, -32728, -32706, -32679, -32647, + -32610, -32568, -32521, -32469, -32413, -32351, -32285, -32214, + -32138, -32057, -31971, -31881, -31785, -31685, -31581, -31471, + -31357, -31237, -31114, -30985, -30852, -30714, -30572, -30425, + -30273, -30117, -29956, -29791, -29621, -29447, -29269, -29086, + -28898, -28707, -28511, -28310, -28106, -27897, -27684, -27466, + -27245, -27020, -26790, -26557, -26319, -26077, -25832, -25583, + -25330, -25073, -24812, -24547, -24279, -24007, -23732, -23453, + -23170, -22884, -22594, -22301, -22005, -21706, -21403, -21097, + -20787, -20475, -20159, -19841, -19519, -19195, -18868, -18537, + -18204, -17869, -17530, -17189, -16846, -16499, -16151, -15800, + -15446, -15090, -14732, -14372, -14010, -13645, -13278, -12910, + -12539, -12167, -11793, -11416, -11039, -10659, -10278, -9896, + -9512, -9126, -8739, -8351, -7961, -7571, -7179, -6786, + -6392, -5997, -5602, -5205, -4808, -4409, -4011, -3611, + -3211, -2811, -2410, -2009, -1607, -1206, -804, -402 }; -int16 C4CosTable[512] = { - 32767, 32765, 32758, 32745, 32728, 32706, 32679, 32647, - 32610, 32568, 32521, 32469, 32413, 32351, 32285, 32214, - 32138, 32057, 31971, 31881, 31785, 31685, 31581, 31471, - 31357, 31237, 31114, 30985, 30852, 30714, 30572, 30425, - 30273, 30117, 29956, 29791, 29621, 29447, 29269, 29086, - 28898, 28707, 28511, 28310, 28106, 27897, 27684, 27466, - 27245, 27020, 26790, 26557, 26319, 26077, 25832, 25583, - 25330, 25073, 24812, 24547, 24279, 24007, 23732, 23453, - 23170, 22884, 22594, 22301, 22005, 21706, 21403, 21097, - 20787, 20475, 20159, 19841, 19519, 19195, 18868, 18537, - 18204, 17869, 17530, 17189, 16846, 16499, 16151, 15800, - 15446, 15090, 14732, 14372, 14010, 13645, 13278, 12910, - 12539, 12167, 11793, 11416, 11039, 10659, 10278, 9896, - 9512, 9126, 8739, 8351, 7961, 7571, 7179, 6786, - 6392, 5997, 5602, 5205, 4808, 4409, 4011, 3611, - 3211, 2811, 2410, 2009, 1607, 1206, 804, 402, - 0, -402, -804, -1206, -1607, -2009, -2410, -2811, - -3211, -3611, -4011, -4409, -4808, -5205, -5602, -5997, - -6392, -6786, -7179, -7571, -7961, -8351, -8739, -9126, - -9512, -9896, -10278, -10659, -11039, -11416, -11793, -12167, - -12539, -12910, -13278, -13645, -14010, -14372, -14732, -15090, - -15446, -15800, -16151, -16499, -16846, -17189, -17530, -17869, - -18204, -18537, -18868, -19195, -19519, -19841, -20159, -20475, - -20787, -21097, -21403, -21706, -22005, -22301, -22594, -22884, - -23170, -23453, -23732, -24007, -24279, -24547, -24812, -25073, - -25330, -25583, -25832, -26077, -26319, -26557, -26790, -27020, - -27245, -27466, -27684, -27897, -28106, -28310, -28511, -28707, - -28898, -29086, -29269, -29447, -29621, -29791, -29956, -30117, - -30273, -30425, -30572, -30714, -30852, -30985, -31114, -31237, - -31357, -31471, -31581, -31685, -31785, -31881, -31971, -32057, - -32138, -32214, -32285, -32351, -32413, -32469, -32521, -32568, - -32610, -32647, -32679, -32706, -32728, -32745, -32758, -32765, - -32767, -32765, -32758, -32745, -32728, -32706, -32679, -32647, - -32610, -32568, -32521, -32469, -32413, -32351, -32285, -32214, - -32138, -32057, -31971, -31881, -31785, -31685, -31581, -31471, - -31357, -31237, -31114, -30985, -30852, -30714, -30572, -30425, - -30273, -30117, -29956, -29791, -29621, -29447, -29269, -29086, - -28898, -28707, -28511, -28310, -28106, -27897, -27684, -27466, - -27245, -27020, -26790, -26557, -26319, -26077, -25832, -25583, - -25330, -25073, -24812, -24547, -24279, -24007, -23732, -23453, - -23170, -22884, -22594, -22301, -22005, -21706, -21403, -21097, - -20787, -20475, -20159, -19841, -19519, -19195, -18868, -18537, - -18204, -17869, -17530, -17189, -16846, -16499, -16151, -15800, - -15446, -15090, -14732, -14372, -14010, -13645, -13278, -12910, - -12539, -12167, -11793, -11416, -11039, -10659, -10278, -9896, - -9512, -9126, -8739, -8351, -7961, -7571, -7179, -6786, - -6392, -5997, -5602, -5205, -4808, -4409, -4011, -3611, - -3211, -2811, -2410, -2009, -1607, -1206, -804, -402, - 0, 402, 804, 1206, 1607, 2009, 2410, 2811, - 3211, 3611, 4011, 4409, 4808, 5205, 5602, 5997, - 6392, 6786, 7179, 7571, 7961, 8351, 8739, 9126, - 9512, 9896, 10278, 10659, 11039, 11416, 11793, 12167, - 12539, 12910, 13278, 13645, 14010, 14372, 14732, 15090, - 15446, 15800, 16151, 16499, 16846, 17189, 17530, 17869, - 18204, 18537, 18868, 19195, 19519, 19841, 20159, 20475, - 20787, 21097, 21403, 21706, 22005, 22301, 22594, 22884, - 23170, 23453, 23732, 24007, 24279, 24547, 24812, 25073, - 25330, 25583, 25832, 26077, 26319, 26557, 26790, 27020, - 27245, 27466, 27684, 27897, 28106, 28310, 28511, 28707, - 28898, 29086, 29269, 29447, 29621, 29791, 29956, 30117, - 30273, 30425, 30572, 30714, 30852, 30985, 31114, 31237, - 31357, 31471, 31581, 31685, 31785, 31881, 31971, 32057, - 32138, 32214, 32285, 32351, 32413, 32469, 32521, 32568, - 32610, 32647, 32679, 32706, 32728, 32745, 32758, 32765 +int16 C4CosTable[512] = +{ + 32767, 32765, 32758, 32745, 32728, 32706, 32679, 32647, + 32610, 32568, 32521, 32469, 32413, 32351, 32285, 32214, + 32138, 32057, 31971, 31881, 31785, 31685, 31581, 31471, + 31357, 31237, 31114, 30985, 30852, 30714, 30572, 30425, + 30273, 30117, 29956, 29791, 29621, 29447, 29269, 29086, + 28898, 28707, 28511, 28310, 28106, 27897, 27684, 27466, + 27245, 27020, 26790, 26557, 26319, 26077, 25832, 25583, + 25330, 25073, 24812, 24547, 24279, 24007, 23732, 23453, + 23170, 22884, 22594, 22301, 22005, 21706, 21403, 21097, + 20787, 20475, 20159, 19841, 19519, 19195, 18868, 18537, + 18204, 17869, 17530, 17189, 16846, 16499, 16151, 15800, + 15446, 15090, 14732, 14372, 14010, 13645, 13278, 12910, + 12539, 12167, 11793, 11416, 11039, 10659, 10278, 9896, + 9512, 9126, 8739, 8351, 7961, 7571, 7179, 6786, + 6392, 5997, 5602, 5205, 4808, 4409, 4011, 3611, + 3211, 2811, 2410, 2009, 1607, 1206, 804, 402, + 0, -402, -804, -1206, -1607, -2009, -2410, -2811, + -3211, -3611, -4011, -4409, -4808, -5205, -5602, -5997, + -6392, -6786, -7179, -7571, -7961, -8351, -8739, -9126, + -9512, -9896, -10278, -10659, -11039, -11416, -11793, -12167, + -12539, -12910, -13278, -13645, -14010, -14372, -14732, -15090, + -15446, -15800, -16151, -16499, -16846, -17189, -17530, -17869, + -18204, -18537, -18868, -19195, -19519, -19841, -20159, -20475, + -20787, -21097, -21403, -21706, -22005, -22301, -22594, -22884, + -23170, -23453, -23732, -24007, -24279, -24547, -24812, -25073, + -25330, -25583, -25832, -26077, -26319, -26557, -26790, -27020, + -27245, -27466, -27684, -27897, -28106, -28310, -28511, -28707, + -28898, -29086, -29269, -29447, -29621, -29791, -29956, -30117, + -30273, -30425, -30572, -30714, -30852, -30985, -31114, -31237, + -31357, -31471, -31581, -31685, -31785, -31881, -31971, -32057, + -32138, -32214, -32285, -32351, -32413, -32469, -32521, -32568, + -32610, -32647, -32679, -32706, -32728, -32745, -32758, -32765, + -32767, -32765, -32758, -32745, -32728, -32706, -32679, -32647, + -32610, -32568, -32521, -32469, -32413, -32351, -32285, -32214, + -32138, -32057, -31971, -31881, -31785, -31685, -31581, -31471, + -31357, -31237, -31114, -30985, -30852, -30714, -30572, -30425, + -30273, -30117, -29956, -29791, -29621, -29447, -29269, -29086, + -28898, -28707, -28511, -28310, -28106, -27897, -27684, -27466, + -27245, -27020, -26790, -26557, -26319, -26077, -25832, -25583, + -25330, -25073, -24812, -24547, -24279, -24007, -23732, -23453, + -23170, -22884, -22594, -22301, -22005, -21706, -21403, -21097, + -20787, -20475, -20159, -19841, -19519, -19195, -18868, -18537, + -18204, -17869, -17530, -17189, -16846, -16499, -16151, -15800, + -15446, -15090, -14732, -14372, -14010, -13645, -13278, -12910, + -12539, -12167, -11793, -11416, -11039, -10659, -10278, -9896, + -9512, -9126, -8739, -8351, -7961, -7571, -7179, -6786, + -6392, -5997, -5602, -5205, -4808, -4409, -4011, -3611, + -3211, -2811, -2410, -2009, -1607, -1206, -804, -402, + 0, 402, 804, 1206, 1607, 2009, 2410, 2811, + 3211, 3611, 4011, 4409, 4808, 5205, 5602, 5997, + 6392, 6786, 7179, 7571, 7961, 8351, 8739, 9126, + 9512, 9896, 10278, 10659, 11039, 11416, 11793, 12167, + 12539, 12910, 13278, 13645, 14010, 14372, 14732, 15090, + 15446, 15800, 16151, 16499, 16846, 17189, 17530, 17869, + 18204, 18537, 18868, 19195, 19519, 19841, 20159, 20475, + 20787, 21097, 21403, 21706, 22005, 22301, 22594, 22884, + 23170, 23453, 23732, 24007, 24279, 24547, 24812, 25073, + 25330, 25583, 25832, 26077, 26319, 26557, 26790, 27020, + 27245, 27466, 27684, 27897, 28106, 28310, 28511, 28707, + 28898, 29086, 29269, 29447, 29621, 29791, 29956, 30117, + 30273, 30425, 30572, 30714, 30852, 30985, 31114, 31237, + 31357, 31471, 31581, 31685, 31785, 31881, 31971, 32057, + 32138, 32214, 32285, 32351, 32413, 32469, 32521, 32568, + 32610, 32647, 32679, 32706, 32728, 32745, 32758, 32765 }; diff --git a/source/cheats.c b/source/cheats.c index 060d2ba..62d9a76 100644 --- a/source/cheats.c +++ b/source/cheats.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -93,114 +93,115 @@ #include "cheats.h" #include "memmap.h" -static bool8 S9xAllHex (const char *code, int len) +static bool8 S9xAllHex(const char* code, int len) { int i; - for (i = 0; i < len; i++) - if ((code [i] < '0' || code [i] > '9') && + for (i = 0; i < len; i++) + if ((code [i] < '0' || code [i] > '9') && (code [i] < 'a' || code [i] > 'f') && (code [i] < 'A' || code [i] > 'F')) - return (FALSE); + return (FALSE); - return (TRUE); + return (TRUE); } -const char *S9xProActionReplayToRaw (const char *code, uint32 *address, uint8 *byte) +const char* S9xProActionReplayToRaw(const char* code, uint32* address, + uint8* byte) { - uint32 data = 0; - if (strlen (code) != 8 || !S9xAllHex (code, 8) || - sscanf (code, "%x", &data) != 1) - return ("Invalid Pro Action Replay code - should be 8 hex digits in length."); - - *address = data >> 8; - *byte = (uint8) data; - return (NULL); + uint32 data = 0; + if (strlen(code) != 8 || !S9xAllHex(code, 8) || + sscanf(code, "%x", &data) != 1) + return ("Invalid Pro Action Replay code - should be 8 hex digits in length."); + + *address = data >> 8; + *byte = (uint8) data; + return (NULL); } -const char *S9xGoldFingerToRaw (const char *code, uint32 *address, bool8 *sram, - uint8 *num_bytes, uint8 bytes[3]) +const char* S9xGoldFingerToRaw(const char* code, uint32* address, bool8* sram, + uint8* num_bytes, uint8 bytes[3]) { - char tmp [15]; - if (strlen (code) != 14) - return ("Invalid Gold Finger code should be 14 hex digits in length."); - - strncpy (tmp, code, 5); - tmp [5] = 0; - if (sscanf (tmp, "%x", address) != 1) - return ("Invalid Gold Finger code."); - - int i; - for (i = 0; i < 3; i++) - { - strncpy (tmp, code + 5 + i * 2, 2); - tmp [2] = 0; - int byte; - if (sscanf (tmp, "%x", &byte) != 1) - break; - bytes [i] = (uint8) byte; - } - *num_bytes = i; - *sram = code [13] == '1'; - return (NULL); + char tmp [15]; + if (strlen(code) != 14) + return ("Invalid Gold Finger code should be 14 hex digits in length."); + + strncpy(tmp, code, 5); + tmp [5] = 0; + if (sscanf(tmp, "%x", address) != 1) + return ("Invalid Gold Finger code."); + + int i; + for (i = 0; i < 3; i++) + { + strncpy(tmp, code + 5 + i * 2, 2); + tmp [2] = 0; + int byte; + if (sscanf(tmp, "%x", &byte) != 1) + break; + bytes [i] = (uint8) byte; + } + *num_bytes = i; + *sram = code [13] == '1'; + return (NULL); } -const char *S9xGameGenieToRaw (const char *code, uint32 *address, uint8 *byte) +const char* S9xGameGenieToRaw(const char* code, uint32* address, uint8* byte) { - char new_code [12]; - - if (strlen (code) != 9 || *(code + 4) != '-' || !S9xAllHex (code, 4) || - !S9xAllHex (code + 5, 4)) - return ("Invalid Game Genie(tm) code - should be 'xxxx-xxxx'."); - - strcpy (new_code, "0x"); - strncpy (new_code + 2, code, 4); - strcpy (new_code + 6, code + 5); - - static char *real_hex = "0123456789ABCDEF"; - static char *genie_hex = "DF4709156BC8A23E"; - - int i; - for (i = 2; i < 10; i++) - { - if (islower (new_code [i])) - new_code [i] = toupper (new_code [i]); - int j; - for (j = 0; j < 16; j++) - { - if (new_code [i] == genie_hex [j]) - { - new_code [i] = real_hex [j]; - break; - } - } - if (j == 16) - return ("Invalid hex-character in Game Genie(tm) code"); - } - uint32 data = 0; - sscanf (new_code, "%x", &data); - *byte = (uint8)(data >> 24); - *address = ((data & 0x003c00) << 10) + - ((data & 0x00003c) << 14) + - ((data & 0xf00000) >> 8) + - ((data & 0x000003) << 10) + - ((data & 0x00c000) >> 6) + - ((data & 0x0f0000) >> 12) + - ((data & 0x0003c0) >> 6); - - return (NULL); + char new_code [12]; + + if (strlen(code) != 9 || *(code + 4) != '-' || !S9xAllHex(code, 4) || + !S9xAllHex(code + 5, 4)) + return ("Invalid Game Genie(tm) code - should be 'xxxx-xxxx'."); + + strcpy(new_code, "0x"); + strncpy(new_code + 2, code, 4); + strcpy(new_code + 6, code + 5); + + static char* real_hex = "0123456789ABCDEF"; + static char* genie_hex = "DF4709156BC8A23E"; + + int i; + for (i = 2; i < 10; i++) + { + if (islower(new_code [i])) + new_code [i] = toupper(new_code [i]); + int j; + for (j = 0; j < 16; j++) + { + if (new_code [i] == genie_hex [j]) + { + new_code [i] = real_hex [j]; + break; + } + } + if (j == 16) + return ("Invalid hex-character in Game Genie(tm) code"); + } + uint32 data = 0; + sscanf(new_code, "%x", &data); + *byte = (uint8)(data >> 24); + *address = ((data & 0x003c00) << 10) + + ((data & 0x00003c) << 14) + + ((data & 0xf00000) >> 8) + + ((data & 0x000003) << 10) + + ((data & 0x00c000) >> 6) + + ((data & 0x0f0000) >> 12) + + ((data & 0x0003c0) >> 6); + + return (NULL); } -void S9xStartCheatSearch (SCheatData *d) +void S9xStartCheatSearch(SCheatData* d) { - // memmove may be required: Source is usually a different malloc, but could be pointed to d->CWRAM [Neb] - memmove (d->CWRAM, d->RAM, 0x20000); - // memmove may be required: Source is usually a different malloc, but could be pointed to d->CSRAM [Neb] - memmove (d->CSRAM, d->SRAM, 0x10000); - // memmove may be required: Source is usually a different malloc, but could be pointed to d->CIRAM [Neb] - memmove (d->CIRAM, &d->FillRAM [0x3000], 0x2000); - memset ((char *) d->WRAM_BITS, 0xff, 0x20000 >> 3); - memset ((char *) d->SRAM_BITS, 0xff, 0x10000 >> 3); - memset ((char *) d->IRAM_BITS, 0xff, 0x2000 >> 3); + // memmove may be required: Source is usually a different malloc, but could be pointed to d->CWRAM [Neb] + memmove(d->CWRAM, d->RAM, 0x20000); + // memmove may be required: Source is usually a different malloc, but could be pointed to d->CSRAM [Neb] + memmove(d->CSRAM, d->SRAM, 0x10000); + // memmove may be required: Source is usually a different malloc, but could be pointed to d->CIRAM [Neb] + memmove(d->CIRAM, &d->FillRAM [0x3000], 0x2000); + memset((char*) d->WRAM_BITS, 0xff, 0x20000 >> 3); + memset((char*) d->SRAM_BITS, 0xff, 0x10000 >> 3); + memset((char*) d->IRAM_BITS, 0xff, 0x2000 >> 3); } #define BIT_CLEAR(a,v) \ @@ -232,213 +233,229 @@ void S9xStartCheatSearch (SCheatData *d) (s) == S9X_24_BITS ? (((int32) ((*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16)) << 8)) >> 8): \ ((int32) (*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16) + (*((m) + (o) + 3) << 24)))) -void S9xSearchForChange (SCheatData *d, S9xCheatComparisonType cmp, - S9xCheatDataSize size, bool8 is_signed, bool8 update) +void S9xSearchForChange(SCheatData* d, S9xCheatComparisonType cmp, + S9xCheatDataSize size, bool8 is_signed, bool8 update) { - int l; - - switch (size) - { - case S9X_8_BITS: l = 0; break; - case S9X_16_BITS: l = 1; break; - case S9X_24_BITS: l = 2; break; - default: - case S9X_32_BITS: l = 3; break; - } - - int i; - if (is_signed) - { - for (i = 0; i < 0x20000 - l; i++) - { - if (TEST_BIT (d->WRAM_BITS, i) && - _C(cmp, _DS(size, d->RAM, i), _DS(size, d->CWRAM, i))) - { - if (update) - d->CWRAM [i] = d->RAM [i]; - } - else - BIT_CLEAR (d->WRAM_BITS, i); - } - - for (i = 0; i < 0x10000 - l; i++) - { - if (TEST_BIT (d->SRAM_BITS, i) && - _C(cmp, _DS(size, d->SRAM, i), _DS(size, d->CSRAM, i))) - { - if (update) - d->CSRAM [i] = d->SRAM [i]; - } - else - BIT_CLEAR (d->SRAM_BITS, i); - } - - for (i = 0; i < 0x2000 - l; i++) - { - if (TEST_BIT (d->IRAM_BITS, i) && - _C(cmp, _DS(size, d->FillRAM + 0x3000, i), _DS(size, d->CIRAM, i))) - { - if (update) - d->CIRAM [i] = d->FillRAM [i + 0x3000]; - } - else - BIT_CLEAR (d->IRAM_BITS, i); - } - } - else - { - for (i = 0; i < 0x20000 - l; i++) - { - if (TEST_BIT (d->WRAM_BITS, i) && - _C(cmp, _D(size, d->RAM, i), _D(size, d->CWRAM, i))) - { - if (update) - d->CWRAM [i] = d->RAM [i]; - } - else - BIT_CLEAR (d->WRAM_BITS, i); - } - - for (i = 0; i < 0x10000 - l; i++) - { - if (TEST_BIT (d->SRAM_BITS, i) && - _C(cmp, _D(size, d->SRAM, i), _D(size, d->CSRAM, i))) - { - if (update) - d->CSRAM [i] = d->SRAM [i]; - } - else - BIT_CLEAR (d->SRAM_BITS, i); - } - - for (i = 0; i < 0x2000 - l; i++) - { - if (TEST_BIT (d->IRAM_BITS, i) && - _C(cmp, _D(size, d->FillRAM + 0x3000, i), _D(size, d->CIRAM, i))) - { - if (update) - d->CIRAM [i] = d->FillRAM [i + 0x3000]; - } - else - BIT_CLEAR (d->IRAM_BITS, i); - } - } + int l; + + switch (size) + { + case S9X_8_BITS: + l = 0; + break; + case S9X_16_BITS: + l = 1; + break; + case S9X_24_BITS: + l = 2; + break; + default: + case S9X_32_BITS: + l = 3; + break; + } + + int i; + if (is_signed) + { + for (i = 0; i < 0x20000 - l; i++) + { + if (TEST_BIT(d->WRAM_BITS, i) && + _C(cmp, _DS(size, d->RAM, i), _DS(size, d->CWRAM, i))) + { + if (update) + d->CWRAM [i] = d->RAM [i]; + } + else + BIT_CLEAR(d->WRAM_BITS, i); + } + + for (i = 0; i < 0x10000 - l; i++) + { + if (TEST_BIT(d->SRAM_BITS, i) && + _C(cmp, _DS(size, d->SRAM, i), _DS(size, d->CSRAM, i))) + { + if (update) + d->CSRAM [i] = d->SRAM [i]; + } + else + BIT_CLEAR(d->SRAM_BITS, i); + } + + for (i = 0; i < 0x2000 - l; i++) + { + if (TEST_BIT(d->IRAM_BITS, i) && + _C(cmp, _DS(size, d->FillRAM + 0x3000, i), _DS(size, d->CIRAM, i))) + { + if (update) + d->CIRAM [i] = d->FillRAM [i + 0x3000]; + } + else + BIT_CLEAR(d->IRAM_BITS, i); + } + } + else + { + for (i = 0; i < 0x20000 - l; i++) + { + if (TEST_BIT(d->WRAM_BITS, i) && + _C(cmp, _D(size, d->RAM, i), _D(size, d->CWRAM, i))) + { + if (update) + d->CWRAM [i] = d->RAM [i]; + } + else + BIT_CLEAR(d->WRAM_BITS, i); + } + + for (i = 0; i < 0x10000 - l; i++) + { + if (TEST_BIT(d->SRAM_BITS, i) && + _C(cmp, _D(size, d->SRAM, i), _D(size, d->CSRAM, i))) + { + if (update) + d->CSRAM [i] = d->SRAM [i]; + } + else + BIT_CLEAR(d->SRAM_BITS, i); + } + + for (i = 0; i < 0x2000 - l; i++) + { + if (TEST_BIT(d->IRAM_BITS, i) && + _C(cmp, _D(size, d->FillRAM + 0x3000, i), _D(size, d->CIRAM, i))) + { + if (update) + d->CIRAM [i] = d->FillRAM [i + 0x3000]; + } + else + BIT_CLEAR(d->IRAM_BITS, i); + } + } } -void S9xSearchForValue (SCheatData *d, S9xCheatComparisonType cmp, - S9xCheatDataSize size, uint32 value, - bool8 is_signed, bool8 update) +void S9xSearchForValue(SCheatData* d, S9xCheatComparisonType cmp, + S9xCheatDataSize size, uint32 value, + bool8 is_signed, bool8 update) { - int l; - - switch (size) - { - case S9X_8_BITS: l = 0; break; - case S9X_16_BITS: l = 1; break; - case S9X_24_BITS: l = 2; break; - default: - case S9X_32_BITS: l = 3; break; - } - - int i; - - if (is_signed) - { - for (i = 0; i < 0x20000 - l; i++) - { - if (TEST_BIT (d->WRAM_BITS, i) && - _C(cmp, _DS(size, d->RAM, i), (int32) value)) - { - if (update) - d->CWRAM [i] = d->RAM [i]; - } - else - BIT_CLEAR (d->WRAM_BITS, i); - } - - for (i = 0; i < 0x10000 - l; i++) - { - if (TEST_BIT (d->SRAM_BITS, i) && - _C(cmp, _DS(size, d->SRAM, i), (int32) value)) - { - if (update) - d->CSRAM [i] = d->SRAM [i]; - } - else - BIT_CLEAR (d->SRAM_BITS, i); - } - - for (i = 0; i < 0x2000 - l; i++) - { - if (TEST_BIT (d->IRAM_BITS, i) && - _C(cmp, _DS(size, d->FillRAM + 0x3000, i), (int32) value)) - { - if (update) - d->CIRAM [i] = d->FillRAM [i + 0x3000]; - } - else - BIT_CLEAR (d->IRAM_BITS, i); - } - } - else - { - for (i = 0; i < 0x20000 - l; i++) - { - if (TEST_BIT (d->WRAM_BITS, i) && - _C(cmp, _D(size, d->RAM, i), value)) - { - if (update) - d->CWRAM [i] = d->RAM [i]; - } - else - BIT_CLEAR (d->WRAM_BITS, i); - } - - for (i = 0; i < 0x10000 - l; i++) - { - if (TEST_BIT (d->SRAM_BITS, i) && - _C(cmp, _D(size, d->SRAM, i), value)) - { - if (update) - d->CSRAM [i] = d->SRAM [i]; - } - else - BIT_CLEAR (d->SRAM_BITS, i); - } - - for (i = 0; i < 0x2000 - l; i++) - { - if (TEST_BIT (d->IRAM_BITS, i) && - _C(cmp, _D(size, d->FillRAM + 0x3000, i), value)) - { - if (update) - d->CIRAM [i] = d->FillRAM [i + 0x3000]; - } - else - BIT_CLEAR (d->IRAM_BITS, i); - } - } + int l; + + switch (size) + { + case S9X_8_BITS: + l = 0; + break; + case S9X_16_BITS: + l = 1; + break; + case S9X_24_BITS: + l = 2; + break; + default: + case S9X_32_BITS: + l = 3; + break; + } + + int i; + + if (is_signed) + { + for (i = 0; i < 0x20000 - l; i++) + { + if (TEST_BIT(d->WRAM_BITS, i) && + _C(cmp, _DS(size, d->RAM, i), (int32) value)) + { + if (update) + d->CWRAM [i] = d->RAM [i]; + } + else + BIT_CLEAR(d->WRAM_BITS, i); + } + + for (i = 0; i < 0x10000 - l; i++) + { + if (TEST_BIT(d->SRAM_BITS, i) && + _C(cmp, _DS(size, d->SRAM, i), (int32) value)) + { + if (update) + d->CSRAM [i] = d->SRAM [i]; + } + else + BIT_CLEAR(d->SRAM_BITS, i); + } + + for (i = 0; i < 0x2000 - l; i++) + { + if (TEST_BIT(d->IRAM_BITS, i) && + _C(cmp, _DS(size, d->FillRAM + 0x3000, i), (int32) value)) + { + if (update) + d->CIRAM [i] = d->FillRAM [i + 0x3000]; + } + else + BIT_CLEAR(d->IRAM_BITS, i); + } + } + else + { + for (i = 0; i < 0x20000 - l; i++) + { + if (TEST_BIT(d->WRAM_BITS, i) && + _C(cmp, _D(size, d->RAM, i), value)) + { + if (update) + d->CWRAM [i] = d->RAM [i]; + } + else + BIT_CLEAR(d->WRAM_BITS, i); + } + + for (i = 0; i < 0x10000 - l; i++) + { + if (TEST_BIT(d->SRAM_BITS, i) && + _C(cmp, _D(size, d->SRAM, i), value)) + { + if (update) + d->CSRAM [i] = d->SRAM [i]; + } + else + BIT_CLEAR(d->SRAM_BITS, i); + } + + for (i = 0; i < 0x2000 - l; i++) + { + if (TEST_BIT(d->IRAM_BITS, i) && + _C(cmp, _D(size, d->FillRAM + 0x3000, i), value)) + { + if (update) + d->CIRAM [i] = d->FillRAM [i + 0x3000]; + } + else + BIT_CLEAR(d->IRAM_BITS, i); + } + } } -void S9xOutputCheatSearchResults (SCheatData *d) +void S9xOutputCheatSearchResults(SCheatData* d) { - int i; - for (i = 0; i < 0x20000; i++) - { - if (TEST_BIT (d->WRAM_BITS, i)) - printf ("WRAM: %05x: %02x\n", i, d->RAM [i]); - } - - for (i = 0; i < 0x10000; i++) - { - if (TEST_BIT (d->SRAM_BITS, i)) - printf ("SRAM: %04x: %02x\n", i, d->SRAM [i]); - } - - for (i = 0; i < 0x2000; i++) - { - if (TEST_BIT (d->IRAM_BITS, i)) - printf ("IRAM: %05x: %02x\n", i, d->FillRAM [i + 0x3000]); - } + int i; + for (i = 0; i < 0x20000; i++) + { + if (TEST_BIT(d->WRAM_BITS, i)) + printf("WRAM: %05x: %02x\n", i, d->RAM [i]); + } + + for (i = 0; i < 0x10000; i++) + { + if (TEST_BIT(d->SRAM_BITS, i)) + printf("SRAM: %04x: %02x\n", i, d->SRAM [i]); + } + + for (i = 0; i < 0x2000; i++) + { + if (TEST_BIT(d->IRAM_BITS, i)) + printf("IRAM: %05x: %02x\n", i, d->FillRAM [i + 0x3000]); + } } diff --git a/source/cheats2.c b/source/cheats2.c index 845918d..8118552 100644 --- a/source/cheats2.c +++ b/source/cheats2.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -95,193 +95,196 @@ extern SCheatData Cheat; -void S9xInitCheatData () +void S9xInitCheatData() { - Cheat.RAM = Memory.RAM; - Cheat.SRAM = Memory.SRAM; - Cheat.FillRAM = Memory.FillRAM; + Cheat.RAM = Memory.RAM; + Cheat.SRAM = Memory.SRAM; + Cheat.FillRAM = Memory.FillRAM; } -void S9xAddCheat (bool8 enable, bool8 save_current_value, - uint32 address, uint8 byte) +void S9xAddCheat(bool8 enable, bool8 save_current_value, + uint32 address, uint8 byte) { - if (Cheat.num_cheats < sizeof (Cheat.c) / sizeof (Cheat.c [0])) - { - Cheat.c [Cheat.num_cheats].address = address; - Cheat.c [Cheat.num_cheats].byte = byte; - Cheat.c [Cheat.num_cheats].enabled = enable; - if (save_current_value) - { - Cheat.c [Cheat.num_cheats].saved_byte = S9xGetByte (address); - Cheat.c [Cheat.num_cheats].saved = TRUE; - } - Cheat.num_cheats++; - if (enable) - S9xApplyCheat(Cheat.num_cheats - 1); - } + if (Cheat.num_cheats < sizeof(Cheat.c) / sizeof(Cheat.c [0])) + { + Cheat.c [Cheat.num_cheats].address = address; + Cheat.c [Cheat.num_cheats].byte = byte; + Cheat.c [Cheat.num_cheats].enabled = enable; + if (save_current_value) + { + Cheat.c [Cheat.num_cheats].saved_byte = S9xGetByte(address); + Cheat.c [Cheat.num_cheats].saved = TRUE; + } + Cheat.num_cheats++; + if (enable) + S9xApplyCheat(Cheat.num_cheats - 1); + } } -void S9xDeleteCheat (uint32 which1) +void S9xDeleteCheat(uint32 which1) { - if (which1 < Cheat.num_cheats) - { - if (Cheat.c [which1].enabled) - S9xRemoveCheat (which1); - - // memmove required: Overlapping addresses [Neb] - memmove (&Cheat.c [which1], &Cheat.c [which1 + 1], - sizeof (Cheat.c [0]) * (Cheat.num_cheats - which1 - 1)); - Cheat.num_cheats--; //MK: This used to set it to 0?? - } + if (which1 < Cheat.num_cheats) + { + if (Cheat.c [which1].enabled) + S9xRemoveCheat(which1); + + // memmove required: Overlapping addresses [Neb] + memmove(&Cheat.c [which1], &Cheat.c [which1 + 1], + sizeof(Cheat.c [0]) * (Cheat.num_cheats - which1 - 1)); + Cheat.num_cheats--; //MK: This used to set it to 0?? + } } -void S9xDeleteCheats () +void S9xDeleteCheats() { - S9xRemoveCheats (); - Cheat.num_cheats = 0; + S9xRemoveCheats(); + Cheat.num_cheats = 0; } -void S9xEnableCheat (uint32 which1) +void S9xEnableCheat(uint32 which1) { - if (which1 < Cheat.num_cheats && !Cheat.c [which1].enabled) - { - Cheat.c [which1].enabled = TRUE; - S9xApplyCheat (which1); - } + if (which1 < Cheat.num_cheats && !Cheat.c [which1].enabled) + { + Cheat.c [which1].enabled = TRUE; + S9xApplyCheat(which1); + } } -void S9xDisableCheat (uint32 which1) +void S9xDisableCheat(uint32 which1) { - if (which1 < Cheat.num_cheats && Cheat.c [which1].enabled) - { - S9xRemoveCheat (which1); - Cheat.c [which1].enabled = FALSE; - } + if (which1 < Cheat.num_cheats && Cheat.c [which1].enabled) + { + S9xRemoveCheat(which1); + Cheat.c [which1].enabled = FALSE; + } } -void S9xRemoveCheat (uint32 which1) +void S9xRemoveCheat(uint32 which1) { - if (Cheat.c [which1].saved) - { - uint32 address = Cheat.c [which1].address; - - int block = (address >> MEMMAP_SHIFT) & MEMMAP_MASK; - uint8 *ptr = Memory.Map [block]; - - if (ptr >= (uint8 *) MAP_LAST) - *(ptr + (address & 0xffff)) = Cheat.c [which1].saved_byte; - else - S9xSetByte (Cheat.c [which1].saved_byte, address); - // Unsave the address for the next call to S9xRemoveCheat. - Cheat.c [which1].saved = FALSE; - } + if (Cheat.c [which1].saved) + { + uint32 address = Cheat.c [which1].address; + + int block = (address >> MEMMAP_SHIFT) & MEMMAP_MASK; + uint8* ptr = Memory.Map [block]; + + if (ptr >= (uint8*) MAP_LAST) + *(ptr + (address & 0xffff)) = Cheat.c [which1].saved_byte; + else + S9xSetByte(Cheat.c [which1].saved_byte, address); + // Unsave the address for the next call to S9xRemoveCheat. + Cheat.c [which1].saved = FALSE; + } } -void S9xApplyCheat (uint32 which1) +void S9xApplyCheat(uint32 which1) { - uint32 address = Cheat.c [which1].address; - - if (!Cheat.c [which1].saved) - Cheat.c [which1].saved_byte = S9xGetByte (address); - - int block = (address >> MEMMAP_SHIFT) & MEMMAP_MASK; - uint8 *ptr = Memory.Map [block]; - - if (ptr >= (uint8 *) MAP_LAST) - *(ptr + (address & 0xffff)) = Cheat.c [which1].byte; - else - S9xSetByte (Cheat.c [which1].byte, address); - Cheat.c [which1].saved = TRUE; + uint32 address = Cheat.c [which1].address; + + if (!Cheat.c [which1].saved) + Cheat.c [which1].saved_byte = S9xGetByte(address); + + int block = (address >> MEMMAP_SHIFT) & MEMMAP_MASK; + uint8* ptr = Memory.Map [block]; + + if (ptr >= (uint8*) MAP_LAST) + *(ptr + (address & 0xffff)) = Cheat.c [which1].byte; + else + S9xSetByte(Cheat.c [which1].byte, address); + Cheat.c [which1].saved = TRUE; } -void S9xApplyCheats () +void S9xApplyCheats() { - uint32 i; - if (Settings.ApplyCheats) - { - for (i = 0; i < Cheat.num_cheats; i++) - if (Cheat.c [i].enabled) - S9xApplyCheat (i); - } + uint32 i; + if (Settings.ApplyCheats) + { + for (i = 0; i < Cheat.num_cheats; i++) + if (Cheat.c [i].enabled) + S9xApplyCheat(i); + } } -void S9xRemoveCheats () +void S9xRemoveCheats() { uint32 i; for (i = 0; i < Cheat.num_cheats; i++) if (Cheat.c [i].enabled) - S9xRemoveCheat (i); + S9xRemoveCheat(i); } -bool8 S9xLoadCheatFile (const char *filename) +bool8 S9xLoadCheatFile(const char* filename) { - Cheat.num_cheats = 0; - - FILE *fs = fopen (filename, "rb"); - uint8 data [8 + MAX_SFCCHEAT_NAME]; - - if (!fs) - return (FALSE); - - while (fread ((void *) data, 1, 8 + MAX_SFCCHEAT_NAME, fs) == 8 + MAX_SFCCHEAT_NAME) - { - if (data[6] != 254 || data[7] != 252) { - fclose (fs); - return (FALSE); - } - Cheat.c [Cheat.num_cheats].enabled = (data [0] & 4) == 0; - Cheat.c [Cheat.num_cheats].byte = data [1]; - Cheat.c [Cheat.num_cheats].address = data [2] | (data [3] << 8) | (data [4] << 16); - Cheat.c [Cheat.num_cheats].saved_byte = data [5]; - Cheat.c [Cheat.num_cheats].saved = (data [0] & 8) != 0; - memcpy (Cheat.c [Cheat.num_cheats].name, &data [8], MAX_SFCCHEAT_NAME - 1); - Cheat.c [Cheat.num_cheats++].name [MAX_SFCCHEAT_NAME - 1] = 0; - } - fclose (fs); - - return (TRUE); + Cheat.num_cheats = 0; + + FILE* fs = fopen(filename, "rb"); + uint8 data [8 + MAX_SFCCHEAT_NAME]; + + if (!fs) + return (FALSE); + + while (fread((void*) data, 1, 8 + MAX_SFCCHEAT_NAME, + fs) == 8 + MAX_SFCCHEAT_NAME) + { + if (data[6] != 254 || data[7] != 252) + { + fclose(fs); + return (FALSE); + } + Cheat.c [Cheat.num_cheats].enabled = (data [0] & 4) == 0; + Cheat.c [Cheat.num_cheats].byte = data [1]; + Cheat.c [Cheat.num_cheats].address = data [2] | (data [3] << 8) | + (data [4] << 16); + Cheat.c [Cheat.num_cheats].saved_byte = data [5]; + Cheat.c [Cheat.num_cheats].saved = (data [0] & 8) != 0; + memcpy(Cheat.c [Cheat.num_cheats].name, &data [8], MAX_SFCCHEAT_NAME - 1); + Cheat.c [Cheat.num_cheats++].name [MAX_SFCCHEAT_NAME - 1] = 0; + } + fclose(fs); + + return (TRUE); } -bool8 S9xSaveCheatFile (const char *filename) +bool8 S9xSaveCheatFile(const char* filename) { - if (Cheat.num_cheats == 0) - { - (void) remove (filename); - return (TRUE); - } - - FILE *fs = fopen (filename, "wb"); - uint8 data [8 + MAX_SFCCHEAT_NAME]; - - if (!fs) - return (FALSE); - - uint32 i; - for (i = 0; i < Cheat.num_cheats; i++) - { - memset (data, 0, 8 + MAX_SFCCHEAT_NAME); - data [6] = 254; - data [7] = 252; - if (!Cheat.c [i].enabled) - data [0] |= 4; - - if (Cheat.c [i].saved) - data [0] |= 8; - - data [1] = Cheat.c [i].byte; - data [2] = (uint8) Cheat.c [i].address; - data [3] = (uint8) (Cheat.c [i].address >> 8); - data [4] = (uint8) (Cheat.c [i].address >> 16); - data [5] = Cheat.c [i].saved_byte; - - memcpy (&data [8], Cheat.c [i].name, MAX_SFCCHEAT_NAME - 1); - if (fwrite (data, 8 + MAX_SFCCHEAT_NAME, 1, fs) != 1) - { - fclose (fs); - return (FALSE); - } - } - - fclose (fs); - return (TRUE); + if (Cheat.num_cheats == 0) + { + (void) remove(filename); + return (TRUE); + } + + FILE* fs = fopen(filename, "wb"); + uint8 data [8 + MAX_SFCCHEAT_NAME]; + + if (!fs) + return (FALSE); + + uint32 i; + for (i = 0; i < Cheat.num_cheats; i++) + { + memset(data, 0, 8 + MAX_SFCCHEAT_NAME); + data [6] = 254; + data [7] = 252; + if (!Cheat.c [i].enabled) + data [0] |= 4; + + if (Cheat.c [i].saved) + data [0] |= 8; + + data [1] = Cheat.c [i].byte; + data [2] = (uint8) Cheat.c [i].address; + data [3] = (uint8)(Cheat.c [i].address >> 8); + data [4] = (uint8)(Cheat.c [i].address >> 16); + data [5] = Cheat.c [i].saved_byte; + + memcpy(&data [8], Cheat.c [i].name, MAX_SFCCHEAT_NAME - 1); + if (fwrite(data, 8 + MAX_SFCCHEAT_NAME, 1, fs) != 1) + { + fclose(fs); + return (FALSE); + } + } + + fclose(fs); + return (TRUE); } diff --git a/source/clip.c b/source/clip.c index c2af922..dd4a16b 100644 --- a/source/clip.c +++ b/source/clip.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -94,8 +94,8 @@ struct Band { - uint32 Left; - uint32 Right; + uint32 Left; + uint32 Right; }; #undef MIN @@ -104,671 +104,662 @@ struct Band #define MAX(A,B) ((A) > (B) ? (A) : (B)) #define BAND_EMPTY(B) (B.Left >= B.Right) #define BANDS_INTERSECT(A,B) ((A.Left >= B.Left && A.Left < B.Right) || \ - (B.Left >= A.Left && B.Left < A.Right)) + (B.Left >= A.Left && B.Left < A.Right)) #define OR_BANDS(R,A,B) {\ R.Left = MIN(A.Left, B.Left); \ - R.Right = MAX(A.Right, B.Right);} + R.Right = MAX(A.Right, B.Right);} #define AND_BANDS(R,A,B) {\ R.Left = MAX(A.Left, B.Left); \ - R.Right = MIN(A.Right, B.Right);} + R.Right = MIN(A.Right, B.Right);} -static int IntCompare (const void *d1, const void *d2) +static int IntCompare(const void* d1, const void* d2) { - if (*(uint32 *) d1 > *(uint32 *) d2) - return (1); - else - if (*(uint32 *) d1 < *(uint32 *) d2) - return (-1); - return (0); + if (*(uint32*) d1 > *(uint32*) d2) + return (1); + else if (*(uint32*) d1 < * (uint32*) d2) + return (-1); + return (0); } -static int BandCompare (const void *d1, const void *d2) +static int BandCompare(const void* d1, const void* d2) { - if (((struct Band *) d1)->Left > ((struct Band *) d2)->Left) - return (1); - else - if (((struct Band *) d1)->Left < ((struct Band *) d2)->Left) - return (-1); - return (0); + if (((struct Band*) d1)->Left > ((struct Band*) d2)->Left) + return (1); + else if (((struct Band*) d1)->Left < ((struct Band*) d2)->Left) + return (-1); + return (0); } -void ComputeClipWindows () +void ComputeClipWindows() { - struct ClipData *pClip = &IPPU.Clip [0]; - int c,w,i; + struct ClipData* pClip = &IPPU.Clip [0]; + int c, w, i; - // Loop around the main screen then the sub-screen. + // Loop around the main screen then the sub-screen. for (c = 0; c < 2; c++, pClip++) - { - // Loop around the colour window then a clip window for each of the - // background layers. + { + // Loop around the colour window then a clip window for each of the + // background layers. for (w = 5; w >= 0; w--) - { - pClip->Count[w] = 0; - - if (w == 5) // The colour window... - { - if (c == 0) // ... on the main screen - { - if ((Memory.FillRAM [0x2130] & 0xc0) == 0xc0) - { - // The whole of the main screen is switched off, - // completely clip everything. + { + pClip->Count[w] = 0; + + if (w == 5) // The colour window... + { + if (c == 0) // ... on the main screen + { + if ((Memory.FillRAM [0x2130] & 0xc0) == 0xc0) + { + // The whole of the main screen is switched off, + // completely clip everything. for (i = 0; i < 6; i++) - { - IPPU.Clip [c].Count [i] = 1; - IPPU.Clip [c].Left [0][i] = 1; - IPPU.Clip [c].Right [0][i] = 0; - } - continue; - } - else if ((Memory.FillRAM [0x2130] & 0xc0) == 0x00) - continue; - } - else - { - // .. colour window on the sub-screen. - if ((Memory.FillRAM [0x2130] & 0x30) == 0x30) - { - // The sub-screen is switched off, completely - // clip everything. + { + IPPU.Clip [c].Count [i] = 1; + IPPU.Clip [c].Left [0][i] = 1; + IPPU.Clip [c].Right [0][i] = 0; + } + continue; + } + else if ((Memory.FillRAM [0x2130] & 0xc0) == 0x00) + continue; + } + else + { + // .. colour window on the sub-screen. + if ((Memory.FillRAM [0x2130] & 0x30) == 0x30) + { + // The sub-screen is switched off, completely + // clip everything. int i; for (i = 0; i < 6; i++) - { - IPPU.Clip [1].Count [i] = 1; - IPPU.Clip [1].Left [0][i] = 1; - IPPU.Clip [1].Right [0][i] = 0; - } - return; - } - else if ((Memory.FillRAM [0x2130] & 0x30) == 0x00) - continue; - } - } - -// if (!Settings.DisableGraphicWindows) - { - if (w == 5 || pClip->Count [5] || - (Memory.FillRAM [0x212c + c] & Memory.FillRAM [0x212e + c] & (1 << w))) - { - struct Band Win1[3]; - struct Band Win2[3]; - uint32 Window1Enabled = 0; - uint32 Window2Enabled = 0; - bool8 invert = (w == 5 && - ((c == 1 && (Memory.FillRAM [0x2130] & 0x30) == 0x10) || - (c == 0 && (Memory.FillRAM [0x2130] & 0xc0) == 0x40))); - - if (w == 5 || - (Memory.FillRAM [0x212c + c] & Memory.FillRAM [0x212e + c] & (1 << w))) - { - if (PPU.ClipWindow1Enable [w]) - { - if (!PPU.ClipWindow1Inside [w]) - { - Win1[Window1Enabled].Left = PPU.Window1Left; - Win1[Window1Enabled++].Right = PPU.Window1Right + 1; - } - else - { - if (PPU.Window1Left <= PPU.Window1Right) - { - if (PPU.Window1Left > 0) - { - Win1[Window1Enabled].Left = 0; - Win1[Window1Enabled++].Right = PPU.Window1Left; - } - if (PPU.Window1Right < 255) - { - Win1[Window1Enabled].Left = PPU.Window1Right + 1; - Win1[Window1Enabled++].Right = 256; - } - if (Window1Enabled == 0) - { - Win1[Window1Enabled].Left = 1; - Win1[Window1Enabled++].Right = 0; - } - } - else - { - // 'outside' a window with no range - - // appears to be the whole screen. - Win1[Window1Enabled].Left = 0; - Win1[Window1Enabled++].Right = 256; - } - } - } - if (PPU.ClipWindow2Enable [w]) - { - if (!PPU.ClipWindow2Inside [w]) - { - Win2[Window2Enabled].Left = PPU.Window2Left; - Win2[Window2Enabled++].Right = PPU.Window2Right + 1; - } - else - { - if (PPU.Window2Left <= PPU.Window2Right) - { - if (PPU.Window2Left > 0) - { - Win2[Window2Enabled].Left = 0; - Win2[Window2Enabled++].Right = PPU.Window2Left; - } - if (PPU.Window2Right < 255) - { - Win2[Window2Enabled].Left = PPU.Window2Right + 1; - Win2[Window2Enabled++].Right = 256; - } - if (Window2Enabled == 0) - { - Win2[Window2Enabled].Left = 1; - Win2[Window2Enabled++].Right = 0; - } - } - else - { - Win2[Window2Enabled].Left = 0; - Win2[Window2Enabled++].Right = 256; - } - } - } - } - if (Window1Enabled && Window2Enabled) - { - // Overlap logic - // - // Each window will be in one of three states: - // 1. (Left > Right. One band) - // 2. | ---------------- | (Left >= 0, Right <= 255, Left <= Right. One band) - // 3. |------------ ----------| (Left1 == 0, Right1 < Left2; Left2 > Right1, Right2 == 255. Two bands) - - struct Band Bands [6]; - int B = 0; - switch (PPU.ClipWindowOverlapLogic [w] ^ 1) - { - case CLIP_OR: - if (Window1Enabled == 1) - { - if (BAND_EMPTY(Win1[0])) - { - B = Window2Enabled; - // memmove converted: Different stack allocations [Neb] - memcpy (Bands, Win2, - sizeof(Win2[0]) * Window2Enabled); - } - else - { - if (Window2Enabled == 1) - { - if (BAND_EMPTY (Win2[0])) - Bands[B++] = Win1[0]; - else - { - if (BANDS_INTERSECT (Win1[0], Win2[0])) - { - OR_BANDS(Bands[0],Win1[0], Win2[0]) - B = 1; - } - else - { - Bands[B++] = Win1[0]; - Bands[B++] = Win2[0]; - } - } - } - else - { - if (BANDS_INTERSECT(Win1[0], Win2[0])) - { - OR_BANDS(Bands[0], Win1[0], Win2[0]) - if (BANDS_INTERSECT(Win1[0], Win2[1])) - OR_BANDS(Bands[1], Win1[0], Win2[1]) - else - Bands[1] = Win2[1]; - B = 1; - if (BANDS_INTERSECT(Bands[0], Bands[1])) - OR_BANDS(Bands[0], Bands[0], Bands[1]) - else - B = 2; - } - else - if (BANDS_INTERSECT(Win1[0], Win2[1])) - { - Bands[B++] = Win2[0]; - OR_BANDS(Bands[B], Win1[0], Win2[1]); - B++; - } - else - { - Bands[0] = Win2[0]; - Bands[1] = Win1[0]; - Bands[2] = Win2[1]; - B = 3; - } - } - } - } - else - if (Window2Enabled == 1) - { - if (BAND_EMPTY(Win2[0])) - { - // Window 2 defines an empty range - just - // use window 1 as the clipping (which - // could also be empty). - B = Window1Enabled; - // memmove converted: Different stack allocations [Neb] - memcpy (Bands, Win1, - sizeof(Win1[0]) * Window1Enabled); - } - else - { - // Window 1 has two bands and Window 2 has one. - // Neither is an empty region. - if (BANDS_INTERSECT(Win2[0], Win1[0])) - { - OR_BANDS(Bands[0], Win2[0], Win1[0]) - if (BANDS_INTERSECT(Win2[0], Win1[1])) - OR_BANDS(Bands[1], Win2[0], Win1[1]) - else - Bands[1] = Win1[1]; - B = 1; - if (BANDS_INTERSECT(Bands[0], Bands[1])) - OR_BANDS(Bands[0], Bands[0], Bands[1]) - else - B = 2; - } - else - if (BANDS_INTERSECT(Win2[0], Win1[1])) - { - Bands[B++] = Win1[0]; - OR_BANDS(Bands[B], Win2[0], Win1[1]); - B++; - } - else - { - Bands[0] = Win1[0]; - Bands[1] = Win2[0]; - Bands[2] = Win1[1]; - B = 3; - } - } - } - else - { - // Both windows have two bands - OR_BANDS(Bands[0], Win1[0], Win2[0]); - OR_BANDS(Bands[1], Win1[1], Win2[1]); - B = 1; - if (BANDS_INTERSECT(Bands[0], Bands[1])) - OR_BANDS(Bands[0], Bands[0], Bands[1]) - else - B = 2; - } - break; - - case CLIP_AND: - if (Window1Enabled == 1) - { - // Window 1 has one band - if (BAND_EMPTY(Win1[0])) - Bands [B++] = Win1[0]; - else - if (Window2Enabled == 1) - { - if (BAND_EMPTY (Win2[0])) - Bands [B++] = Win2[0]; - else - { - AND_BANDS(Bands[0], Win1[0], Win2[0]); - B = 1; - } - } - else - { - AND_BANDS(Bands[0], Win1[0], Win2[0]); - AND_BANDS(Bands[1], Win1[0], Win2[1]); - B = 2; - } - } - else - if (Window2Enabled == 1) - { - if (BAND_EMPTY(Win2[0])) - Bands[B++] = Win2[0]; - else - { - // Window 1 has two bands. - AND_BANDS(Bands[0], Win1[0], Win2[0]); - AND_BANDS(Bands[1], Win1[1], Win2[0]); - B = 2; - } - } - else - { - // Both windows have two bands. - AND_BANDS(Bands[0], Win1[0], Win2[0]); - AND_BANDS(Bands[1], Win1[1], Win2[1]); - B = 2; - if (BANDS_INTERSECT(Win1[0], Win2[1])) - { - AND_BANDS(Bands[2], Win1[0], Win2[1]); - B = 3; - } - else - if (BANDS_INTERSECT(Win1[1], Win2[0])) - { - AND_BANDS(Bands[2], Win1[1], Win2[0]); - B = 3; - } - } - break; - case CLIP_XNOR: - invert = !invert; - // Fall... - - case CLIP_XOR: - if (Window1Enabled == 1 && BAND_EMPTY(Win1[0])) - { - B = Window2Enabled; - // memmove converted: Different stack allocations [Neb] - memcpy (Bands, Win2, - sizeof(Win2[0]) * Window2Enabled); - } - else - if (Window2Enabled == 1 && BAND_EMPTY(Win2[0])) - { - B = Window1Enabled; - // memmove converted: Different stack allocations [Neb] - memcpy (Bands, Win1, - sizeof(Win1[0]) * Window1Enabled); - } - else - { - uint32 p = 0; - uint32 points [10]; - uint32 i; - - invert = !invert; - // Build an array of points (window edges) - points [p++] = 0; - for (i = 0; i < Window1Enabled; i++) - { - points [p++] = Win1[i].Left; - points [p++] = Win1[i].Right; - } - for (i = 0; i < Window2Enabled; i++) - { - points [p++] = Win2[i].Left; - points [p++] = Win2[i].Right; - } - points [p++] = 256; - // Sort them - qsort ((void *) points, p, sizeof (points [0]), - IntCompare); - for (i = 0; i < p; i += 2) - { - if (points [i] == points [i + 1]) - continue; - Bands [B].Left = points [i]; - while (i + 2 < p && - points [i + 1] == points [i + 2]) - { - i += 2; - } - Bands [B++].Right = points [i + 1]; - } - } - break; - } - if (invert) - { - int b; - int j = 0; - int empty_band_count = 0; - - // First remove all empty bands from the list. - for (b = 0; b < B; b++) - { - if (!BAND_EMPTY(Bands[b])) - { - if (b != j) - Bands[j] = Bands[b]; - j++; - } - else - empty_band_count++; - } - - if (j > 0) - { - if (j == 1) - { - j = 0; - // Easy case to deal with, so special case it. - - if (Bands[0].Left > 0) - { - pClip->Left[j][w] = 0; - pClip->Right[j++][w] = Bands[0].Left + 1; - } - if (Bands[0].Right < 256) - { - pClip->Left[j][w] = Bands[0].Right; - pClip->Right[j++][w] = 256; - } - if (j == 0) - { - pClip->Left[j][w] = 1; - pClip->Right[j++][w] = 0; - } - } - else - { - // Now sort the bands into order - B = j; - qsort ((void *) Bands, B, - sizeof (Bands [0]), BandCompare); - - // Now invert the area the bands cover - j = 0; - for (b = 0; b < B; b++) - { - if (b == 0 && Bands[b].Left > 0) - { - pClip->Left[j][w] = 0; - pClip->Right[j++][w] = Bands[b].Left + 1; - } - else - if (b == B - 1 && Bands[b].Right < 256) - { - pClip->Left[j][w] = Bands[b].Right; - pClip->Right[j++][w] = 256; - } - if (b < B - 1) - { - pClip->Left[j][w] = Bands[b].Right; - pClip->Right[j++][w] = Bands[b + 1].Left + 1; - } - } - } - } - else - { - // Inverting a window that consisted of only - // empty bands is the whole width of the screen. - // Needed for Mario Kart's rear-view mirror display. - if (empty_band_count) - { - pClip->Left[j][w] = 0; - pClip->Right[j][w] = 256; - j++; - } - } - pClip->Count[w] = j; - } - else - { + { + IPPU.Clip [1].Count [i] = 1; + IPPU.Clip [1].Left [0][i] = 1; + IPPU.Clip [1].Right [0][i] = 0; + } + return; + } + else if ((Memory.FillRAM [0x2130] & 0x30) == 0x00) + continue; + } + } + + // if (!Settings.DisableGraphicWindows) + { + if (w == 5 || pClip->Count [5] || + (Memory.FillRAM [0x212c + c] & Memory.FillRAM [0x212e + c] & (1 << w))) + { + struct Band Win1[3]; + struct Band Win2[3]; + uint32 Window1Enabled = 0; + uint32 Window2Enabled = 0; + bool8 invert = (w == 5 && + ((c == 1 && (Memory.FillRAM [0x2130] & 0x30) == 0x10) || + (c == 0 && (Memory.FillRAM [0x2130] & 0xc0) == 0x40))); + + if (w == 5 || + (Memory.FillRAM [0x212c + c] & Memory.FillRAM [0x212e + c] & (1 << w))) + { + if (PPU.ClipWindow1Enable [w]) + { + if (!PPU.ClipWindow1Inside [w]) + { + Win1[Window1Enabled].Left = PPU.Window1Left; + Win1[Window1Enabled++].Right = PPU.Window1Right + 1; + } + else + { + if (PPU.Window1Left <= PPU.Window1Right) + { + if (PPU.Window1Left > 0) + { + Win1[Window1Enabled].Left = 0; + Win1[Window1Enabled++].Right = PPU.Window1Left; + } + if (PPU.Window1Right < 255) + { + Win1[Window1Enabled].Left = PPU.Window1Right + 1; + Win1[Window1Enabled++].Right = 256; + } + if (Window1Enabled == 0) + { + Win1[Window1Enabled].Left = 1; + Win1[Window1Enabled++].Right = 0; + } + } + else + { + // 'outside' a window with no range - + // appears to be the whole screen. + Win1[Window1Enabled].Left = 0; + Win1[Window1Enabled++].Right = 256; + } + } + } + if (PPU.ClipWindow2Enable [w]) + { + if (!PPU.ClipWindow2Inside [w]) + { + Win2[Window2Enabled].Left = PPU.Window2Left; + Win2[Window2Enabled++].Right = PPU.Window2Right + 1; + } + else + { + if (PPU.Window2Left <= PPU.Window2Right) + { + if (PPU.Window2Left > 0) + { + Win2[Window2Enabled].Left = 0; + Win2[Window2Enabled++].Right = PPU.Window2Left; + } + if (PPU.Window2Right < 255) + { + Win2[Window2Enabled].Left = PPU.Window2Right + 1; + Win2[Window2Enabled++].Right = 256; + } + if (Window2Enabled == 0) + { + Win2[Window2Enabled].Left = 1; + Win2[Window2Enabled++].Right = 0; + } + } + else + { + Win2[Window2Enabled].Left = 0; + Win2[Window2Enabled++].Right = 256; + } + } + } + } + if (Window1Enabled && Window2Enabled) + { + // Overlap logic + // + // Each window will be in one of three states: + // 1. (Left > Right. One band) + // 2. | ---------------- | (Left >= 0, Right <= 255, Left <= Right. One band) + // 3. |------------ ----------| (Left1 == 0, Right1 < Left2; Left2 > Right1, Right2 == 255. Two bands) + + struct Band Bands [6]; + int B = 0; + switch (PPU.ClipWindowOverlapLogic [w] ^ 1) + { + case CLIP_OR: + if (Window1Enabled == 1) + { + if (BAND_EMPTY(Win1[0])) + { + B = Window2Enabled; + // memmove converted: Different stack allocations [Neb] + memcpy(Bands, Win2, + sizeof(Win2[0]) * Window2Enabled); + } + else + { + if (Window2Enabled == 1) + { + if (BAND_EMPTY(Win2[0])) + Bands[B++] = Win1[0]; + else + { + if (BANDS_INTERSECT(Win1[0], Win2[0])) + { + OR_BANDS(Bands[0], Win1[0], Win2[0]) + B = 1; + } + else + { + Bands[B++] = Win1[0]; + Bands[B++] = Win2[0]; + } + } + } + else + { + if (BANDS_INTERSECT(Win1[0], Win2[0])) + { + OR_BANDS(Bands[0], Win1[0], Win2[0]) + if (BANDS_INTERSECT(Win1[0], Win2[1])) + OR_BANDS(Bands[1], Win1[0], Win2[1]) + else + Bands[1] = Win2[1]; + B = 1; + if (BANDS_INTERSECT(Bands[0], Bands[1])) + OR_BANDS(Bands[0], Bands[0], Bands[1]) + else + B = 2; + } + else if (BANDS_INTERSECT(Win1[0], Win2[1])) + { + Bands[B++] = Win2[0]; + OR_BANDS(Bands[B], Win1[0], Win2[1]); + B++; + } + else + { + Bands[0] = Win2[0]; + Bands[1] = Win1[0]; + Bands[2] = Win2[1]; + B = 3; + } + } + } + } + else if (Window2Enabled == 1) + { + if (BAND_EMPTY(Win2[0])) + { + // Window 2 defines an empty range - just + // use window 1 as the clipping (which + // could also be empty). + B = Window1Enabled; + // memmove converted: Different stack allocations [Neb] + memcpy(Bands, Win1, + sizeof(Win1[0]) * Window1Enabled); + } + else + { + // Window 1 has two bands and Window 2 has one. + // Neither is an empty region. + if (BANDS_INTERSECT(Win2[0], Win1[0])) + { + OR_BANDS(Bands[0], Win2[0], Win1[0]) + if (BANDS_INTERSECT(Win2[0], Win1[1])) + OR_BANDS(Bands[1], Win2[0], Win1[1]) + else + Bands[1] = Win1[1]; + B = 1; + if (BANDS_INTERSECT(Bands[0], Bands[1])) + OR_BANDS(Bands[0], Bands[0], Bands[1]) + else + B = 2; + } + else if (BANDS_INTERSECT(Win2[0], Win1[1])) + { + Bands[B++] = Win1[0]; + OR_BANDS(Bands[B], Win2[0], Win1[1]); + B++; + } + else + { + Bands[0] = Win1[0]; + Bands[1] = Win2[0]; + Bands[2] = Win1[1]; + B = 3; + } + } + } + else + { + // Both windows have two bands + OR_BANDS(Bands[0], Win1[0], Win2[0]); + OR_BANDS(Bands[1], Win1[1], Win2[1]); + B = 1; + if (BANDS_INTERSECT(Bands[0], Bands[1])) + OR_BANDS(Bands[0], Bands[0], Bands[1]) + else + B = 2; + } + break; + + case CLIP_AND: + if (Window1Enabled == 1) + { + // Window 1 has one band + if (BAND_EMPTY(Win1[0])) + Bands [B++] = Win1[0]; + else if (Window2Enabled == 1) + { + if (BAND_EMPTY(Win2[0])) + Bands [B++] = Win2[0]; + else + { + AND_BANDS(Bands[0], Win1[0], Win2[0]); + B = 1; + } + } + else + { + AND_BANDS(Bands[0], Win1[0], Win2[0]); + AND_BANDS(Bands[1], Win1[0], Win2[1]); + B = 2; + } + } + else if (Window2Enabled == 1) + { + if (BAND_EMPTY(Win2[0])) + Bands[B++] = Win2[0]; + else + { + // Window 1 has two bands. + AND_BANDS(Bands[0], Win1[0], Win2[0]); + AND_BANDS(Bands[1], Win1[1], Win2[0]); + B = 2; + } + } + else + { + // Both windows have two bands. + AND_BANDS(Bands[0], Win1[0], Win2[0]); + AND_BANDS(Bands[1], Win1[1], Win2[1]); + B = 2; + if (BANDS_INTERSECT(Win1[0], Win2[1])) + { + AND_BANDS(Bands[2], Win1[0], Win2[1]); + B = 3; + } + else if (BANDS_INTERSECT(Win1[1], Win2[0])) + { + AND_BANDS(Bands[2], Win1[1], Win2[0]); + B = 3; + } + } + break; + case CLIP_XNOR: + invert = !invert; + // Fall... + + case CLIP_XOR: + if (Window1Enabled == 1 && BAND_EMPTY(Win1[0])) + { + B = Window2Enabled; + // memmove converted: Different stack allocations [Neb] + memcpy(Bands, Win2, + sizeof(Win2[0]) * Window2Enabled); + } + else if (Window2Enabled == 1 && BAND_EMPTY(Win2[0])) + { + B = Window1Enabled; + // memmove converted: Different stack allocations [Neb] + memcpy(Bands, Win1, + sizeof(Win1[0]) * Window1Enabled); + } + else + { + uint32 p = 0; + uint32 points [10]; + uint32 i; + + invert = !invert; + // Build an array of points (window edges) + points [p++] = 0; + for (i = 0; i < Window1Enabled; i++) + { + points [p++] = Win1[i].Left; + points [p++] = Win1[i].Right; + } + for (i = 0; i < Window2Enabled; i++) + { + points [p++] = Win2[i].Left; + points [p++] = Win2[i].Right; + } + points [p++] = 256; + // Sort them + qsort((void*) points, p, sizeof(points [0]), + IntCompare); + for (i = 0; i < p; i += 2) + { + if (points [i] == points [i + 1]) + continue; + Bands [B].Left = points [i]; + while (i + 2 < p && + points [i + 1] == points [i + 2]) + i += 2; + Bands [B++].Right = points [i + 1]; + } + } + break; + } + if (invert) + { + int b; + int j = 0; + int empty_band_count = 0; + + // First remove all empty bands from the list. + for (b = 0; b < B; b++) + { + if (!BAND_EMPTY(Bands[b])) + { + if (b != j) + Bands[j] = Bands[b]; + j++; + } + else + empty_band_count++; + } + + if (j > 0) + { + if (j == 1) + { + j = 0; + // Easy case to deal with, so special case it. + + if (Bands[0].Left > 0) + { + pClip->Left[j][w] = 0; + pClip->Right[j++][w] = Bands[0].Left + 1; + } + if (Bands[0].Right < 256) + { + pClip->Left[j][w] = Bands[0].Right; + pClip->Right[j++][w] = 256; + } + if (j == 0) + { + pClip->Left[j][w] = 1; + pClip->Right[j++][w] = 0; + } + } + else + { + // Now sort the bands into order + B = j; + qsort((void*) Bands, B, + sizeof(Bands [0]), BandCompare); + + // Now invert the area the bands cover + j = 0; + for (b = 0; b < B; b++) + { + if (b == 0 && Bands[b].Left > 0) + { + pClip->Left[j][w] = 0; + pClip->Right[j++][w] = Bands[b].Left + 1; + } + else if (b == B - 1 && Bands[b].Right < 256) + { + pClip->Left[j][w] = Bands[b].Right; + pClip->Right[j++][w] = 256; + } + if (b < B - 1) + { + pClip->Left[j][w] = Bands[b].Right; + pClip->Right[j++][w] = Bands[b + 1].Left + 1; + } + } + } + } + else + { + // Inverting a window that consisted of only + // empty bands is the whole width of the screen. + // Needed for Mario Kart's rear-view mirror display. + if (empty_band_count) + { + pClip->Left[j][w] = 0; + pClip->Right[j][w] = 256; + j++; + } + } + pClip->Count[w] = j; + } + else + { int j; for (j = 0; j < B; j++) - { - pClip->Left[j][w] = Bands[j].Left; - pClip->Right[j][w] = Bands[j].Right; - } - pClip->Count [w] = B; - } - } - else - { - // Only one window enabled so no need to perform - // complex overlap logic... - - if (Window1Enabled) - { - if (invert) - { - int j = 0; - - if (Window1Enabled == 1) - { - if (Win1[0].Left <= Win1[0].Right) - { - if (Win1[0].Left > 0) - { - pClip->Left[j][w] = 0; - pClip->Right[j++][w] = Win1[0].Left; - } - if (Win1[0].Right < 256) - { - pClip->Left[j][w] = Win1[0].Right; - pClip->Right[j++][w] = 256; - } - if (j == 0) - { - pClip->Left[j][w] = 1; - pClip->Right[j++][w] = 0; - } - } - else - { - pClip->Left[j][w] = 0; - pClip->Right[j++][w] = 256; - } - } - else - { - pClip->Left [j][w] = Win1[0].Right; - pClip->Right[j++][w] = Win1[1].Left; - } - pClip->Count [w] = j; - } - else - { + { + pClip->Left[j][w] = Bands[j].Left; + pClip->Right[j][w] = Bands[j].Right; + } + pClip->Count [w] = B; + } + } + else + { + // Only one window enabled so no need to perform + // complex overlap logic... + + if (Window1Enabled) + { + if (invert) + { + int j = 0; + + if (Window1Enabled == 1) + { + if (Win1[0].Left <= Win1[0].Right) + { + if (Win1[0].Left > 0) + { + pClip->Left[j][w] = 0; + pClip->Right[j++][w] = Win1[0].Left; + } + if (Win1[0].Right < 256) + { + pClip->Left[j][w] = Win1[0].Right; + pClip->Right[j++][w] = 256; + } + if (j == 0) + { + pClip->Left[j][w] = 1; + pClip->Right[j++][w] = 0; + } + } + else + { + pClip->Left[j][w] = 0; + pClip->Right[j++][w] = 256; + } + } + else + { + pClip->Left [j][w] = Win1[0].Right; + pClip->Right[j++][w] = Win1[1].Left; + } + pClip->Count [w] = j; + } + else + { uint32 j; for (j = 0; j < Window1Enabled; j++) - { - pClip->Left [j][w] = Win1[j].Left; - pClip->Right [j][w] = Win1[j].Right; - } - pClip->Count [w] = Window1Enabled; - } - } - else - if (Window2Enabled) - { - if (invert) - { - int j = 0; - if (Window2Enabled == 1) - { - if (Win2[0].Left <= Win2[0].Right) - { - if (Win2[0].Left > 0) - { - pClip->Left[j][w] = 0; - pClip->Right[j++][w] = Win2[0].Left; - } - if (Win2[0].Right < 256) - { - pClip->Left[j][w] = Win2[0].Right; - pClip->Right[j++][w] = 256; - } - if (j == 0) - { - pClip->Left[j][w] = 1; - pClip->Right[j++][w] = 0; - } - } - else - { - pClip->Left[j][w] = 0; - pClip->Right[j++][w] = 256; - } - } - else - { - pClip->Left [j][w] = Win2[0].Right; - pClip->Right[j++][w] = Win2[1].Left + 1; - } - pClip->Count [w] = j; - } - else - { - uint32 j; - for (j = 0; j < Window2Enabled; j++) - { - pClip->Left [j][w] = Win2[j].Left; - pClip->Right [j][w] = Win2[j].Right; - } - pClip->Count [w] = Window2Enabled; - } - } - } - - if (w != 5 && pClip->Count [5]) - { - // Colour window enabled. Set the - // clip windows for all remaining backgrounds to be - // the same as the colour window. - if (pClip->Count [w] == 0) - { + { + pClip->Left [j][w] = Win1[j].Left; + pClip->Right [j][w] = Win1[j].Right; + } + pClip->Count [w] = Window1Enabled; + } + } + else if (Window2Enabled) + { + if (invert) + { + int j = 0; + if (Window2Enabled == 1) + { + if (Win2[0].Left <= Win2[0].Right) + { + if (Win2[0].Left > 0) + { + pClip->Left[j][w] = 0; + pClip->Right[j++][w] = Win2[0].Left; + } + if (Win2[0].Right < 256) + { + pClip->Left[j][w] = Win2[0].Right; + pClip->Right[j++][w] = 256; + } + if (j == 0) + { + pClip->Left[j][w] = 1; + pClip->Right[j++][w] = 0; + } + } + else + { + pClip->Left[j][w] = 0; + pClip->Right[j++][w] = 256; + } + } + else + { + pClip->Left [j][w] = Win2[0].Right; + pClip->Right[j++][w] = Win2[1].Left + 1; + } + pClip->Count [w] = j; + } + else + { + uint32 j; + for (j = 0; j < Window2Enabled; j++) + { + pClip->Left [j][w] = Win2[j].Left; + pClip->Right [j][w] = Win2[j].Right; + } + pClip->Count [w] = Window2Enabled; + } + } + } + + if (w != 5 && pClip->Count [5]) + { + // Colour window enabled. Set the + // clip windows for all remaining backgrounds to be + // the same as the colour window. + if (pClip->Count [w] == 0) + { uint32 i; - pClip->Count [w] = pClip->Count [5]; + pClip->Count [w] = pClip->Count [5]; for (i = 0; i < pClip->Count [w]; i++) - { - pClip->Left [i][w] = pClip->Left [i][5]; - pClip->Right [i][w] = pClip->Right [i][5]; - } - } - else - { - // Intersect the colour window with the bg's - // own clip window. + { + pClip->Left [i][w] = pClip->Left [i][5]; + pClip->Right [i][w] = pClip->Right [i][5]; + } + } + else + { + // Intersect the colour window with the bg's + // own clip window. uint32 i; for (i = 0; i < pClip->Count [w]; i++) - { - uint32 j; - for (j = 0; j < pClip->Count [5]; j++) - { - if((pClip->Left[i][w] >= pClip->Left[j][5] && pClip->Left[i][w] < pClip->Right[j][5]) || (pClip->Left[j][5] >= pClip->Left[i][w] && pClip->Left[j][5] < pClip->Right[i][w])){ - // Found an intersection! - pClip->Left[i][w]=MAX(pClip->Left[i][w], pClip->Left[j][5]); - pClip->Right[i][w]=MIN(pClip->Right[i][w], pClip->Right[j][5]); - goto Clip_ok; - } - } - // no intersection, nullify it - pClip->Left[i][w]=1; - pClip->Right[i][w]=0; + { + uint32 j; + for (j = 0; j < pClip->Count [5]; j++) + { + if ((pClip->Left[i][w] >= pClip->Left[j][5] + && pClip->Left[i][w] < pClip->Right[j][5]) + || (pClip->Left[j][5] >= pClip->Left[i][w] + && pClip->Left[j][5] < pClip->Right[i][w])) + { + // Found an intersection! + pClip->Left[i][w] = MAX(pClip->Left[i][w], pClip->Left[j][5]); + pClip->Right[i][w] = MIN(pClip->Right[i][w], pClip->Right[j][5]); + goto Clip_ok; + } + } + // no intersection, nullify it + pClip->Left[i][w] = 1; + pClip->Right[i][w] = 0; Clip_ok: - j=0; // dummy statement - } - } - } - } // if (w == 5 | ... - } // if (!Settings.DisableGraphicWindows) - } // for (int w... - } // for (int c... + j = 0; // dummy statement + } + } + } + } // if (w == 5 | ... + } // if (!Settings.DisableGraphicWindows) + } // for (int w... + } // for (int c... } diff --git a/source/cpu.c b/source/cpu.c index 51adb61..977ac77 100644 --- a/source/cpu.c +++ b/source/cpu.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -107,131 +107,131 @@ extern struct FxInit_s SuperFX; -void S9xResetSuperFX () +void S9xResetSuperFX() { - SuperFX.vFlags = 0; //FX_FLAG_ROM_BUFFER;// | FX_FLAG_ADDRESS_CHECKING; - FxReset (&SuperFX); + SuperFX.vFlags = 0; //FX_FLAG_ROM_BUFFER;// | FX_FLAG_ADDRESS_CHECKING; + FxReset(&SuperFX); } #endif -void S9xResetCPU () +void S9xResetCPU() { - ICPU.Registers.PB = 0; - ICPU.Registers.PC = S9xGetWord (0xFFFC); - ICPU.Registers.D.W = 0; - ICPU.Registers.DB = 0; - ICPU.Registers.SH = 1; - ICPU.Registers.SL = 0xFF; - ICPU.Registers.XH = 0; - ICPU.Registers.YH = 0; - ICPU.Registers.P.W = 0; - - ICPU.ShiftedPB = 0; - ICPU.ShiftedDB = 0; - SetFlags (MemoryFlag | IndexFlag | IRQ | Emulation); - ClearFlags (Decimal); - - CPU.Flags = CPU.Flags & (DEBUG_MODE_FLAG | TRACE_FLAG); - CPU.BranchSkip = FALSE; - CPU.NMIActive = FALSE; - CPU.IRQActive = FALSE; - CPU.WaitingForInterrupt = FALSE; - CPU.InDMA = FALSE; - CPU.WhichEvent = HBLANK_START_EVENT; - CPU.PC = NULL; - CPU.PCBase = NULL; - CPU.PCAtOpcodeStart = NULL; - CPU.WaitAddress = NULL; - CPU.WaitCounter = 0; - CPU.Cycles = 0; - CPU.NextEvent = Settings.HBlankStart; - CPU.V_Counter = 0; - CPU.MemSpeed = SLOW_ONE_CYCLE; - CPU.MemSpeedx2 = SLOW_ONE_CYCLE * 2; - CPU.FastROMSpeed = SLOW_ONE_CYCLE; - CPU.AutoSaveTimer = 0; - CPU.SRAMModified = FALSE; - // CPU.NMITriggerPoint = 4; // Set when ROM image loaded - CPU.BRKTriggered = FALSE; - //CPU.TriedInterleavedMode2 = FALSE; // Reset when ROM image loaded - CPU.NMICycleCount = 0; - CPU.IRQCycleCount = 0; - S9xSetPCBase (ICPU.Registers.PC); - - ICPU.S9xOpcodes = S9xOpcodesE1; - ICPU.CPUExecuting = TRUE; - - S9xUnpackStatus(); + ICPU.Registers.PB = 0; + ICPU.Registers.PC = S9xGetWord(0xFFFC); + ICPU.Registers.D.W = 0; + ICPU.Registers.DB = 0; + ICPU.Registers.SH = 1; + ICPU.Registers.SL = 0xFF; + ICPU.Registers.XH = 0; + ICPU.Registers.YH = 0; + ICPU.Registers.P.W = 0; + + ICPU.ShiftedPB = 0; + ICPU.ShiftedDB = 0; + SetFlags(MemoryFlag | IndexFlag | IRQ | Emulation); + ClearFlags(Decimal); + + CPU.Flags = CPU.Flags & (DEBUG_MODE_FLAG | TRACE_FLAG); + CPU.BranchSkip = FALSE; + CPU.NMIActive = FALSE; + CPU.IRQActive = FALSE; + CPU.WaitingForInterrupt = FALSE; + CPU.InDMA = FALSE; + CPU.WhichEvent = HBLANK_START_EVENT; + CPU.PC = NULL; + CPU.PCBase = NULL; + CPU.PCAtOpcodeStart = NULL; + CPU.WaitAddress = NULL; + CPU.WaitCounter = 0; + CPU.Cycles = 0; + CPU.NextEvent = Settings.HBlankStart; + CPU.V_Counter = 0; + CPU.MemSpeed = SLOW_ONE_CYCLE; + CPU.MemSpeedx2 = SLOW_ONE_CYCLE * 2; + CPU.FastROMSpeed = SLOW_ONE_CYCLE; + CPU.AutoSaveTimer = 0; + CPU.SRAMModified = FALSE; + // CPU.NMITriggerPoint = 4; // Set when ROM image loaded + CPU.BRKTriggered = FALSE; + //CPU.TriedInterleavedMode2 = FALSE; // Reset when ROM image loaded + CPU.NMICycleCount = 0; + CPU.IRQCycleCount = 0; + S9xSetPCBase(ICPU.Registers.PC); + + ICPU.S9xOpcodes = S9xOpcodesE1; + ICPU.CPUExecuting = TRUE; + + S9xUnpackStatus(); } #ifdef ZSNES_FX -void S9xResetSuperFX (); +void S9xResetSuperFX(); bool8 WinterGold = 0; -extern uint8 *C4Ram; +extern uint8* C4Ram; #endif -void S9xReset (void) +void S9xReset(void) { - if (Settings.SuperFX) - S9xResetSuperFX (); + if (Settings.SuperFX) + S9xResetSuperFX(); #ifdef ZSNES_FX - WinterGold = Settings.WinterGold; + WinterGold = Settings.WinterGold; #endif - ZeroMemory (Memory.FillRAM, 0x8000); - memset (Memory.VRAM, 0x00, 0x10000); - memset (Memory.RAM, 0x55, 0x20000); - - if(Settings.SPC7110) - S9xSpc7110Reset(); - S9xResetCPU (); - S9xResetPPU (); - S9xResetSRTC (); - if (Settings.SDD1) - S9xResetSDD1 (); - - S9xResetDMA (); - S9xResetAPU (); - S9xResetDSP1 (); - S9xSA1Init (); - if (Settings.C4) - S9xInitC4 (); - S9xInitCheatData (); - if(Settings.OBC1) - ResetOBC1(); - -// Settings.Paused = FALSE; + ZeroMemory(Memory.FillRAM, 0x8000); + memset(Memory.VRAM, 0x00, 0x10000); + memset(Memory.RAM, 0x55, 0x20000); + + if (Settings.SPC7110) + S9xSpc7110Reset(); + S9xResetCPU(); + S9xResetPPU(); + S9xResetSRTC(); + if (Settings.SDD1) + S9xResetSDD1(); + + S9xResetDMA(); + S9xResetAPU(); + S9xResetDSP1(); + S9xSA1Init(); + if (Settings.C4) + S9xInitC4(); + S9xInitCheatData(); + if (Settings.OBC1) + ResetOBC1(); + + // Settings.Paused = FALSE; } -void S9xSoftReset (void) +void S9xSoftReset(void) { - if (Settings.SuperFX) - S9xResetSuperFX (); + if (Settings.SuperFX) + S9xResetSuperFX(); #ifdef ZSNES_FX - WinterGold = Settings.WinterGold; + WinterGold = Settings.WinterGold; #endif - ZeroMemory (Memory.FillRAM, 0x8000); - memset (Memory.VRAM, 0x00, 0x10000); - // memset (Memory.RAM, 0x55, 0x20000); - - if(Settings.SPC7110) - S9xSpc7110Reset(); - S9xResetCPU (); - S9xSoftResetPPU (); - S9xResetSRTC (); - if (Settings.SDD1) - S9xResetSDD1 (); - - S9xResetDMA (); - S9xResetAPU (); - S9xResetDSP1 (); - if(Settings.OBC1) - ResetOBC1(); - S9xSA1Init (); - if (Settings.C4) - S9xInitC4 (); - S9xInitCheatData (); - -// Settings.Paused = FALSE; + ZeroMemory(Memory.FillRAM, 0x8000); + memset(Memory.VRAM, 0x00, 0x10000); + // memset (Memory.RAM, 0x55, 0x20000); + + if (Settings.SPC7110) + S9xSpc7110Reset(); + S9xResetCPU(); + S9xSoftResetPPU(); + S9xResetSRTC(); + if (Settings.SDD1) + S9xResetSDD1(); + + S9xResetDMA(); + S9xResetAPU(); + S9xResetDSP1(); + if (Settings.OBC1) + ResetOBC1(); + S9xSA1Init(); + if (Settings.C4) + S9xInitC4(); + S9xInitCheatData(); + + // Settings.Paused = FALSE; } diff --git a/source/cpuaddr.h b/source/cpuaddr.h index 6335495..3ca6dbf 100644 --- a/source/cpuaddr.h +++ b/source/cpuaddr.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -90,291 +90,293 @@ #ifndef _CPUADDR_H_ #define _CPUADDR_H_ -typedef enum { - NONE = 0, - READ = 1, - WRITE = 2, - MODIFY = 3, - JUMP = 4 +typedef enum +{ + NONE = 0, + READ = 1, + WRITE = 2, + MODIFY = 3, + JUMP = 4 } AccessMode; // The type for a function that can run after the addressing mode is resolved: // void NAME (long Addr) {...} -typedef void (*InternalOp) (long); +typedef void (*InternalOp)(long); -static void Immediate8 (AccessMode a, InternalOp op) +static void Immediate8(AccessMode a, InternalOp op) { - long Addr = ICPU.ShiftedPB + CPU.PC - CPU.PCBase; - CPU.PC++; - (*op)(Addr); + long Addr = ICPU.ShiftedPB + CPU.PC - CPU.PCBase; + CPU.PC++; + (*op)(Addr); } -static void Immediate16 (AccessMode a, InternalOp op) +static void Immediate16(AccessMode a, InternalOp op) { - long Addr = ICPU.ShiftedPB + CPU.PC - CPU.PCBase; - CPU.PC += 2; - (*op)(Addr); + long Addr = ICPU.ShiftedPB + CPU.PC - CPU.PCBase; + CPU.PC += 2; + (*op)(Addr); } -static void Relative (AccessMode a, InternalOp op) +static void Relative(AccessMode a, InternalOp op) { - int8 Int8 = *CPU.PC++; - long Addr = ((intptr_t) (CPU.PC - CPU.PCBase) + Int8) & 0xffff; - (*op)(Addr); + int8 Int8 = *CPU.PC++; + long Addr = ((intptr_t)(CPU.PC - CPU.PCBase) + Int8) & 0xffff; + (*op)(Addr); } -static void RelativeLong (AccessMode a, InternalOp op) +static void RelativeLong(AccessMode a, InternalOp op) { - long Addr; + long Addr; #ifdef FAST_LSB_WORD_ACCESS - Addr = *(uint16 *) CPU.PC; + Addr = *(uint16*) CPU.PC; #else - Addr = *CPU.PC + (*(CPU.PC + 1) << 8); + Addr = *CPU.PC + (*(CPU.PC + 1) << 8); #endif - CPU.PC += 2; - Addr += (CPU.PC - CPU.PCBase); - Addr &= 0xffff; - (*op)(Addr); + CPU.PC += 2; + Addr += (CPU.PC - CPU.PCBase); + Addr &= 0xffff; + (*op)(Addr); } -static void AbsoluteIndexedIndirect (AccessMode a, InternalOp op) +static void AbsoluteIndexedIndirect(AccessMode a, InternalOp op) { - long Addr; + long Addr; #ifdef FAST_LSB_WORD_ACCESS - Addr = (ICPU.Registers.X.W + *(uint16 *) CPU.PC) & 0xffff; + Addr = (ICPU.Registers.X.W + * (uint16*) CPU.PC) & 0xffff; #else - Addr = (ICPU.Registers.X.W + *CPU.PC + (*(CPU.PC + 1) << 8)) & 0xffff; + Addr = (ICPU.Registers.X.W + *CPU.PC + (*(CPU.PC + 1) << 8)) & 0xffff; #endif - OpenBus = *(CPU.PC + 1); - CPU.PC += 2; - Addr = S9xGetWord (ICPU.ShiftedPB + Addr); - if(a&READ) OpenBus = (uint8)(Addr>>8); - (*op)(Addr); + OpenBus = *(CPU.PC + 1); + CPU.PC += 2; + Addr = S9xGetWord(ICPU.ShiftedPB + Addr); + if (a & READ) OpenBus = (uint8)(Addr >> 8); + (*op)(Addr); } -static void AbsoluteIndirectLong (AccessMode a, InternalOp op) +static void AbsoluteIndirectLong(AccessMode a, InternalOp op) { - long Addr; + long Addr; #ifdef FAST_LSB_WORD_ACCESS - Addr = *(uint16 *) CPU.PC; + Addr = *(uint16*) CPU.PC; #else - Addr = *CPU.PC + (*(CPU.PC + 1) << 8); + Addr = *CPU.PC + (*(CPU.PC + 1) << 8); #endif - OpenBus = *(CPU.PC + 1); - CPU.PC += 2; - if(a&READ) { - Addr = S9xGetWord (Addr) | ((OpenBus=S9xGetByte (Addr + 2)) << 16); - } else { - Addr = S9xGetWord (Addr) | (S9xGetByte (Addr + 2) << 16); - } - (*op)(Addr); + OpenBus = *(CPU.PC + 1); + CPU.PC += 2; + if (a & READ) + Addr = S9xGetWord(Addr) | ((OpenBus = S9xGetByte(Addr + 2)) << 16); + else + Addr = S9xGetWord(Addr) | (S9xGetByte(Addr + 2) << 16); + (*op)(Addr); } -static void AbsoluteIndirect (AccessMode a, InternalOp op) +static void AbsoluteIndirect(AccessMode a, InternalOp op) { - long Addr; + long Addr; #ifdef FAST_LSB_WORD_ACCESS - Addr = *(uint16 *) CPU.PC; + Addr = *(uint16*) CPU.PC; #else - Addr = *CPU.PC + (*(CPU.PC + 1) << 8); + Addr = *CPU.PC + (*(CPU.PC + 1) << 8); #endif - OpenBus = *(CPU.PC + 1); - CPU.PC += 2; - Addr = S9xGetWord (Addr); - if(a&READ) OpenBus = (uint8)(Addr>>8); - Addr += ICPU.ShiftedPB; - (*op)(Addr); + OpenBus = *(CPU.PC + 1); + CPU.PC += 2; + Addr = S9xGetWord(Addr); + if (a & READ) OpenBus = (uint8)(Addr >> 8); + Addr += ICPU.ShiftedPB; + (*op)(Addr); } -static void Absolute (AccessMode a, InternalOp op) +static void Absolute(AccessMode a, InternalOp op) { - long Addr; + long Addr; #ifdef FAST_LSB_WORD_ACCESS - Addr = *(uint16 *) CPU.PC + ICPU.ShiftedDB; + Addr = *(uint16*) CPU.PC + ICPU.ShiftedDB; #else - Addr = *CPU.PC + (*(CPU.PC + 1) << 8) + ICPU.ShiftedDB; + Addr = *CPU.PC + (*(CPU.PC + 1) << 8) + ICPU.ShiftedDB; #endif - if(a&READ) OpenBus = *(CPU.PC+1); - CPU.PC += 2; - (*op)(Addr); + if (a & READ) OpenBus = *(CPU.PC + 1); + CPU.PC += 2; + (*op)(Addr); } -static void AbsoluteLong (AccessMode a, InternalOp op) +static void AbsoluteLong(AccessMode a, InternalOp op) { - long Addr; + long Addr; #ifdef FAST_LSB_WORD_ACCESS - Addr = (*(uint32 *) CPU.PC) & 0xffffff; + Addr = (*(uint32*) CPU.PC) & 0xffffff; #elif defined FAST_ALIGNED_LSB_WORD_ACCESS - if (((intptr_t) CPU.PC & 1) == 0) - Addr = (*(uint16 *) CPU.PC) + (*(CPU.PC + 2) << 16); - else - Addr = *CPU.PC + ((*(uint16 *) (CPU.PC + 1)) << 8); + if (((intptr_t) CPU.PC & 1) == 0) + Addr = (*(uint16*) CPU.PC) + (*(CPU.PC + 2) << 16); + else + Addr = *CPU.PC + ((*(uint16*)(CPU.PC + 1)) << 8); #else - Addr = *CPU.PC + (*(CPU.PC + 1) << 8) + (*(CPU.PC + 2) << 16); + Addr = *CPU.PC + (*(CPU.PC + 1) << 8) + (*(CPU.PC + 2) << 16); #endif - if(a&READ) OpenBus = *(CPU.PC+2); - CPU.PC += 3; - (*op)(Addr); + if (a & READ) OpenBus = *(CPU.PC + 2); + CPU.PC += 3; + (*op)(Addr); } static void Direct(AccessMode a, InternalOp op) { - if(a&READ) OpenBus = *CPU.PC; - long Addr = (*CPU.PC++ + ICPU.Registers.D.W) & 0xffff; -// if (ICPU.Registers.DL != 0) CPU.Cycles += ONE_CYCLE; - (*op)(Addr); + if (a & READ) OpenBus = *CPU.PC; + long Addr = (*CPU.PC++ + ICPU.Registers.D.W) & 0xffff; + // if (ICPU.Registers.DL != 0) CPU.Cycles += ONE_CYCLE; + (*op)(Addr); } -static void DirectIndirectIndexed (AccessMode a, InternalOp op) +static void DirectIndirectIndexed(AccessMode a, InternalOp op) { - OpenBus = *CPU.PC; - long Addr = (*CPU.PC++ + ICPU.Registers.D.W) & 0xffff; + OpenBus = *CPU.PC; + long Addr = (*CPU.PC++ + ICPU.Registers.D.W) & 0xffff; - Addr = S9xGetWord (Addr); - if(a&READ) OpenBus = (uint8)(Addr>>8); - Addr += ICPU.ShiftedDB + ICPU.Registers.Y.W; + Addr = S9xGetWord(Addr); + if (a & READ) OpenBus = (uint8)(Addr >> 8); + Addr += ICPU.ShiftedDB + ICPU.Registers.Y.W; -// if (ICPU.Registers.DL != 0) CPU.Cycles += ONE_CYCLE; - // XXX: always add one if STA - // XXX: else Add one cycle if crosses page boundary - (*op)(Addr); + // if (ICPU.Registers.DL != 0) CPU.Cycles += ONE_CYCLE; + // XXX: always add one if STA + // XXX: else Add one cycle if crosses page boundary + (*op)(Addr); } -static void DirectIndirectIndexedLong (AccessMode a, InternalOp op) +static void DirectIndirectIndexedLong(AccessMode a, InternalOp op) { - OpenBus = *CPU.PC; - long Addr = (*CPU.PC++ + ICPU.Registers.D.W) & 0xffff; - - if(a&READ){ - Addr = S9xGetWord (Addr) + ((OpenBus = S9xGetByte (Addr + 2)) << 16) + ICPU.Registers.Y.W; - } else { - Addr = S9xGetWord (Addr) + (S9xGetByte (Addr + 2) << 16) + ICPU.Registers.Y.W; - } -// if (ICPU.Registers.DL != 0) CPU.Cycles += ONE_CYCLE; - (*op)(Addr); + OpenBus = *CPU.PC; + long Addr = (*CPU.PC++ + ICPU.Registers.D.W) & 0xffff; + + if (a & READ) + Addr = S9xGetWord(Addr) + ((OpenBus = S9xGetByte(Addr + 2)) << 16) + + ICPU.Registers.Y.W; + else + Addr = S9xGetWord(Addr) + (S9xGetByte(Addr + 2) << 16) + ICPU.Registers.Y.W; + // if (ICPU.Registers.DL != 0) CPU.Cycles += ONE_CYCLE; + (*op)(Addr); } static void DirectIndexedIndirect(AccessMode a, InternalOp op) { - OpenBus = *CPU.PC; - long Addr = (*CPU.PC++ + ICPU.Registers.D.W + ICPU.Registers.X.W) & 0xffff; + OpenBus = *CPU.PC; + long Addr = (*CPU.PC++ + ICPU.Registers.D.W + ICPU.Registers.X.W) & 0xffff; - Addr = S9xGetWord (Addr); - if(a&READ) OpenBus = (uint8)(Addr>>8); - Addr += ICPU.ShiftedDB; - (*op)(Addr); + Addr = S9xGetWord(Addr); + if (a & READ) OpenBus = (uint8)(Addr >> 8); + Addr += ICPU.ShiftedDB; + (*op)(Addr); } -static void DirectIndexedX (AccessMode a, InternalOp op) +static void DirectIndexedX(AccessMode a, InternalOp op) { - if(a&READ) OpenBus = *CPU.PC; - long Addr = (*CPU.PC++ + ICPU.Registers.D.W + ICPU.Registers.X.W); - Addr &= CheckEmulation() ? 0xff : 0xffff; + if (a & READ) OpenBus = *CPU.PC; + long Addr = (*CPU.PC++ + ICPU.Registers.D.W + ICPU.Registers.X.W); + Addr &= CheckEmulation() ? 0xff : 0xffff; - (*op)(Addr); + (*op)(Addr); } -static void DirectIndexedY (AccessMode a, InternalOp op) +static void DirectIndexedY(AccessMode a, InternalOp op) { - if(a&READ) OpenBus = *CPU.PC; - long Addr = (*CPU.PC++ + ICPU.Registers.D.W + ICPU.Registers.Y.W); - Addr &= CheckEmulation() ? 0xff : 0xffff; - (*op)(Addr); + if (a & READ) OpenBus = *CPU.PC; + long Addr = (*CPU.PC++ + ICPU.Registers.D.W + ICPU.Registers.Y.W); + Addr &= CheckEmulation() ? 0xff : 0xffff; + (*op)(Addr); } -static void AbsoluteIndexedX (AccessMode a, InternalOp op) +static void AbsoluteIndexedX(AccessMode a, InternalOp op) { - long Addr; + long Addr; #ifdef FAST_LSB_WORD_ACCESS - Addr = ICPU.ShiftedDB + *(uint16 *) CPU.PC + ICPU.Registers.X.W; + Addr = ICPU.ShiftedDB + *(uint16*) CPU.PC + ICPU.Registers.X.W; #else - Addr = ICPU.ShiftedDB + *CPU.PC + (*(CPU.PC + 1) << 8) + - ICPU.Registers.X.W; + Addr = ICPU.ShiftedDB + *CPU.PC + (*(CPU.PC + 1) << 8) + + ICPU.Registers.X.W; #endif - if(a&READ) OpenBus = *(CPU.PC+1); - CPU.PC += 2; - // XXX: always add one cycle for ROL, LSR, etc - // XXX: else is cross page boundary add one cycle - (*op)(Addr); + if (a & READ) OpenBus = *(CPU.PC + 1); + CPU.PC += 2; + // XXX: always add one cycle for ROL, LSR, etc + // XXX: else is cross page boundary add one cycle + (*op)(Addr); } -static void AbsoluteIndexedY (AccessMode a, InternalOp op) +static void AbsoluteIndexedY(AccessMode a, InternalOp op) { - long Addr; + long Addr; #ifdef FAST_LSB_WORD_ACCESS - Addr = ICPU.ShiftedDB + *(uint16 *) CPU.PC + ICPU.Registers.Y.W; + Addr = ICPU.ShiftedDB + *(uint16*) CPU.PC + ICPU.Registers.Y.W; #else - Addr = ICPU.ShiftedDB + *CPU.PC + (*(CPU.PC + 1) << 8) + - ICPU.Registers.Y.W; -#endif - if(a&READ) OpenBus = *(CPU.PC+1); - CPU.PC += 2; - // XXX: always add cycle for STA - // XXX: else is cross page boundary add one cycle - (*op)(Addr); + Addr = ICPU.ShiftedDB + *CPU.PC + (*(CPU.PC + 1) << 8) + + ICPU.Registers.Y.W; +#endif + if (a & READ) OpenBus = *(CPU.PC + 1); + CPU.PC += 2; + // XXX: always add cycle for STA + // XXX: else is cross page boundary add one cycle + (*op)(Addr); } -static void AbsoluteLongIndexedX (AccessMode a, InternalOp op) +static void AbsoluteLongIndexedX(AccessMode a, InternalOp op) { - long Addr; + long Addr; #ifdef FAST_LSB_WORD_ACCESS - Addr = (*(uint32 *) CPU.PC + ICPU.Registers.X.W) & 0xffffff; + Addr = (*(uint32*) CPU.PC + ICPU.Registers.X.W) & 0xffffff; #elif defined FAST_ALIGNED_LSB_WORD_ACCESS - if (((intptr_t) CPU.PC & 1) == 0) - Addr = ((*(uint16 *) CPU.PC) + (*(CPU.PC + 2) << 16) + ICPU.Registers.X.W) & 0xFFFFFF; - else - Addr = (*CPU.PC + ((*(uint16 *) (CPU.PC + 1)) << 8) + ICPU.Registers.X.W) & 0xFFFFFF; + if (((intptr_t) CPU.PC & 1) == 0) + Addr = ((*(uint16*) CPU.PC) + (*(CPU.PC + 2) << 16) + ICPU.Registers.X.W) & + 0xFFFFFF; + else + Addr = (*CPU.PC + ((*(uint16*)(CPU.PC + 1)) << 8) + ICPU.Registers.X.W) & + 0xFFFFFF; #else - Addr = (*CPU.PC + (*(CPU.PC + 1) << 8) + (*(CPU.PC + 2) << 16) + ICPU.Registers.X.W) & 0xffffff; + Addr = (*CPU.PC + (*(CPU.PC + 1) << 8) + (*(CPU.PC + 2) << 16) + + ICPU.Registers.X.W) & 0xffffff; #endif - if(a&READ) OpenBus = *(CPU.PC+2); - CPU.PC += 3; - (*op)(Addr); + if (a & READ) OpenBus = *(CPU.PC + 2); + CPU.PC += 3; + (*op)(Addr); } -static void DirectIndirect (AccessMode a, InternalOp op) +static void DirectIndirect(AccessMode a, InternalOp op) { - OpenBus = *CPU.PC; - long Addr = (*CPU.PC++ + ICPU.Registers.D.W) & 0xffff; - Addr = S9xGetWord (Addr); - if(a&READ) OpenBus = (uint8)(Addr>>8); - Addr += ICPU.ShiftedDB; - -// if (ICPU.Registers.DL != 0) CPU.Cycles += ONE_CYCLE; - (*op)(Addr); + OpenBus = *CPU.PC; + long Addr = (*CPU.PC++ + ICPU.Registers.D.W) & 0xffff; + Addr = S9xGetWord(Addr); + if (a & READ) OpenBus = (uint8)(Addr >> 8); + Addr += ICPU.ShiftedDB; + + // if (ICPU.Registers.DL != 0) CPU.Cycles += ONE_CYCLE; + (*op)(Addr); } -static void DirectIndirectLong (AccessMode a, InternalOp op) +static void DirectIndirectLong(AccessMode a, InternalOp op) { - OpenBus = *CPU.PC; - long Addr = (*CPU.PC++ + ICPU.Registers.D.W) & 0xffff; - if(a&READ){ - Addr = S9xGetWord (Addr) + ((OpenBus=S9xGetByte (Addr + 2)) << 16); - } else { - Addr = S9xGetWord (Addr) + (S9xGetByte (Addr + 2) << 16); - } -// if (ICPU.Registers.DL != 0) CPU.Cycles += ONE_CYCLE; - (*op)(Addr); + OpenBus = *CPU.PC; + long Addr = (*CPU.PC++ + ICPU.Registers.D.W) & 0xffff; + if (a & READ) + Addr = S9xGetWord(Addr) + ((OpenBus = S9xGetByte(Addr + 2)) << 16); + else + Addr = S9xGetWord(Addr) + (S9xGetByte(Addr + 2) << 16); + // if (ICPU.Registers.DL != 0) CPU.Cycles += ONE_CYCLE; + (*op)(Addr); } -static void StackRelative (AccessMode a, InternalOp op) +static void StackRelative(AccessMode a, InternalOp op) { - if(a&READ) OpenBus = *CPU.PC; - long Addr = (*CPU.PC++ + ICPU.Registers.S.W) & 0xffff; - (*op)(Addr); + if (a & READ) OpenBus = *CPU.PC; + long Addr = (*CPU.PC++ + ICPU.Registers.S.W) & 0xffff; + (*op)(Addr); } -static void StackRelativeIndirectIndexed (AccessMode a, InternalOp op) +static void StackRelativeIndirectIndexed(AccessMode a, InternalOp op) { - OpenBus = *CPU.PC; - long Addr = (*CPU.PC++ + ICPU.Registers.S.W) & 0xffff; - Addr = S9xGetWord (Addr); - if(a&READ) OpenBus = (uint8)(Addr>>8); - Addr = (Addr + ICPU.ShiftedDB + - ICPU.Registers.Y.W) & 0xffffff; - (*op)(Addr); + OpenBus = *CPU.PC; + long Addr = (*CPU.PC++ + ICPU.Registers.S.W) & 0xffff; + Addr = S9xGetWord(Addr); + if (a & READ) OpenBus = (uint8)(Addr >> 8); + Addr = (Addr + ICPU.ShiftedDB + + ICPU.Registers.Y.W) & 0xffffff; + (*op)(Addr); } #endif diff --git a/source/cpuexec.c b/source/cpuexec.c index 02c4edd..e015863 100644 --- a/source/cpuexec.c +++ b/source/cpuexec.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -108,12 +108,12 @@ #include "display.h" #endif -extern void S9xProcessSound (unsigned int); +extern void S9xProcessSound(unsigned int); -void S9xMainLoop_SA1_SFX (void); -void S9xMainLoop_SA1_NoSFX (void); -void S9xMainLoop_NoSA1_SFX (void); -void S9xMainLoop_NoSA1_NoSFX (void); +void S9xMainLoop_SA1_SFX(void); +void S9xMainLoop_SA1_NoSFX(void); +void S9xMainLoop_NoSA1_SFX(void); +void S9xMainLoop_NoSA1_NoSFX(void); /* * This is a CATSFC modification inspired by a Snes9x-Euphoria modification. @@ -124,336 +124,352 @@ void S9xMainLoop_NoSA1_NoSFX (void); * to propagate modifications to the SA1_NoSFX, NoSA1_SFX and NoSA1_NoSFX * versions. */ -void S9xMainLoop (void) +void S9xMainLoop(void) { - if (Settings.SA1) - { - if (Settings.SuperFX) S9xMainLoop_SA1_SFX (); - else /* if (!Settings.SuperFX) */ S9xMainLoop_SA1_NoSFX (); - } - else /* if (!Settings.SA1) */ - { - if (Settings.SuperFX) S9xMainLoop_NoSA1_SFX (); - else /* if (!Settings.SuperFX) */ S9xMainLoop_NoSA1_NoSFX (); - } + if (Settings.SA1) + { + if (Settings.SuperFX) S9xMainLoop_SA1_SFX(); + else /* if (!Settings.SuperFX) */ S9xMainLoop_SA1_NoSFX(); + } + else /* if (!Settings.SA1) */ + { + if (Settings.SuperFX) S9xMainLoop_NoSA1_SFX(); + else /* if (!Settings.SuperFX) */ S9xMainLoop_NoSA1_NoSFX(); + } } -void S9xMainLoop_SA1_SFX (void) +void S9xMainLoop_SA1_SFX(void) { - for (;;) - { - APU_EXECUTE (); - - if (CPU.Flags) - { - if (CPU.Flags & NMI_FLAG) - { - if (--CPU.NMICycleCount == 0) { - CPU.Flags &= ~NMI_FLAG; - if (CPU.WaitingForInterrupt) { - CPU.WaitingForInterrupt = FALSE; - CPU.PC++; - } - S9xOpcode_NMI (); - } - } - - CHECK_SOUND (); - - if (CPU.Flags & IRQ_PENDING_FLAG) - { - if (CPU.IRQCycleCount == 0) - { - if (CPU.WaitingForInterrupt) { - CPU.WaitingForInterrupt = FALSE; - CPU.PC++; - } - if (CPU.IRQActive && !Settings.DisableIRQ) { - if (!CheckFlag (IRQ)) - S9xOpcode_IRQ (); - } - else - CPU.Flags &= ~IRQ_PENDING_FLAG; - } - else - { - if(--CPU.IRQCycleCount==0 && CheckFlag (IRQ)) - CPU.IRQCycleCount=1; - } - } - - if (CPU.Flags & SCAN_KEYS_FLAG) - break; - } + for (;;) + { + APU_EXECUTE(); + + if (CPU.Flags) + { + if (CPU.Flags & NMI_FLAG) + { + if (--CPU.NMICycleCount == 0) + { + CPU.Flags &= ~NMI_FLAG; + if (CPU.WaitingForInterrupt) + { + CPU.WaitingForInterrupt = FALSE; + CPU.PC++; + } + S9xOpcode_NMI(); + } + } + + CHECK_SOUND(); + + if (CPU.Flags & IRQ_PENDING_FLAG) + { + if (CPU.IRQCycleCount == 0) + { + if (CPU.WaitingForInterrupt) + { + CPU.WaitingForInterrupt = FALSE; + CPU.PC++; + } + if (CPU.IRQActive && !Settings.DisableIRQ) + { + if (!CheckFlag(IRQ)) + S9xOpcode_IRQ(); + } + else + CPU.Flags &= ~IRQ_PENDING_FLAG; + } + else + { + if (--CPU.IRQCycleCount == 0 && CheckFlag(IRQ)) + CPU.IRQCycleCount = 1; + } + } + + if (CPU.Flags & SCAN_KEYS_FLAG) + break; + } #ifdef CPU_SHUTDOWN - CPU.PCAtOpcodeStart = CPU.PC; + CPU.PCAtOpcodeStart = CPU.PC; #endif - CPU.Cycles += CPU.MemSpeed; - - (*ICPU.S9xOpcodes [*CPU.PC++].S9xOpcode) (); - - if (SA1.Executing) - S9xSA1MainLoop (); - DO_HBLANK_CHECK_SFX(); - } - - ICPU.Registers.PC = CPU.PC - CPU.PCBase; - S9xPackStatus (); - IAPU.Registers.PC = IAPU.PC - IAPU.RAM; - S9xAPUPackStatus (); - if (CPU.Flags & SCAN_KEYS_FLAG) - { - S9xSyncSpeed (); - CPU.Flags &= ~SCAN_KEYS_FLAG; - } + CPU.Cycles += CPU.MemSpeed; + + (*ICPU.S9xOpcodes [*CPU.PC++].S9xOpcode)(); + + if (SA1.Executing) + S9xSA1MainLoop(); + DO_HBLANK_CHECK_SFX(); + } + + ICPU.Registers.PC = CPU.PC - CPU.PCBase; + S9xPackStatus(); + IAPU.Registers.PC = IAPU.PC - IAPU.RAM; + S9xAPUPackStatus(); + if (CPU.Flags & SCAN_KEYS_FLAG) + { + S9xSyncSpeed(); + CPU.Flags &= ~SCAN_KEYS_FLAG; + } #ifdef DETECT_NASTY_FX_INTERLEAVE - if (CPU.BRKTriggered && Settings.SuperFX && !CPU.TriedInterleavedMode2) - { - CPU.TriedInterleavedMode2 = TRUE; - CPU.BRKTriggered = FALSE; - S9xDeinterleaveMode2 (); - } + if (CPU.BRKTriggered && Settings.SuperFX && !CPU.TriedInterleavedMode2) + { + CPU.TriedInterleavedMode2 = TRUE; + CPU.BRKTriggered = FALSE; + S9xDeinterleaveMode2(); + } #endif } -void S9xMainLoop_SA1_NoSFX (void) +void S9xMainLoop_SA1_NoSFX(void) { - for (;;) - { - APU_EXECUTE (); - - if (CPU.Flags) - { - if (CPU.Flags & NMI_FLAG) - { - if (--CPU.NMICycleCount == 0) { - CPU.Flags &= ~NMI_FLAG; - if (CPU.WaitingForInterrupt) { - CPU.WaitingForInterrupt = FALSE; - CPU.PC++; - } - S9xOpcode_NMI (); - } - } - - CHECK_SOUND (); - - if (CPU.Flags & IRQ_PENDING_FLAG) - { - if (CPU.IRQCycleCount == 0) - { - if (CPU.WaitingForInterrupt) { - CPU.WaitingForInterrupt = FALSE; - CPU.PC++; - } - if (CPU.IRQActive && !Settings.DisableIRQ) { - if (!CheckFlag (IRQ)) - S9xOpcode_IRQ (); - } - else - CPU.Flags &= ~IRQ_PENDING_FLAG; - } - else - { - if(--CPU.IRQCycleCount==0 && CheckFlag (IRQ)) - CPU.IRQCycleCount=1; - } - } - - if (CPU.Flags & SCAN_KEYS_FLAG) - break; - } + for (;;) + { + APU_EXECUTE(); + + if (CPU.Flags) + { + if (CPU.Flags & NMI_FLAG) + { + if (--CPU.NMICycleCount == 0) + { + CPU.Flags &= ~NMI_FLAG; + if (CPU.WaitingForInterrupt) + { + CPU.WaitingForInterrupt = FALSE; + CPU.PC++; + } + S9xOpcode_NMI(); + } + } + + CHECK_SOUND(); + + if (CPU.Flags & IRQ_PENDING_FLAG) + { + if (CPU.IRQCycleCount == 0) + { + if (CPU.WaitingForInterrupt) + { + CPU.WaitingForInterrupt = FALSE; + CPU.PC++; + } + if (CPU.IRQActive && !Settings.DisableIRQ) + { + if (!CheckFlag(IRQ)) + S9xOpcode_IRQ(); + } + else + CPU.Flags &= ~IRQ_PENDING_FLAG; + } + else + { + if (--CPU.IRQCycleCount == 0 && CheckFlag(IRQ)) + CPU.IRQCycleCount = 1; + } + } + + if (CPU.Flags & SCAN_KEYS_FLAG) + break; + } #ifdef CPU_SHUTDOWN - CPU.PCAtOpcodeStart = CPU.PC; + CPU.PCAtOpcodeStart = CPU.PC; #endif - CPU.Cycles += CPU.MemSpeed; - - (*ICPU.S9xOpcodes [*CPU.PC++].S9xOpcode) (); - - if (SA1.Executing) - S9xSA1MainLoop (); - DO_HBLANK_CHECK_NoSFX(); - } - - ICPU.Registers.PC = CPU.PC - CPU.PCBase; - S9xPackStatus (); - IAPU.Registers.PC = IAPU.PC - IAPU.RAM; - S9xAPUPackStatus (); - if (CPU.Flags & SCAN_KEYS_FLAG) - { - S9xSyncSpeed (); - CPU.Flags &= ~SCAN_KEYS_FLAG; - } + CPU.Cycles += CPU.MemSpeed; + + (*ICPU.S9xOpcodes [*CPU.PC++].S9xOpcode)(); + + if (SA1.Executing) + S9xSA1MainLoop(); + DO_HBLANK_CHECK_NoSFX(); + } + + ICPU.Registers.PC = CPU.PC - CPU.PCBase; + S9xPackStatus(); + IAPU.Registers.PC = IAPU.PC - IAPU.RAM; + S9xAPUPackStatus(); + if (CPU.Flags & SCAN_KEYS_FLAG) + { + S9xSyncSpeed(); + CPU.Flags &= ~SCAN_KEYS_FLAG; + } } -void S9xMainLoop_NoSA1_SFX (void) +void S9xMainLoop_NoSA1_SFX(void) { - for (;;) - { - APU_EXECUTE (); - - if (CPU.Flags) - { - if (CPU.Flags & NMI_FLAG) - { - if (--CPU.NMICycleCount == 0) { - CPU.Flags &= ~NMI_FLAG; - if (CPU.WaitingForInterrupt) { - CPU.WaitingForInterrupt = FALSE; - CPU.PC++; - } - S9xOpcode_NMI (); - } - } - - CHECK_SOUND (); - - if (CPU.Flags & IRQ_PENDING_FLAG) - { - if (CPU.IRQCycleCount == 0) - { - if (CPU.WaitingForInterrupt) { - CPU.WaitingForInterrupt = FALSE; - CPU.PC++; - } - if (CPU.IRQActive && !Settings.DisableIRQ) { - if (!CheckFlag (IRQ)) - S9xOpcode_IRQ (); - } - else - CPU.Flags &= ~IRQ_PENDING_FLAG; - } - else - { - if(--CPU.IRQCycleCount==0 && CheckFlag (IRQ)) - CPU.IRQCycleCount=1; - } - } - - if (CPU.Flags & SCAN_KEYS_FLAG) - break; - } + for (;;) + { + APU_EXECUTE(); + + if (CPU.Flags) + { + if (CPU.Flags & NMI_FLAG) + { + if (--CPU.NMICycleCount == 0) + { + CPU.Flags &= ~NMI_FLAG; + if (CPU.WaitingForInterrupt) + { + CPU.WaitingForInterrupt = FALSE; + CPU.PC++; + } + S9xOpcode_NMI(); + } + } + + CHECK_SOUND(); + + if (CPU.Flags & IRQ_PENDING_FLAG) + { + if (CPU.IRQCycleCount == 0) + { + if (CPU.WaitingForInterrupt) + { + CPU.WaitingForInterrupt = FALSE; + CPU.PC++; + } + if (CPU.IRQActive && !Settings.DisableIRQ) + { + if (!CheckFlag(IRQ)) + S9xOpcode_IRQ(); + } + else + CPU.Flags &= ~IRQ_PENDING_FLAG; + } + else + { + if (--CPU.IRQCycleCount == 0 && CheckFlag(IRQ)) + CPU.IRQCycleCount = 1; + } + } + + if (CPU.Flags & SCAN_KEYS_FLAG) + break; + } #ifdef CPU_SHUTDOWN - CPU.PCAtOpcodeStart = CPU.PC; + CPU.PCAtOpcodeStart = CPU.PC; #endif - CPU.Cycles += CPU.MemSpeed; - - (*ICPU.S9xOpcodes [*CPU.PC++].S9xOpcode) (); - - DO_HBLANK_CHECK_SFX(); - } - - ICPU.Registers.PC = CPU.PC - CPU.PCBase; - S9xPackStatus (); - IAPU.Registers.PC = IAPU.PC - IAPU.RAM; - S9xAPUPackStatus (); - if (CPU.Flags & SCAN_KEYS_FLAG) - { - S9xSyncSpeed (); - CPU.Flags &= ~SCAN_KEYS_FLAG; - } + CPU.Cycles += CPU.MemSpeed; + + (*ICPU.S9xOpcodes [*CPU.PC++].S9xOpcode)(); + + DO_HBLANK_CHECK_SFX(); + } + + ICPU.Registers.PC = CPU.PC - CPU.PCBase; + S9xPackStatus(); + IAPU.Registers.PC = IAPU.PC - IAPU.RAM; + S9xAPUPackStatus(); + if (CPU.Flags & SCAN_KEYS_FLAG) + { + S9xSyncSpeed(); + CPU.Flags &= ~SCAN_KEYS_FLAG; + } #ifdef DETECT_NASTY_FX_INTERLEAVE - if (CPU.BRKTriggered && Settings.SuperFX && !CPU.TriedInterleavedMode2) - { - CPU.TriedInterleavedMode2 = TRUE; - CPU.BRKTriggered = FALSE; - S9xDeinterleaveMode2 (); - } + if (CPU.BRKTriggered && Settings.SuperFX && !CPU.TriedInterleavedMode2) + { + CPU.TriedInterleavedMode2 = TRUE; + CPU.BRKTriggered = FALSE; + S9xDeinterleaveMode2(); + } #endif } -void S9xMainLoop_NoSA1_NoSFX (void) +void S9xMainLoop_NoSA1_NoSFX(void) { - for (;;) - { - APU_EXECUTE (); - - if (CPU.Flags) - { - if (CPU.Flags & NMI_FLAG) - { - if (--CPU.NMICycleCount == 0) { - CPU.Flags &= ~NMI_FLAG; - if (CPU.WaitingForInterrupt) { - CPU.WaitingForInterrupt = FALSE; - CPU.PC++; - } - S9xOpcode_NMI (); - } - } - - CHECK_SOUND (); - - if (CPU.Flags & IRQ_PENDING_FLAG) - { - if (CPU.IRQCycleCount == 0) - { - if (CPU.WaitingForInterrupt) { - CPU.WaitingForInterrupt = FALSE; - CPU.PC++; - } - if (CPU.IRQActive && !Settings.DisableIRQ) { - if (!CheckFlag (IRQ)) - S9xOpcode_IRQ (); - } - else - CPU.Flags &= ~IRQ_PENDING_FLAG; - } - else - { - if(--CPU.IRQCycleCount==0 && CheckFlag (IRQ)) - CPU.IRQCycleCount=1; - } - } - - if (CPU.Flags & SCAN_KEYS_FLAG) - break; - } + for (;;) + { + APU_EXECUTE(); + + if (CPU.Flags) + { + if (CPU.Flags & NMI_FLAG) + { + if (--CPU.NMICycleCount == 0) + { + CPU.Flags &= ~NMI_FLAG; + if (CPU.WaitingForInterrupt) + { + CPU.WaitingForInterrupt = FALSE; + CPU.PC++; + } + S9xOpcode_NMI(); + } + } + + CHECK_SOUND(); + + if (CPU.Flags & IRQ_PENDING_FLAG) + { + if (CPU.IRQCycleCount == 0) + { + if (CPU.WaitingForInterrupt) + { + CPU.WaitingForInterrupt = FALSE; + CPU.PC++; + } + if (CPU.IRQActive && !Settings.DisableIRQ) + { + if (!CheckFlag(IRQ)) + S9xOpcode_IRQ(); + } + else + CPU.Flags &= ~IRQ_PENDING_FLAG; + } + else + { + if (--CPU.IRQCycleCount == 0 && CheckFlag(IRQ)) + CPU.IRQCycleCount = 1; + } + } + + if (CPU.Flags & SCAN_KEYS_FLAG) + break; + } #ifdef CPU_SHUTDOWN - CPU.PCAtOpcodeStart = CPU.PC; + CPU.PCAtOpcodeStart = CPU.PC; #endif - CPU.Cycles += CPU.MemSpeed; - - (*ICPU.S9xOpcodes [*CPU.PC++].S9xOpcode) (); - - DO_HBLANK_CHECK_NoSFX(); - } - - ICPU.Registers.PC = CPU.PC - CPU.PCBase; - S9xPackStatus (); - IAPU.Registers.PC = IAPU.PC - IAPU.RAM; - S9xAPUPackStatus (); - if (CPU.Flags & SCAN_KEYS_FLAG) - { - S9xSyncSpeed (); - CPU.Flags &= ~SCAN_KEYS_FLAG; - } + CPU.Cycles += CPU.MemSpeed; + + (*ICPU.S9xOpcodes [*CPU.PC++].S9xOpcode)(); + + DO_HBLANK_CHECK_NoSFX(); + } + + ICPU.Registers.PC = CPU.PC - CPU.PCBase; + S9xPackStatus(); + IAPU.Registers.PC = IAPU.PC - IAPU.RAM; + S9xAPUPackStatus(); + if (CPU.Flags & SCAN_KEYS_FLAG) + { + S9xSyncSpeed(); + CPU.Flags &= ~SCAN_KEYS_FLAG; + } } -void S9xSetIRQ (uint32 source) +void S9xSetIRQ(uint32 source) { - CPU.IRQActive |= source; - CPU.Flags |= IRQ_PENDING_FLAG; - CPU.IRQCycleCount = 3; - if (CPU.WaitingForInterrupt) - { - // Force IRQ to trigger immediately after WAI - - // Final Fantasy Mystic Quest crashes without this. - CPU.IRQCycleCount = 0; - CPU.WaitingForInterrupt = FALSE; - CPU.PC++; - } + CPU.IRQActive |= source; + CPU.Flags |= IRQ_PENDING_FLAG; + CPU.IRQCycleCount = 3; + if (CPU.WaitingForInterrupt) + { + // Force IRQ to trigger immediately after WAI - + // Final Fantasy Mystic Quest crashes without this. + CPU.IRQCycleCount = 0; + CPU.WaitingForInterrupt = FALSE; + CPU.PC++; + } } -void S9xClearIRQ (uint32 source) +void S9xClearIRQ(uint32 source) { - CLEAR_IRQ_SOURCE (source); + CLEAR_IRQ_SOURCE(source); } /* @@ -464,380 +480,372 @@ void S9xClearIRQ (uint32 source) * The original version of S9xDoHBlankProcessing is S9xDoHBlankProcessing_SFX * below. Remember to propagate modifications to the NoSFX version. */ -void S9xDoHBlankProcessing_SFX () +void S9xDoHBlankProcessing_SFX() { #ifdef CPU_SHUTDOWN - CPU.WaitCounter++; + CPU.WaitCounter++; #endif - switch (CPU.WhichEvent) - { - case HBLANK_START_EVENT: + switch (CPU.WhichEvent) + { + case HBLANK_START_EVENT: #ifdef ACCUMULATE_JOYPAD -/* - * This call allows NDSSFC to synchronise the DS controller more often. - * If porting a later version of Snes9x into NDSSFC, it is essential to - * preserve it. - */ - if ((CPU.V_Counter & 0xF) == 0) - NDSSFCAccumulateJoypad (); + /* + * This call allows NDSSFC to synchronise the DS controller more often. + * If porting a later version of Snes9x into NDSSFC, it is essential to + * preserve it. + */ + if ((CPU.V_Counter & 0xF) == 0) + NDSSFCAccumulateJoypad(); #endif - if (IPPU.HDMA && CPU.V_Counter <= PPU.ScreenHeight) - IPPU.HDMA = S9xDoHDMA (IPPU.HDMA); + if (IPPU.HDMA && CPU.V_Counter <= PPU.ScreenHeight) + IPPU.HDMA = S9xDoHDMA(IPPU.HDMA); - break; + break; - case HBLANK_END_EVENT: - S9xSuperFXExec (); + case HBLANK_END_EVENT: + S9xSuperFXExec(); #ifndef STORM - if (Settings.SoundSync) - S9xGenerateSound (); + if (Settings.SoundSync) + S9xGenerateSound(); #endif - CPU.Cycles -= Settings.H_Max; - if (IAPU.APUExecuting) - { - APU.Cycles -= Settings.H_Max; + CPU.Cycles -= Settings.H_Max; + if (IAPU.APUExecuting) + { + APU.Cycles -= Settings.H_Max; #ifdef MK_APU - S9xCatchupCount(); + S9xCatchupCount(); #endif - } - else - APU.Cycles = 0; - - CPU.NextEvent = -1; - ICPU.Scanline++; - - if (++CPU.V_Counter >= (Settings.PAL ? SNES_MAX_PAL_VCOUNTER : SNES_MAX_NTSC_VCOUNTER)) - { - CPU.V_Counter = 0; - Memory.FillRAM[0x213F]^=0x80; - PPU.RangeTimeOver = 0; - CPU.NMIActive = FALSE; - ICPU.Frame++; - PPU.HVBeamCounterLatched = 0; - CPU.Flags |= SCAN_KEYS_FLAG; - S9xStartHDMA (); - } - - S9xProcessSound (0); - - if (PPU.VTimerEnabled && !PPU.HTimerEnabled && CPU.V_Counter == PPU.IRQVBeamPos) - { - S9xSetIRQ (PPU_V_BEAM_IRQ_SOURCE); - } - - if (CPU.V_Counter == PPU.ScreenHeight + FIRST_VISIBLE_LINE) - { - // Start of V-blank - S9xEndScreenRefresh (); - IPPU.HDMA = 0; - // Bits 7 and 6 of $4212 are computed when read in S9xGetPPU. - missing.dma_this_frame = 0; - IPPU.MaxBrightness = PPU.Brightness; - PPU.ForcedBlanking = (Memory.FillRAM [0x2100] >> 7) & 1; - - if(!PPU.ForcedBlanking) - { - PPU.OAMAddr = PPU.SavedOAMAddr; - - uint8 tmp = 0; - if(PPU.OAMPriorityRotation) - tmp = (PPU.OAMAddr&0xFE)>>1; - if((PPU.OAMFlip&1) || PPU.FirstSprite!=tmp) - { - PPU.FirstSprite=tmp; - IPPU.OBJChanged=TRUE; - } - - PPU.OAMFlip = 0; - } - - Memory.FillRAM[0x4210] = 0x80 |Model->_5A22; - if (Memory.FillRAM[0x4200] & 0x80) - { - CPU.NMIActive = TRUE; - CPU.Flags |= NMI_FLAG; - CPU.NMICycleCount = CPU.NMITriggerPoint; - } + } + else + APU.Cycles = 0; + + CPU.NextEvent = -1; + ICPU.Scanline++; + + if (++CPU.V_Counter >= (Settings.PAL ? SNES_MAX_PAL_VCOUNTER : + SNES_MAX_NTSC_VCOUNTER)) + { + CPU.V_Counter = 0; + Memory.FillRAM[0x213F] ^= 0x80; + PPU.RangeTimeOver = 0; + CPU.NMIActive = FALSE; + ICPU.Frame++; + PPU.HVBeamCounterLatched = 0; + CPU.Flags |= SCAN_KEYS_FLAG; + S9xStartHDMA(); + } + + S9xProcessSound(0); + + if (PPU.VTimerEnabled && !PPU.HTimerEnabled && CPU.V_Counter == PPU.IRQVBeamPos) + S9xSetIRQ(PPU_V_BEAM_IRQ_SOURCE); + + if (CPU.V_Counter == PPU.ScreenHeight + FIRST_VISIBLE_LINE) + { + // Start of V-blank + S9xEndScreenRefresh(); + IPPU.HDMA = 0; + // Bits 7 and 6 of $4212 are computed when read in S9xGetPPU. + missing.dma_this_frame = 0; + IPPU.MaxBrightness = PPU.Brightness; + PPU.ForcedBlanking = (Memory.FillRAM [0x2100] >> 7) & 1; + + if (!PPU.ForcedBlanking) + { + PPU.OAMAddr = PPU.SavedOAMAddr; + + uint8 tmp = 0; + if (PPU.OAMPriorityRotation) + tmp = (PPU.OAMAddr & 0xFE) >> 1; + if ((PPU.OAMFlip & 1) || PPU.FirstSprite != tmp) + { + PPU.FirstSprite = tmp; + IPPU.OBJChanged = TRUE; + } + + PPU.OAMFlip = 0; + } + + Memory.FillRAM[0x4210] = 0x80 | Model->_5A22; + if (Memory.FillRAM[0x4200] & 0x80) + { + CPU.NMIActive = TRUE; + CPU.Flags |= NMI_FLAG; + CPU.NMICycleCount = CPU.NMITriggerPoint; + } #ifdef OLD_SNAPSHOT_CODE - if (CPU.Flags & SAVE_SNAPSHOT_FLAG) - { - CPU.Flags &= ~SAVE_SNAPSHOT_FLAG; - Registers.PC = CPU.PC - CPU.PCBase; - S9xPackStatus (); - S9xAPUPackStatus (); - Snapshot (NULL); - } + if (CPU.Flags & SAVE_SNAPSHOT_FLAG) + { + CPU.Flags &= ~SAVE_SNAPSHOT_FLAG; + Registers.PC = CPU.PC - CPU.PCBase; + S9xPackStatus(); + S9xAPUPackStatus(); + Snapshot(NULL); + } +#endif + } + + if (CPU.V_Counter == PPU.ScreenHeight + 3) + S9xUpdateJoypads(); + + if (CPU.V_Counter == FIRST_VISIBLE_LINE) + { + Memory.FillRAM[0x4210] = Model->_5A22; + CPU.Flags &= ~NMI_FLAG; + S9xStartScreenRefresh(); + } + if (CPU.V_Counter >= FIRST_VISIBLE_LINE && + CPU.V_Counter < PPU.ScreenHeight + FIRST_VISIBLE_LINE) + RenderLine(CPU.V_Counter - FIRST_VISIBLE_LINE); + // Use TimerErrorCounter to skip update of SPC700 timers once + // every 128 updates. Needed because this section of code is called + // once every emulated 63.5 microseconds, which coresponds to + // 15.750KHz, but the SPC700 timers need to be updated at multiples + // of 8KHz, hence the error correction. + // IAPU.TimerErrorCounter++; + // if (IAPU.TimerErrorCounter >= ) + // IAPU.TimerErrorCounter = 0; + // else + { + if (APU.TimerEnabled [2]) + { + APU.Timer [2] += 4; + while (APU.Timer [2] >= APU.TimerTarget [2]) + { + IAPU.RAM [0xff] = (IAPU.RAM [0xff] + 1) & 0xf; + APU.Timer [2] -= APU.TimerTarget [2]; +#ifdef SPC700_SHUTDOWN + IAPU.WaitCounter++; + IAPU.APUExecuting = TRUE; #endif - } - - if (CPU.V_Counter == PPU.ScreenHeight + 3) - S9xUpdateJoypads (); - - if (CPU.V_Counter == FIRST_VISIBLE_LINE) - { - Memory.FillRAM[0x4210] = Model->_5A22; - CPU.Flags &= ~NMI_FLAG; - S9xStartScreenRefresh (); - } - if (CPU.V_Counter >= FIRST_VISIBLE_LINE && - CPU.V_Counter < PPU.ScreenHeight + FIRST_VISIBLE_LINE) - { - RenderLine (CPU.V_Counter - FIRST_VISIBLE_LINE); - } - // Use TimerErrorCounter to skip update of SPC700 timers once - // every 128 updates. Needed because this section of code is called - // once every emulated 63.5 microseconds, which coresponds to - // 15.750KHz, but the SPC700 timers need to be updated at multiples - // of 8KHz, hence the error correction. -// IAPU.TimerErrorCounter++; -// if (IAPU.TimerErrorCounter >= ) -// IAPU.TimerErrorCounter = 0; -// else - { - if (APU.TimerEnabled [2]) - { - APU.Timer [2] += 4; - while (APU.Timer [2] >= APU.TimerTarget [2]) - { - IAPU.RAM [0xff] = (IAPU.RAM [0xff] + 1) & 0xf; - APU.Timer [2] -= APU.TimerTarget [2]; -#ifdef SPC700_SHUTDOWN - IAPU.WaitCounter++; - IAPU.APUExecuting = TRUE; + } + } + if (CPU.V_Counter & 1) + { + if (APU.TimerEnabled [0]) + { + APU.Timer [0]++; + if (APU.Timer [0] >= APU.TimerTarget [0]) + { + IAPU.RAM [0xfd] = (IAPU.RAM [0xfd] + 1) & 0xf; + APU.Timer [0] = 0; +#ifdef SPC700_SHUTDOWN + IAPU.WaitCounter++; + IAPU.APUExecuting = TRUE; #endif - } - } - if (CPU.V_Counter & 1) - { - if (APU.TimerEnabled [0]) - { - APU.Timer [0]++; - if (APU.Timer [0] >= APU.TimerTarget [0]) - { - IAPU.RAM [0xfd] = (IAPU.RAM [0xfd] + 1) & 0xf; - APU.Timer [0] = 0; -#ifdef SPC700_SHUTDOWN - IAPU.WaitCounter++; - IAPU.APUExecuting = TRUE; + } + } + if (APU.TimerEnabled [1]) + { + APU.Timer [1]++; + if (APU.Timer [1] >= APU.TimerTarget [1]) + { + IAPU.RAM [0xfe] = (IAPU.RAM [0xfe] + 1) & 0xf; + APU.Timer [1] = 0; +#ifdef SPC700_SHUTDOWN + IAPU.WaitCounter++; + IAPU.APUExecuting = TRUE; #endif - } - } - if (APU.TimerEnabled [1]) - { - APU.Timer [1]++; - if (APU.Timer [1] >= APU.TimerTarget [1]) - { - IAPU.RAM [0xfe] = (IAPU.RAM [0xfe] + 1) & 0xf; - APU.Timer [1] = 0; -#ifdef SPC700_SHUTDOWN - IAPU.WaitCounter++; - IAPU.APUExecuting = TRUE; -#endif - } - } - } - } - break; - - case HTIMER_BEFORE_EVENT: - case HTIMER_AFTER_EVENT: - if (PPU.HTimerEnabled && (!PPU.VTimerEnabled || CPU.V_Counter == PPU.IRQVBeamPos)) - { - S9xSetIRQ (PPU_H_BEAM_IRQ_SOURCE); - } - break; - } - - S9xReschedule (); + } + } + } + } + break; + + case HTIMER_BEFORE_EVENT: + case HTIMER_AFTER_EVENT: + if (PPU.HTimerEnabled && (!PPU.VTimerEnabled + || CPU.V_Counter == PPU.IRQVBeamPos)) + S9xSetIRQ(PPU_H_BEAM_IRQ_SOURCE); + break; + } + + S9xReschedule(); } -void S9xDoHBlankProcessing_NoSFX () +void S9xDoHBlankProcessing_NoSFX() { #ifdef CPU_SHUTDOWN - CPU.WaitCounter++; + CPU.WaitCounter++; #endif - switch (CPU.WhichEvent) - { - case HBLANK_START_EVENT: + switch (CPU.WhichEvent) + { + case HBLANK_START_EVENT: #ifdef ACCUMULATE_JOYPAD -/* - * This call allows NDSSFC to synchronise the DS controller more often. - * If porting a later version of Snes9x into NDSSFC, it is essential to - * preserve it. - */ - NDSSFCAccumulateJoypad (); + /* + * This call allows NDSSFC to synchronise the DS controller more often. + * If porting a later version of Snes9x into NDSSFC, it is essential to + * preserve it. + */ + NDSSFCAccumulateJoypad(); #endif - if (IPPU.HDMA && CPU.V_Counter <= PPU.ScreenHeight) - IPPU.HDMA = S9xDoHDMA (IPPU.HDMA); + if (IPPU.HDMA && CPU.V_Counter <= PPU.ScreenHeight) + IPPU.HDMA = S9xDoHDMA(IPPU.HDMA); - break; + break; - case HBLANK_END_EVENT: + case HBLANK_END_EVENT: #ifndef STORM - if (Settings.SoundSync) - S9xGenerateSound (); + if (Settings.SoundSync) + S9xGenerateSound(); #endif - CPU.Cycles -= Settings.H_Max; - if (IAPU.APUExecuting) - { - APU.Cycles -= Settings.H_Max; + CPU.Cycles -= Settings.H_Max; + if (IAPU.APUExecuting) + { + APU.Cycles -= Settings.H_Max; #ifdef MK_APU - S9xCatchupCount(); + S9xCatchupCount(); #endif - } - else - APU.Cycles = 0; - - CPU.NextEvent = -1; - ICPU.Scanline++; - - if (++CPU.V_Counter >= (Settings.PAL ? SNES_MAX_PAL_VCOUNTER : SNES_MAX_NTSC_VCOUNTER)) - { - CPU.V_Counter = 0; - Memory.FillRAM[0x213F]^=0x80; - PPU.RangeTimeOver = 0; - CPU.NMIActive = FALSE; - ICPU.Frame++; - PPU.HVBeamCounterLatched = 0; - CPU.Flags |= SCAN_KEYS_FLAG; - S9xStartHDMA (); - } - - S9xProcessSound (0); - - if (PPU.VTimerEnabled && !PPU.HTimerEnabled && CPU.V_Counter == PPU.IRQVBeamPos) - { - S9xSetIRQ (PPU_V_BEAM_IRQ_SOURCE); - } - - if (CPU.V_Counter == PPU.ScreenHeight + FIRST_VISIBLE_LINE) - { - // Start of V-blank - S9xEndScreenRefresh (); - IPPU.HDMA = 0; - // Bits 7 and 6 of $4212 are computed when read in S9xGetPPU. - missing.dma_this_frame = 0; - IPPU.MaxBrightness = PPU.Brightness; - PPU.ForcedBlanking = (Memory.FillRAM [0x2100] >> 7) & 1; - - if(!PPU.ForcedBlanking) - { - PPU.OAMAddr = PPU.SavedOAMAddr; - - uint8 tmp = 0; - if(PPU.OAMPriorityRotation) - tmp = (PPU.OAMAddr&0xFE)>>1; - if((PPU.OAMFlip&1) || PPU.FirstSprite!=tmp) - { - PPU.FirstSprite=tmp; - IPPU.OBJChanged=TRUE; - } - - PPU.OAMFlip = 0; - } - - Memory.FillRAM[0x4210] = 0x80 |Model->_5A22; - if (Memory.FillRAM[0x4200] & 0x80) - { - CPU.NMIActive = TRUE; - CPU.Flags |= NMI_FLAG; - CPU.NMICycleCount = CPU.NMITriggerPoint; - } + } + else + APU.Cycles = 0; + + CPU.NextEvent = -1; + ICPU.Scanline++; + + if (++CPU.V_Counter >= (Settings.PAL ? SNES_MAX_PAL_VCOUNTER : + SNES_MAX_NTSC_VCOUNTER)) + { + CPU.V_Counter = 0; + Memory.FillRAM[0x213F] ^= 0x80; + PPU.RangeTimeOver = 0; + CPU.NMIActive = FALSE; + ICPU.Frame++; + PPU.HVBeamCounterLatched = 0; + CPU.Flags |= SCAN_KEYS_FLAG; + S9xStartHDMA(); + } + + S9xProcessSound(0); + + if (PPU.VTimerEnabled && !PPU.HTimerEnabled && CPU.V_Counter == PPU.IRQVBeamPos) + S9xSetIRQ(PPU_V_BEAM_IRQ_SOURCE); + + if (CPU.V_Counter == PPU.ScreenHeight + FIRST_VISIBLE_LINE) + { + // Start of V-blank + S9xEndScreenRefresh(); + IPPU.HDMA = 0; + // Bits 7 and 6 of $4212 are computed when read in S9xGetPPU. + missing.dma_this_frame = 0; + IPPU.MaxBrightness = PPU.Brightness; + PPU.ForcedBlanking = (Memory.FillRAM [0x2100] >> 7) & 1; + + if (!PPU.ForcedBlanking) + { + PPU.OAMAddr = PPU.SavedOAMAddr; + + uint8 tmp = 0; + if (PPU.OAMPriorityRotation) + tmp = (PPU.OAMAddr & 0xFE) >> 1; + if ((PPU.OAMFlip & 1) || PPU.FirstSprite != tmp) + { + PPU.FirstSprite = tmp; + IPPU.OBJChanged = TRUE; + } + + PPU.OAMFlip = 0; + } + + Memory.FillRAM[0x4210] = 0x80 | Model->_5A22; + if (Memory.FillRAM[0x4200] & 0x80) + { + CPU.NMIActive = TRUE; + CPU.Flags |= NMI_FLAG; + CPU.NMICycleCount = CPU.NMITriggerPoint; + } #ifdef OLD_SNAPSHOT_CODE - if (CPU.Flags & SAVE_SNAPSHOT_FLAG) - { - CPU.Flags &= ~SAVE_SNAPSHOT_FLAG; - Registers.PC = CPU.PC - CPU.PCBase; - S9xPackStatus (); - S9xAPUPackStatus (); - Snapshot (NULL); - } + if (CPU.Flags & SAVE_SNAPSHOT_FLAG) + { + CPU.Flags &= ~SAVE_SNAPSHOT_FLAG; + Registers.PC = CPU.PC - CPU.PCBase; + S9xPackStatus(); + S9xAPUPackStatus(); + Snapshot(NULL); + } +#endif + } + + if (CPU.V_Counter == PPU.ScreenHeight + 3) + S9xUpdateJoypads(); + + if (CPU.V_Counter == FIRST_VISIBLE_LINE) + { + Memory.FillRAM[0x4210] = Model->_5A22; + CPU.Flags &= ~NMI_FLAG; + S9xStartScreenRefresh(); + } + if (CPU.V_Counter >= FIRST_VISIBLE_LINE && + CPU.V_Counter < PPU.ScreenHeight + FIRST_VISIBLE_LINE) + RenderLine(CPU.V_Counter - FIRST_VISIBLE_LINE); + // Use TimerErrorCounter to skip update of SPC700 timers once + // every 128 updates. Needed because this section of code is called + // once every emulated 63.5 microseconds, which coresponds to + // 15.750KHz, but the SPC700 timers need to be updated at multiples + // of 8KHz, hence the error correction. + // IAPU.TimerErrorCounter++; + // if (IAPU.TimerErrorCounter >= ) + // IAPU.TimerErrorCounter = 0; + // else + { + if (APU.TimerEnabled [2]) + { + APU.Timer [2] += 4; + while (APU.Timer [2] >= APU.TimerTarget [2]) + { + IAPU.RAM [0xff] = (IAPU.RAM [0xff] + 1) & 0xf; + APU.Timer [2] -= APU.TimerTarget [2]; +#ifdef SPC700_SHUTDOWN + IAPU.WaitCounter++; + IAPU.APUExecuting = TRUE; #endif - } - - if (CPU.V_Counter == PPU.ScreenHeight + 3) - S9xUpdateJoypads (); - - if (CPU.V_Counter == FIRST_VISIBLE_LINE) - { - Memory.FillRAM[0x4210] = Model->_5A22; - CPU.Flags &= ~NMI_FLAG; - S9xStartScreenRefresh (); - } - if (CPU.V_Counter >= FIRST_VISIBLE_LINE && - CPU.V_Counter < PPU.ScreenHeight + FIRST_VISIBLE_LINE) - { - RenderLine (CPU.V_Counter - FIRST_VISIBLE_LINE); - } - // Use TimerErrorCounter to skip update of SPC700 timers once - // every 128 updates. Needed because this section of code is called - // once every emulated 63.5 microseconds, which coresponds to - // 15.750KHz, but the SPC700 timers need to be updated at multiples - // of 8KHz, hence the error correction. -// IAPU.TimerErrorCounter++; -// if (IAPU.TimerErrorCounter >= ) -// IAPU.TimerErrorCounter = 0; -// else - { - if (APU.TimerEnabled [2]) - { - APU.Timer [2] += 4; - while (APU.Timer [2] >= APU.TimerTarget [2]) - { - IAPU.RAM [0xff] = (IAPU.RAM [0xff] + 1) & 0xf; - APU.Timer [2] -= APU.TimerTarget [2]; -#ifdef SPC700_SHUTDOWN - IAPU.WaitCounter++; - IAPU.APUExecuting = TRUE; + } + } + if (CPU.V_Counter & 1) + { + if (APU.TimerEnabled [0]) + { + APU.Timer [0]++; + if (APU.Timer [0] >= APU.TimerTarget [0]) + { + IAPU.RAM [0xfd] = (IAPU.RAM [0xfd] + 1) & 0xf; + APU.Timer [0] = 0; +#ifdef SPC700_SHUTDOWN + IAPU.WaitCounter++; + IAPU.APUExecuting = TRUE; #endif - } - } - if (CPU.V_Counter & 1) - { - if (APU.TimerEnabled [0]) - { - APU.Timer [0]++; - if (APU.Timer [0] >= APU.TimerTarget [0]) - { - IAPU.RAM [0xfd] = (IAPU.RAM [0xfd] + 1) & 0xf; - APU.Timer [0] = 0; -#ifdef SPC700_SHUTDOWN - IAPU.WaitCounter++; - IAPU.APUExecuting = TRUE; + } + } + if (APU.TimerEnabled [1]) + { + APU.Timer [1]++; + if (APU.Timer [1] >= APU.TimerTarget [1]) + { + IAPU.RAM [0xfe] = (IAPU.RAM [0xfe] + 1) & 0xf; + APU.Timer [1] = 0; +#ifdef SPC700_SHUTDOWN + IAPU.WaitCounter++; + IAPU.APUExecuting = TRUE; #endif - } - } - if (APU.TimerEnabled [1]) - { - APU.Timer [1]++; - if (APU.Timer [1] >= APU.TimerTarget [1]) - { - IAPU.RAM [0xfe] = (IAPU.RAM [0xfe] + 1) & 0xf; - APU.Timer [1] = 0; -#ifdef SPC700_SHUTDOWN - IAPU.WaitCounter++; - IAPU.APUExecuting = TRUE; -#endif - } - } - } - } - break; - - case HTIMER_BEFORE_EVENT: - case HTIMER_AFTER_EVENT: - if (PPU.HTimerEnabled && (!PPU.VTimerEnabled || CPU.V_Counter == PPU.IRQVBeamPos)) - { - S9xSetIRQ (PPU_H_BEAM_IRQ_SOURCE); - } - break; - } - - S9xReschedule (); + } + } + } + } + break; + + case HTIMER_BEFORE_EVENT: + case HTIMER_AFTER_EVENT: + if (PPU.HTimerEnabled && (!PPU.VTimerEnabled + || CPU.V_Counter == PPU.IRQVBeamPos)) + S9xSetIRQ(PPU_H_BEAM_IRQ_SOURCE); + break; + } + + S9xReschedule(); } diff --git a/source/cpuexec.h b/source/cpuexec.h index 346b90e..3eb6064 100644 --- a/source/cpuexec.h +++ b/source/cpuexec.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -95,44 +95,45 @@ #define DO_HBLANK_CHECK_SFX() \ if (CPU.Cycles >= CPU.NextEvent) \ - S9xDoHBlankProcessing_SFX (); + S9xDoHBlankProcessing_SFX (); #define DO_HBLANK_CHECK_NoSFX() \ if (CPU.Cycles >= CPU.NextEvent) \ - S9xDoHBlankProcessing_NoSFX (); + S9xDoHBlankProcessing_NoSFX (); -typedef struct { +typedef struct +{ #ifdef __WIN32__ - void (__cdecl *S9xOpcode)( void); + void (__cdecl* S9xOpcode)(void); #else - void (*S9xOpcode)( void); + void (*S9xOpcode)(void); #endif -}SOpcodes; +} SOpcodes; typedef struct { - uint8 *Speed; - SOpcodes *S9xOpcodes; - SRegisters Registers; - uint8 _Carry; - uint8 _Zero; - uint8 _Negative; - uint8 _Overflow; - bool8 CPUExecuting; - uint32 ShiftedPB; - uint32 ShiftedDB; - uint32 Frame; - uint32 Scanline; - uint32 FrameAdvanceCount; -}SICPU; - -void S9xMainLoop (void); -void S9xReset (void); -void S9xSoftReset (void); -void S9xDoHBlankProcessing_SFX (); -void S9xDoHBlankProcessing_NoSFX (); -void S9xClearIRQ (uint32); -void S9xSetIRQ (uint32); + uint8* Speed; + SOpcodes* S9xOpcodes; + SRegisters Registers; + uint8 _Carry; + uint8 _Zero; + uint8 _Negative; + uint8 _Overflow; + bool8 CPUExecuting; + uint32 ShiftedPB; + uint32 ShiftedDB; + uint32 Frame; + uint32 Scanline; + uint32 FrameAdvanceCount; +} SICPU; + +void S9xMainLoop(void); +void S9xReset(void); +void S9xSoftReset(void); +void S9xDoHBlankProcessing_SFX(); +void S9xDoHBlankProcessing_NoSFX(); +void S9xClearIRQ(uint32); +void S9xSetIRQ(uint32); extern SOpcodes S9xOpcodesE1 [256]; extern SOpcodes S9xOpcodesM1X1 [256]; @@ -144,86 +145,75 @@ extern SICPU ICPU; STATIC inline void S9xUnpackStatus() { - ICPU._Zero = (ICPU.Registers.PL & Zero) == 0; - ICPU._Negative = (ICPU.Registers.PL & Negative); - ICPU._Carry = (ICPU.Registers.PL & Carry); - ICPU._Overflow = (ICPU.Registers.PL & Overflow) >> 6; + ICPU._Zero = (ICPU.Registers.PL & Zero) == 0; + ICPU._Negative = (ICPU.Registers.PL & Negative); + ICPU._Carry = (ICPU.Registers.PL & Carry); + ICPU._Overflow = (ICPU.Registers.PL & Overflow) >> 6; } STATIC inline void S9xPackStatus() { - ICPU.Registers.PL &= ~(Zero | Negative | Carry | Overflow); - ICPU.Registers.PL |= ICPU._Carry | ((ICPU._Zero == 0) << 1) | - (ICPU._Negative & 0x80) | (ICPU._Overflow << 6); + ICPU.Registers.PL &= ~(Zero | Negative | Carry | Overflow); + ICPU.Registers.PL |= ICPU._Carry | ((ICPU._Zero == 0) << 1) | + (ICPU._Negative & 0x80) | (ICPU._Overflow << 6); } -STATIC inline void CLEAR_IRQ_SOURCE (uint32 M) +STATIC inline void CLEAR_IRQ_SOURCE(uint32 M) { - CPU.IRQActive &= ~M; - if (!CPU.IRQActive) - CPU.Flags &= ~IRQ_PENDING_FLAG; + CPU.IRQActive &= ~M; + if (!CPU.IRQActive) + CPU.Flags &= ~IRQ_PENDING_FLAG; } - -STATIC inline void S9xFixCycles () + +STATIC inline void S9xFixCycles() { - if (CheckEmulation ()) - { - ICPU.S9xOpcodes = S9xOpcodesE1; - } - else - if (CheckMemory ()) - { - if (CheckIndex ()) - { - ICPU.S9xOpcodes = S9xOpcodesM1X1; - } - else - { - ICPU.S9xOpcodes = S9xOpcodesM1X0; - } - } - else - { - if (CheckIndex ()) - { - ICPU.S9xOpcodes = S9xOpcodesM0X1; - } - else - { - ICPU.S9xOpcodes = S9xOpcodesM0X0; - } - } + if (CheckEmulation()) + ICPU.S9xOpcodes = S9xOpcodesE1; + else if (CheckMemory()) + { + if (CheckIndex()) + ICPU.S9xOpcodes = S9xOpcodesM1X1; + else + ICPU.S9xOpcodes = S9xOpcodesM1X0; + } + else + { + if (CheckIndex()) + ICPU.S9xOpcodes = S9xOpcodesM0X1; + else + ICPU.S9xOpcodes = S9xOpcodesM0X0; + } } -STATIC inline void S9xReschedule () +STATIC inline void S9xReschedule() { - uint8 which; - long max; - - if (CPU.WhichEvent == HBLANK_START_EVENT || - CPU.WhichEvent == HTIMER_AFTER_EVENT) - { - which = HBLANK_END_EVENT; - max = Settings.H_Max; - } - else - { - which = HBLANK_START_EVENT; - max = Settings.HBlankStart; - } - - if (PPU.HTimerEnabled && - (long) PPU.HTimerPosition < max && - (long) PPU.HTimerPosition > CPU.NextEvent && - (!PPU.VTimerEnabled || - (PPU.VTimerEnabled && CPU.V_Counter == PPU.IRQVBeamPos))) - { - which = (long) PPU.HTimerPosition < Settings.HBlankStart ? - HTIMER_BEFORE_EVENT : HTIMER_AFTER_EVENT; - max = PPU.HTimerPosition; - } - CPU.NextEvent = max; - CPU.WhichEvent = which; + uint8 which; + long max; + + if (CPU.WhichEvent == HBLANK_START_EVENT || + CPU.WhichEvent == HTIMER_AFTER_EVENT) + { + which = HBLANK_END_EVENT; + max = Settings.H_Max; + } + else + { + which = HBLANK_START_EVENT; + max = Settings.HBlankStart; + } + + if (PPU.HTimerEnabled && + (long) PPU.HTimerPosition < max && + (long) PPU.HTimerPosition > CPU.NextEvent && + (!PPU.VTimerEnabled || + (PPU.VTimerEnabled && CPU.V_Counter == PPU.IRQVBeamPos))) + { + which = (long) PPU.HTimerPosition < Settings.HBlankStart ? + HTIMER_BEFORE_EVENT : HTIMER_AFTER_EVENT; + max = PPU.HTimerPosition; + } + CPU.NextEvent = max; + CPU.WhichEvent = which; } #endif diff --git a/source/cpumacro.h b/source/cpumacro.h index c5ed835..89ac88c 100644 --- a/source/cpumacro.h +++ b/source/cpumacro.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -90,752 +90,746 @@ #ifndef _CPUMACRO_H_ #define _CPUMACRO_H_ -static void SetZN16 (uint16 Work) -{ - ICPU._Zero = Work != 0; - ICPU._Negative = (uint8) (Work >> 8); -} - -static void SetZN8 (uint8 Work) -{ - ICPU._Zero = Work; - ICPU._Negative = Work; -} - -static void ADC8 (long Addr) -{ - uint8 Work8 = S9xGetByte (Addr); - - if (CheckDecimal ()) - { - uint8 A1 = (ICPU.Registers.A.W) & 0xF; - uint8 A2 = (ICPU.Registers.A.W >> 4) & 0xF; - uint8 W1 = Work8 & 0xF; - uint8 W2 = (Work8 >> 4) & 0xF; - - A1 += W1 + CheckCarry(); - if (A1 > 9) - { - A1 -= 10; - A1 &= 0xF; - A2++; - } - - A2 += W2; - if (A2 > 9) - { - A2 -= 10; - A2 &= 0xF; - SetCarry (); - } - else - { - ClearCarry (); - } - - int8 Ans8 = (A2 << 4) | A1; - if (~(ICPU.Registers.AL ^ Work8) & - (Work8 ^ Ans8) & 0x80) - SetOverflow(); - else - ClearOverflow(); - ICPU.Registers.AL = Ans8; - } - else - { - int16 Ans16 = ICPU.Registers.AL + Work8 + CheckCarry(); - - ICPU._Carry = Ans16 >= 0x100; - - if (~(ICPU.Registers.AL ^ Work8) & - (Work8 ^ (uint8) Ans16) & 0x80) - SetOverflow(); - else - ClearOverflow(); - ICPU.Registers.AL = (uint8) Ans16; - } - SetZN8 (ICPU.Registers.AL); -} - -static void ADC16 (long Addr) -{ - uint16 Work16 = S9xGetWord (Addr); - - if (CheckDecimal ()) - { - uint8 A1 = (ICPU.Registers.A.W) & 0xF; - uint8 A2 = (ICPU.Registers.A.W >> 4) & 0xF; - uint8 A3 = (ICPU.Registers.A.W >> 8) & 0xF; - uint8 A4 = (ICPU.Registers.A.W >> 12) & 0xF; - uint8 W1 = Work16 & 0xF; - uint8 W2 = (Work16 >> 4) & 0xF; - uint8 W3 = (Work16 >> 8) & 0xF; - uint8 W4 = (Work16 >> 12) & 0xF; - - A1 += W1 + CheckCarry (); - if (A1 > 9) - { - A1 -= 10; - A1 &= 0xF; - A2++; - } - - A2 += W2; - if (A2 > 9) - { - A2 -= 10; - A2 &= 0xF; - A3++; - } - - A3 += W3; - if (A3 > 9) - { - A3 -= 10; - A3 &= 0xF; - A4++; - } - - A4 += W4; - if (A4 > 9) - { - A4 -= 10; - A4 &= 0xF; - SetCarry (); - } - else - { - ClearCarry (); - } - - uint16 Ans16 = (A4 << 12) | (A3 << 8) | (A2 << 4) | (A1); - if (~(ICPU.Registers.A.W ^ Work16) & - (Work16 ^ Ans16) & 0x8000) - SetOverflow(); - else - ClearOverflow(); - ICPU.Registers.A.W = Ans16; - } - else - { - uint32 Ans32 = ICPU.Registers.A.W + Work16 + CheckCarry(); - - ICPU._Carry = Ans32 >= 0x10000; - - if (~(ICPU.Registers.A.W ^ Work16) & - (Work16 ^ (uint16) Ans32) & 0x8000) - SetOverflow(); - else - ClearOverflow(); - ICPU.Registers.A.W = (uint16) Ans32; - } - SetZN16 (ICPU.Registers.A.W); -} - -static void AND16 (long Addr) -{ - ICPU.Registers.A.W &= S9xGetWord (Addr); - SetZN16 (ICPU.Registers.A.W); -} - -static void AND8 (long Addr) -{ - ICPU.Registers.AL &= S9xGetByte (Addr); - SetZN8 (ICPU.Registers.AL); -} - -static inline void A_ASL16 () +static void SetZN16(uint16 Work) +{ + ICPU._Zero = Work != 0; + ICPU._Negative = (uint8)(Work >> 8); +} + +static void SetZN8(uint8 Work) +{ + ICPU._Zero = Work; + ICPU._Negative = Work; +} + +static void ADC8(long Addr) +{ + uint8 Work8 = S9xGetByte(Addr); + + if (CheckDecimal()) + { + uint8 A1 = (ICPU.Registers.A.W) & 0xF; + uint8 A2 = (ICPU.Registers.A.W >> 4) & 0xF; + uint8 W1 = Work8 & 0xF; + uint8 W2 = (Work8 >> 4) & 0xF; + + A1 += W1 + CheckCarry(); + if (A1 > 9) + { + A1 -= 10; + A1 &= 0xF; + A2++; + } + + A2 += W2; + if (A2 > 9) + { + A2 -= 10; + A2 &= 0xF; + SetCarry(); + } + else + ClearCarry(); + + int8 Ans8 = (A2 << 4) | A1; + if (~(ICPU.Registers.AL ^ Work8) & + (Work8 ^ Ans8) & 0x80) + SetOverflow(); + else + ClearOverflow(); + ICPU.Registers.AL = Ans8; + } + else + { + int16 Ans16 = ICPU.Registers.AL + Work8 + CheckCarry(); + + ICPU._Carry = Ans16 >= 0x100; + + if (~(ICPU.Registers.AL ^ Work8) & + (Work8 ^ (uint8) Ans16) & 0x80) + SetOverflow(); + else + ClearOverflow(); + ICPU.Registers.AL = (uint8) Ans16; + } + SetZN8(ICPU.Registers.AL); +} + +static void ADC16(long Addr) +{ + uint16 Work16 = S9xGetWord(Addr); + + if (CheckDecimal()) + { + uint8 A1 = (ICPU.Registers.A.W) & 0xF; + uint8 A2 = (ICPU.Registers.A.W >> 4) & 0xF; + uint8 A3 = (ICPU.Registers.A.W >> 8) & 0xF; + uint8 A4 = (ICPU.Registers.A.W >> 12) & 0xF; + uint8 W1 = Work16 & 0xF; + uint8 W2 = (Work16 >> 4) & 0xF; + uint8 W3 = (Work16 >> 8) & 0xF; + uint8 W4 = (Work16 >> 12) & 0xF; + + A1 += W1 + CheckCarry(); + if (A1 > 9) + { + A1 -= 10; + A1 &= 0xF; + A2++; + } + + A2 += W2; + if (A2 > 9) + { + A2 -= 10; + A2 &= 0xF; + A3++; + } + + A3 += W3; + if (A3 > 9) + { + A3 -= 10; + A3 &= 0xF; + A4++; + } + + A4 += W4; + if (A4 > 9) + { + A4 -= 10; + A4 &= 0xF; + SetCarry(); + } + else + ClearCarry(); + + uint16 Ans16 = (A4 << 12) | (A3 << 8) | (A2 << 4) | (A1); + if (~(ICPU.Registers.A.W ^ Work16) & + (Work16 ^ Ans16) & 0x8000) + SetOverflow(); + else + ClearOverflow(); + ICPU.Registers.A.W = Ans16; + } + else + { + uint32 Ans32 = ICPU.Registers.A.W + Work16 + CheckCarry(); + + ICPU._Carry = Ans32 >= 0x10000; + + if (~(ICPU.Registers.A.W ^ Work16) & + (Work16 ^ (uint16) Ans32) & 0x8000) + SetOverflow(); + else + ClearOverflow(); + ICPU.Registers.A.W = (uint16) Ans32; + } + SetZN16(ICPU.Registers.A.W); +} + +static void AND16(long Addr) +{ + ICPU.Registers.A.W &= S9xGetWord(Addr); + SetZN16(ICPU.Registers.A.W); +} + +static void AND8(long Addr) +{ + ICPU.Registers.AL &= S9xGetByte(Addr); + SetZN8(ICPU.Registers.AL); +} + +static inline void A_ASL16() { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - ICPU._Carry = (ICPU.Registers.AH & 0x80) != 0; - ICPU.Registers.A.W <<= 1; - SetZN16 (ICPU.Registers.A.W); + ICPU._Carry = (ICPU.Registers.AH & 0x80) != 0; + ICPU.Registers.A.W <<= 1; + SetZN16(ICPU.Registers.A.W); } -static inline void A_ASL8 () +static inline void A_ASL8() { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - ICPU._Carry = (ICPU.Registers.AL & 0x80) != 0; - ICPU.Registers.AL <<= 1; - SetZN8 (ICPU.Registers.AL); + ICPU._Carry = (ICPU.Registers.AL & 0x80) != 0; + ICPU.Registers.AL <<= 1; + SetZN8(ICPU.Registers.AL); } -static void ASL16 (long Addr) +static void ASL16(long Addr) { - uint16 Work16 = S9xGetWord (Addr); - ICPU._Carry = (Work16 & 0x8000) != 0; - Work16 <<= 1; - //S9xSetWord (Work16, Addr); - S9xSetByte(Work16>>8, Addr+1); - S9xSetByte(Work16&0xFF, Addr); - SetZN16 (Work16); + uint16 Work16 = S9xGetWord(Addr); + ICPU._Carry = (Work16 & 0x8000) != 0; + Work16 <<= 1; + //S9xSetWord (Work16, Addr); + S9xSetByte(Work16 >> 8, Addr + 1); + S9xSetByte(Work16 & 0xFF, Addr); + SetZN16(Work16); } -static void ASL8 (long Addr) +static void ASL8(long Addr) { - uint8 Work8 = S9xGetByte (Addr); - ICPU._Carry = (Work8 & 0x80) != 0; - Work8 <<= 1; - S9xSetByte (Work8, Addr); - SetZN8 (Work8); + uint8 Work8 = S9xGetByte(Addr); + ICPU._Carry = (Work8 & 0x80) != 0; + Work8 <<= 1; + S9xSetByte(Work8, Addr); + SetZN8(Work8); } -static void BIT16 (long Addr) +static void BIT16(long Addr) { - uint16 Work16 = S9xGetWord (Addr); - ICPU._Overflow = (Work16 & 0x4000) != 0; - ICPU._Negative = (uint8) (Work16 >> 8); - ICPU._Zero = (Work16 & ICPU.Registers.A.W) != 0; + uint16 Work16 = S9xGetWord(Addr); + ICPU._Overflow = (Work16 & 0x4000) != 0; + ICPU._Negative = (uint8)(Work16 >> 8); + ICPU._Zero = (Work16 & ICPU.Registers.A.W) != 0; } -static void BIT8 (long Addr) +static void BIT8(long Addr) { - uint8 Work8 = S9xGetByte (Addr); - ICPU._Overflow = (Work8 & 0x40) != 0; - ICPU._Negative = Work8; - ICPU._Zero = Work8 & ICPU.Registers.AL; + uint8 Work8 = S9xGetByte(Addr); + ICPU._Overflow = (Work8 & 0x40) != 0; + ICPU._Negative = Work8; + ICPU._Zero = Work8 & ICPU.Registers.AL; } -static void CMP16 (long Addr) +static void CMP16(long Addr) { - int32 Int32 = (long) ICPU.Registers.A.W - - (long) S9xGetWord (Addr); - ICPU._Carry = Int32 >= 0; - SetZN16 ((uint16) Int32); + int32 Int32 = (long) ICPU.Registers.A.W - + (long) S9xGetWord(Addr); + ICPU._Carry = Int32 >= 0; + SetZN16((uint16) Int32); } -static void CMP8 (long Addr) +static void CMP8(long Addr) { - int16 Int16 = (short) ICPU.Registers.AL - - (short) S9xGetByte (Addr); - ICPU._Carry = Int16 >= 0; - SetZN8 ((uint8) Int16); + int16 Int16 = (short) ICPU.Registers.AL - + (short) S9xGetByte(Addr); + ICPU._Carry = Int16 >= 0; + SetZN8((uint8) Int16); } -static void CMX16 (long Addr) +static void CMX16(long Addr) { - int32 Int32 = (long) ICPU.Registers.X.W - - (long) S9xGetWord (Addr); - ICPU._Carry = Int32 >= 0; - SetZN16 ((uint16) Int32); + int32 Int32 = (long) ICPU.Registers.X.W - + (long) S9xGetWord(Addr); + ICPU._Carry = Int32 >= 0; + SetZN16((uint16) Int32); } -static void CMX8 (long Addr) +static void CMX8(long Addr) { - int16 Int16 = (short) ICPU.Registers.XL - - (short) S9xGetByte (Addr); - ICPU._Carry = Int16 >= 0; - SetZN8 ((uint8) Int16); + int16 Int16 = (short) ICPU.Registers.XL - + (short) S9xGetByte(Addr); + ICPU._Carry = Int16 >= 0; + SetZN8((uint8) Int16); } -static void CMY16 (long Addr) +static void CMY16(long Addr) { - int32 Int32 = (long) ICPU.Registers.Y.W - - (long) S9xGetWord (Addr); - ICPU._Carry = Int32 >= 0; - SetZN16 ((uint16) Int32); + int32 Int32 = (long) ICPU.Registers.Y.W - + (long) S9xGetWord(Addr); + ICPU._Carry = Int32 >= 0; + SetZN16((uint16) Int32); } -static void CMY8 (long Addr) +static void CMY8(long Addr) { - int16 Int16 = (short) ICPU.Registers.YL - - (short) S9xGetByte (Addr); - ICPU._Carry = Int16 >= 0; - SetZN8 ((uint8) Int16); + int16 Int16 = (short) ICPU.Registers.YL - + (short) S9xGetByte(Addr); + ICPU._Carry = Int16 >= 0; + SetZN8((uint8) Int16); } -static inline void A_DEC16 () +static inline void A_DEC16() { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif #ifdef CPU_SHUTDOWN - CPU.WaitAddress = NULL; + CPU.WaitAddress = NULL; #endif - ICPU.Registers.A.W--; - SetZN16 (ICPU.Registers.A.W); + ICPU.Registers.A.W--; + SetZN16(ICPU.Registers.A.W); } -static inline void A_DEC8 () +static inline void A_DEC8() { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif #ifdef CPU_SHUTDOWN - CPU.WaitAddress = NULL; + CPU.WaitAddress = NULL; #endif - ICPU.Registers.AL--; - SetZN8 (ICPU.Registers.AL); + ICPU.Registers.AL--; + SetZN8(ICPU.Registers.AL); } -static void DEC16 (long Addr) +static void DEC16(long Addr) { #ifdef CPU_SHUTDOWN - CPU.WaitAddress = NULL; + CPU.WaitAddress = NULL; #endif - uint16 Work16 = S9xGetWord (Addr) - 1; - //S9xSetWord (Work16, Addr); - S9xSetByte (Work16>>8, Addr+1); - S9xSetByte (Work16&0xFF, Addr); - SetZN16 (Work16); + uint16 Work16 = S9xGetWord(Addr) - 1; + //S9xSetWord (Work16, Addr); + S9xSetByte(Work16 >> 8, Addr + 1); + S9xSetByte(Work16 & 0xFF, Addr); + SetZN16(Work16); } -static void DEC8 (long Addr) +static void DEC8(long Addr) { #ifdef CPU_SHUTDOWN - CPU.WaitAddress = NULL; + CPU.WaitAddress = NULL; #endif - uint8 Work8 = S9xGetByte (Addr) - 1; - S9xSetByte (Work8, Addr); - SetZN8 (Work8); + uint8 Work8 = S9xGetByte(Addr) - 1; + S9xSetByte(Work8, Addr); + SetZN8(Work8); } -static void EOR16 (long Addr) +static void EOR16(long Addr) { - ICPU.Registers.A.W ^= S9xGetWord (Addr); - SetZN16 (ICPU.Registers.A.W); + ICPU.Registers.A.W ^= S9xGetWord(Addr); + SetZN16(ICPU.Registers.A.W); } -static void EOR8 (long Addr) +static void EOR8(long Addr) { - ICPU.Registers.AL ^= S9xGetByte (Addr); - SetZN8 (ICPU.Registers.AL); + ICPU.Registers.AL ^= S9xGetByte(Addr); + SetZN8(ICPU.Registers.AL); } -static inline void A_INC16 () +static inline void A_INC16() { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif #ifdef CPU_SHUTDOWN - CPU.WaitAddress = NULL; + CPU.WaitAddress = NULL; #endif - ICPU.Registers.A.W++; - SetZN16 (ICPU.Registers.A.W); + ICPU.Registers.A.W++; + SetZN16(ICPU.Registers.A.W); } -static inline void A_INC8 () +static inline void A_INC8() { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif #ifdef CPU_SHUTDOWN - CPU.WaitAddress = NULL; + CPU.WaitAddress = NULL; #endif - ICPU.Registers.AL++; - SetZN8 (ICPU.Registers.AL); + ICPU.Registers.AL++; + SetZN8(ICPU.Registers.AL); } -static void INC16 (long Addr) +static void INC16(long Addr) { #ifdef CPU_SHUTDOWN - CPU.WaitAddress = NULL; + CPU.WaitAddress = NULL; #endif - uint16 Work16 = S9xGetWord (Addr) + 1; - //S9xSetWord (Work16, Addr); - S9xSetByte (Work16>>8, Addr+1); - S9xSetByte (Work16&0xFF, Addr); - SetZN16 (Work16); + uint16 Work16 = S9xGetWord(Addr) + 1; + //S9xSetWord (Work16, Addr); + S9xSetByte(Work16 >> 8, Addr + 1); + S9xSetByte(Work16 & 0xFF, Addr); + SetZN16(Work16); } -static void INC8 (long Addr) +static void INC8(long Addr) { #ifdef CPU_SHUTDOWN - CPU.WaitAddress = NULL; + CPU.WaitAddress = NULL; #endif - uint8 Work8 = S9xGetByte (Addr) + 1; - S9xSetByte (Work8, Addr); - SetZN8 (Work8); + uint8 Work8 = S9xGetByte(Addr) + 1; + S9xSetByte(Work8, Addr); + SetZN8(Work8); } -static void LDA16 (long Addr) +static void LDA16(long Addr) { - ICPU.Registers.A.W = S9xGetWord (Addr); - SetZN16 (ICPU.Registers.A.W); + ICPU.Registers.A.W = S9xGetWord(Addr); + SetZN16(ICPU.Registers.A.W); } -static void LDA8 (long Addr) +static void LDA8(long Addr) { - ICPU.Registers.AL = S9xGetByte (Addr); - SetZN8 (ICPU.Registers.AL); + ICPU.Registers.AL = S9xGetByte(Addr); + SetZN8(ICPU.Registers.AL); } -static void LDX16 (long Addr) +static void LDX16(long Addr) { - ICPU.Registers.X.W = S9xGetWord (Addr); - SetZN16 (ICPU.Registers.X.W); + ICPU.Registers.X.W = S9xGetWord(Addr); + SetZN16(ICPU.Registers.X.W); } -static void LDX8 (long Addr) +static void LDX8(long Addr) { - ICPU.Registers.XL = S9xGetByte (Addr); - SetZN8 (ICPU.Registers.XL); + ICPU.Registers.XL = S9xGetByte(Addr); + SetZN8(ICPU.Registers.XL); } -static void LDY16 (long Addr) +static void LDY16(long Addr) { - ICPU.Registers.Y.W = S9xGetWord (Addr); - SetZN16 (ICPU.Registers.Y.W); + ICPU.Registers.Y.W = S9xGetWord(Addr); + SetZN16(ICPU.Registers.Y.W); } -static void LDY8 (long Addr) +static void LDY8(long Addr) { - ICPU.Registers.YL = S9xGetByte (Addr); - SetZN8 (ICPU.Registers.YL); + ICPU.Registers.YL = S9xGetByte(Addr); + SetZN8(ICPU.Registers.YL); } -static inline void A_LSR16 () +static inline void A_LSR16() { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - ICPU._Carry = ICPU.Registers.AL & 1; - ICPU.Registers.A.W >>= 1; - SetZN16 (ICPU.Registers.A.W); + ICPU._Carry = ICPU.Registers.AL & 1; + ICPU.Registers.A.W >>= 1; + SetZN16(ICPU.Registers.A.W); } -static inline void A_LSR8 () +static inline void A_LSR8() { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - ICPU._Carry = ICPU.Registers.AL & 1; - ICPU.Registers.AL >>= 1; - SetZN8 (ICPU.Registers.AL); + ICPU._Carry = ICPU.Registers.AL & 1; + ICPU.Registers.AL >>= 1; + SetZN8(ICPU.Registers.AL); } -static void LSR16 (long Addr) +static void LSR16(long Addr) { - uint16 Work16 = S9xGetWord (Addr); - ICPU._Carry = Work16 & 1; - Work16 >>= 1; - //S9xSetWord (Work16, Addr); - S9xSetByte (Work16>>8, Addr+1); - S9xSetByte (Work16&0xFF, Addr); - SetZN16 (Work16); + uint16 Work16 = S9xGetWord(Addr); + ICPU._Carry = Work16 & 1; + Work16 >>= 1; + //S9xSetWord (Work16, Addr); + S9xSetByte(Work16 >> 8, Addr + 1); + S9xSetByte(Work16 & 0xFF, Addr); + SetZN16(Work16); } -static void LSR8 (long Addr) +static void LSR8(long Addr) { - uint8 Work8 = S9xGetByte (Addr); - ICPU._Carry = Work8 & 1; - Work8 >>= 1; - S9xSetByte (Work8, Addr); - SetZN8 (Work8); + uint8 Work8 = S9xGetByte(Addr); + ICPU._Carry = Work8 & 1; + Work8 >>= 1; + S9xSetByte(Work8, Addr); + SetZN8(Work8); } -static void ORA16 (long Addr) +static void ORA16(long Addr) { - ICPU.Registers.A.W |= S9xGetWord (Addr); - SetZN16 (ICPU.Registers.A.W); + ICPU.Registers.A.W |= S9xGetWord(Addr); + SetZN16(ICPU.Registers.A.W); } -static void ORA8 (long Addr) +static void ORA8(long Addr) { - ICPU.Registers.AL |= S9xGetByte (Addr); - SetZN8 (ICPU.Registers.AL); + ICPU.Registers.AL |= S9xGetByte(Addr); + SetZN8(ICPU.Registers.AL); } -static inline void A_ROL16 () +static inline void A_ROL16() { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - uint32 Work32 = (ICPU.Registers.A.W << 1) | CheckCarry(); - ICPU._Carry = Work32 >= 0x10000; - ICPU.Registers.A.W = (uint16) Work32; - SetZN16 ((uint16) Work32); + uint32 Work32 = (ICPU.Registers.A.W << 1) | CheckCarry(); + ICPU._Carry = Work32 >= 0x10000; + ICPU.Registers.A.W = (uint16) Work32; + SetZN16((uint16) Work32); } -static inline void A_ROL8 () +static inline void A_ROL8() { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - uint16 Work16 = ICPU.Registers.AL; - Work16 <<= 1; - Work16 |= CheckCarry(); - ICPU._Carry = Work16 >= 0x100; - ICPU.Registers.AL = (uint8) Work16; - SetZN8 ((uint8) Work16); + uint16 Work16 = ICPU.Registers.AL; + Work16 <<= 1; + Work16 |= CheckCarry(); + ICPU._Carry = Work16 >= 0x100; + ICPU.Registers.AL = (uint8) Work16; + SetZN8((uint8) Work16); } -static void ROL16 (long Addr) +static void ROL16(long Addr) { - uint32 Work32 = S9xGetWord (Addr); - Work32 <<= 1; - Work32 |= CheckCarry(); - ICPU._Carry = Work32 >= 0x10000; - //S9xSetWord ((uint16) Work32, Addr); - S9xSetByte((Work32>>8)&0xFF, Addr+1); - S9xSetByte(Work32&0xFF, Addr); - SetZN16 ((uint16) Work32); + uint32 Work32 = S9xGetWord(Addr); + Work32 <<= 1; + Work32 |= CheckCarry(); + ICPU._Carry = Work32 >= 0x10000; + //S9xSetWord ((uint16) Work32, Addr); + S9xSetByte((Work32 >> 8) & 0xFF, Addr + 1); + S9xSetByte(Work32 & 0xFF, Addr); + SetZN16((uint16) Work32); } -static void ROL8 (long Addr) +static void ROL8(long Addr) { - uint16 Work16 = S9xGetByte (Addr); - Work16 <<= 1; - Work16 |= CheckCarry (); - ICPU._Carry = Work16 >= 0x100; - S9xSetByte ((uint8) Work16, Addr); - SetZN8 ((uint8) Work16); + uint16 Work16 = S9xGetByte(Addr); + Work16 <<= 1; + Work16 |= CheckCarry(); + ICPU._Carry = Work16 >= 0x100; + S9xSetByte((uint8) Work16, Addr); + SetZN8((uint8) Work16); } -static inline void A_ROR16 () +static inline void A_ROR16() { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - uint32 Work32 = ICPU.Registers.A.W; - Work32 |= (int) CheckCarry() << 16; - ICPU._Carry = (uint8) (Work32 & 1); - Work32 >>= 1; - ICPU.Registers.A.W = (uint16) Work32; - SetZN16 ((uint16) Work32); + uint32 Work32 = ICPU.Registers.A.W; + Work32 |= (int) CheckCarry() << 16; + ICPU._Carry = (uint8)(Work32 & 1); + Work32 >>= 1; + ICPU.Registers.A.W = (uint16) Work32; + SetZN16((uint16) Work32); } -static inline void A_ROR8 () +static inline void A_ROR8() { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - uint16 Work16 = ICPU.Registers.AL | ((uint16) CheckCarry() << 8); - ICPU._Carry = (uint8) Work16 & 1; - Work16 >>= 1; - ICPU.Registers.AL = (uint8) Work16; - SetZN8 ((uint8) Work16); -} - -static void ROR16 (long Addr) -{ - uint32 Work32 = S9xGetWord (Addr); - Work32 |= (int) CheckCarry() << 16; - ICPU._Carry = (uint8) (Work32 & 1); - Work32 >>= 1; - //S9xSetWord ((uint16) Work32, Addr); - S9xSetByte ( (Work32>>8)&0x00FF, Addr+1); - S9xSetByte (Work32&0x00FF, Addr); - SetZN16 ((uint16) Work32); -} - -static void ROR8 (long Addr) -{ - uint16 Work16 = S9xGetByte (Addr); - Work16 |= (int) CheckCarry () << 8; - ICPU._Carry = (uint8) (Work16 & 1); - Work16 >>= 1; - S9xSetByte ((uint8) Work16, Addr); - SetZN8 ((uint8) Work16); -} - -static void SBC16 (long Addr) -{ - uint16 Work16 = S9xGetWord (Addr); - - if (CheckDecimal ()) - { - uint8 A1 = (ICPU.Registers.A.W) & 0xF; - uint8 A2 = (ICPU.Registers.A.W >> 4) & 0xF; - uint8 A3 = (ICPU.Registers.A.W >> 8) & 0xF; - uint8 A4 = (ICPU.Registers.A.W >> 12) & 0xF; - uint8 W1 = Work16 & 0xF; - uint8 W2 = (Work16 >> 4) & 0xF; - uint8 W3 = (Work16 >> 8) & 0xF; - uint8 W4 = (Work16 >> 12) & 0xF; - - A1 -= W1 + !CheckCarry (); - A2 -= W2; - A3 -= W3; - A4 -= W4; - if (A1 > 9) - { - A1 += 10; - A2--; - } - if (A2 > 9) - { - A2 += 10; - A3--; - } - if (A3 > 9) - { - A3 += 10; - A4--; - } - if (A4 > 9) - { - A4 += 10; - ClearCarry (); - } - else - { - SetCarry (); - } - - uint16 Ans16 = (A4 << 12) | (A3 << 8) | (A2 << 4) | (A1); - if ((ICPU.Registers.A.W ^ Work16) & - (ICPU.Registers.A.W ^ Ans16) & 0x8000) - SetOverflow(); - else - ClearOverflow(); - ICPU.Registers.A.W = Ans16; - SetZN16 (ICPU.Registers.A.W); - } - else - { - - int32 Int32 = (long) ICPU.Registers.A.W - (long) Work16 + (long) CheckCarry() - 1; - - ICPU._Carry = Int32 >= 0; - - if ((ICPU.Registers.A.W ^ Work16) & - (ICPU.Registers.A.W ^ (uint16) Int32) & 0x8000) - SetOverflow(); - else - ClearOverflow (); - ICPU.Registers.A.W = (uint16) Int32; - SetZN16 (ICPU.Registers.A.W); - } -} + uint16 Work16 = ICPU.Registers.AL | ((uint16) CheckCarry() << 8); + ICPU._Carry = (uint8) Work16 & 1; + Work16 >>= 1; + ICPU.Registers.AL = (uint8) Work16; + SetZN8((uint8) Work16); +} + +static void ROR16(long Addr) +{ + uint32 Work32 = S9xGetWord(Addr); + Work32 |= (int) CheckCarry() << 16; + ICPU._Carry = (uint8)(Work32 & 1); + Work32 >>= 1; + //S9xSetWord ((uint16) Work32, Addr); + S9xSetByte((Work32 >> 8) & 0x00FF, Addr + 1); + S9xSetByte(Work32 & 0x00FF, Addr); + SetZN16((uint16) Work32); +} + +static void ROR8(long Addr) +{ + uint16 Work16 = S9xGetByte(Addr); + Work16 |= (int) CheckCarry() << 8; + ICPU._Carry = (uint8)(Work16 & 1); + Work16 >>= 1; + S9xSetByte((uint8) Work16, Addr); + SetZN8((uint8) Work16); +} + +static void SBC16(long Addr) +{ + uint16 Work16 = S9xGetWord(Addr); + + if (CheckDecimal()) + { + uint8 A1 = (ICPU.Registers.A.W) & 0xF; + uint8 A2 = (ICPU.Registers.A.W >> 4) & 0xF; + uint8 A3 = (ICPU.Registers.A.W >> 8) & 0xF; + uint8 A4 = (ICPU.Registers.A.W >> 12) & 0xF; + uint8 W1 = Work16 & 0xF; + uint8 W2 = (Work16 >> 4) & 0xF; + uint8 W3 = (Work16 >> 8) & 0xF; + uint8 W4 = (Work16 >> 12) & 0xF; + + A1 -= W1 + !CheckCarry(); + A2 -= W2; + A3 -= W3; + A4 -= W4; + if (A1 > 9) + { + A1 += 10; + A2--; + } + if (A2 > 9) + { + A2 += 10; + A3--; + } + if (A3 > 9) + { + A3 += 10; + A4--; + } + if (A4 > 9) + { + A4 += 10; + ClearCarry(); + } + else + SetCarry(); + + uint16 Ans16 = (A4 << 12) | (A3 << 8) | (A2 << 4) | (A1); + if ((ICPU.Registers.A.W ^ Work16) & + (ICPU.Registers.A.W ^ Ans16) & 0x8000) + SetOverflow(); + else + ClearOverflow(); + ICPU.Registers.A.W = Ans16; + SetZN16(ICPU.Registers.A.W); + } + else + { + + int32 Int32 = (long) ICPU.Registers.A.W - (long) Work16 + + (long) CheckCarry() - 1; + + ICPU._Carry = Int32 >= 0; + + if ((ICPU.Registers.A.W ^ Work16) & + (ICPU.Registers.A.W ^ (uint16) Int32) & 0x8000) + SetOverflow(); + else + ClearOverflow(); + ICPU.Registers.A.W = (uint16) Int32; + SetZN16(ICPU.Registers.A.W); + } +} -static void SBC8 (long Addr) +static void SBC8(long Addr) { - uint8 Work8 = S9xGetByte (Addr); - if (CheckDecimal ()) - { - uint8 A1 = (ICPU.Registers.A.W) & 0xF; - uint8 A2 = (ICPU.Registers.A.W >> 4) & 0xF; - uint8 W1 = Work8 & 0xF; - uint8 W2 = (Work8 >> 4) & 0xF; + uint8 Work8 = S9xGetByte(Addr); + if (CheckDecimal()) + { + uint8 A1 = (ICPU.Registers.A.W) & 0xF; + uint8 A2 = (ICPU.Registers.A.W >> 4) & 0xF; + uint8 W1 = Work8 & 0xF; + uint8 W2 = (Work8 >> 4) & 0xF; - A1 -= W1 + !CheckCarry (); - A2 -= W2; - if (A1 > 9) - { - A1 += 10; - A2--; - } - if (A2 > 9) - { - A2 += 10; - ClearCarry (); - } - else - { - SetCarry (); - } + A1 -= W1 + !CheckCarry(); + A2 -= W2; + if (A1 > 9) + { + A1 += 10; + A2--; + } + if (A2 > 9) + { + A2 += 10; + ClearCarry(); + } + else + SetCarry(); - uint8 Ans8 = (A2 << 4) | A1; - if ((ICPU.Registers.AL ^ Work8) & - (ICPU.Registers.AL ^ Ans8) & 0x80) - SetOverflow (); - else - ClearOverflow (); - ICPU.Registers.AL = Ans8; - SetZN8 (ICPU.Registers.AL); - } - else - { - int16 Int16 = (short) ICPU.Registers.AL - (short) Work8 + (short) CheckCarry() - 1; + uint8 Ans8 = (A2 << 4) | A1; + if ((ICPU.Registers.AL ^ Work8) & + (ICPU.Registers.AL ^ Ans8) & 0x80) + SetOverflow(); + else + ClearOverflow(); + ICPU.Registers.AL = Ans8; + SetZN8(ICPU.Registers.AL); + } + else + { + int16 Int16 = (short) ICPU.Registers.AL - (short) Work8 + + (short) CheckCarry() - 1; - ICPU._Carry = Int16 >= 0; - if ((ICPU.Registers.AL ^ Work8) & - (ICPU.Registers.AL ^ (uint8) Int16) & 0x80) - SetOverflow (); - else - ClearOverflow (); - ICPU.Registers.AL = (uint8) Int16; - SetZN8 (ICPU.Registers.AL); - } + ICPU._Carry = Int16 >= 0; + if ((ICPU.Registers.AL ^ Work8) & + (ICPU.Registers.AL ^ (uint8) Int16) & 0x80) + SetOverflow(); + else + ClearOverflow(); + ICPU.Registers.AL = (uint8) Int16; + SetZN8(ICPU.Registers.AL); + } } -static void STA16 (long Addr) +static void STA16(long Addr) { - S9xSetWord (ICPU.Registers.A.W, Addr); + S9xSetWord(ICPU.Registers.A.W, Addr); } -static void STA8 (long Addr) +static void STA8(long Addr) { - S9xSetByte (ICPU.Registers.AL, Addr); + S9xSetByte(ICPU.Registers.AL, Addr); } -static void STX16 (long Addr) +static void STX16(long Addr) { - S9xSetWord (ICPU.Registers.X.W, Addr); + S9xSetWord(ICPU.Registers.X.W, Addr); } -static void STX8 (long Addr) +static void STX8(long Addr) { - S9xSetByte (ICPU.Registers.XL, Addr); + S9xSetByte(ICPU.Registers.XL, Addr); } -static void STY16 (long Addr) +static void STY16(long Addr) { - S9xSetWord (ICPU.Registers.Y.W, Addr); + S9xSetWord(ICPU.Registers.Y.W, Addr); } -static void STY8 (long Addr) +static void STY8(long Addr) { - S9xSetByte (ICPU.Registers.YL, Addr); + S9xSetByte(ICPU.Registers.YL, Addr); } -static void STZ16 (long Addr) +static void STZ16(long Addr) { - S9xSetWord (0, Addr); + S9xSetWord(0, Addr); } -static void STZ8 (long Addr) +static void STZ8(long Addr) { - S9xSetByte (0, Addr); + S9xSetByte(0, Addr); } -static void TSB16 (long Addr) +static void TSB16(long Addr) { - uint16 Work16 = S9xGetWord (Addr); - ICPU._Zero = (Work16 & ICPU.Registers.A.W) != 0; - Work16 |= ICPU.Registers.A.W; - //S9xSetWord (Work16, Addr); - S9xSetByte (Work16>>8, Addr+1); - S9xSetByte (Work16&0xFF, Addr); + uint16 Work16 = S9xGetWord(Addr); + ICPU._Zero = (Work16 & ICPU.Registers.A.W) != 0; + Work16 |= ICPU.Registers.A.W; + //S9xSetWord (Work16, Addr); + S9xSetByte(Work16 >> 8, Addr + 1); + S9xSetByte(Work16 & 0xFF, Addr); } -static void TSB8 (long Addr) +static void TSB8(long Addr) { - uint8 Work8 = S9xGetByte (Addr); - ICPU._Zero = Work8 & ICPU.Registers.AL; - Work8 |= ICPU.Registers.AL; - S9xSetByte (Work8, Addr); + uint8 Work8 = S9xGetByte(Addr); + ICPU._Zero = Work8 & ICPU.Registers.AL; + Work8 |= ICPU.Registers.AL; + S9xSetByte(Work8, Addr); } -static void TRB16 (long Addr) +static void TRB16(long Addr) { - uint16 Work16 = S9xGetWord (Addr); - ICPU._Zero = (Work16 & ICPU.Registers.A.W) != 0; - Work16 &= ~ICPU.Registers.A.W; - //S9xSetWord (Work16, Addr); - S9xSetByte (Work16>>8, Addr+1); - S9xSetByte (Work16&0xFF, Addr); + uint16 Work16 = S9xGetWord(Addr); + ICPU._Zero = (Work16 & ICPU.Registers.A.W) != 0; + Work16 &= ~ICPU.Registers.A.W; + //S9xSetWord (Work16, Addr); + S9xSetByte(Work16 >> 8, Addr + 1); + S9xSetByte(Work16 & 0xFF, Addr); } -static void TRB8 (long Addr) +static void TRB8(long Addr) { - uint8 Work8 = S9xGetByte (Addr); - ICPU._Zero = Work8 & ICPU.Registers.AL; - Work8 &= ~ICPU.Registers.AL; - S9xSetByte (Work8, Addr); + uint8 Work8 = S9xGetByte(Addr); + ICPU._Zero = Work8 & ICPU.Registers.AL; + Work8 &= ~ICPU.Registers.AL; + S9xSetByte(Work8, Addr); } #endif diff --git a/source/cpuops.c b/source/cpuops.c index 14a627f..895ccc3 100644 --- a/source/cpuops.c +++ b/source/cpuops.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -108,3203 +108,3203 @@ long OpAddress; // For use with the opcodes whose functions here examine the OpAddress. -static void OpAddressPassthrough (long Addr) +static void OpAddressPassthrough(long Addr) { - OpAddress = Addr; + OpAddress = Addr; } /* ADC *************************************************************************************** */ -static void Op69M1 (void) +static void Op69M1(void) { - Immediate8 (READ, ADC8); + Immediate8(READ, ADC8); } -static void Op69M0 (void) +static void Op69M0(void) { - Immediate16 (READ, ADC16); + Immediate16(READ, ADC16); } -static void Op65M1 (void) +static void Op65M1(void) { - Direct (READ, ADC8); + Direct(READ, ADC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op65M0 (void) +static void Op65M0(void) { - Direct (READ, ADC16); + Direct(READ, ADC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op75M1 (void) +static void Op75M1(void) { - DirectIndexedX (READ, ADC8); + DirectIndexedX(READ, ADC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void Op75M0 (void) +static void Op75M0(void) { - DirectIndexedX (READ, ADC16); + DirectIndexedX(READ, ADC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void Op72M1 (void) +static void Op72M1(void) { - DirectIndirect (READ, ADC8); + DirectIndirect(READ, ADC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op72M0 (void) +static void Op72M0(void) { - DirectIndirect (READ, ADC16); + DirectIndirect(READ, ADC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op61M1 (void) +static void Op61M1(void) { - DirectIndexedIndirect (READ, ADC8); + DirectIndexedIndirect(READ, ADC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op61M0 (void) +static void Op61M0(void) { - DirectIndexedIndirect (READ, ADC16); + DirectIndexedIndirect(READ, ADC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op71M1 (void) +static void Op71M1(void) { - DirectIndirectIndexed (READ, ADC8); + DirectIndirectIndexed(READ, ADC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op71M0 (void) +static void Op71M0(void) { - DirectIndirectIndexed (READ, ADC16); + DirectIndirectIndexed(READ, ADC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op67M1 (void) +static void Op67M1(void) { - DirectIndirectLong (READ, ADC8); + DirectIndirectLong(READ, ADC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op67M0 (void) +static void Op67M0(void) { - DirectIndirectLong (READ, ADC16); + DirectIndirectLong(READ, ADC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op77M1 (void) +static void Op77M1(void) { - DirectIndirectIndexedLong (READ, ADC8); + DirectIndirectIndexedLong(READ, ADC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op77M0 (void) +static void Op77M0(void) { - DirectIndirectIndexedLong (READ, ADC16); + DirectIndirectIndexedLong(READ, ADC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op6DM1 (void) +static void Op6DM1(void) { - Absolute (READ, ADC8); + Absolute(READ, ADC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op6DM0 (void) +static void Op6DM0(void) { - Absolute (READ, ADC16); + Absolute(READ, ADC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op7DM1 (void) +static void Op7DM1(void) { - AbsoluteIndexedX (READ, ADC8); + AbsoluteIndexedX(READ, ADC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op7DM0 (void) +static void Op7DM0(void) { - AbsoluteIndexedX (READ, ADC16); + AbsoluteIndexedX(READ, ADC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op79M1 (void) +static void Op79M1(void) { - AbsoluteIndexedY (READ, ADC8); + AbsoluteIndexedY(READ, ADC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op79M0 (void) +static void Op79M0(void) { - AbsoluteIndexedY (READ, ADC16); + AbsoluteIndexedY(READ, ADC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op6FM1 (void) +static void Op6FM1(void) { - AbsoluteLong (READ, ADC8); + AbsoluteLong(READ, ADC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void Op6FM0 (void) +static void Op6FM0(void) { - AbsoluteLong (READ, ADC16); + AbsoluteLong(READ, ADC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void Op7FM1 (void) +static void Op7FM1(void) { - AbsoluteLongIndexedX (READ, ADC8); + AbsoluteLongIndexedX(READ, ADC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void Op7FM0 (void) +static void Op7FM0(void) { - AbsoluteLongIndexedX (READ, ADC16); + AbsoluteLongIndexedX(READ, ADC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void Op63M1 (void) +static void Op63M1(void) { - StackRelative (READ, ADC8); + StackRelative(READ, ADC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif } -static void Op63M0 (void) +static void Op63M0(void) { - StackRelative (READ, ADC16); + StackRelative(READ, ADC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif } -static void Op73M1 (void) +static void Op73M1(void) { - StackRelativeIndirectIndexed (READ, ADC8); + StackRelativeIndirectIndexed(READ, ADC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; + CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; #endif } -static void Op73M0 (void) +static void Op73M0(void) { - StackRelativeIndirectIndexed (READ, ADC16); + StackRelativeIndirectIndexed(READ, ADC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; + CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; #endif } /**********************************************************************************************/ /* AND *************************************************************************************** */ -static void Op29M1 (void) +static void Op29M1(void) { - ICPU.Registers.AL &= *CPU.PC++; + ICPU.Registers.AL &= *CPU.PC++; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif - SetZN8 (ICPU.Registers.AL); + SetZN8(ICPU.Registers.AL); } -static void Op29M0 (void) +static void Op29M0(void) { #ifdef FAST_LSB_WORD_ACCESS - ICPU.Registers.A.W &= *(uint16 *) CPU.PC; + ICPU.Registers.A.W &= *(uint16*) CPU.PC; #else - ICPU.Registers.A.W &= *CPU.PC + (*(CPU.PC + 1) << 8); + ICPU.Registers.A.W &= *CPU.PC + (*(CPU.PC + 1) << 8); #endif - CPU.PC += 2; + CPU.PC += 2; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif - SetZN16 (ICPU.Registers.A.W); + SetZN16(ICPU.Registers.A.W); } -static void Op25M1 (void) +static void Op25M1(void) { - Direct (READ, AND8); + Direct(READ, AND8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op25M0 (void) +static void Op25M0(void) { - Direct (READ, AND16); + Direct(READ, AND16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op35M1 (void) +static void Op35M1(void) { - DirectIndexedX (READ, AND8); + DirectIndexedX(READ, AND8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void Op35M0 (void) +static void Op35M0(void) { - DirectIndexedX (READ, AND16); + DirectIndexedX(READ, AND16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void Op32M1 (void) +static void Op32M1(void) { - DirectIndirect (READ, AND8); + DirectIndirect(READ, AND8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op32M0 (void) +static void Op32M0(void) { - DirectIndirect (READ, AND16); + DirectIndirect(READ, AND16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op21M1 (void) +static void Op21M1(void) { - DirectIndexedIndirect (READ, AND8); + DirectIndexedIndirect(READ, AND8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op21M0 (void) +static void Op21M0(void) { - DirectIndexedIndirect (READ, AND16); + DirectIndexedIndirect(READ, AND16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op31M1 (void) +static void Op31M1(void) { - DirectIndirectIndexed (READ, AND8); + DirectIndirectIndexed(READ, AND8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op31M0 (void) +static void Op31M0(void) { - DirectIndirectIndexed (READ, AND16); + DirectIndirectIndexed(READ, AND16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op27M1 (void) +static void Op27M1(void) { - DirectIndirectLong (READ, AND8); + DirectIndirectLong(READ, AND8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op27M0 (void) +static void Op27M0(void) { - DirectIndirectLong (READ, AND16); + DirectIndirectLong(READ, AND16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op37M1 (void) +static void Op37M1(void) { - DirectIndirectIndexedLong (READ, AND8); + DirectIndirectIndexedLong(READ, AND8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op37M0 (void) +static void Op37M0(void) { - DirectIndirectIndexedLong (READ, AND16); + DirectIndirectIndexedLong(READ, AND16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op2DM1 (void) +static void Op2DM1(void) { - Absolute (READ, AND8); + Absolute(READ, AND8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op2DM0 (void) +static void Op2DM0(void) { - Absolute (READ, AND16); + Absolute(READ, AND16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op3DM1 (void) +static void Op3DM1(void) { - AbsoluteIndexedX (READ, AND8); + AbsoluteIndexedX(READ, AND8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op3DM0 (void) +static void Op3DM0(void) { - AbsoluteIndexedX (READ, AND16); + AbsoluteIndexedX(READ, AND16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op39M1 (void) +static void Op39M1(void) { - AbsoluteIndexedY (READ, AND8); + AbsoluteIndexedY(READ, AND8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op39M0 (void) +static void Op39M0(void) { - AbsoluteIndexedY (READ, AND16); + AbsoluteIndexedY(READ, AND16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op2FM1 (void) +static void Op2FM1(void) { - AbsoluteLong (READ, AND8); + AbsoluteLong(READ, AND8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void Op2FM0 (void) +static void Op2FM0(void) { - AbsoluteLong (READ, AND16); + AbsoluteLong(READ, AND16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void Op3FM1 (void) +static void Op3FM1(void) { - AbsoluteLongIndexedX (READ, AND8); + AbsoluteLongIndexedX(READ, AND8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void Op3FM0 (void) +static void Op3FM0(void) { - AbsoluteLongIndexedX (READ, AND16); + AbsoluteLongIndexedX(READ, AND16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void Op23M1 (void) +static void Op23M1(void) { - StackRelative (READ, AND8); + StackRelative(READ, AND8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif } -static void Op23M0 (void) +static void Op23M0(void) { - StackRelative (READ, AND16); + StackRelative(READ, AND16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif } -static void Op33M1 (void) +static void Op33M1(void) { - StackRelativeIndirectIndexed (READ, AND8); + StackRelativeIndirectIndexed(READ, AND8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; + CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; #endif } -static void Op33M0 (void) +static void Op33M0(void) { - StackRelativeIndirectIndexed (READ, AND16); + StackRelativeIndirectIndexed(READ, AND16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; + CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; #endif } /**********************************************************************************************/ /* ASL *************************************************************************************** */ -static void Op0AM1 (void) +static void Op0AM1(void) { - A_ASL8 (); + A_ASL8(); } -static void Op0AM0 (void) +static void Op0AM0(void) { - A_ASL16 (); + A_ASL16(); } -static void Op06M1 (void) +static void Op06M1(void) { - Direct (MODIFY, ASL8); + Direct(MODIFY, ASL8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op06M0 (void) +static void Op06M0(void) { - Direct (MODIFY, ASL16); + Direct(MODIFY, ASL16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op16M1 (void) +static void Op16M1(void) { - DirectIndexedX (MODIFY, ASL8); + DirectIndexedX(MODIFY, ASL8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op16M0 (void) +static void Op16M0(void) { - DirectIndexedX (MODIFY, ASL16); + DirectIndexedX(MODIFY, ASL16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op0EM1 (void) +static void Op0EM1(void) { - Absolute (MODIFY, ASL8); + Absolute(MODIFY, ASL8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op0EM0 (void) +static void Op0EM0(void) { - Absolute (MODIFY, ASL16); + Absolute(MODIFY, ASL16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op1EM1 (void) +static void Op1EM1(void) { - AbsoluteIndexedX (MODIFY, ASL8); + AbsoluteIndexedX(MODIFY, ASL8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op1EM0 (void) +static void Op1EM0(void) { - AbsoluteIndexedX (MODIFY, ASL16); + AbsoluteIndexedX(MODIFY, ASL16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } /**********************************************************************************************/ /* BIT *************************************************************************************** */ -static void Op89M1 (void) +static void Op89M1(void) { - ICPU._Zero = ICPU.Registers.AL & *CPU.PC++; + ICPU._Zero = ICPU.Registers.AL & *CPU.PC++; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op89M0 (void) +static void Op89M0(void) { #ifdef FAST_LSB_WORD_ACCESS - ICPU._Zero = (ICPU.Registers.A.W & *(uint16 *) CPU.PC) != 0; + ICPU._Zero = (ICPU.Registers.A.W & *(uint16*) CPU.PC) != 0; #else - ICPU._Zero = (ICPU.Registers.A.W & (*CPU.PC + (*(CPU.PC + 1) << 8))) != 0; -#endif + ICPU._Zero = (ICPU.Registers.A.W & (*CPU.PC + (*(CPU.PC + 1) << 8))) != 0; +#endif #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif - CPU.PC += 2; + CPU.PC += 2; } -static void Op24M1 (void) +static void Op24M1(void) { - Direct (READ, BIT8); + Direct(READ, BIT8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op24M0 (void) +static void Op24M0(void) { - Direct (READ, BIT16); + Direct(READ, BIT16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op34M1 (void) +static void Op34M1(void) { - DirectIndexedX (READ, BIT8); + DirectIndexedX(READ, BIT8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void Op34M0 (void) +static void Op34M0(void) { - DirectIndexedX (READ, BIT16); + DirectIndexedX(READ, BIT16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void Op2CM1 (void) +static void Op2CM1(void) { - Absolute (READ, BIT8); + Absolute(READ, BIT8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op2CM0 (void) +static void Op2CM0(void) { - Absolute (READ, BIT16); + Absolute(READ, BIT16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op3CM1 (void) +static void Op3CM1(void) { - AbsoluteIndexedX (READ, BIT8); + AbsoluteIndexedX(READ, BIT8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op3CM0 (void) +static void Op3CM0(void) { - AbsoluteIndexedX (READ, BIT16); + AbsoluteIndexedX(READ, BIT16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } /**********************************************************************************************/ /* CMP *************************************************************************************** */ -static void OpC9M1 (void) +static void OpC9M1(void) { - int32 Int32 = (int) ICPU.Registers.AL - (intptr_t) *CPU.PC++; - ICPU._Carry = Int32 >= 0; - SetZN8 ((uint8) Int32); + int32 Int32 = (int) ICPU.Registers.AL - (intptr_t) * CPU.PC++; + ICPU._Carry = Int32 >= 0; + SetZN8((uint8) Int32); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpC9M0 (void) +static void OpC9M0(void) { - int32 Int32; -#ifdef FAST_LSB_WORD_ACCESS - Int32 = (long) ICPU.Registers.A.W - (long) *(uint16 *) CPU.PC; + int32 Int32; +#ifdef FAST_LSB_WORD_ACCESS + Int32 = (long) ICPU.Registers.A.W - (long) * (uint16*) CPU.PC; #else - Int32 = (long) ICPU.Registers.A.W - - (long) (*CPU.PC + (*(CPU.PC + 1) << 8)); + Int32 = (long) ICPU.Registers.A.W - + (long)(*CPU.PC + (*(CPU.PC + 1) << 8)); #endif - ICPU._Carry = Int32 >= 0; - SetZN16 ((uint16) Int32); - CPU.PC += 2; + ICPU._Carry = Int32 >= 0; + SetZN16((uint16) Int32); + CPU.PC += 2; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpC5M1 (void) +static void OpC5M1(void) { - Direct (READ, CMP8); + Direct(READ, CMP8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpC5M0 (void) +static void OpC5M0(void) { - Direct (READ, CMP16); + Direct(READ, CMP16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpD5M1 (void) +static void OpD5M1(void) { - DirectIndexedX (READ, CMP8); + DirectIndexedX(READ, CMP8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void OpD5M0 (void) +static void OpD5M0(void) { - DirectIndexedX (READ, CMP16); + DirectIndexedX(READ, CMP16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void OpD2M1 (void) +static void OpD2M1(void) { - DirectIndirect (READ, CMP8); + DirectIndirect(READ, CMP8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpD2M0 (void) +static void OpD2M0(void) { - DirectIndirect (READ, CMP16); + DirectIndirect(READ, CMP16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpC1M1 (void) +static void OpC1M1(void) { - DirectIndexedIndirect (READ, CMP8); + DirectIndexedIndirect(READ, CMP8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpC1M0 (void) +static void OpC1M0(void) { - DirectIndexedIndirect (READ, CMP16); + DirectIndexedIndirect(READ, CMP16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpD1M1 (void) +static void OpD1M1(void) { - DirectIndirectIndexed (READ, CMP8); + DirectIndirectIndexed(READ, CMP8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpD1M0 (void) +static void OpD1M0(void) { - DirectIndirectIndexed (READ, CMP16); + DirectIndirectIndexed(READ, CMP16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpC7M1 (void) +static void OpC7M1(void) { - DirectIndirectLong (READ, CMP8); + DirectIndirectLong(READ, CMP8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpC7M0 (void) +static void OpC7M0(void) { - DirectIndirectLong (READ, CMP16); + DirectIndirectLong(READ, CMP16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpD7M1 (void) +static void OpD7M1(void) { - DirectIndirectIndexedLong (READ, CMP8); + DirectIndirectIndexedLong(READ, CMP8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpD7M0 (void) +static void OpD7M0(void) { - DirectIndirectIndexedLong (READ, CMP16); + DirectIndirectIndexedLong(READ, CMP16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpCDM1 (void) +static void OpCDM1(void) { - Absolute (READ, CMP8); + Absolute(READ, CMP8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpCDM0 (void) +static void OpCDM0(void) { - Absolute (READ, CMP16); + Absolute(READ, CMP16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpDDM1 (void) +static void OpDDM1(void) { - AbsoluteIndexedX (READ, CMP8); + AbsoluteIndexedX(READ, CMP8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpDDM0 (void) +static void OpDDM0(void) { - AbsoluteIndexedX (READ, CMP16); + AbsoluteIndexedX(READ, CMP16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpD9M1 (void) +static void OpD9M1(void) { - AbsoluteIndexedY (READ, CMP8); + AbsoluteIndexedY(READ, CMP8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpD9M0 (void) +static void OpD9M0(void) { - AbsoluteIndexedY (READ, CMP16); + AbsoluteIndexedY(READ, CMP16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpCFM1 (void) +static void OpCFM1(void) { - AbsoluteLong (READ, CMP8); + AbsoluteLong(READ, CMP8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void OpCFM0 (void) +static void OpCFM0(void) { - AbsoluteLong (READ, CMP16); + AbsoluteLong(READ, CMP16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void OpDFM1 (void) +static void OpDFM1(void) { - AbsoluteLongIndexedX (READ, CMP8); + AbsoluteLongIndexedX(READ, CMP8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void OpDFM0 (void) +static void OpDFM0(void) { - AbsoluteLongIndexedX (READ, CMP16); + AbsoluteLongIndexedX(READ, CMP16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void OpC3M1 (void) +static void OpC3M1(void) { - StackRelative (READ, CMP8); + StackRelative(READ, CMP8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif } -static void OpC3M0 (void) +static void OpC3M0(void) { - StackRelative (READ, CMP16); + StackRelative(READ, CMP16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif } -static void OpD3M1 (void) +static void OpD3M1(void) { - StackRelativeIndirectIndexed (READ, CMP8); + StackRelativeIndirectIndexed(READ, CMP8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; + CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; #endif } -static void OpD3M0 (void) +static void OpD3M0(void) { - StackRelativeIndirectIndexed (READ, CMP16); + StackRelativeIndirectIndexed(READ, CMP16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; + CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; #endif } /**********************************************************************************************/ /* CMX *************************************************************************************** */ -static void OpE0X1 (void) +static void OpE0X1(void) { - int32 Int32 = (int) ICPU.Registers.XL - (intptr_t) *CPU.PC++; - ICPU._Carry = Int32 >= 0; - SetZN8 ((uint8) Int32); + int32 Int32 = (int) ICPU.Registers.XL - (intptr_t) * CPU.PC++; + ICPU._Carry = Int32 >= 0; + SetZN8((uint8) Int32); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpE0X0 (void) +static void OpE0X0(void) { - int32 Int32; -#ifdef FAST_LSB_WORD_ACCESS - Int32 = (long) ICPU.Registers.X.W - (long) *(uint16 *) CPU.PC; + int32 Int32; +#ifdef FAST_LSB_WORD_ACCESS + Int32 = (long) ICPU.Registers.X.W - (long) * (uint16*) CPU.PC; #else - Int32 = (long) ICPU.Registers.X.W - - (long) (*CPU.PC + (*(CPU.PC + 1) << 8)); + Int32 = (long) ICPU.Registers.X.W - + (long)(*CPU.PC + (*(CPU.PC + 1) << 8)); #endif - ICPU._Carry = Int32 >= 0; - SetZN16 ((uint16) Int32); - CPU.PC += 2; + ICPU._Carry = Int32 >= 0; + SetZN16((uint16) Int32); + CPU.PC += 2; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpE4X1 (void) +static void OpE4X1(void) { - Direct (READ, CMX8); + Direct(READ, CMX8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpE4X0 (void) +static void OpE4X0(void) { - Direct (READ, CMX16); + Direct(READ, CMX16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpECX1 (void) +static void OpECX1(void) { - Absolute (READ, CMX8); + Absolute(READ, CMX8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpECX0 (void) +static void OpECX0(void) { - Absolute (READ, CMX16); + Absolute(READ, CMX16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } /**********************************************************************************************/ /* CMY *************************************************************************************** */ -static void OpC0X1 (void) +static void OpC0X1(void) { - int32 Int32 = (int) ICPU.Registers.YL - (intptr_t) *CPU.PC++; - ICPU._Carry = Int32 >= 0; - SetZN8 ((uint8) Int32); + int32 Int32 = (int) ICPU.Registers.YL - (intptr_t) * CPU.PC++; + ICPU._Carry = Int32 >= 0; + SetZN8((uint8) Int32); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpC0X0 (void) +static void OpC0X0(void) { - int32 Int32; -#ifdef FAST_LSB_WORD_ACCESS - Int32 = (long) ICPU.Registers.Y.W - (long) *(uint16 *) CPU.PC; + int32 Int32; +#ifdef FAST_LSB_WORD_ACCESS + Int32 = (long) ICPU.Registers.Y.W - (long) * (uint16*) CPU.PC; #else - Int32 = (long) ICPU.Registers.Y.W - - (long) (*CPU.PC + (*(CPU.PC + 1) << 8)); + Int32 = (long) ICPU.Registers.Y.W - + (long)(*CPU.PC + (*(CPU.PC + 1) << 8)); #endif - ICPU._Carry = Int32 >= 0; - SetZN16 ((uint16) Int32); - CPU.PC += 2; + ICPU._Carry = Int32 >= 0; + SetZN16((uint16) Int32); + CPU.PC += 2; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpC4X1 (void) +static void OpC4X1(void) { - Direct (READ, CMY8); + Direct(READ, CMY8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpC4X0 (void) +static void OpC4X0(void) { - Direct (READ, CMY16); + Direct(READ, CMY16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpCCX1 (void) +static void OpCCX1(void) { - Absolute (READ, CMY8); + Absolute(READ, CMY8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpCCX0 (void) +static void OpCCX0(void) { - Absolute (READ, CMY16); + Absolute(READ, CMY16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } /**********************************************************************************************/ /* DEC *************************************************************************************** */ -static void Op3AM1 (void) +static void Op3AM1(void) { - A_DEC8 (); + A_DEC8(); } -static void Op3AM0 (void) +static void Op3AM0(void) { - A_DEC16 (); + A_DEC16(); } -static void OpC6M1 (void) +static void OpC6M1(void) { - Direct (MODIFY, DEC8); + Direct(MODIFY, DEC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void OpC6M0 (void) +static void OpC6M0(void) { - Direct (MODIFY, DEC16); + Direct(MODIFY, DEC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void OpD6M1 (void) +static void OpD6M1(void) { - DirectIndexedX (MODIFY, DEC8); + DirectIndexedX(MODIFY, DEC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE /* memory */ + ONE_CYCLE /* opcode */; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE /* memory */ + ONE_CYCLE /* opcode */; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void OpD6M0 (void) +static void OpD6M0(void) { - DirectIndexedX (MODIFY, DEC16); + DirectIndexedX(MODIFY, DEC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE /* memory */ + ONE_CYCLE /* opcode */; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE /* memory */ + ONE_CYCLE /* opcode */; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void OpCEM1 (void) +static void OpCEM1(void) { - Absolute (MODIFY, DEC8); + Absolute(MODIFY, DEC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void OpCEM0 (void) +static void OpCEM0(void) { - Absolute (MODIFY, DEC16); + Absolute(MODIFY, DEC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void OpDEM1 (void) +static void OpDEM1(void) { - AbsoluteIndexedX (MODIFY, DEC8); + AbsoluteIndexedX(MODIFY, DEC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void OpDEM0 (void) +static void OpDEM0(void) { - AbsoluteIndexedX (MODIFY, DEC16); + AbsoluteIndexedX(MODIFY, DEC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } /**********************************************************************************************/ /* EOR *************************************************************************************** */ -static void Op49M1 (void) +static void Op49M1(void) { - ICPU.Registers.AL ^= *CPU.PC++; + ICPU.Registers.AL ^= *CPU.PC++; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif - SetZN8 (ICPU.Registers.AL); + SetZN8(ICPU.Registers.AL); } -static void Op49M0 (void) +static void Op49M0(void) { #ifdef FAST_LSB_WORD_ACCESS - ICPU.Registers.A.W ^= *(uint16 *) CPU.PC; + ICPU.Registers.A.W ^= *(uint16*) CPU.PC; #else - ICPU.Registers.A.W ^= *CPU.PC + (*(CPU.PC + 1) << 8); + ICPU.Registers.A.W ^= *CPU.PC + (*(CPU.PC + 1) << 8); #endif - CPU.PC += 2; + CPU.PC += 2; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif - SetZN16 (ICPU.Registers.A.W); + SetZN16(ICPU.Registers.A.W); } -static void Op45M1 (void) +static void Op45M1(void) { - Direct (READ, EOR8); + Direct(READ, EOR8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op45M0 (void) +static void Op45M0(void) { - Direct (READ, EOR16); + Direct(READ, EOR16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op55M1 (void) +static void Op55M1(void) { - DirectIndexedX (READ, EOR8); + DirectIndexedX(READ, EOR8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void Op55M0 (void) +static void Op55M0(void) { - DirectIndexedX (READ, EOR16); + DirectIndexedX(READ, EOR16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void Op52M1 (void) +static void Op52M1(void) { - DirectIndirect (READ, EOR8); + DirectIndirect(READ, EOR8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op52M0 (void) +static void Op52M0(void) { - DirectIndirect (READ, EOR16); + DirectIndirect(READ, EOR16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op41M1 (void) +static void Op41M1(void) { - DirectIndexedIndirect (READ, EOR8); + DirectIndexedIndirect(READ, EOR8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op41M0 (void) +static void Op41M0(void) { - DirectIndexedIndirect (READ, EOR16); + DirectIndexedIndirect(READ, EOR16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op51M1 (void) +static void Op51M1(void) { - DirectIndirectIndexed (READ, EOR8); + DirectIndirectIndexed(READ, EOR8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op51M0 (void) +static void Op51M0(void) { - DirectIndirectIndexed (READ, EOR16); + DirectIndirectIndexed(READ, EOR16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op47M1 (void) +static void Op47M1(void) { - DirectIndirectLong (READ, EOR8); + DirectIndirectLong(READ, EOR8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op47M0 (void) +static void Op47M0(void) { - DirectIndirectLong (READ, EOR16); + DirectIndirectLong(READ, EOR16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op57M1 (void) +static void Op57M1(void) { - DirectIndirectIndexedLong (READ, EOR8); + DirectIndirectIndexedLong(READ, EOR8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op57M0 (void) +static void Op57M0(void) { - DirectIndirectIndexedLong (READ, EOR16); + DirectIndirectIndexedLong(READ, EOR16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op4DM1 (void) +static void Op4DM1(void) { - Absolute (READ, EOR8); + Absolute(READ, EOR8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op4DM0 (void) +static void Op4DM0(void) { - Absolute (READ, EOR16); + Absolute(READ, EOR16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op5DM1 (void) +static void Op5DM1(void) { - AbsoluteIndexedX (READ, EOR8); + AbsoluteIndexedX(READ, EOR8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op5DM0 (void) +static void Op5DM0(void) { - AbsoluteIndexedX (READ, EOR16); + AbsoluteIndexedX(READ, EOR16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op59M1 (void) +static void Op59M1(void) { - AbsoluteIndexedY (READ, EOR8); + AbsoluteIndexedY(READ, EOR8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op59M0 (void) +static void Op59M0(void) { - AbsoluteIndexedY (READ, EOR16); + AbsoluteIndexedY(READ, EOR16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op4FM1 (void) +static void Op4FM1(void) { - AbsoluteLong (READ, EOR8); + AbsoluteLong(READ, EOR8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void Op4FM0 (void) +static void Op4FM0(void) { - AbsoluteLong (READ, EOR16); + AbsoluteLong(READ, EOR16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void Op5FM1 (void) +static void Op5FM1(void) { - AbsoluteLongIndexedX (READ, EOR8); + AbsoluteLongIndexedX(READ, EOR8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void Op5FM0 (void) +static void Op5FM0(void) { - AbsoluteLongIndexedX (READ, EOR16); + AbsoluteLongIndexedX(READ, EOR16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void Op43M1 (void) +static void Op43M1(void) { - StackRelative (READ, EOR8); + StackRelative(READ, EOR8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif } -static void Op43M0 (void) +static void Op43M0(void) { - StackRelative (READ, EOR16); + StackRelative(READ, EOR16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif } -static void Op53M1 (void) +static void Op53M1(void) { - StackRelativeIndirectIndexed (READ, EOR8); + StackRelativeIndirectIndexed(READ, EOR8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; + CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; #endif } -static void Op53M0 (void) +static void Op53M0(void) { - StackRelativeIndirectIndexed (READ, EOR16); + StackRelativeIndirectIndexed(READ, EOR16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; + CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; #endif } /**********************************************************************************************/ /* INC *************************************************************************************** */ -static void Op1AM1 (void) +static void Op1AM1(void) { - A_INC8 (); + A_INC8(); } -static void Op1AM0 (void) +static void Op1AM0(void) { - A_INC16 (); + A_INC16(); } -static void OpE6M1 (void) +static void OpE6M1(void) { - Direct (MODIFY, INC8); + Direct(MODIFY, INC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void OpE6M0 (void) +static void OpE6M0(void) { - Direct (MODIFY, INC16); + Direct(MODIFY, INC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void OpF6M1 (void) +static void OpF6M1(void) { - DirectIndexedX (MODIFY, INC8); + DirectIndexedX(MODIFY, INC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE /* memory */ + ONE_CYCLE /* opcode */; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE /* memory */ + ONE_CYCLE /* opcode */; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void OpF6M0 (void) +static void OpF6M0(void) { - DirectIndexedX (MODIFY, INC16); + DirectIndexedX(MODIFY, INC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE /* memory */ + ONE_CYCLE /* opcode */; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE /* memory */ + ONE_CYCLE /* opcode */; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void OpEEM1 (void) +static void OpEEM1(void) { - Absolute (MODIFY, INC8); + Absolute(MODIFY, INC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void OpEEM0 (void) +static void OpEEM0(void) { - Absolute (MODIFY, INC16); + Absolute(MODIFY, INC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void OpFEM1 (void) +static void OpFEM1(void) { - AbsoluteIndexedX (MODIFY, INC8); + AbsoluteIndexedX(MODIFY, INC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void OpFEM0 (void) +static void OpFEM0(void) { - AbsoluteIndexedX (MODIFY, INC16); + AbsoluteIndexedX(MODIFY, INC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } /**********************************************************************************************/ /* LDA *************************************************************************************** */ -static void OpA9M1 (void) +static void OpA9M1(void) { - ICPU.Registers.AL = *CPU.PC++; + ICPU.Registers.AL = *CPU.PC++; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif - SetZN8 (ICPU.Registers.AL); + SetZN8(ICPU.Registers.AL); } -static void OpA9M0 (void) +static void OpA9M0(void) { #ifdef FAST_LSB_WORD_ACCESS - ICPU.Registers.A.W = *(uint16 *) CPU.PC; + ICPU.Registers.A.W = *(uint16*) CPU.PC; #else - ICPU.Registers.A.W = *CPU.PC + (*(CPU.PC + 1) << 8); + ICPU.Registers.A.W = *CPU.PC + (*(CPU.PC + 1) << 8); #endif - CPU.PC += 2; + CPU.PC += 2; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif - SetZN16 (ICPU.Registers.A.W); + SetZN16(ICPU.Registers.A.W); } -static void OpA5M1 (void) +static void OpA5M1(void) { - Direct (READ, LDA8); + Direct(READ, LDA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpA5M0 (void) +static void OpA5M0(void) { - Direct (READ, LDA16); + Direct(READ, LDA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpB5M1 (void) +static void OpB5M1(void) { - DirectIndexedX (READ, LDA8); + DirectIndexedX(READ, LDA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void OpB5M0 (void) +static void OpB5M0(void) { - DirectIndexedX (READ, LDA16); + DirectIndexedX(READ, LDA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void OpB2M1 (void) +static void OpB2M1(void) { - DirectIndirect (READ, LDA8); + DirectIndirect(READ, LDA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpB2M0 (void) +static void OpB2M0(void) { - DirectIndirect (READ, LDA16); + DirectIndirect(READ, LDA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpA1M1 (void) +static void OpA1M1(void) { - DirectIndexedIndirect (READ, LDA8); + DirectIndexedIndirect(READ, LDA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpA1M0 (void) +static void OpA1M0(void) { - DirectIndexedIndirect (READ, LDA16); + DirectIndexedIndirect(READ, LDA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpB1M1 (void) +static void OpB1M1(void) { - DirectIndirectIndexed (READ, LDA8); + DirectIndirectIndexed(READ, LDA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpB1M0 (void) +static void OpB1M0(void) { - DirectIndirectIndexed (READ, LDA16); + DirectIndirectIndexed(READ, LDA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpA7M1 (void) +static void OpA7M1(void) { - DirectIndirectLong (READ, LDA8); + DirectIndirectLong(READ, LDA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpA7M0 (void) +static void OpA7M0(void) { - DirectIndirectLong (READ, LDA16); + DirectIndirectLong(READ, LDA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpB7M1 (void) +static void OpB7M1(void) { - DirectIndirectIndexedLong (READ, LDA8); + DirectIndirectIndexedLong(READ, LDA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpB7M0 (void) +static void OpB7M0(void) { - DirectIndirectIndexedLong (READ, LDA16); + DirectIndirectIndexedLong(READ, LDA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpADM1 (void) +static void OpADM1(void) { - Absolute (READ, LDA8); + Absolute(READ, LDA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpADM0 (void) +static void OpADM0(void) { - Absolute (READ, LDA16); + Absolute(READ, LDA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpBDM1 (void) +static void OpBDM1(void) { - AbsoluteIndexedX (READ, LDA8); + AbsoluteIndexedX(READ, LDA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpBDM0 (void) +static void OpBDM0(void) { - AbsoluteIndexedX (READ, LDA16); + AbsoluteIndexedX(READ, LDA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpB9M1 (void) +static void OpB9M1(void) { - AbsoluteIndexedY (READ, LDA8); + AbsoluteIndexedY(READ, LDA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpB9M0 (void) +static void OpB9M0(void) { - AbsoluteIndexedY (READ, LDA16); + AbsoluteIndexedY(READ, LDA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpAFM1 (void) +static void OpAFM1(void) { - AbsoluteLong (READ, LDA8); + AbsoluteLong(READ, LDA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void OpAFM0 (void) +static void OpAFM0(void) { - AbsoluteLong (READ, LDA16); + AbsoluteLong(READ, LDA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void OpBFM1 (void) +static void OpBFM1(void) { - AbsoluteLongIndexedX (READ, LDA8); + AbsoluteLongIndexedX(READ, LDA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void OpBFM0 (void) +static void OpBFM0(void) { - AbsoluteLongIndexedX (READ, LDA16); + AbsoluteLongIndexedX(READ, LDA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void OpA3M1 (void) +static void OpA3M1(void) { - StackRelative (READ, LDA8); + StackRelative(READ, LDA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif } -static void OpA3M0 (void) +static void OpA3M0(void) { - StackRelative (READ, LDA16); + StackRelative(READ, LDA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif } -static void OpB3M1 (void) +static void OpB3M1(void) { - StackRelativeIndirectIndexed (READ, LDA8); + StackRelativeIndirectIndexed(READ, LDA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; + CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; #endif } -static void OpB3M0 (void) +static void OpB3M0(void) { - StackRelativeIndirectIndexed (READ, LDA16); + StackRelativeIndirectIndexed(READ, LDA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; + CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; #endif } /**********************************************************************************************/ /* LDX *************************************************************************************** */ -static void OpA2X1 (void) +static void OpA2X1(void) { - ICPU.Registers.XL = *CPU.PC++; + ICPU.Registers.XL = *CPU.PC++; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif - SetZN8 (ICPU.Registers.XL); + SetZN8(ICPU.Registers.XL); } -static void OpA2X0 (void) +static void OpA2X0(void) { #ifdef FAST_LSB_WORD_ACCESS - ICPU.Registers.X.W = *(uint16 *) CPU.PC; + ICPU.Registers.X.W = *(uint16*) CPU.PC; #else - ICPU.Registers.X.W = *CPU.PC + (*(CPU.PC + 1) << 8); + ICPU.Registers.X.W = *CPU.PC + (*(CPU.PC + 1) << 8); #endif - CPU.PC += 2; + CPU.PC += 2; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif - SetZN16 (ICPU.Registers.X.W); + SetZN16(ICPU.Registers.X.W); } -static void OpA6X1 (void) +static void OpA6X1(void) { - Direct (READ, LDX8); + Direct(READ, LDX8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpA6X0 (void) +static void OpA6X0(void) { - Direct (READ, LDX16); + Direct(READ, LDX16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpB6X1 (void) +static void OpB6X1(void) { - DirectIndexedY (READ, LDX8); + DirectIndexedY(READ, LDX8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void OpB6X0 (void) +static void OpB6X0(void) { - DirectIndexedY (READ, LDX16); + DirectIndexedY(READ, LDX16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void OpAEX1 (void) +static void OpAEX1(void) { - Absolute (READ, LDX8); + Absolute(READ, LDX8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpAEX0 (void) +static void OpAEX0(void) { - Absolute (READ, LDX16); + Absolute(READ, LDX16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpBEX1 (void) +static void OpBEX1(void) { - AbsoluteIndexedY (READ, LDX8); + AbsoluteIndexedY(READ, LDX8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpBEX0 (void) +static void OpBEX0(void) { - AbsoluteIndexedY (READ, LDX16); + AbsoluteIndexedY(READ, LDX16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } /**********************************************************************************************/ /* LDY *************************************************************************************** */ -static void OpA0X1 (void) +static void OpA0X1(void) { - ICPU.Registers.YL = *CPU.PC++; + ICPU.Registers.YL = *CPU.PC++; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif - SetZN8 (ICPU.Registers.YL); + SetZN8(ICPU.Registers.YL); } -static void OpA0X0 (void) +static void OpA0X0(void) { #ifdef FAST_LSB_WORD_ACCESS - ICPU.Registers.Y.W = *(uint16 *) CPU.PC; + ICPU.Registers.Y.W = *(uint16*) CPU.PC; #else - ICPU.Registers.Y.W = *CPU.PC + (*(CPU.PC + 1) << 8); + ICPU.Registers.Y.W = *CPU.PC + (*(CPU.PC + 1) << 8); #endif - CPU.PC += 2; + CPU.PC += 2; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif - SetZN16 (ICPU.Registers.Y.W); + SetZN16(ICPU.Registers.Y.W); } -static void OpA4X1 (void) +static void OpA4X1(void) { - Direct (READ, LDY8); + Direct(READ, LDY8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpA4X0 (void) +static void OpA4X0(void) { - Direct (READ, LDY16); + Direct(READ, LDY16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpB4X1 (void) +static void OpB4X1(void) { - DirectIndexedX (READ, LDY8); + DirectIndexedX(READ, LDY8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void OpB4X0 (void) +static void OpB4X0(void) { - DirectIndexedX (READ, LDY16); + DirectIndexedX(READ, LDY16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void OpACX1 (void) +static void OpACX1(void) { - Absolute (READ, LDY8); + Absolute(READ, LDY8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpACX0 (void) +static void OpACX0(void) { - Absolute (READ, LDY16); + Absolute(READ, LDY16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpBCX1 (void) +static void OpBCX1(void) { - AbsoluteIndexedX (READ, LDY8); + AbsoluteIndexedX(READ, LDY8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpBCX0 (void) +static void OpBCX0(void) { - AbsoluteIndexedX (READ, LDY16); + AbsoluteIndexedX(READ, LDY16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } /**********************************************************************************************/ /* LSR *************************************************************************************** */ -static void Op4AM1 (void) +static void Op4AM1(void) { - A_LSR8 (); + A_LSR8(); } -static void Op4AM0 (void) +static void Op4AM0(void) { - A_LSR16 (); + A_LSR16(); } -static void Op46M1 (void) +static void Op46M1(void) { - Direct (MODIFY, LSR8); + Direct(MODIFY, LSR8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op46M0 (void) +static void Op46M0(void) { - Direct (MODIFY, LSR16); + Direct(MODIFY, LSR16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op56M1 (void) +static void Op56M1(void) { - DirectIndexedX (MODIFY, LSR8); + DirectIndexedX(MODIFY, LSR8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE /* memory */ + ONE_CYCLE /* opcode */; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE /* memory */ + ONE_CYCLE /* opcode */; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void Op56M0 (void) +static void Op56M0(void) { - DirectIndexedX (MODIFY, LSR16); + DirectIndexedX(MODIFY, LSR16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE /* memory */ + ONE_CYCLE /* opcode */; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE /* memory */ + ONE_CYCLE /* opcode */; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void Op4EM1 (void) +static void Op4EM1(void) { - Absolute (MODIFY, LSR8); + Absolute(MODIFY, LSR8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op4EM0 (void) +static void Op4EM0(void) { - Absolute (MODIFY, LSR16); + Absolute(MODIFY, LSR16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op5EM1 (void) +static void Op5EM1(void) { - AbsoluteIndexedX (MODIFY, LSR8); + AbsoluteIndexedX(MODIFY, LSR8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op5EM0 (void) +static void Op5EM0(void) { - AbsoluteIndexedX (MODIFY, LSR16); + AbsoluteIndexedX(MODIFY, LSR16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } /**********************************************************************************************/ /* ORA *************************************************************************************** */ -static void Op09M1 (void) +static void Op09M1(void) { - ICPU.Registers.AL |= *CPU.PC++; + ICPU.Registers.AL |= *CPU.PC++; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif - SetZN8 (ICPU.Registers.AL); + SetZN8(ICPU.Registers.AL); } -static void Op09M0 (void) +static void Op09M0(void) { #ifdef FAST_LSB_WORD_ACCESS - ICPU.Registers.A.W |= *(uint16 *) CPU.PC; + ICPU.Registers.A.W |= *(uint16*) CPU.PC; #else - ICPU.Registers.A.W |= *CPU.PC + (*(CPU.PC + 1) << 8); + ICPU.Registers.A.W |= *CPU.PC + (*(CPU.PC + 1) << 8); #endif - CPU.PC += 2; + CPU.PC += 2; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif - SetZN16 (ICPU.Registers.A.W); + SetZN16(ICPU.Registers.A.W); } -static void Op05M1 (void) +static void Op05M1(void) { - Direct (READ, ORA8); + Direct(READ, ORA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op05M0 (void) +static void Op05M0(void) { - Direct (READ, ORA16); + Direct(READ, ORA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op15M1 (void) +static void Op15M1(void) { - DirectIndexedX (READ, ORA8); + DirectIndexedX(READ, ORA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void Op15M0 (void) +static void Op15M0(void) { - DirectIndexedX (READ, ORA16); + DirectIndexedX(READ, ORA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void Op12M1 (void) +static void Op12M1(void) { - DirectIndirect (READ, ORA8); + DirectIndirect(READ, ORA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op12M0 (void) +static void Op12M0(void) { - DirectIndirect (READ, ORA16); + DirectIndirect(READ, ORA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op01M1 (void) +static void Op01M1(void) { - DirectIndexedIndirect (READ, ORA8); + DirectIndexedIndirect(READ, ORA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op01M0 (void) +static void Op01M0(void) { - DirectIndexedIndirect (READ, ORA16); + DirectIndexedIndirect(READ, ORA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op11M1 (void) +static void Op11M1(void) { - DirectIndirectIndexed (READ, ORA8); + DirectIndirectIndexed(READ, ORA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op11M0 (void) +static void Op11M0(void) { - DirectIndirectIndexed (READ, ORA16); + DirectIndirectIndexed(READ, ORA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op07M1 (void) +static void Op07M1(void) { - DirectIndirectLong (READ, ORA8); + DirectIndirectLong(READ, ORA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op07M0 (void) +static void Op07M0(void) { - DirectIndirectLong (READ, ORA16); + DirectIndirectLong(READ, ORA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op17M1 (void) +static void Op17M1(void) { - DirectIndirectIndexedLong (READ, ORA8); + DirectIndirectIndexedLong(READ, ORA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op17M0 (void) +static void Op17M0(void) { - DirectIndirectIndexedLong (READ, ORA16); + DirectIndirectIndexedLong(READ, ORA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op0DM1 (void) +static void Op0DM1(void) { - Absolute (READ, ORA8); + Absolute(READ, ORA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op0DM0 (void) +static void Op0DM0(void) { - Absolute (READ, ORA16); + Absolute(READ, ORA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op1DM1 (void) +static void Op1DM1(void) { - AbsoluteIndexedX (READ, ORA8); + AbsoluteIndexedX(READ, ORA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op1DM0 (void) +static void Op1DM0(void) { - AbsoluteIndexedX (READ, ORA16); + AbsoluteIndexedX(READ, ORA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op19M1 (void) +static void Op19M1(void) { - AbsoluteIndexedY (READ, ORA8); + AbsoluteIndexedY(READ, ORA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op19M0 (void) +static void Op19M0(void) { - AbsoluteIndexedY (READ, ORA16); + AbsoluteIndexedY(READ, ORA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op0FM1 (void) +static void Op0FM1(void) { - AbsoluteLong (READ, ORA8); + AbsoluteLong(READ, ORA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void Op0FM0 (void) +static void Op0FM0(void) { - AbsoluteLong (READ, ORA16); + AbsoluteLong(READ, ORA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void Op1FM1 (void) +static void Op1FM1(void) { - AbsoluteLongIndexedX (READ, ORA8); + AbsoluteLongIndexedX(READ, ORA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void Op1FM0 (void) +static void Op1FM0(void) { - AbsoluteLongIndexedX (READ, ORA16); + AbsoluteLongIndexedX(READ, ORA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void Op03M1 (void) +static void Op03M1(void) { - StackRelative (READ, ORA8); + StackRelative(READ, ORA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif } -static void Op03M0 (void) +static void Op03M0(void) { - StackRelative (READ, ORA16); + StackRelative(READ, ORA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif } -static void Op13M1 (void) +static void Op13M1(void) { - StackRelativeIndirectIndexed (READ, ORA8); + StackRelativeIndirectIndexed(READ, ORA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; + CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; #endif } -static void Op13M0 (void) +static void Op13M0(void) { - StackRelativeIndirectIndexed (READ, ORA16); + StackRelativeIndirectIndexed(READ, ORA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; + CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; #endif } /**********************************************************************************************/ /* ROL *************************************************************************************** */ -static void Op2AM1 (void) +static void Op2AM1(void) { - A_ROL8 (); + A_ROL8(); } -static void Op2AM0 (void) +static void Op2AM0(void) { - A_ROL16 (); + A_ROL16(); } -static void Op26M1 (void) +static void Op26M1(void) { - Direct (MODIFY, ROL8); + Direct(MODIFY, ROL8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op26M0 (void) +static void Op26M0(void) { - Direct (MODIFY, ROL16); + Direct(MODIFY, ROL16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op36M1 (void) +static void Op36M1(void) { - DirectIndexedX (MODIFY, ROL8); + DirectIndexedX(MODIFY, ROL8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE /* memory */ + ONE_CYCLE /* opcode */; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE /* memory */ + ONE_CYCLE /* opcode */; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void Op36M0 (void) +static void Op36M0(void) { - DirectIndexedX (MODIFY, ROL16); + DirectIndexedX(MODIFY, ROL16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE /* memory */ + ONE_CYCLE /* opcode */; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE /* memory */ + ONE_CYCLE /* opcode */; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void Op2EM1 (void) +static void Op2EM1(void) { - Absolute (MODIFY, ROL8); + Absolute(MODIFY, ROL8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op2EM0 (void) +static void Op2EM0(void) { - Absolute (MODIFY, ROL16); + Absolute(MODIFY, ROL16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op3EM1 (void) +static void Op3EM1(void) { - AbsoluteIndexedX (MODIFY, ROL8); + AbsoluteIndexedX(MODIFY, ROL8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op3EM0 (void) +static void Op3EM0(void) { - AbsoluteIndexedX (MODIFY, ROL16); + AbsoluteIndexedX(MODIFY, ROL16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } /**********************************************************************************************/ /* ROR *************************************************************************************** */ -static void Op6AM1 (void) +static void Op6AM1(void) { - A_ROR8 (); + A_ROR8(); } -static void Op6AM0 (void) +static void Op6AM0(void) { - A_ROR16 (); + A_ROR16(); } -static void Op66M1 (void) +static void Op66M1(void) { - Direct (MODIFY, ROR8); + Direct(MODIFY, ROR8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op66M0 (void) +static void Op66M0(void) { - Direct (MODIFY, ROR16); + Direct(MODIFY, ROR16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op76M1 (void) +static void Op76M1(void) { - DirectIndexedX (MODIFY, ROR8); + DirectIndexedX(MODIFY, ROR8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE /* memory */ + ONE_CYCLE /* opcode */; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE /* memory */ + ONE_CYCLE /* opcode */; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void Op76M0 (void) +static void Op76M0(void) { - DirectIndexedX (MODIFY, ROR16); + DirectIndexedX(MODIFY, ROR16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE /* memory */ + ONE_CYCLE /* opcode */; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE /* memory */ + ONE_CYCLE /* opcode */; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void Op6EM1 (void) +static void Op6EM1(void) { - Absolute (MODIFY, ROR8); + Absolute(MODIFY, ROR8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op6EM0 (void) +static void Op6EM0(void) { - Absolute (MODIFY, ROR16); + Absolute(MODIFY, ROR16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op7EM1 (void) +static void Op7EM1(void) { - AbsoluteIndexedX (MODIFY, ROR8); + AbsoluteIndexedX(MODIFY, ROR8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op7EM0 (void) +static void Op7EM0(void) { - AbsoluteIndexedX (MODIFY, ROR16); + AbsoluteIndexedX(MODIFY, ROR16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } /**********************************************************************************************/ /* SBC *************************************************************************************** */ -static void OpE9M1 (void) +static void OpE9M1(void) { - Immediate8 (READ, SBC8); + Immediate8(READ, SBC8); } -static void OpE9M0 (void) +static void OpE9M0(void) { - Immediate16 (READ, SBC16); + Immediate16(READ, SBC16); } -static void OpE5M1 (void) +static void OpE5M1(void) { - Direct (READ, SBC8); + Direct(READ, SBC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpE5M0 (void) +static void OpE5M0(void) { - Direct (READ, SBC16); + Direct(READ, SBC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpF5M1 (void) +static void OpF5M1(void) { - DirectIndexedX (READ, SBC8); + DirectIndexedX(READ, SBC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void OpF5M0 (void) +static void OpF5M0(void) { - DirectIndexedX (READ, SBC16); + DirectIndexedX(READ, SBC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void OpF2M1 (void) +static void OpF2M1(void) { - DirectIndirect (READ, SBC8); + DirectIndirect(READ, SBC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpF2M0 (void) +static void OpF2M0(void) { - DirectIndirect (READ, SBC16); + DirectIndirect(READ, SBC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpE1M1 (void) +static void OpE1M1(void) { - DirectIndexedIndirect (READ, SBC8); + DirectIndexedIndirect(READ, SBC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpE1M0 (void) +static void OpE1M0(void) { - DirectIndexedIndirect (READ, SBC16); + DirectIndexedIndirect(READ, SBC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpF1M1 (void) +static void OpF1M1(void) { - DirectIndirectIndexed (READ, SBC8); + DirectIndirectIndexed(READ, SBC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpF1M0 (void) +static void OpF1M0(void) { - DirectIndirectIndexed (READ, SBC16); + DirectIndirectIndexed(READ, SBC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpE7M1 (void) +static void OpE7M1(void) { - DirectIndirectLong (READ, SBC8); + DirectIndirectLong(READ, SBC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpE7M0 (void) +static void OpE7M0(void) { - DirectIndirectLong (READ, SBC16); + DirectIndirectLong(READ, SBC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpF7M1 (void) +static void OpF7M1(void) { - DirectIndirectIndexedLong (READ, SBC8); + DirectIndirectIndexedLong(READ, SBC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpF7M0 (void) +static void OpF7M0(void) { - DirectIndirectIndexedLong (READ, SBC16); + DirectIndirectIndexedLong(READ, SBC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void OpEDM1 (void) +static void OpEDM1(void) { - Absolute (READ, SBC8); + Absolute(READ, SBC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpEDM0 (void) +static void OpEDM0(void) { - Absolute (READ, SBC16); + Absolute(READ, SBC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpFDM1 (void) +static void OpFDM1(void) { - AbsoluteIndexedX (READ, SBC8); + AbsoluteIndexedX(READ, SBC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpFDM0 (void) +static void OpFDM0(void) { - AbsoluteIndexedX (READ, SBC16); + AbsoluteIndexedX(READ, SBC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpF9M1 (void) +static void OpF9M1(void) { - AbsoluteIndexedY (READ, SBC8); + AbsoluteIndexedY(READ, SBC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpF9M0 (void) +static void OpF9M0(void) { - AbsoluteIndexedY (READ, SBC16); + AbsoluteIndexedY(READ, SBC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void OpEFM1 (void) +static void OpEFM1(void) { - AbsoluteLong (READ, SBC8); + AbsoluteLong(READ, SBC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void OpEFM0 (void) +static void OpEFM0(void) { - AbsoluteLong (READ, SBC16); + AbsoluteLong(READ, SBC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void OpFFM1 (void) +static void OpFFM1(void) { - AbsoluteLongIndexedX (READ, SBC8); + AbsoluteLongIndexedX(READ, SBC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void OpFFM0 (void) +static void OpFFM0(void) { - AbsoluteLongIndexedX (READ, SBC16); + AbsoluteLongIndexedX(READ, SBC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void OpE3M1 (void) +static void OpE3M1(void) { - StackRelative (READ, SBC8); + StackRelative(READ, SBC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif } -static void OpE3M0 (void) +static void OpE3M0(void) { - StackRelative (READ, SBC16); + StackRelative(READ, SBC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif } -static void OpF3M1 (void) +static void OpF3M1(void) { - StackRelativeIndirectIndexed (READ, SBC8); + StackRelativeIndirectIndexed(READ, SBC8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; + CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; #endif } -static void OpF3M0 (void) +static void OpF3M0(void) { - StackRelativeIndirectIndexed (READ, SBC16); + StackRelativeIndirectIndexed(READ, SBC16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; + CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; #endif } /**********************************************************************************************/ /* STA *************************************************************************************** */ -static void Op85M1 (void) +static void Op85M1(void) { - Direct (WRITE, STA8); + Direct(WRITE, STA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op85M0 (void) +static void Op85M0(void) { - Direct (WRITE, STA16); + Direct(WRITE, STA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op95M1 (void) +static void Op95M1(void) { - DirectIndexedX (WRITE, STA8); + DirectIndexedX(WRITE, STA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void Op95M0 (void) +static void Op95M0(void) { - DirectIndexedX (WRITE, STA16); + DirectIndexedX(WRITE, STA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void Op92M1 (void) +static void Op92M1(void) { - DirectIndirect (WRITE, STA8); + DirectIndirect(WRITE, STA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op92M0 (void) +static void Op92M0(void) { - DirectIndirect (WRITE, STA16); + DirectIndirect(WRITE, STA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op81M1 (void) +static void Op81M1(void) { - DirectIndexedIndirect (WRITE, STA8); + DirectIndexedIndirect(WRITE, STA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif #ifdef noVAR_CYCLES - if (CheckIndex ()) - CPU.Cycles += ONE_CYCLE; + if (CheckIndex()) + CPU.Cycles += ONE_CYCLE; #endif } -static void Op81M0 (void) +static void Op81M0(void) { - DirectIndexedIndirect (WRITE, STA16); + DirectIndexedIndirect(WRITE, STA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif #ifdef noVAR_CYCLES - if (CheckIndex ()) - CPU.Cycles += ONE_CYCLE; + if (CheckIndex()) + CPU.Cycles += ONE_CYCLE; #endif } -static void Op91M1 (void) +static void Op91M1(void) { - DirectIndirectIndexed (WRITE, STA8); + DirectIndirectIndexed(WRITE, STA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op91M0 (void) +static void Op91M0(void) { - DirectIndirectIndexed (WRITE, STA16); + DirectIndirectIndexed(WRITE, STA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op87M1 (void) +static void Op87M1(void) { - DirectIndirectLong (WRITE, STA8); + DirectIndirectLong(WRITE, STA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op87M0 (void) +static void Op87M0(void) { - DirectIndirectLong (WRITE, STA16); + DirectIndirectLong(WRITE, STA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op97M1 (void) +static void Op97M1(void) { - DirectIndirectIndexedLong (WRITE, STA8); + DirectIndirectIndexedLong(WRITE, STA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op97M0 (void) +static void Op97M0(void) { - DirectIndirectIndexedLong (WRITE, STA16); + DirectIndirectIndexedLong(WRITE, STA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op8DM1 (void) +static void Op8DM1(void) { - Absolute (WRITE, STA8); + Absolute(WRITE, STA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op8DM0 (void) +static void Op8DM0(void) { - Absolute (WRITE, STA16); + Absolute(WRITE, STA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op9DM1 (void) +static void Op9DM1(void) { - AbsoluteIndexedX (WRITE, STA8); + AbsoluteIndexedX(WRITE, STA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op9DM0 (void) +static void Op9DM0(void) { - AbsoluteIndexedX (WRITE, STA16); + AbsoluteIndexedX(WRITE, STA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op99M1 (void) +static void Op99M1(void) { - AbsoluteIndexedY (WRITE, STA8); + AbsoluteIndexedY(WRITE, STA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op99M0 (void) +static void Op99M0(void) { - AbsoluteIndexedY (WRITE, STA16); + AbsoluteIndexedY(WRITE, STA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op8FM1 (void) +static void Op8FM1(void) { - AbsoluteLong (WRITE, STA8); + AbsoluteLong(WRITE, STA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void Op8FM0 (void) +static void Op8FM0(void) { - AbsoluteLong (WRITE, STA16); + AbsoluteLong(WRITE, STA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void Op9FM1 (void) +static void Op9FM1(void) { - AbsoluteLongIndexedX (WRITE, STA8); + AbsoluteLongIndexedX(WRITE, STA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void Op9FM0 (void) +static void Op9FM0(void) { - AbsoluteLongIndexedX (WRITE, STA16); + AbsoluteLongIndexedX(WRITE, STA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif } -static void Op83M1 (void) +static void Op83M1(void) { - StackRelative (WRITE, STA8); + StackRelative(WRITE, STA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif } -static void Op83M0 (void) +static void Op83M0(void) { - StackRelative (WRITE, STA16); + StackRelative(WRITE, STA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif } -static void Op93M1 (void) +static void Op93M1(void) { - StackRelativeIndirectIndexed (WRITE, STA8); + StackRelativeIndirectIndexed(WRITE, STA8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; + CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; #endif } -static void Op93M0 (void) +static void Op93M0(void) { - StackRelativeIndirectIndexed (WRITE, STA16); + StackRelativeIndirectIndexed(WRITE, STA16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; + CPU.Cycles += CPU.MemSpeed + TWO_CYCLES; #endif } /**********************************************************************************************/ /* STX *************************************************************************************** */ -static void Op86X1 (void) +static void Op86X1(void) { - Direct (WRITE, STX8); + Direct(WRITE, STX8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op86X0 (void) +static void Op86X0(void) { - Direct (WRITE, STX16); + Direct(WRITE, STX16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op96X1 (void) +static void Op96X1(void) { - DirectIndexedY (WRITE, STX8); + DirectIndexedY(WRITE, STX8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void Op96X0 (void) +static void Op96X0(void) { - DirectIndexedY (WRITE, STX16); + DirectIndexedY(WRITE, STX16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void Op8EX1 (void) +static void Op8EX1(void) { - Absolute (WRITE, STX8); + Absolute(WRITE, STX8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op8EX0 (void) +static void Op8EX0(void) { - Absolute (WRITE, STX16); + Absolute(WRITE, STX16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } /**********************************************************************************************/ /* STY *************************************************************************************** */ -static void Op84X1 (void) +static void Op84X1(void) { - Direct (WRITE, STY8); + Direct(WRITE, STY8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op84X0 (void) +static void Op84X0(void) { - Direct (WRITE, STY16); + Direct(WRITE, STY16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op94X1 (void) +static void Op94X1(void) { - DirectIndexedX (WRITE, STY8); + DirectIndexedX(WRITE, STY8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void Op94X0 (void) +static void Op94X0(void) { - DirectIndexedX (WRITE, STY16); + DirectIndexedX(WRITE, STY16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void Op8CX1 (void) +static void Op8CX1(void) { - Absolute (WRITE, STY8); + Absolute(WRITE, STY8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op8CX0 (void) +static void Op8CX0(void) { - Absolute (WRITE, STY16); + Absolute(WRITE, STY16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } /**********************************************************************************************/ /* STZ *************************************************************************************** */ -static void Op64M1 (void) +static void Op64M1(void) { - Direct (WRITE, STZ8); + Direct(WRITE, STZ8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op64M0 (void) +static void Op64M0(void) { - Direct (WRITE, STZ16); + Direct(WRITE, STZ16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif } -static void Op74M1 (void) +static void Op74M1(void) { - DirectIndexedX (WRITE, STZ8); + DirectIndexedX(WRITE, STZ8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void Op74M0 (void) +static void Op74M0(void) { - DirectIndexedX (WRITE, STZ16); + DirectIndexedX(WRITE, STZ16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -// if (ICPU.Registers.DL != 0) -// CPU.Cycles += TWO_CYCLES; -// else -// CPU.Cycles += ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + // if (ICPU.Registers.DL != 0) + // CPU.Cycles += TWO_CYCLES; + // else + // CPU.Cycles += ONE_CYCLE; #endif } -static void Op9CM1 (void) +static void Op9CM1(void) { - Absolute (WRITE, STZ8); + Absolute(WRITE, STZ8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op9CM0 (void) +static void Op9CM0(void) { - Absolute (WRITE, STZ16); + Absolute(WRITE, STZ16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op9EM1 (void) +static void Op9EM1(void) { - AbsoluteIndexedX (WRITE, STZ8); + AbsoluteIndexedX(WRITE, STZ8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } -static void Op9EM0 (void) +static void Op9EM0(void) { - AbsoluteIndexedX (WRITE, STZ16); + AbsoluteIndexedX(WRITE, STZ16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif } /**********************************************************************************************/ /* TRB *************************************************************************************** */ -static void Op14M1 (void) +static void Op14M1(void) { - Direct (MODIFY, TRB8); + Direct(MODIFY, TRB8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op14M0 (void) +static void Op14M0(void) { - Direct (MODIFY, TRB16); + Direct(MODIFY, TRB16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op1CM1 (void) +static void Op1CM1(void) { - Absolute (MODIFY, TRB8); + Absolute(MODIFY, TRB8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op1CM0 (void) +static void Op1CM0(void) { - Absolute (MODIFY, TRB16); + Absolute(MODIFY, TRB16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } /**********************************************************************************************/ /* TSB *************************************************************************************** */ -static void Op04M1 (void) +static void Op04M1(void) { - Direct (MODIFY, TSB8); + Direct(MODIFY, TSB8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op04M0 (void) +static void Op04M0(void) { - Direct (MODIFY, TSB16); + Direct(MODIFY, TSB16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeed /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op0CM1 (void) +static void Op0CM1(void) { - Absolute (MODIFY, TSB8); + Absolute(MODIFY, TSB8); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } -static void Op0CM0 (void) +static void Op0CM0(void) { - Absolute (MODIFY, TSB16); + Absolute(MODIFY, TSB16); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; + CPU.Cycles += CPU.MemSpeedx2 /* memory */ + ONE_CYCLE /* opcode */; #endif } @@ -3315,44 +3315,44 @@ static void Op0CM0 (void) #define BranchCheck0()\ if( CPU.BranchSkip)\ {\ - CPU.BranchSkip = FALSE;\ - if (!Settings.SoundSkipMethod)\ - if( CPU.PC - CPU.PCBase > OpAddress)\ - return;\ + CPU.BranchSkip = FALSE;\ + if (!Settings.SoundSkipMethod)\ + if( CPU.PC - CPU.PCBase > OpAddress)\ + return;\ } #define BranchCheck1()\ if( CPU.BranchSkip)\ {\ - CPU.BranchSkip = FALSE;\ - if (!Settings.SoundSkipMethod) {\ - if( CPU.PC - CPU.PCBase > OpAddress)\ - return;\ - } else \ - if (Settings.SoundSkipMethod == 1)\ - return;\ - if (Settings.SoundSkipMethod == 3)\ - if( CPU.PC - CPU.PCBase > OpAddress)\ - return;\ - else\ - CPU.PC = CPU.PCBase + OpAddress;\ + CPU.BranchSkip = FALSE;\ + if (!Settings.SoundSkipMethod) {\ + if( CPU.PC - CPU.PCBase > OpAddress)\ + return;\ + } else \ + if (Settings.SoundSkipMethod == 1)\ + return;\ + if (Settings.SoundSkipMethod == 3)\ + if( CPU.PC - CPU.PCBase > OpAddress)\ + return;\ + else\ + CPU.PC = CPU.PCBase + OpAddress;\ } #define BranchCheck2()\ if( CPU.BranchSkip)\ {\ - CPU.BranchSkip = FALSE;\ - if (!Settings.SoundSkipMethod) {\ - if( CPU.PC - CPU.PCBase > OpAddress)\ - return;\ - } else \ - if (Settings.SoundSkipMethod == 1)\ - CPU.PC = CPU.PCBase + OpAddress;\ - if (Settings.SoundSkipMethod == 3)\ - if (CPU.PC - CPU.PCBase > OpAddress)\ - return;\ - else\ - CPU.PC = CPU.PCBase + OpAddress;\ + CPU.BranchSkip = FALSE;\ + if (!Settings.SoundSkipMethod) {\ + if( CPU.PC - CPU.PCBase > OpAddress)\ + return;\ + } else \ + if (Settings.SoundSkipMethod == 1)\ + CPU.PC = CPU.PCBase + OpAddress;\ + if (Settings.SoundSkipMethod == 3)\ + if (CPU.PC - CPU.PCBase > OpAddress)\ + return;\ + else\ + CPU.PC = CPU.PCBase + OpAddress;\ } #else #define BranchCheck0() @@ -3364,50 +3364,50 @@ static void Op0CM0 (void) #ifndef SA1_OPCODES static inline void CPUShutdown() { - if (Settings.Shutdown && CPU.PC == CPU.WaitAddress) - { - // Don't skip cycles with a pending NMI or IRQ - could cause delayed - // interrupt. Interrupts are delayed for a few cycles already, but - // the delay could allow the shutdown code to cycle skip again. - // Was causing screen flashing on Top Gear 3000. - - if (CPU.WaitCounter == 0 && - !(CPU.Flags & (IRQ_PENDING_FLAG | NMI_FLAG))) - { - CPU.WaitAddress = NULL; - if (Settings.SA1) - S9xSA1ExecuteDuringSleep (); - CPU.Cycles = CPU.NextEvent; - if (IAPU.APUExecuting) - { - ICPU.CPUExecuting = FALSE; - do - { - APU_EXECUTE1(); - } while (APU.Cycles < CPU.NextEvent); - ICPU.CPUExecuting = TRUE; - } - } - else - if (CPU.WaitCounter >= 2) - CPU.WaitCounter = 1; - else - CPU.WaitCounter--; - } + if (Settings.Shutdown && CPU.PC == CPU.WaitAddress) + { + // Don't skip cycles with a pending NMI or IRQ - could cause delayed + // interrupt. Interrupts are delayed for a few cycles already, but + // the delay could allow the shutdown code to cycle skip again. + // Was causing screen flashing on Top Gear 3000. + + if (CPU.WaitCounter == 0 && + !(CPU.Flags & (IRQ_PENDING_FLAG | NMI_FLAG))) + { + CPU.WaitAddress = NULL; + if (Settings.SA1) + S9xSA1ExecuteDuringSleep(); + CPU.Cycles = CPU.NextEvent; + if (IAPU.APUExecuting) + { + ICPU.CPUExecuting = FALSE; + do + { + APU_EXECUTE1(); + } + while (APU.Cycles < CPU.NextEvent); + ICPU.CPUExecuting = TRUE; + } + } + else if (CPU.WaitCounter >= 2) + CPU.WaitCounter = 1; + else + CPU.WaitCounter--; + } } #else inline void CPUShutdown() { - if (Settings.Shutdown && CPU.PC == CPU.WaitAddress) - { - if (CPU.WaitCounter >= 1) - { - SA1.Executing = FALSE; - SA1.CPUExecuting = FALSE; - } - else - CPU.WaitCounter++; - } + if (Settings.Shutdown && CPU.PC == CPU.WaitAddress) + { + if (CPU.WaitCounter >= 1) + { + SA1.Executing = FALSE; + SA1.CPUExecuting = FALSE; + } + else + CPU.WaitCounter++; + } } #endif #else @@ -3415,339 +3415,323 @@ inline void CPUShutdown() #endif /* BCC */ -static void Op90 (void) +static void Op90(void) { - Relative (JUMP, OpAddressPassthrough); - BranchCheck0 (); - if (!CheckCarry ()) - { - CPU.PC = CPU.PCBase + OpAddress; + Relative(JUMP, OpAddressPassthrough); + BranchCheck0(); + if (!CheckCarry()) + { + CPU.PC = CPU.PCBase + OpAddress; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif - CPUShutdown(); - } + CPUShutdown(); + } #ifndef SA1_OPCODES - else - { - CPU.Cycles += CPU.MemSpeed; - } + else + CPU.Cycles += CPU.MemSpeed; #endif } /* BCS */ -static void OpB0 (void) +static void OpB0(void) { - Relative (JUMP, OpAddressPassthrough); - BranchCheck0 (); - if (CheckCarry ()) - { - CPU.PC = CPU.PCBase + OpAddress; + Relative(JUMP, OpAddressPassthrough); + BranchCheck0(); + if (CheckCarry()) + { + CPU.PC = CPU.PCBase + OpAddress; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif - CPUShutdown (); - } + CPUShutdown(); + } #ifndef SA1_OPCODES - else - { - CPU.Cycles += CPU.MemSpeed; - } + else + CPU.Cycles += CPU.MemSpeed; #endif } /* BEQ */ -static void OpF0 (void) +static void OpF0(void) { - Relative (JUMP, OpAddressPassthrough); - BranchCheck2 (); - if (CheckZero ()) - { - CPU.PC = CPU.PCBase + OpAddress; + Relative(JUMP, OpAddressPassthrough); + BranchCheck2(); + if (CheckZero()) + { + CPU.PC = CPU.PCBase + OpAddress; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif - CPUShutdown (); - } + CPUShutdown(); + } #ifndef SA1_OPCODES - else - { - CPU.Cycles += CPU.MemSpeed; - } + else + CPU.Cycles += CPU.MemSpeed; #endif } /* BMI */ -static void Op30 (void) +static void Op30(void) { - Relative (JUMP, OpAddressPassthrough); - BranchCheck1 (); - if (CheckNegative ()) - { - CPU.PC = CPU.PCBase + OpAddress; + Relative(JUMP, OpAddressPassthrough); + BranchCheck1(); + if (CheckNegative()) + { + CPU.PC = CPU.PCBase + OpAddress; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif - CPUShutdown (); - } + CPUShutdown(); + } #ifndef SA1_OPCODES - else - { - CPU.Cycles += CPU.MemSpeed; - } + else + CPU.Cycles += CPU.MemSpeed; #endif } /* BNE */ -static void OpD0 (void) +static void OpD0(void) { - Relative (JUMP, OpAddressPassthrough); - BranchCheck1 (); - if (!CheckZero ()) - { - CPU.PC = CPU.PCBase + OpAddress; + Relative(JUMP, OpAddressPassthrough); + BranchCheck1(); + if (!CheckZero()) + { + CPU.PC = CPU.PCBase + OpAddress; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif - CPUShutdown (); - } + CPUShutdown(); + } #ifndef SA1_OPCODES - else - { - CPU.Cycles += CPU.MemSpeed; - } + else + CPU.Cycles += CPU.MemSpeed; #endif } /* BPL */ -static void Op10 (void) +static void Op10(void) { - Relative (JUMP, OpAddressPassthrough); - BranchCheck1 (); - if (!CheckNegative ()) - { - CPU.PC = CPU.PCBase + OpAddress; + Relative(JUMP, OpAddressPassthrough); + BranchCheck1(); + if (!CheckNegative()) + { + CPU.PC = CPU.PCBase + OpAddress; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif - CPUShutdown (); - } + CPUShutdown(); + } #ifndef SA1_OPCODES - else - { - CPU.Cycles += CPU.MemSpeed; - } + else + CPU.Cycles += CPU.MemSpeed; #endif } /* BRA */ -static void Op80 (void) +static void Op80(void) { - Relative (JUMP, OpAddressPassthrough); - CPU.PC = CPU.PCBase + OpAddress; + Relative(JUMP, OpAddressPassthrough); + CPU.PC = CPU.PCBase + OpAddress; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif - CPUShutdown (); + CPUShutdown(); } /* BVC */ -static void Op50 (void) +static void Op50(void) { - Relative (JUMP, OpAddressPassthrough); - BranchCheck0 (); - if (!CheckOverflow ()) - { - CPU.PC = CPU.PCBase + OpAddress; + Relative(JUMP, OpAddressPassthrough); + BranchCheck0(); + if (!CheckOverflow()) + { + CPU.PC = CPU.PCBase + OpAddress; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif - CPUShutdown (); - } + CPUShutdown(); + } #ifndef SA1_OPCODES - else - { - CPU.Cycles += CPU.MemSpeed; - } + else + CPU.Cycles += CPU.MemSpeed; #endif } /* BVS */ -static void Op70 (void) +static void Op70(void) { - Relative (JUMP, OpAddressPassthrough); - BranchCheck0 (); - if (CheckOverflow ()) - { - CPU.PC = CPU.PCBase + OpAddress; + Relative(JUMP, OpAddressPassthrough); + BranchCheck0(); + if (CheckOverflow()) + { + CPU.PC = CPU.PCBase + OpAddress; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; #endif - CPUShutdown (); - } + CPUShutdown(); + } #ifndef SA1_OPCODES - else - { - CPU.Cycles += CPU.MemSpeed; - } + else + CPU.Cycles += CPU.MemSpeed; #endif } /**********************************************************************************************/ /* ClearFlag Instructions ******************************************************************** */ /* CLC */ -static void Op18 (void) +static void Op18(void) { - ClearCarry (); + ClearCarry(); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif } /* CLD */ -static void OpD8 (void) +static void OpD8(void) { - ClearDecimal (); + ClearDecimal(); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif } /* CLI */ -static void Op58 (void) +static void Op58(void) { - ClearIRQ (); + ClearIRQ(); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif -/* CHECK_FOR_IRQ(); */ + /* CHECK_FOR_IRQ(); */ } /* CLV */ -static void OpB8 (void) +static void OpB8(void) { - ClearOverflow (); + ClearOverflow(); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif } /**********************************************************************************************/ /* DEX/DEY *********************************************************************************** */ -static void OpCAX1 (void) +static void OpCAX1(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif #ifdef CPU_SHUTDOWN - CPU.WaitAddress = NULL; + CPU.WaitAddress = NULL; #endif - ICPU.Registers.XL--; - SetZN8 (ICPU.Registers.XL); + ICPU.Registers.XL--; + SetZN8(ICPU.Registers.XL); } -static void OpCAX0 (void) +static void OpCAX0(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif #ifdef CPU_SHUTDOWN - CPU.WaitAddress = NULL; + CPU.WaitAddress = NULL; #endif - ICPU.Registers.X.W--; - SetZN16 (ICPU.Registers.X.W); + ICPU.Registers.X.W--; + SetZN16(ICPU.Registers.X.W); } -static void Op88X1 (void) +static void Op88X1(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif #ifdef CPU_SHUTDOWN - CPU.WaitAddress = NULL; + CPU.WaitAddress = NULL; #endif - ICPU.Registers.YL--; - SetZN8 (ICPU.Registers.YL); + ICPU.Registers.YL--; + SetZN8(ICPU.Registers.YL); } -static void Op88X0 (void) +static void Op88X0(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif #ifdef CPU_SHUTDOWN - CPU.WaitAddress = NULL; + CPU.WaitAddress = NULL; #endif - ICPU.Registers.Y.W--; - SetZN16 (ICPU.Registers.Y.W); + ICPU.Registers.Y.W--; + SetZN16(ICPU.Registers.Y.W); } /**********************************************************************************************/ /* INX/INY *********************************************************************************** */ -static void OpE8X1 (void) +static void OpE8X1(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif #ifdef CPU_SHUTDOWN - CPU.WaitAddress = NULL; + CPU.WaitAddress = NULL; #endif - ICPU.Registers.XL++; - SetZN8 (ICPU.Registers.XL); + ICPU.Registers.XL++; + SetZN8(ICPU.Registers.XL); } -static void OpE8X0 (void) +static void OpE8X0(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif #ifdef CPU_SHUTDOWN - CPU.WaitAddress = NULL; + CPU.WaitAddress = NULL; #endif - ICPU.Registers.X.W++; - SetZN16 (ICPU.Registers.X.W); + ICPU.Registers.X.W++; + SetZN16(ICPU.Registers.X.W); } -static void OpC8X1 (void) +static void OpC8X1(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif #ifdef CPU_SHUTDOWN - CPU.WaitAddress = NULL; + CPU.WaitAddress = NULL; #endif - ICPU.Registers.YL++; - SetZN8 (ICPU.Registers.YL); + ICPU.Registers.YL++; + SetZN8(ICPU.Registers.YL); } -static void OpC8X0 (void) +static void OpC8X0(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif #ifdef CPU_SHUTDOWN - CPU.WaitAddress = NULL; + CPU.WaitAddress = NULL; #endif - ICPU.Registers.Y.W++; - SetZN16 (ICPU.Registers.Y.W); + ICPU.Registers.Y.W++; + SetZN16(ICPU.Registers.Y.W); } /**********************************************************************************************/ /* NOP *************************************************************************************** */ -static void OpEA (void) +static void OpEA(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif } /**********************************************************************************************/ @@ -3755,1268 +3739,1272 @@ static void OpEA (void) /* PUSH Instructions ************************************************************************* */ /* #define PushW(w) \ * S9xSetWord (w, ICPU.Registers.S.W - 1);\ - * ICPU.Registers.S.W -= 2; + * ICPU.Registers.S.W -= 2; */ #define PushB(b)\ S9xSetByte (b, ICPU.Registers.S.W--); #define PushBE(b)\ - S9xSetByte (b, ICPU.Registers.S.W--);\ - ICPU.Registers.SH=0x01; + S9xSetByte (b, ICPU.Registers.S.W--);\ + ICPU.Registers.SH=0x01; #define PushW(w) \ S9xSetByte ((w)>>8, ICPU.Registers.S.W);\ - S9xSetByte ((w)&0xff, (ICPU.Registers.S.W - 1)&0xFFFF);\ + S9xSetByte ((w)&0xff, (ICPU.Registers.S.W - 1)&0xFFFF);\ ICPU.Registers.S.W -= 2; #define PushWE(w) \ S9xSetByte ((w)>>8, ICPU.Registers.S.W--);\ - ICPU.Registers.SH=0x01;\ - S9xSetByte ((w)&0xff, (ICPU.Registers.S.W--)&0xFFFF);\ + ICPU.Registers.SH=0x01;\ + S9xSetByte ((w)&0xff, (ICPU.Registers.S.W--)&0xFFFF);\ ICPU.Registers.SH = 0x01; #define PushWENew(w) \ S9xSetByte ((w)>>8, ICPU.Registers.S.W--);\ - S9xSetByte ((w)&0xff, (ICPU.Registers.S.W--)&0xFFFF);\ + S9xSetByte ((w)&0xff, (ICPU.Registers.S.W--)&0xFFFF);\ ICPU.Registers.SH = 0x01; //PEA NL -static void OpF4E1 (void) +static void OpF4E1(void) { - Absolute (NONE, OpAddressPassthrough); + Absolute(NONE, OpAddressPassthrough); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif - PushWENew ((unsigned short)OpAddress); + PushWENew((unsigned short)OpAddress); } -static void OpF4 (void) +static void OpF4(void) { - Absolute (NONE, OpAddressPassthrough); + Absolute(NONE, OpAddressPassthrough); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif - PushW ((unsigned short)OpAddress); + PushW((unsigned short)OpAddress); } //PEI NL -static void OpD4E1 (void) +static void OpD4E1(void) { - DirectIndirect (NONE, OpAddressPassthrough); + DirectIndirect(NONE, OpAddressPassthrough); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif - PushWENew ((unsigned short)OpAddress); + PushWENew((unsigned short)OpAddress); } -static void OpD4 (void) +static void OpD4(void) { - DirectIndirect (NONE, OpAddressPassthrough); + DirectIndirect(NONE, OpAddressPassthrough); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeed; #endif - PushW ((unsigned short)OpAddress); + PushW((unsigned short)OpAddress); } //PER NL -static void Op62E1 (void) +static void Op62E1(void) { - RelativeLong (NONE, OpAddressPassthrough); + RelativeLong(NONE, OpAddressPassthrough); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeedx2 + ONE_CYCLE; #endif - PushWENew ((unsigned short)OpAddress); + PushWENew((unsigned short)OpAddress); } -static void Op62 (void) +static void Op62(void) { - RelativeLong (NONE, OpAddressPassthrough); + RelativeLong(NONE, OpAddressPassthrough); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeedx2 + ONE_CYCLE; #endif - PushW ((unsigned short)OpAddress); + PushW((unsigned short)OpAddress); } //PHA -static void Op48E1 (void) +static void Op48E1(void) { - PushBE (ICPU.Registers.AL); + PushBE(ICPU.Registers.AL); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif } -static void Op48M1 (void) +static void Op48M1(void) { - PushB (ICPU.Registers.AL); + PushB(ICPU.Registers.AL); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif } -static void Op48M0 (void) +static void Op48M0(void) { - PushW (ICPU.Registers.A.W); + PushW(ICPU.Registers.A.W); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif } //PHB -static void Op8BE1 (void) +static void Op8BE1(void) { - PushBE (ICPU.Registers.DB); + PushBE(ICPU.Registers.DB); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif } -static void Op8B (void) +static void Op8B(void) { - PushB (ICPU.Registers.DB); + PushB(ICPU.Registers.DB); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif } //PHD NL -static void Op0BE1 (void) +static void Op0BE1(void) { - PushWENew (ICPU.Registers.D.W); + PushWENew(ICPU.Registers.D.W); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif } -static void Op0B (void) +static void Op0B(void) { - PushW (ICPU.Registers.D.W); + PushW(ICPU.Registers.D.W); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif } //PHK -static void Op4BE1 (void) +static void Op4BE1(void) { - PushBE (ICPU.Registers.PB); + PushBE(ICPU.Registers.PB); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif } -static void Op4B (void) +static void Op4B(void) { - PushB (ICPU.Registers.PB); + PushB(ICPU.Registers.PB); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif } //PHP -static void Op08E1 (void) +static void Op08E1(void) { - S9xPackStatus (); - PushBE (ICPU.Registers.PL); + S9xPackStatus(); + PushBE(ICPU.Registers.PL); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif } -static void Op08 (void) +static void Op08(void) { - S9xPackStatus (); - PushB (ICPU.Registers.PL); + S9xPackStatus(); + PushB(ICPU.Registers.PL); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif } //PHX -static void OpDAE1 (void) +static void OpDAE1(void) { - PushBE (ICPU.Registers.XL); + PushBE(ICPU.Registers.XL); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif } -static void OpDAX1 (void) +static void OpDAX1(void) { - PushB (ICPU.Registers.XL); + PushB(ICPU.Registers.XL); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif } -static void OpDAX0 (void) +static void OpDAX0(void) { - PushW (ICPU.Registers.X.W); + PushW(ICPU.Registers.X.W); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif } //PHY -static void Op5AE1 (void) +static void Op5AE1(void) { - PushBE (ICPU.Registers.YL); + PushBE(ICPU.Registers.YL); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif } -static void Op5AX1 (void) +static void Op5AX1(void) { - PushB (ICPU.Registers.YL); + PushB(ICPU.Registers.YL); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif } -static void Op5AX0 (void) +static void Op5AX0(void) { - PushW (ICPU.Registers.Y.W); + PushW(ICPU.Registers.Y.W); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif } /**********************************************************************************************/ /* PULL Instructions ************************************************************************* */ #define PullW(w) \ - w = S9xGetByte (++ICPU.Registers.S.W); \ - w |= (S9xGetByte (++ICPU.Registers.S.W)<<8); + w = S9xGetByte (++ICPU.Registers.S.W); \ + w |= (S9xGetByte (++ICPU.Registers.S.W)<<8); -/* w = S9xGetWord (ICPU.Registers.S.W + 1); \ - ICPU.Registers.S.W += 2; +/* w = S9xGetWord (ICPU.Registers.S.W + 1); \ + ICPU.Registers.S.W += 2; */ #define PullB(b)\ - b = S9xGetByte (++ICPU.Registers.S.W); + b = S9xGetByte (++ICPU.Registers.S.W); #define PullBE(b)\ - ICPU.Registers.S.W++;\ - ICPU.Registers.SH=0x01;\ - b = S9xGetByte (ICPU.Registers.S.W); + ICPU.Registers.S.W++;\ + ICPU.Registers.SH=0x01;\ + b = S9xGetByte (ICPU.Registers.S.W); #define PullWE(w) \ - ICPU.Registers.S.W++;\ - ICPU.Registers.SH=0x01;\ - w = S9xGetByte (ICPU.Registers.S.W); \ - ICPU.Registers.S.W++; \ - ICPU.Registers.SH=0x01;\ - w |= (S9xGetByte (ICPU.Registers.S.W)<<8); + ICPU.Registers.S.W++;\ + ICPU.Registers.SH=0x01;\ + w = S9xGetByte (ICPU.Registers.S.W); \ + ICPU.Registers.S.W++; \ + ICPU.Registers.SH=0x01;\ + w |= (S9xGetByte (ICPU.Registers.S.W)<<8); #define PullWENew(w) \ - PullW(w);\ - ICPU.Registers.SH=0x01; + PullW(w);\ + ICPU.Registers.SH=0x01; //PLA -static void Op68E1 (void) +static void Op68E1(void) { #ifndef SA1_OPCODES - CPU.Cycles += TWO_CYCLES; + CPU.Cycles += TWO_CYCLES; #endif - PullBE (ICPU.Registers.AL); - SetZN8 (ICPU.Registers.AL); + PullBE(ICPU.Registers.AL); + SetZN8(ICPU.Registers.AL); } -static void Op68M1 (void) +static void Op68M1(void) { #ifndef SA1_OPCODES - CPU.Cycles += TWO_CYCLES; + CPU.Cycles += TWO_CYCLES; #endif - PullB (ICPU.Registers.AL); - SetZN8 (ICPU.Registers.AL); + PullB(ICPU.Registers.AL); + SetZN8(ICPU.Registers.AL); } -static void Op68M0 (void) +static void Op68M0(void) { #ifndef SA1_OPCODES - CPU.Cycles += TWO_CYCLES; + CPU.Cycles += TWO_CYCLES; #endif - PullW (ICPU.Registers.A.W); - SetZN16 (ICPU.Registers.A.W); + PullW(ICPU.Registers.A.W); + SetZN16(ICPU.Registers.A.W); } //PLB -static void OpABE1 (void) +static void OpABE1(void) { #ifndef SA1_OPCODES - CPU.Cycles += TWO_CYCLES; + CPU.Cycles += TWO_CYCLES; #endif - PullBE (ICPU.Registers.DB); - SetZN8 (ICPU.Registers.DB); - ICPU.ShiftedDB = ICPU.Registers.DB << 16; + PullBE(ICPU.Registers.DB); + SetZN8(ICPU.Registers.DB); + ICPU.ShiftedDB = ICPU.Registers.DB << 16; } -static void OpAB (void) +static void OpAB(void) { #ifndef SA1_OPCODES - CPU.Cycles += TWO_CYCLES; + CPU.Cycles += TWO_CYCLES; #endif - PullB (ICPU.Registers.DB); - SetZN8 (ICPU.Registers.DB); - ICPU.ShiftedDB = ICPU.Registers.DB << 16; + PullB(ICPU.Registers.DB); + SetZN8(ICPU.Registers.DB); + ICPU.ShiftedDB = ICPU.Registers.DB << 16; } /* PHP */ //PLD NL -static void Op2BE1 (void) +static void Op2BE1(void) { #ifndef SA1_OPCODES - CPU.Cycles += TWO_CYCLES; + CPU.Cycles += TWO_CYCLES; #endif - PullWENew (ICPU.Registers.D.W); - SetZN16 (ICPU.Registers.D.W); + PullWENew(ICPU.Registers.D.W); + SetZN16(ICPU.Registers.D.W); } -static void Op2B (void) +static void Op2B(void) { #ifndef SA1_OPCODES - CPU.Cycles += TWO_CYCLES; + CPU.Cycles += TWO_CYCLES; #endif - PullW (ICPU.Registers.D.W); - SetZN16 (ICPU.Registers.D.W); + PullW(ICPU.Registers.D.W); + SetZN16(ICPU.Registers.D.W); } /* PLP */ -static void Op28E1 (void) +static void Op28E1(void) { #ifndef SA1_OPCODES - CPU.Cycles += TWO_CYCLES; + CPU.Cycles += TWO_CYCLES; #endif - PullBE (ICPU.Registers.PL); - S9xUnpackStatus (); + PullBE(ICPU.Registers.PL); + S9xUnpackStatus(); - if (CheckIndex ()) - { - ICPU.Registers.XH = 0; - ICPU.Registers.YH = 0; - } - S9xFixCycles(); -/* CHECK_FOR_IRQ();*/ + if (CheckIndex()) + { + ICPU.Registers.XH = 0; + ICPU.Registers.YH = 0; + } + S9xFixCycles(); + /* CHECK_FOR_IRQ();*/ } -static void Op28 (void) +static void Op28(void) { #ifndef SA1_OPCODES - CPU.Cycles += TWO_CYCLES; + CPU.Cycles += TWO_CYCLES; #endif - PullB (ICPU.Registers.PL); - S9xUnpackStatus (); + PullB(ICPU.Registers.PL); + S9xUnpackStatus(); - if (CheckIndex ()) - { - ICPU.Registers.XH = 0; - ICPU.Registers.YH = 0; - } - S9xFixCycles(); -/* CHECK_FOR_IRQ();*/ + if (CheckIndex()) + { + ICPU.Registers.XH = 0; + ICPU.Registers.YH = 0; + } + S9xFixCycles(); + /* CHECK_FOR_IRQ();*/ } //PLX -static void OpFAE1 (void) +static void OpFAE1(void) { #ifndef SA1_OPCODES - CPU.Cycles += TWO_CYCLES; + CPU.Cycles += TWO_CYCLES; #endif - PullBE (ICPU.Registers.XL); - SetZN8 (ICPU.Registers.XL); + PullBE(ICPU.Registers.XL); + SetZN8(ICPU.Registers.XL); } -static void OpFAX1 (void) +static void OpFAX1(void) { #ifndef SA1_OPCODES - CPU.Cycles += TWO_CYCLES; + CPU.Cycles += TWO_CYCLES; #endif - PullB (ICPU.Registers.XL); - SetZN8 (ICPU.Registers.XL); + PullB(ICPU.Registers.XL); + SetZN8(ICPU.Registers.XL); } -static void OpFAX0 (void) +static void OpFAX0(void) { #ifndef SA1_OPCODES - CPU.Cycles += TWO_CYCLES; + CPU.Cycles += TWO_CYCLES; #endif - PullW (ICPU.Registers.X.W); - SetZN16 (ICPU.Registers.X.W); + PullW(ICPU.Registers.X.W); + SetZN16(ICPU.Registers.X.W); } //PLY -static void Op7AE1 (void) +static void Op7AE1(void) { #ifndef SA1_OPCODES - CPU.Cycles += TWO_CYCLES; + CPU.Cycles += TWO_CYCLES; #endif - PullBE (ICPU.Registers.YL); - SetZN8 (ICPU.Registers.YL); + PullBE(ICPU.Registers.YL); + SetZN8(ICPU.Registers.YL); } -static void Op7AX1 (void) +static void Op7AX1(void) { #ifndef SA1_OPCODES - CPU.Cycles += TWO_CYCLES; + CPU.Cycles += TWO_CYCLES; #endif - PullB (ICPU.Registers.YL); - SetZN8 (ICPU.Registers.YL); + PullB(ICPU.Registers.YL); + SetZN8(ICPU.Registers.YL); } -static void Op7AX0 (void) +static void Op7AX0(void) { #ifndef SA1_OPCODES - CPU.Cycles += TWO_CYCLES; + CPU.Cycles += TWO_CYCLES; #endif - PullW (ICPU.Registers.Y.W); - SetZN16 (ICPU.Registers.Y.W); + PullW(ICPU.Registers.Y.W); + SetZN16(ICPU.Registers.Y.W); } /**********************************************************************************************/ /* SetFlag Instructions ********************************************************************** */ /* SEC */ -static void Op38 (void) +static void Op38(void) { - SetCarry (); + SetCarry(); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif } /* SED */ -static void OpF8 (void) +static void OpF8(void) { - SetDecimal (); + SetDecimal(); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - missing.decimal_mode = 1; + missing.decimal_mode = 1; } /* SEI */ -static void Op78 (void) +static void Op78(void) { - SetIRQ (); + SetIRQ(); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif } /**********************************************************************************************/ /* Transfer Instructions ********************************************************************* */ /* TAX8 */ -static void OpAAX1 (void) +static void OpAAX1(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - ICPU.Registers.XL = ICPU.Registers.AL; - SetZN8 (ICPU.Registers.XL); + ICPU.Registers.XL = ICPU.Registers.AL; + SetZN8(ICPU.Registers.XL); } /* TAX16 */ -static void OpAAX0 (void) +static void OpAAX0(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - ICPU.Registers.X.W = ICPU.Registers.A.W; - SetZN16 (ICPU.Registers.X.W); + ICPU.Registers.X.W = ICPU.Registers.A.W; + SetZN16(ICPU.Registers.X.W); } /* TAY8 */ -static void OpA8X1 (void) +static void OpA8X1(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - ICPU.Registers.YL = ICPU.Registers.AL; - SetZN8 (ICPU.Registers.YL); + ICPU.Registers.YL = ICPU.Registers.AL; + SetZN8(ICPU.Registers.YL); } /* TAY16 */ -static void OpA8X0 (void) +static void OpA8X0(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - ICPU.Registers.Y.W = ICPU.Registers.A.W; - SetZN16 (ICPU.Registers.Y.W); + ICPU.Registers.Y.W = ICPU.Registers.A.W; + SetZN16(ICPU.Registers.Y.W); } -static void Op5B (void) +static void Op5B(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - ICPU.Registers.D.W = ICPU.Registers.A.W; - SetZN16 (ICPU.Registers.D.W); + ICPU.Registers.D.W = ICPU.Registers.A.W; + SetZN16(ICPU.Registers.D.W); } -static void Op1B (void) +static void Op1B(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - ICPU.Registers.S.W = ICPU.Registers.A.W; - if (CheckEmulation()) - ICPU.Registers.SH = 1; + ICPU.Registers.S.W = ICPU.Registers.A.W; + if (CheckEmulation()) + ICPU.Registers.SH = 1; } -static void Op7B (void) +static void Op7B(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - ICPU.Registers.A.W = ICPU.Registers.D.W; - SetZN16 (ICPU.Registers.A.W); + ICPU.Registers.A.W = ICPU.Registers.D.W; + SetZN16(ICPU.Registers.A.W); } -static void Op3B (void) +static void Op3B(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - ICPU.Registers.A.W = ICPU.Registers.S.W; - SetZN16 (ICPU.Registers.A.W); + ICPU.Registers.A.W = ICPU.Registers.S.W; + SetZN16(ICPU.Registers.A.W); } -static void OpBAX1 (void) +static void OpBAX1(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - ICPU.Registers.XL = ICPU.Registers.SL; - SetZN8 (ICPU.Registers.XL); + ICPU.Registers.XL = ICPU.Registers.SL; + SetZN8(ICPU.Registers.XL); } -static void OpBAX0 (void) +static void OpBAX0(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - ICPU.Registers.X.W = ICPU.Registers.S.W; - SetZN16 (ICPU.Registers.X.W); + ICPU.Registers.X.W = ICPU.Registers.S.W; + SetZN16(ICPU.Registers.X.W); } -static void Op8AM1 (void) +static void Op8AM1(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - ICPU.Registers.AL = ICPU.Registers.XL; - SetZN8 (ICPU.Registers.AL); + ICPU.Registers.AL = ICPU.Registers.XL; + SetZN8(ICPU.Registers.AL); } -static void Op8AM0 (void) +static void Op8AM0(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - ICPU.Registers.A.W = ICPU.Registers.X.W; - SetZN16 (ICPU.Registers.A.W); + ICPU.Registers.A.W = ICPU.Registers.X.W; + SetZN16(ICPU.Registers.A.W); } -static void Op9A (void) +static void Op9A(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - ICPU.Registers.S.W = ICPU.Registers.X.W; - if (CheckEmulation()) - ICPU.Registers.SH = 1; + ICPU.Registers.S.W = ICPU.Registers.X.W; + if (CheckEmulation()) + ICPU.Registers.SH = 1; } -static void Op9BX1 (void) +static void Op9BX1(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - ICPU.Registers.YL = ICPU.Registers.XL; - SetZN8 (ICPU.Registers.YL); + ICPU.Registers.YL = ICPU.Registers.XL; + SetZN8(ICPU.Registers.YL); } -static void Op9BX0 (void) +static void Op9BX0(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - ICPU.Registers.Y.W = ICPU.Registers.X.W; - SetZN16 (ICPU.Registers.Y.W); + ICPU.Registers.Y.W = ICPU.Registers.X.W; + SetZN16(ICPU.Registers.Y.W); } -static void Op98M1 (void) +static void Op98M1(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - ICPU.Registers.AL = ICPU.Registers.YL; - SetZN8 (ICPU.Registers.AL); + ICPU.Registers.AL = ICPU.Registers.YL; + SetZN8(ICPU.Registers.AL); } -static void Op98M0 (void) +static void Op98M0(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - ICPU.Registers.A.W = ICPU.Registers.Y.W; - SetZN16 (ICPU.Registers.A.W); + ICPU.Registers.A.W = ICPU.Registers.Y.W; + SetZN16(ICPU.Registers.A.W); } -static void OpBBX1 (void) +static void OpBBX1(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - ICPU.Registers.XL = ICPU.Registers.YL; - SetZN8 (ICPU.Registers.XL); + ICPU.Registers.XL = ICPU.Registers.YL; + SetZN8(ICPU.Registers.XL); } -static void OpBBX0 (void) +static void OpBBX0(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - ICPU.Registers.X.W = ICPU.Registers.Y.W; - SetZN16 (ICPU.Registers.X.W); + ICPU.Registers.X.W = ICPU.Registers.Y.W; + SetZN16(ICPU.Registers.X.W); } /**********************************************************************************************/ /* XCE *************************************************************************************** */ -static void OpFB (void) +static void OpFB(void) { #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - uint8 A1 = ICPU._Carry; - uint8 A2 = ICPU.Registers.PH; - ICPU._Carry = A2 & 1; - ICPU.Registers.PH = A1; + uint8 A1 = ICPU._Carry; + uint8 A2 = ICPU.Registers.PH; + ICPU._Carry = A2 & 1; + ICPU.Registers.PH = A1; - if (CheckEmulation()) - { - SetFlags (MemoryFlag | IndexFlag); - ICPU.Registers.SH = 1; - missing.emulate6502 = 1; - } - if (CheckIndex ()) - { - ICPU.Registers.XH = 0; - ICPU.Registers.YH = 0; - } - S9xFixCycles(); + if (CheckEmulation()) + { + SetFlags(MemoryFlag | IndexFlag); + ICPU.Registers.SH = 1; + missing.emulate6502 = 1; + } + if (CheckIndex()) + { + ICPU.Registers.XH = 0; + ICPU.Registers.YH = 0; + } + S9xFixCycles(); } /**********************************************************************************************/ /* BRK *************************************************************************************** */ -static void Op00 (void) +static void Op00(void) { #ifndef SA1_OPCODES - CPU.BRKTriggered = TRUE; + CPU.BRKTriggered = TRUE; #endif - if (!CheckEmulation()) - { - PushB (ICPU.Registers.PB); - PushW (CPU.PC - CPU.PCBase + 1); - S9xPackStatus (); - PushB (ICPU.Registers.PL); - OpenBus = ICPU.Registers.PL; - ClearDecimal (); - SetIRQ (); + if (!CheckEmulation()) + { + PushB(ICPU.Registers.PB); + PushW(CPU.PC - CPU.PCBase + 1); + S9xPackStatus(); + PushB(ICPU.Registers.PL); + OpenBus = ICPU.Registers.PL; + ClearDecimal(); + SetIRQ(); - ICPU.Registers.PB = 0; - ICPU.ShiftedPB = 0; - S9xSetPCBase (S9xGetWord (0xFFE6)); + ICPU.Registers.PB = 0; + ICPU.ShiftedPB = 0; + S9xSetPCBase(S9xGetWord(0xFFE6)); #ifndef SA1_OPCODES - CPU.Cycles += TWO_CYCLES; + CPU.Cycles += TWO_CYCLES; #endif - } - else - { - PushW (CPU.PC - CPU.PCBase); - S9xPackStatus (); - PushB (ICPU.Registers.PL); - OpenBus = ICPU.Registers.PL; - ClearDecimal (); - SetIRQ (); + } + else + { + PushW(CPU.PC - CPU.PCBase); + S9xPackStatus(); + PushB(ICPU.Registers.PL); + OpenBus = ICPU.Registers.PL; + ClearDecimal(); + SetIRQ(); - ICPU.Registers.PB = 0; - ICPU.ShiftedPB = 0; - S9xSetPCBase (S9xGetWord (0xFFFE)); + ICPU.Registers.PB = 0; + ICPU.ShiftedPB = 0; + S9xSetPCBase(S9xGetWord(0xFFFE)); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; + CPU.Cycles += ONE_CYCLE; #endif - } + } } /**********************************************************************************************/ /* BRL ************************************************************************************** */ -static void Op82 (void) +static void Op82(void) { - RelativeLong (JUMP, OpAddressPassthrough); + RelativeLong(JUMP, OpAddressPassthrough); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeedx2 + ONE_CYCLE; #endif - S9xSetPCBase (ICPU.ShiftedPB + OpAddress); + S9xSetPCBase(ICPU.ShiftedPB + OpAddress); } /**********************************************************************************************/ /* IRQ *************************************************************************************** */ -void S9xOpcode_IRQ (void) -{ - if (!CheckEmulation()) - { - PushB (ICPU.Registers.PB); - PushW (CPU.PC - CPU.PCBase); - S9xPackStatus (); - PushB (ICPU.Registers.PL); - OpenBus = ICPU.Registers.PL; - ClearDecimal (); - SetIRQ (); - - ICPU.Registers.PB = 0; - ICPU.ShiftedPB = 0; +void S9xOpcode_IRQ(void) +{ + if (!CheckEmulation()) + { + PushB(ICPU.Registers.PB); + PushW(CPU.PC - CPU.PCBase); + S9xPackStatus(); + PushB(ICPU.Registers.PL); + OpenBus = ICPU.Registers.PL; + ClearDecimal(); + SetIRQ(); + + ICPU.Registers.PB = 0; + ICPU.ShiftedPB = 0; #ifdef SA1_OPCODES - S9xSA1SetPCBase (Memory.FillRAM [0x2207] | - (Memory.FillRAM [0x2208] << 8)); + S9xSA1SetPCBase(Memory.FillRAM [0x2207] | + (Memory.FillRAM [0x2208] << 8)); #else - if (Settings.SA1 && (Memory.FillRAM [0x2209] & 0x40)) - S9xSetPCBase (Memory.FillRAM [0x220e] | - (Memory.FillRAM [0x220f] << 8)); - else - S9xSetPCBase (S9xGetWord (0xFFEE)); - CPU.Cycles += TWO_CYCLES; -#endif - } - else - { - PushW (CPU.PC - CPU.PCBase); - S9xPackStatus (); - PushB (ICPU.Registers.PL); - OpenBus = ICPU.Registers.PL; - ClearDecimal (); - SetIRQ (); - - ICPU.Registers.PB = 0; - ICPU.ShiftedPB = 0; + if (Settings.SA1 && (Memory.FillRAM [0x2209] & 0x40)) + S9xSetPCBase(Memory.FillRAM [0x220e] | + (Memory.FillRAM [0x220f] << 8)); + else + S9xSetPCBase(S9xGetWord(0xFFEE)); + CPU.Cycles += TWO_CYCLES; +#endif + } + else + { + PushW(CPU.PC - CPU.PCBase); + S9xPackStatus(); + PushB(ICPU.Registers.PL); + OpenBus = ICPU.Registers.PL; + ClearDecimal(); + SetIRQ(); + + ICPU.Registers.PB = 0; + ICPU.ShiftedPB = 0; #ifdef SA1_OPCODES - S9xSA1SetPCBase (Memory.FillRAM [0x2207] | - (Memory.FillRAM [0x2208] << 8)); + S9xSA1SetPCBase(Memory.FillRAM [0x2207] | + (Memory.FillRAM [0x2208] << 8)); #else - if (Settings.SA1 && (Memory.FillRAM [0x2209] & 0x40)) - S9xSetPCBase (Memory.FillRAM [0x220e] | - (Memory.FillRAM [0x220f] << 8)); - else - S9xSetPCBase (S9xGetWord (0xFFFE)); - CPU.Cycles += ONE_CYCLE; + if (Settings.SA1 && (Memory.FillRAM [0x2209] & 0x40)) + S9xSetPCBase(Memory.FillRAM [0x220e] | + (Memory.FillRAM [0x220f] << 8)); + else + S9xSetPCBase(S9xGetWord(0xFFFE)); + CPU.Cycles += ONE_CYCLE; #endif - } + } } /**********************************************************************************************/ /* NMI *************************************************************************************** */ -void S9xOpcode_NMI (void) -{ - if (!CheckEmulation()) - { - PushB (ICPU.Registers.PB); - PushW (CPU.PC - CPU.PCBase); - S9xPackStatus (); - PushB (ICPU.Registers.PL); - OpenBus = ICPU.Registers.PL; - ClearDecimal (); - SetIRQ (); - - ICPU.Registers.PB = 0; - ICPU.ShiftedPB = 0; +void S9xOpcode_NMI(void) +{ + if (!CheckEmulation()) + { + PushB(ICPU.Registers.PB); + PushW(CPU.PC - CPU.PCBase); + S9xPackStatus(); + PushB(ICPU.Registers.PL); + OpenBus = ICPU.Registers.PL; + ClearDecimal(); + SetIRQ(); + + ICPU.Registers.PB = 0; + ICPU.ShiftedPB = 0; #ifdef SA1_OPCODES - S9xSA1SetPCBase (Memory.FillRAM [0x2205] | - (Memory.FillRAM [0x2206] << 8)); + S9xSA1SetPCBase(Memory.FillRAM [0x2205] | + (Memory.FillRAM [0x2206] << 8)); #else - if (Settings.SA1 && (Memory.FillRAM [0x2209] & 0x20)) - S9xSetPCBase (Memory.FillRAM [0x220c] | - (Memory.FillRAM [0x220d] << 8)); - else - S9xSetPCBase (S9xGetWord (0xFFEA)); - CPU.Cycles += TWO_CYCLES; -#endif - } - else - { - PushW (CPU.PC - CPU.PCBase); - S9xPackStatus (); - PushB (ICPU.Registers.PL); - OpenBus = ICPU.Registers.PL; - ClearDecimal (); - SetIRQ (); - - ICPU.Registers.PB = 0; - ICPU.ShiftedPB = 0; + if (Settings.SA1 && (Memory.FillRAM [0x2209] & 0x20)) + S9xSetPCBase(Memory.FillRAM [0x220c] | + (Memory.FillRAM [0x220d] << 8)); + else + S9xSetPCBase(S9xGetWord(0xFFEA)); + CPU.Cycles += TWO_CYCLES; +#endif + } + else + { + PushW(CPU.PC - CPU.PCBase); + S9xPackStatus(); + PushB(ICPU.Registers.PL); + OpenBus = ICPU.Registers.PL; + ClearDecimal(); + SetIRQ(); + + ICPU.Registers.PB = 0; + ICPU.ShiftedPB = 0; #ifdef SA1_OPCODES - S9xSA1SetPCBase (Memory.FillRAM [0x2205] | - (Memory.FillRAM [0x2206] << 8)); + S9xSA1SetPCBase(Memory.FillRAM [0x2205] | + (Memory.FillRAM [0x2206] << 8)); #else - if (Settings.SA1 && (Memory.FillRAM [0x2209] & 0x20)) - S9xSetPCBase (Memory.FillRAM [0x220c] | - (Memory.FillRAM [0x220d] << 8)); - else - S9xSetPCBase (S9xGetWord (0xFFFA)); - CPU.Cycles += ONE_CYCLE; + if (Settings.SA1 && (Memory.FillRAM [0x2209] & 0x20)) + S9xSetPCBase(Memory.FillRAM [0x220c] | + (Memory.FillRAM [0x220d] << 8)); + else + S9xSetPCBase(S9xGetWord(0xFFFA)); + CPU.Cycles += ONE_CYCLE; #endif - } + } } /**********************************************************************************************/ /* COP *************************************************************************************** */ -static void Op02 (void) -{ - if (!CheckEmulation()) - { - PushB (ICPU.Registers.PB); - PushW (CPU.PC - CPU.PCBase + 1); - S9xPackStatus (); - PushB (ICPU.Registers.PL); - OpenBus = ICPU.Registers.PL; - ClearDecimal (); - SetIRQ (); - - ICPU.Registers.PB = 0; - ICPU.ShiftedPB = 0; - S9xSetPCBase (S9xGetWord (0xFFE4)); -#ifndef SA1_OPCODES - CPU.Cycles += TWO_CYCLES; -#endif - } - else - { - PushW (CPU.PC - CPU.PCBase); - S9xPackStatus (); - PushB (ICPU.Registers.PL); - OpenBus = ICPU.Registers.PL; - ClearDecimal (); - SetIRQ (); - - ICPU.Registers.PB = 0; - ICPU.ShiftedPB = 0; - S9xSetPCBase (S9xGetWord (0xFFF4)); -#ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE; -#endif - } +static void Op02(void) +{ + if (!CheckEmulation()) + { + PushB(ICPU.Registers.PB); + PushW(CPU.PC - CPU.PCBase + 1); + S9xPackStatus(); + PushB(ICPU.Registers.PL); + OpenBus = ICPU.Registers.PL; + ClearDecimal(); + SetIRQ(); + + ICPU.Registers.PB = 0; + ICPU.ShiftedPB = 0; + S9xSetPCBase(S9xGetWord(0xFFE4)); +#ifndef SA1_OPCODES + CPU.Cycles += TWO_CYCLES; +#endif + } + else + { + PushW(CPU.PC - CPU.PCBase); + S9xPackStatus(); + PushB(ICPU.Registers.PL); + OpenBus = ICPU.Registers.PL; + ClearDecimal(); + SetIRQ(); + + ICPU.Registers.PB = 0; + ICPU.ShiftedPB = 0; + S9xSetPCBase(S9xGetWord(0xFFF4)); +#ifndef SA1_OPCODES + CPU.Cycles += ONE_CYCLE; +#endif + } } /**********************************************************************************************/ /* JML *************************************************************************************** */ -static void OpDC (void) +static void OpDC(void) { - AbsoluteIndirectLong (JUMP, OpAddressPassthrough); + AbsoluteIndirectLong(JUMP, OpAddressPassthrough); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + TWO_CYCLES; + CPU.Cycles += CPU.MemSpeedx2 + TWO_CYCLES; #endif - ICPU.Registers.PB = (uint8) (OpAddress >> 16); - ICPU.ShiftedPB = OpAddress & 0xff0000; - S9xSetPCBase (OpAddress); + ICPU.Registers.PB = (uint8)(OpAddress >> 16); + ICPU.ShiftedPB = OpAddress & 0xff0000; + S9xSetPCBase(OpAddress); } -static void Op5C (void) +static void Op5C(void) { - AbsoluteLong (JUMP, OpAddressPassthrough); + AbsoluteLong(JUMP, OpAddressPassthrough); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif - ICPU.Registers.PB = (uint8) (OpAddress >> 16); - ICPU.ShiftedPB = OpAddress & 0xff0000; - S9xSetPCBase (OpAddress); + ICPU.Registers.PB = (uint8)(OpAddress >> 16); + ICPU.ShiftedPB = OpAddress & 0xff0000; + S9xSetPCBase(OpAddress); } /**********************************************************************************************/ /* JMP *************************************************************************************** */ -static void Op4C (void) +static void Op4C(void) { - Absolute (JUMP, OpAddressPassthrough); + Absolute(JUMP, OpAddressPassthrough); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif - S9xSetPCBase (ICPU.ShiftedPB + (OpAddress & 0xffff)); + S9xSetPCBase(ICPU.ShiftedPB + (OpAddress & 0xffff)); #if defined(CPU_SHUTDOWN) && defined(SA1_OPCODES) - CPUShutdown (); + CPUShutdown(); #endif } -static void Op6C (void) +static void Op6C(void) { - AbsoluteIndirect (JUMP, OpAddressPassthrough); + AbsoluteIndirect(JUMP, OpAddressPassthrough); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2; + CPU.Cycles += CPU.MemSpeedx2; #endif - S9xSetPCBase (ICPU.ShiftedPB + (OpAddress & 0xffff)); + S9xSetPCBase(ICPU.ShiftedPB + (OpAddress & 0xffff)); } -static void Op7C (void) +static void Op7C(void) { - AbsoluteIndexedIndirect (JUMP, OpAddressPassthrough); + AbsoluteIndexedIndirect(JUMP, OpAddressPassthrough); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeedx2 + ONE_CYCLE; #endif - S9xSetPCBase (ICPU.ShiftedPB + OpAddress); + S9xSetPCBase(ICPU.ShiftedPB + OpAddress); } /**********************************************************************************************/ /* JSL/RTL *********************************************************************************** */ -static void Op22E1 (void) +static void Op22E1(void) { - AbsoluteLong (JUMP, OpAddressPassthrough); + AbsoluteLong(JUMP, OpAddressPassthrough); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif - PushB (ICPU.Registers.PB); - PushWENew (CPU.PC - CPU.PCBase - 1); - ICPU.Registers.PB = (uint8) (OpAddress >> 16); - ICPU.ShiftedPB = OpAddress & 0xff0000; - S9xSetPCBase (OpAddress); + PushB(ICPU.Registers.PB); + PushWENew(CPU.PC - CPU.PCBase - 1); + ICPU.Registers.PB = (uint8)(OpAddress >> 16); + ICPU.ShiftedPB = OpAddress & 0xff0000; + S9xSetPCBase(OpAddress); } -static void Op22 (void) +static void Op22(void) { - AbsoluteLong (JUMP, OpAddressPassthrough); + AbsoluteLong(JUMP, OpAddressPassthrough); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; + CPU.Cycles += CPU.MemSpeedx2 + CPU.MemSpeed; #endif - PushB (ICPU.Registers.PB); - PushW (CPU.PC - CPU.PCBase - 1); - ICPU.Registers.PB = (uint8) (OpAddress >> 16); - ICPU.ShiftedPB = OpAddress & 0xff0000; - S9xSetPCBase (OpAddress); + PushB(ICPU.Registers.PB); + PushW(CPU.PC - CPU.PCBase - 1); + ICPU.Registers.PB = (uint8)(OpAddress >> 16); + ICPU.ShiftedPB = OpAddress & 0xff0000; + S9xSetPCBase(OpAddress); } -static void Op6BE1 (void) +static void Op6BE1(void) { - PullWENew (ICPU.Registers.PC); - PullB (ICPU.Registers.PB); - ICPU.ShiftedPB = ICPU.Registers.PB << 16; - S9xSetPCBase (ICPU.ShiftedPB + ((ICPU.Registers.PC + 1) & 0xffff)); + PullWENew(ICPU.Registers.PC); + PullB(ICPU.Registers.PB); + ICPU.ShiftedPB = ICPU.Registers.PB << 16; + S9xSetPCBase(ICPU.ShiftedPB + ((ICPU.Registers.PC + 1) & 0xffff)); #ifndef SA1_OPCODES - CPU.Cycles += TWO_CYCLES; + CPU.Cycles += TWO_CYCLES; #endif } -static void Op6B (void) +static void Op6B(void) { - PullW (ICPU.Registers.PC); - PullB (ICPU.Registers.PB); - ICPU.ShiftedPB = ICPU.Registers.PB << 16; - S9xSetPCBase (ICPU.ShiftedPB + ((ICPU.Registers.PC + 1) & 0xffff)); + PullW(ICPU.Registers.PC); + PullB(ICPU.Registers.PB); + ICPU.ShiftedPB = ICPU.Registers.PB << 16; + S9xSetPCBase(ICPU.ShiftedPB + ((ICPU.Registers.PC + 1) & 0xffff)); #ifndef SA1_OPCODES - CPU.Cycles += TWO_CYCLES; + CPU.Cycles += TWO_CYCLES; #endif } /**********************************************************************************************/ /* JSR/RTS *********************************************************************************** */ -static void Op20 (void) +static void Op20(void) { - Absolute (JUMP, OpAddressPassthrough); + Absolute(JUMP, OpAddressPassthrough); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeedx2 + ONE_CYCLE; #endif - PushW (CPU.PC - CPU.PCBase - 1); - S9xSetPCBase (ICPU.ShiftedPB + (OpAddress & 0xffff)); + PushW(CPU.PC - CPU.PCBase - 1); + S9xSetPCBase(ICPU.ShiftedPB + (OpAddress & 0xffff)); } //JSR a,x -static void OpFCE1 (void) +static void OpFCE1(void) { - AbsoluteIndexedIndirect (JUMP, OpAddressPassthrough); + AbsoluteIndexedIndirect(JUMP, OpAddressPassthrough); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeedx2 + ONE_CYCLE; #endif - PushWENew (CPU.PC - CPU.PCBase - 1); - S9xSetPCBase (ICPU.ShiftedPB + OpAddress); + PushWENew(CPU.PC - CPU.PCBase - 1); + S9xSetPCBase(ICPU.ShiftedPB + OpAddress); } -static void OpFC (void) +static void OpFC(void) { - AbsoluteIndexedIndirect (JUMP, OpAddressPassthrough); + AbsoluteIndexedIndirect(JUMP, OpAddressPassthrough); #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + ONE_CYCLE; + CPU.Cycles += CPU.MemSpeedx2 + ONE_CYCLE; #endif - PushW (CPU.PC - CPU.PCBase - 1); - S9xSetPCBase (ICPU.ShiftedPB + OpAddress); + PushW(CPU.PC - CPU.PCBase - 1); + S9xSetPCBase(ICPU.ShiftedPB + OpAddress); } -static void Op60 (void) +static void Op60(void) { - PullW (ICPU.Registers.PC); - S9xSetPCBase (ICPU.ShiftedPB + ((ICPU.Registers.PC + 1) & 0xffff)); + PullW(ICPU.Registers.PC); + S9xSetPCBase(ICPU.ShiftedPB + ((ICPU.Registers.PC + 1) & 0xffff)); #ifndef SA1_OPCODES - CPU.Cycles += ONE_CYCLE * 3; + CPU.Cycles += ONE_CYCLE * 3; #endif } /**********************************************************************************************/ /* MVN/MVP *********************************************************************************** */ -static void Op54X1 (void) +static void Op54X1(void) { - uint32 SrcBank; + uint32 SrcBank; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + TWO_CYCLES; + CPU.Cycles += CPU.MemSpeedx2 + TWO_CYCLES; #endif - - ICPU.Registers.DB = *CPU.PC++; - ICPU.ShiftedDB = ICPU.Registers.DB << 16; - OpenBus = SrcBank = *CPU.PC++; - S9xSetByte (S9xGetByte ((SrcBank << 16) + ICPU.Registers.X.W), - ICPU.ShiftedDB + ICPU.Registers.Y.W); + ICPU.Registers.DB = *CPU.PC++; + ICPU.ShiftedDB = ICPU.Registers.DB << 16; + OpenBus = SrcBank = *CPU.PC++; - ICPU.Registers.XL++; - ICPU.Registers.YL++; - ICPU.Registers.A.W--; - if (ICPU.Registers.A.W != 0xffff) - CPU.PC -= 3; + S9xSetByte(S9xGetByte((SrcBank << 16) + ICPU.Registers.X.W), + ICPU.ShiftedDB + ICPU.Registers.Y.W); + + ICPU.Registers.XL++; + ICPU.Registers.YL++; + ICPU.Registers.A.W--; + if (ICPU.Registers.A.W != 0xffff) + CPU.PC -= 3; } -static void Op54X0 (void) +static void Op54X0(void) { - uint32 SrcBank; + uint32 SrcBank; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + TWO_CYCLES; + CPU.Cycles += CPU.MemSpeedx2 + TWO_CYCLES; #endif - - ICPU.Registers.DB = *CPU.PC++; - ICPU.ShiftedDB = ICPU.Registers.DB << 16; - OpenBus = SrcBank = *CPU.PC++; - S9xSetByte (S9xGetByte ((SrcBank << 16) + ICPU.Registers.X.W), - ICPU.ShiftedDB + ICPU.Registers.Y.W); + ICPU.Registers.DB = *CPU.PC++; + ICPU.ShiftedDB = ICPU.Registers.DB << 16; + OpenBus = SrcBank = *CPU.PC++; + + S9xSetByte(S9xGetByte((SrcBank << 16) + ICPU.Registers.X.W), + ICPU.ShiftedDB + ICPU.Registers.Y.W); - ICPU.Registers.X.W++; - ICPU.Registers.Y.W++; - ICPU.Registers.A.W--; - if (ICPU.Registers.A.W != 0xffff) - CPU.PC -= 3; + ICPU.Registers.X.W++; + ICPU.Registers.Y.W++; + ICPU.Registers.A.W--; + if (ICPU.Registers.A.W != 0xffff) + CPU.PC -= 3; } -static void Op44X1 (void) +static void Op44X1(void) { - uint32 SrcBank; + uint32 SrcBank; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + TWO_CYCLES; -#endif - ICPU.Registers.DB = *CPU.PC++; - ICPU.ShiftedDB = ICPU.Registers.DB << 16; - OpenBus = SrcBank = *CPU.PC++; - S9xSetByte (S9xGetByte ((SrcBank << 16) + ICPU.Registers.X.W), - ICPU.ShiftedDB + ICPU.Registers.Y.W); + CPU.Cycles += CPU.MemSpeedx2 + TWO_CYCLES; +#endif + ICPU.Registers.DB = *CPU.PC++; + ICPU.ShiftedDB = ICPU.Registers.DB << 16; + OpenBus = SrcBank = *CPU.PC++; + S9xSetByte(S9xGetByte((SrcBank << 16) + ICPU.Registers.X.W), + ICPU.ShiftedDB + ICPU.Registers.Y.W); - ICPU.Registers.XL--; - ICPU.Registers.YL--; - ICPU.Registers.A.W--; - if (ICPU.Registers.A.W != 0xffff) - CPU.PC -= 3; + ICPU.Registers.XL--; + ICPU.Registers.YL--; + ICPU.Registers.A.W--; + if (ICPU.Registers.A.W != 0xffff) + CPU.PC -= 3; } -static void Op44X0 (void) +static void Op44X0(void) { - uint32 SrcBank; + uint32 SrcBank; #ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeedx2 + TWO_CYCLES; -#endif - ICPU.Registers.DB = *CPU.PC++; - ICPU.ShiftedDB = ICPU.Registers.DB << 16; - OpenBus = SrcBank = *CPU.PC++; - S9xSetByte (S9xGetByte ((SrcBank << 16) + ICPU.Registers.X.W), - ICPU.ShiftedDB + ICPU.Registers.Y.W); + CPU.Cycles += CPU.MemSpeedx2 + TWO_CYCLES; +#endif + ICPU.Registers.DB = *CPU.PC++; + ICPU.ShiftedDB = ICPU.Registers.DB << 16; + OpenBus = SrcBank = *CPU.PC++; + S9xSetByte(S9xGetByte((SrcBank << 16) + ICPU.Registers.X.W), + ICPU.ShiftedDB + ICPU.Registers.Y.W); - ICPU.Registers.X.W--; - ICPU.Registers.Y.W--; - ICPU.Registers.A.W--; - if (ICPU.Registers.A.W != 0xffff) - CPU.PC -= 3; + ICPU.Registers.X.W--; + ICPU.Registers.Y.W--; + ICPU.Registers.A.W--; + if (ICPU.Registers.A.W != 0xffff) + CPU.PC -= 3; } /**********************************************************************************************/ /* REP/SEP *********************************************************************************** */ -static void OpC2 (void) -{ - uint8 Work8 = ~*CPU.PC++; - ICPU.Registers.PL &= Work8; - ICPU._Carry &= Work8; - ICPU._Overflow &= (Work8 >> 6); - ICPU._Negative &= Work8; - ICPU._Zero |= ~Work8 & Zero; - -#ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -#endif - if (CheckEmulation()) - { - SetFlags (MemoryFlag | IndexFlag); - missing.emulate6502 = 1; - } - if (CheckIndex ()) - { - ICPU.Registers.XH = 0; - ICPU.Registers.YH = 0; - } - S9xFixCycles(); -/* CHECK_FOR_IRQ(); */ -} - -static void OpE2 (void) -{ - uint8 Work8 = *CPU.PC++; - ICPU.Registers.PL |= Work8; - ICPU._Carry |= Work8 & 1; - ICPU._Overflow |= (Work8 >> 6) & 1; - ICPU._Negative |= Work8; - if (Work8 & Zero) - ICPU._Zero = 0; -#ifndef SA1_OPCODES - CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; -#endif - if (CheckEmulation()) - { - SetFlags (MemoryFlag | IndexFlag); - missing.emulate6502 = 1; - } - if (CheckIndex ()) - { - ICPU.Registers.XH = 0; - ICPU.Registers.YH = 0; - } - S9xFixCycles(); +static void OpC2(void) +{ + uint8 Work8 = ~*CPU.PC++; + ICPU.Registers.PL &= Work8; + ICPU._Carry &= Work8; + ICPU._Overflow &= (Work8 >> 6); + ICPU._Negative &= Work8; + ICPU._Zero |= ~Work8 & Zero; + +#ifndef SA1_OPCODES + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; +#endif + if (CheckEmulation()) + { + SetFlags(MemoryFlag | IndexFlag); + missing.emulate6502 = 1; + } + if (CheckIndex()) + { + ICPU.Registers.XH = 0; + ICPU.Registers.YH = 0; + } + S9xFixCycles(); + /* CHECK_FOR_IRQ(); */ +} + +static void OpE2(void) +{ + uint8 Work8 = *CPU.PC++; + ICPU.Registers.PL |= Work8; + ICPU._Carry |= Work8 & 1; + ICPU._Overflow |= (Work8 >> 6) & 1; + ICPU._Negative |= Work8; + if (Work8 & Zero) + ICPU._Zero = 0; +#ifndef SA1_OPCODES + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; +#endif + if (CheckEmulation()) + { + SetFlags(MemoryFlag | IndexFlag); + missing.emulate6502 = 1; + } + if (CheckIndex()) + { + ICPU.Registers.XH = 0; + ICPU.Registers.YH = 0; + } + S9xFixCycles(); } /**********************************************************************************************/ /* XBA *************************************************************************************** */ -static void OpEB (void) +static void OpEB(void) { - uint8 Work8 = ICPU.Registers.AL; - ICPU.Registers.AL = ICPU.Registers.AH; - ICPU.Registers.AH = Work8; + uint8 Work8 = ICPU.Registers.AL; + ICPU.Registers.AL = ICPU.Registers.AH; + ICPU.Registers.AH = Work8; - SetZN8 (ICPU.Registers.AL); + SetZN8(ICPU.Registers.AL); #ifndef SA1_OPCODES - CPU.Cycles += TWO_CYCLES; + CPU.Cycles += TWO_CYCLES; #endif } /**********************************************************************************************/ /* RTI *************************************************************************************** */ -static void Op40 (void) -{ - PullB (ICPU.Registers.PL); - S9xUnpackStatus (); - PullW (ICPU.Registers.PC); - if (!CheckEmulation()) - { - PullB (ICPU.Registers.PB); - ICPU.ShiftedPB = ICPU.Registers.PB << 16; - } - else - { - SetFlags (MemoryFlag | IndexFlag); - missing.emulate6502 = 1; - } - S9xSetPCBase (ICPU.ShiftedPB + ICPU.Registers.PC); - if (CheckIndex ()) - { - ICPU.Registers.XH = 0; - ICPU.Registers.YH = 0; - } -#ifndef SA1_OPCODES - CPU.Cycles += TWO_CYCLES; -#endif - S9xFixCycles(); -/* CHECK_FOR_IRQ(); */ +static void Op40(void) +{ + PullB(ICPU.Registers.PL); + S9xUnpackStatus(); + PullW(ICPU.Registers.PC); + if (!CheckEmulation()) + { + PullB(ICPU.Registers.PB); + ICPU.ShiftedPB = ICPU.Registers.PB << 16; + } + else + { + SetFlags(MemoryFlag | IndexFlag); + missing.emulate6502 = 1; + } + S9xSetPCBase(ICPU.ShiftedPB + ICPU.Registers.PC); + if (CheckIndex()) + { + ICPU.Registers.XH = 0; + ICPU.Registers.YH = 0; + } +#ifndef SA1_OPCODES + CPU.Cycles += TWO_CYCLES; +#endif + S9xFixCycles(); + /* CHECK_FOR_IRQ(); */ } /**********************************************************************************************/ /* STP/WAI/DB ******************************************************************************** */ // WAI -static void OpCB (void) +static void OpCB(void) { -// Ok, let's just C-ify the ASM versions separately. + // Ok, let's just C-ify the ASM versions separately. #ifdef SA1_OPCODES - SA1.WaitingForInterrupt = TRUE; - SA1.PC--; + SA1.WaitingForInterrupt = TRUE; + SA1.PC--; #if 0 -// XXX: FIXME - if(Settings.Shutdown){ - SA1.Cycles = SA1.NextEvent; - if (IAPU.APUExecuting) - { - SA1.Executing = FALSE; - do - { - APU_EXECUTE1 (, } while (APU.Cycles < SA1.NextEvent, SA1.Executing = TRUE; - } - } + // XXX: FIXME + if (Settings.Shutdown) + { + SA1.Cycles = SA1.NextEvent; + if (IAPU.APUExecuting) + { + SA1.Executing = FALSE; + do + { + APU_EXECUTE1(, + } + while (APU.Cycles < SA1.NextEvent, SA1.Executing = TRUE; + } +} #endif #else // SA1_OPCODES #if 0 - if (CPU.IRQActive) - { + if (CPU.IRQActive) + { #ifndef SA1_OPCODES - CPU.Cycles += TWO_CYCLES; + CPU.Cycles += TWO_CYCLES; #endif - } - else + } + else #endif - { - CPU.WaitingForInterrupt = TRUE; - CPU.PC--; + { + CPU.WaitingForInterrupt = TRUE; + CPU.PC--; #ifdef CPU_SHUTDOWN - if (Settings.Shutdown) - { - CPU.Cycles = CPU.NextEvent; - if (IAPU.APUExecuting) - { - ICPU.CPUExecuting = FALSE; - do - { - APU_EXECUTE1 (); - } while (APU.Cycles < CPU.NextEvent); - ICPU.CPUExecuting = TRUE; - } - } - else - { -#ifndef SA1_OPCODES - CPU.Cycles += TWO_CYCLES; + if (Settings.Shutdown) + { + CPU.Cycles = CPU.NextEvent; + if (IAPU.APUExecuting) + { + ICPU.CPUExecuting = FALSE; + do + { + APU_EXECUTE1(); + } + while (APU.Cycles < CPU.NextEvent); + ICPU.CPUExecuting = TRUE; + } + } + else + { +#ifndef SA1_OPCODES + CPU.Cycles += TWO_CYCLES; #endif - } + } #endif - } + } #endif // SA1_OPCODES } // STP -static void OpDB (void) +static void OpDB(void) { - CPU.PC--; - CPU.Flags |= DEBUG_MODE_FLAG; + CPU.PC--; + CPU.Flags |= DEBUG_MODE_FLAG; } // Reserved S9xOpcode -static void Op42 (void) +static void Op42(void) { } @@ -5027,281 +5015,281 @@ static void Op42 (void) /*****************************************************************************/ SOpcodes S9xOpcodesM1X1[256] = { - {Op00}, {Op01M1}, {Op02}, {Op03M1}, {Op04M1}, - {Op05M1}, {Op06M1}, {Op07M1}, {Op08}, {Op09M1}, - {Op0AM1}, {Op0B}, {Op0CM1}, {Op0DM1}, {Op0EM1}, - {Op0FM1}, {Op10}, {Op11M1}, {Op12M1}, {Op13M1}, - {Op14M1}, {Op15M1}, {Op16M1}, {Op17M1}, {Op18}, - {Op19M1}, {Op1AM1}, {Op1B}, {Op1CM1}, {Op1DM1}, - {Op1EM1}, {Op1FM1}, {Op20}, {Op21M1}, {Op22}, - {Op23M1}, {Op24M1}, {Op25M1}, {Op26M1}, {Op27M1}, - {Op28}, {Op29M1}, {Op2AM1}, {Op2B}, {Op2CM1}, - {Op2DM1}, {Op2EM1}, {Op2FM1}, {Op30}, {Op31M1}, - {Op32M1}, {Op33M1}, {Op34M1}, {Op35M1}, {Op36M1}, - {Op37M1}, {Op38}, {Op39M1}, {Op3AM1}, {Op3B}, - {Op3CM1}, {Op3DM1}, {Op3EM1}, {Op3FM1}, {Op40}, - {Op41M1}, {Op42}, {Op43M1}, {Op44X1}, {Op45M1}, - {Op46M1}, {Op47M1}, {Op48M1}, {Op49M1}, {Op4AM1}, - {Op4B}, {Op4C}, {Op4DM1}, {Op4EM1}, {Op4FM1}, - {Op50}, {Op51M1}, {Op52M1}, {Op53M1}, {Op54X1}, - {Op55M1}, {Op56M1}, {Op57M1}, {Op58}, {Op59M1}, - {Op5AX1}, {Op5B}, {Op5C}, {Op5DM1}, {Op5EM1}, - {Op5FM1}, {Op60}, {Op61M1}, {Op62}, {Op63M1}, - {Op64M1}, {Op65M1}, {Op66M1}, {Op67M1}, {Op68M1}, - {Op69M1}, {Op6AM1}, {Op6B}, {Op6C}, {Op6DM1}, - {Op6EM1}, {Op6FM1}, {Op70}, {Op71M1}, {Op72M1}, - {Op73M1}, {Op74M1}, {Op75M1}, {Op76M1}, {Op77M1}, - {Op78}, {Op79M1}, {Op7AX1}, {Op7B}, {Op7C}, - {Op7DM1}, {Op7EM1}, {Op7FM1}, {Op80}, {Op81M1}, - {Op82}, {Op83M1}, {Op84X1}, {Op85M1}, {Op86X1}, - {Op87M1}, {Op88X1}, {Op89M1}, {Op8AM1}, {Op8B}, - {Op8CX1}, {Op8DM1}, {Op8EX1}, {Op8FM1}, {Op90}, - {Op91M1}, {Op92M1}, {Op93M1}, {Op94X1}, {Op95M1}, - {Op96X1}, {Op97M1}, {Op98M1}, {Op99M1}, {Op9A}, - {Op9BX1}, {Op9CM1}, {Op9DM1}, {Op9EM1}, {Op9FM1}, - {OpA0X1}, {OpA1M1}, {OpA2X1}, {OpA3M1}, {OpA4X1}, - {OpA5M1}, {OpA6X1}, {OpA7M1}, {OpA8X1}, {OpA9M1}, - {OpAAX1}, {OpAB}, {OpACX1}, {OpADM1}, {OpAEX1}, - {OpAFM1}, {OpB0}, {OpB1M1}, {OpB2M1}, {OpB3M1}, - {OpB4X1}, {OpB5M1}, {OpB6X1}, {OpB7M1}, {OpB8}, - {OpB9M1}, {OpBAX1}, {OpBBX1}, {OpBCX1}, {OpBDM1}, - {OpBEX1}, {OpBFM1}, {OpC0X1}, {OpC1M1}, {OpC2}, - {OpC3M1}, {OpC4X1}, {OpC5M1}, {OpC6M1}, {OpC7M1}, - {OpC8X1}, {OpC9M1}, {OpCAX1}, {OpCB}, {OpCCX1}, - {OpCDM1}, {OpCEM1}, {OpCFM1}, {OpD0}, {OpD1M1}, - {OpD2M1}, {OpD3M1}, {OpD4}, {OpD5M1}, {OpD6M1}, - {OpD7M1}, {OpD8}, {OpD9M1}, {OpDAX1}, {OpDB}, - {OpDC}, {OpDDM1}, {OpDEM1}, {OpDFM1}, {OpE0X1}, - {OpE1M1}, {OpE2}, {OpE3M1}, {OpE4X1}, {OpE5M1}, - {OpE6M1}, {OpE7M1}, {OpE8X1}, {OpE9M1}, {OpEA}, - {OpEB}, {OpECX1}, {OpEDM1}, {OpEEM1}, {OpEFM1}, - {OpF0}, {OpF1M1}, {OpF2M1}, {OpF3M1}, {OpF4}, - {OpF5M1}, {OpF6M1}, {OpF7M1}, {OpF8}, {OpF9M1}, - {OpFAX1}, {OpFB}, {OpFC}, {OpFDM1}, {OpFEM1}, - {OpFFM1} + {Op00}, {Op01M1}, {Op02}, {Op03M1}, {Op04M1}, + {Op05M1}, {Op06M1}, {Op07M1}, {Op08}, {Op09M1}, + {Op0AM1}, {Op0B}, {Op0CM1}, {Op0DM1}, {Op0EM1}, + {Op0FM1}, {Op10}, {Op11M1}, {Op12M1}, {Op13M1}, + {Op14M1}, {Op15M1}, {Op16M1}, {Op17M1}, {Op18}, + {Op19M1}, {Op1AM1}, {Op1B}, {Op1CM1}, {Op1DM1}, + {Op1EM1}, {Op1FM1}, {Op20}, {Op21M1}, {Op22}, + {Op23M1}, {Op24M1}, {Op25M1}, {Op26M1}, {Op27M1}, + {Op28}, {Op29M1}, {Op2AM1}, {Op2B}, {Op2CM1}, + {Op2DM1}, {Op2EM1}, {Op2FM1}, {Op30}, {Op31M1}, + {Op32M1}, {Op33M1}, {Op34M1}, {Op35M1}, {Op36M1}, + {Op37M1}, {Op38}, {Op39M1}, {Op3AM1}, {Op3B}, + {Op3CM1}, {Op3DM1}, {Op3EM1}, {Op3FM1}, {Op40}, + {Op41M1}, {Op42}, {Op43M1}, {Op44X1}, {Op45M1}, + {Op46M1}, {Op47M1}, {Op48M1}, {Op49M1}, {Op4AM1}, + {Op4B}, {Op4C}, {Op4DM1}, {Op4EM1}, {Op4FM1}, + {Op50}, {Op51M1}, {Op52M1}, {Op53M1}, {Op54X1}, + {Op55M1}, {Op56M1}, {Op57M1}, {Op58}, {Op59M1}, + {Op5AX1}, {Op5B}, {Op5C}, {Op5DM1}, {Op5EM1}, + {Op5FM1}, {Op60}, {Op61M1}, {Op62}, {Op63M1}, + {Op64M1}, {Op65M1}, {Op66M1}, {Op67M1}, {Op68M1}, + {Op69M1}, {Op6AM1}, {Op6B}, {Op6C}, {Op6DM1}, + {Op6EM1}, {Op6FM1}, {Op70}, {Op71M1}, {Op72M1}, + {Op73M1}, {Op74M1}, {Op75M1}, {Op76M1}, {Op77M1}, + {Op78}, {Op79M1}, {Op7AX1}, {Op7B}, {Op7C}, + {Op7DM1}, {Op7EM1}, {Op7FM1}, {Op80}, {Op81M1}, + {Op82}, {Op83M1}, {Op84X1}, {Op85M1}, {Op86X1}, + {Op87M1}, {Op88X1}, {Op89M1}, {Op8AM1}, {Op8B}, + {Op8CX1}, {Op8DM1}, {Op8EX1}, {Op8FM1}, {Op90}, + {Op91M1}, {Op92M1}, {Op93M1}, {Op94X1}, {Op95M1}, + {Op96X1}, {Op97M1}, {Op98M1}, {Op99M1}, {Op9A}, + {Op9BX1}, {Op9CM1}, {Op9DM1}, {Op9EM1}, {Op9FM1}, + {OpA0X1}, {OpA1M1}, {OpA2X1}, {OpA3M1}, {OpA4X1}, + {OpA5M1}, {OpA6X1}, {OpA7M1}, {OpA8X1}, {OpA9M1}, + {OpAAX1}, {OpAB}, {OpACX1}, {OpADM1}, {OpAEX1}, + {OpAFM1}, {OpB0}, {OpB1M1}, {OpB2M1}, {OpB3M1}, + {OpB4X1}, {OpB5M1}, {OpB6X1}, {OpB7M1}, {OpB8}, + {OpB9M1}, {OpBAX1}, {OpBBX1}, {OpBCX1}, {OpBDM1}, + {OpBEX1}, {OpBFM1}, {OpC0X1}, {OpC1M1}, {OpC2}, + {OpC3M1}, {OpC4X1}, {OpC5M1}, {OpC6M1}, {OpC7M1}, + {OpC8X1}, {OpC9M1}, {OpCAX1}, {OpCB}, {OpCCX1}, + {OpCDM1}, {OpCEM1}, {OpCFM1}, {OpD0}, {OpD1M1}, + {OpD2M1}, {OpD3M1}, {OpD4}, {OpD5M1}, {OpD6M1}, + {OpD7M1}, {OpD8}, {OpD9M1}, {OpDAX1}, {OpDB}, + {OpDC}, {OpDDM1}, {OpDEM1}, {OpDFM1}, {OpE0X1}, + {OpE1M1}, {OpE2}, {OpE3M1}, {OpE4X1}, {OpE5M1}, + {OpE6M1}, {OpE7M1}, {OpE8X1}, {OpE9M1}, {OpEA}, + {OpEB}, {OpECX1}, {OpEDM1}, {OpEEM1}, {OpEFM1}, + {OpF0}, {OpF1M1}, {OpF2M1}, {OpF3M1}, {OpF4}, + {OpF5M1}, {OpF6M1}, {OpF7M1}, {OpF8}, {OpF9M1}, + {OpFAX1}, {OpFB}, {OpFC}, {OpFDM1}, {OpFEM1}, + {OpFFM1} }; SOpcodes S9xOpcodesE1[256] = { - {Op00}, {Op01M1}, {Op02}, {Op03M1}, {Op04M1}, - {Op05M1}, {Op06M1}, {Op07M1}, {Op08E1}, {Op09M1}, - {Op0AM1}, {Op0BE1}, {Op0CM1}, {Op0DM1}, {Op0EM1}, - {Op0FM1}, {Op10}, {Op11M1}, {Op12M1}, {Op13M1}, - {Op14M1}, {Op15M1}, {Op16M1}, {Op17M1}, {Op18}, - {Op19M1}, {Op1AM1}, {Op1B}, {Op1CM1}, {Op1DM1}, - {Op1EM1}, {Op1FM1}, {Op20}, {Op21M1}, {Op22E1}, - {Op23M1}, {Op24M1}, {Op25M1}, {Op26M1}, {Op27M1}, - {Op28}, {Op29M1}, {Op2AM1}, {Op2BE1}, {Op2CM1}, - {Op2DM1}, {Op2EM1}, {Op2FM1}, {Op30}, {Op31M1}, - {Op32M1}, {Op33M1}, {Op34M1}, {Op35M1}, {Op36M1}, - {Op37M1}, {Op38}, {Op39M1}, {Op3AM1}, {Op3B}, - {Op3CM1}, {Op3DM1}, {Op3EM1}, {Op3FM1}, {Op40}, - {Op41M1}, {Op42}, {Op43M1}, {Op44X1}, {Op45M1}, - {Op46M1}, {Op47M1}, {Op48E1}, {Op49M1}, {Op4AM1}, - {Op4BE1}, {Op4C}, {Op4DM1}, {Op4EM1}, {Op4FM1}, - {Op50}, {Op51M1}, {Op52M1}, {Op53M1}, {Op54X1}, - {Op55M1}, {Op56M1}, {Op57M1}, {Op58}, {Op59M1}, - {Op5AE1}, {Op5B}, {Op5C}, {Op5DM1}, {Op5EM1}, - {Op5FM1}, {Op60}, {Op61M1}, {Op62E1}, {Op63M1}, - {Op64M1}, {Op65M1}, {Op66M1}, {Op67M1}, {Op68E1}, - {Op69M1}, {Op6AM1}, {Op6BE1}, {Op6C}, {Op6DM1}, - {Op6EM1}, {Op6FM1}, {Op70}, {Op71M1}, {Op72M1}, - {Op73M1}, {Op74M1}, {Op75M1}, {Op76M1}, {Op77M1}, - {Op78}, {Op79M1}, {Op7AE1}, {Op7B}, {Op7C}, - {Op7DM1}, {Op7EM1}, {Op7FM1}, {Op80}, {Op81M1}, - {Op82}, {Op83M1}, {Op84X1}, {Op85M1}, {Op86X1}, - {Op87M1}, {Op88X1}, {Op89M1}, {Op8AM1}, {Op8BE1}, - {Op8CX1}, {Op8DM1}, {Op8EX1}, {Op8FM1}, {Op90}, - {Op91M1}, {Op92M1}, {Op93M1}, {Op94X1}, {Op95M1}, - {Op96X1}, {Op97M1}, {Op98M1}, {Op99M1}, {Op9A}, - {Op9BX1}, {Op9CM1}, {Op9DM1}, {Op9EM1}, {Op9FM1}, - {OpA0X1}, {OpA1M1}, {OpA2X1}, {OpA3M1}, {OpA4X1}, - {OpA5M1}, {OpA6X1}, {OpA7M1}, {OpA8X1}, {OpA9M1}, - {OpAAX1}, {OpABE1}, {OpACX1}, {OpADM1}, {OpAEX1}, - {OpAFM1}, {OpB0}, {OpB1M1}, {OpB2M1}, {OpB3M1}, - {OpB4X1}, {OpB5M1}, {OpB6X1}, {OpB7M1}, {OpB8}, - {OpB9M1}, {OpBAX1}, {OpBBX1}, {OpBCX1}, {OpBDM1}, - {OpBEX1}, {OpBFM1}, {OpC0X1}, {OpC1M1}, {OpC2}, - {OpC3M1}, {OpC4X1}, {OpC5M1}, {OpC6M1}, {OpC7M1}, - {OpC8X1}, {OpC9M1}, {OpCAX1}, {OpCB}, {OpCCX1}, - {OpCDM1}, {OpCEM1}, {OpCFM1}, {OpD0}, {OpD1M1}, - {OpD2M1}, {OpD3M1}, {OpD4E1}, {OpD5M1}, {OpD6M1}, - {OpD7M1}, {OpD8}, {OpD9M1}, {OpDAE1}, {OpDB}, - {OpDC}, {OpDDM1}, {OpDEM1}, {OpDFM1}, {OpE0X1}, - {OpE1M1}, {OpE2}, {OpE3M1}, {OpE4X1}, {OpE5M1}, - {OpE6M1}, {OpE7M1}, {OpE8X1}, {OpE9M1}, {OpEA}, - {OpEB}, {OpECX1}, {OpEDM1}, {OpEEM1}, {OpEFM1}, - {OpF0}, {OpF1M1}, {OpF2M1}, {OpF3M1}, {OpF4E1}, - {OpF5M1}, {OpF6M1}, {OpF7M1}, {OpF8}, {OpF9M1}, - {OpFAE1}, {OpFB}, {OpFCE1}, {OpFDM1}, {OpFEM1}, - {OpFFM1} + {Op00}, {Op01M1}, {Op02}, {Op03M1}, {Op04M1}, + {Op05M1}, {Op06M1}, {Op07M1}, {Op08E1}, {Op09M1}, + {Op0AM1}, {Op0BE1}, {Op0CM1}, {Op0DM1}, {Op0EM1}, + {Op0FM1}, {Op10}, {Op11M1}, {Op12M1}, {Op13M1}, + {Op14M1}, {Op15M1}, {Op16M1}, {Op17M1}, {Op18}, + {Op19M1}, {Op1AM1}, {Op1B}, {Op1CM1}, {Op1DM1}, + {Op1EM1}, {Op1FM1}, {Op20}, {Op21M1}, {Op22E1}, + {Op23M1}, {Op24M1}, {Op25M1}, {Op26M1}, {Op27M1}, + {Op28}, {Op29M1}, {Op2AM1}, {Op2BE1}, {Op2CM1}, + {Op2DM1}, {Op2EM1}, {Op2FM1}, {Op30}, {Op31M1}, + {Op32M1}, {Op33M1}, {Op34M1}, {Op35M1}, {Op36M1}, + {Op37M1}, {Op38}, {Op39M1}, {Op3AM1}, {Op3B}, + {Op3CM1}, {Op3DM1}, {Op3EM1}, {Op3FM1}, {Op40}, + {Op41M1}, {Op42}, {Op43M1}, {Op44X1}, {Op45M1}, + {Op46M1}, {Op47M1}, {Op48E1}, {Op49M1}, {Op4AM1}, + {Op4BE1}, {Op4C}, {Op4DM1}, {Op4EM1}, {Op4FM1}, + {Op50}, {Op51M1}, {Op52M1}, {Op53M1}, {Op54X1}, + {Op55M1}, {Op56M1}, {Op57M1}, {Op58}, {Op59M1}, + {Op5AE1}, {Op5B}, {Op5C}, {Op5DM1}, {Op5EM1}, + {Op5FM1}, {Op60}, {Op61M1}, {Op62E1}, {Op63M1}, + {Op64M1}, {Op65M1}, {Op66M1}, {Op67M1}, {Op68E1}, + {Op69M1}, {Op6AM1}, {Op6BE1}, {Op6C}, {Op6DM1}, + {Op6EM1}, {Op6FM1}, {Op70}, {Op71M1}, {Op72M1}, + {Op73M1}, {Op74M1}, {Op75M1}, {Op76M1}, {Op77M1}, + {Op78}, {Op79M1}, {Op7AE1}, {Op7B}, {Op7C}, + {Op7DM1}, {Op7EM1}, {Op7FM1}, {Op80}, {Op81M1}, + {Op82}, {Op83M1}, {Op84X1}, {Op85M1}, {Op86X1}, + {Op87M1}, {Op88X1}, {Op89M1}, {Op8AM1}, {Op8BE1}, + {Op8CX1}, {Op8DM1}, {Op8EX1}, {Op8FM1}, {Op90}, + {Op91M1}, {Op92M1}, {Op93M1}, {Op94X1}, {Op95M1}, + {Op96X1}, {Op97M1}, {Op98M1}, {Op99M1}, {Op9A}, + {Op9BX1}, {Op9CM1}, {Op9DM1}, {Op9EM1}, {Op9FM1}, + {OpA0X1}, {OpA1M1}, {OpA2X1}, {OpA3M1}, {OpA4X1}, + {OpA5M1}, {OpA6X1}, {OpA7M1}, {OpA8X1}, {OpA9M1}, + {OpAAX1}, {OpABE1}, {OpACX1}, {OpADM1}, {OpAEX1}, + {OpAFM1}, {OpB0}, {OpB1M1}, {OpB2M1}, {OpB3M1}, + {OpB4X1}, {OpB5M1}, {OpB6X1}, {OpB7M1}, {OpB8}, + {OpB9M1}, {OpBAX1}, {OpBBX1}, {OpBCX1}, {OpBDM1}, + {OpBEX1}, {OpBFM1}, {OpC0X1}, {OpC1M1}, {OpC2}, + {OpC3M1}, {OpC4X1}, {OpC5M1}, {OpC6M1}, {OpC7M1}, + {OpC8X1}, {OpC9M1}, {OpCAX1}, {OpCB}, {OpCCX1}, + {OpCDM1}, {OpCEM1}, {OpCFM1}, {OpD0}, {OpD1M1}, + {OpD2M1}, {OpD3M1}, {OpD4E1}, {OpD5M1}, {OpD6M1}, + {OpD7M1}, {OpD8}, {OpD9M1}, {OpDAE1}, {OpDB}, + {OpDC}, {OpDDM1}, {OpDEM1}, {OpDFM1}, {OpE0X1}, + {OpE1M1}, {OpE2}, {OpE3M1}, {OpE4X1}, {OpE5M1}, + {OpE6M1}, {OpE7M1}, {OpE8X1}, {OpE9M1}, {OpEA}, + {OpEB}, {OpECX1}, {OpEDM1}, {OpEEM1}, {OpEFM1}, + {OpF0}, {OpF1M1}, {OpF2M1}, {OpF3M1}, {OpF4E1}, + {OpF5M1}, {OpF6M1}, {OpF7M1}, {OpF8}, {OpF9M1}, + {OpFAE1}, {OpFB}, {OpFCE1}, {OpFDM1}, {OpFEM1}, + {OpFFM1} }; SOpcodes S9xOpcodesM1X0[256] = { - {Op00}, {Op01M1}, {Op02}, {Op03M1}, {Op04M1}, - {Op05M1}, {Op06M1}, {Op07M1}, {Op08}, {Op09M1}, - {Op0AM1}, {Op0B}, {Op0CM1}, {Op0DM1}, {Op0EM1}, - {Op0FM1}, {Op10}, {Op11M1}, {Op12M1}, {Op13M1}, - {Op14M1}, {Op15M1}, {Op16M1}, {Op17M1}, {Op18}, - {Op19M1}, {Op1AM1}, {Op1B}, {Op1CM1}, {Op1DM1}, - {Op1EM1}, {Op1FM1}, {Op20}, {Op21M1}, {Op22}, - {Op23M1}, {Op24M1}, {Op25M1}, {Op26M1}, {Op27M1}, - {Op28}, {Op29M1}, {Op2AM1}, {Op2B}, {Op2CM1}, - {Op2DM1}, {Op2EM1}, {Op2FM1}, {Op30}, {Op31M1}, - {Op32M1}, {Op33M1}, {Op34M1}, {Op35M1}, {Op36M1}, - {Op37M1}, {Op38}, {Op39M1}, {Op3AM1}, {Op3B}, - {Op3CM1}, {Op3DM1}, {Op3EM1}, {Op3FM1}, {Op40}, - {Op41M1}, {Op42}, {Op43M1}, {Op44X0}, {Op45M1}, - {Op46M1}, {Op47M1}, {Op48M1}, {Op49M1}, {Op4AM1}, - {Op4B}, {Op4C}, {Op4DM1}, {Op4EM1}, {Op4FM1}, - {Op50}, {Op51M1}, {Op52M1}, {Op53M1}, {Op54X0}, - {Op55M1}, {Op56M1}, {Op57M1}, {Op58}, {Op59M1}, - {Op5AX0}, {Op5B}, {Op5C}, {Op5DM1}, {Op5EM1}, - {Op5FM1}, {Op60}, {Op61M1}, {Op62}, {Op63M1}, - {Op64M1}, {Op65M1}, {Op66M1}, {Op67M1}, {Op68M1}, - {Op69M1}, {Op6AM1}, {Op6B}, {Op6C}, {Op6DM1}, - {Op6EM1}, {Op6FM1}, {Op70}, {Op71M1}, {Op72M1}, - {Op73M1}, {Op74M1}, {Op75M1}, {Op76M1}, {Op77M1}, - {Op78}, {Op79M1}, {Op7AX0}, {Op7B}, {Op7C}, - {Op7DM1}, {Op7EM1}, {Op7FM1}, {Op80}, {Op81M1}, - {Op82}, {Op83M1}, {Op84X0}, {Op85M1}, {Op86X0}, - {Op87M1}, {Op88X0}, {Op89M1}, {Op8AM1}, {Op8B}, - {Op8CX0}, {Op8DM1}, {Op8EX0}, {Op8FM1}, {Op90}, - {Op91M1}, {Op92M1}, {Op93M1}, {Op94X0}, {Op95M1}, - {Op96X0}, {Op97M1}, {Op98M1}, {Op99M1}, {Op9A}, - {Op9BX0}, {Op9CM1}, {Op9DM1}, {Op9EM1}, {Op9FM1}, - {OpA0X0}, {OpA1M1}, {OpA2X0}, {OpA3M1}, {OpA4X0}, - {OpA5M1}, {OpA6X0}, {OpA7M1}, {OpA8X0}, {OpA9M1}, - {OpAAX0}, {OpAB}, {OpACX0}, {OpADM1}, {OpAEX0}, - {OpAFM1}, {OpB0}, {OpB1M1}, {OpB2M1}, {OpB3M1}, - {OpB4X0}, {OpB5M1}, {OpB6X0}, {OpB7M1}, {OpB8}, - {OpB9M1}, {OpBAX0}, {OpBBX0}, {OpBCX0}, {OpBDM1}, - {OpBEX0}, {OpBFM1}, {OpC0X0}, {OpC1M1}, {OpC2}, - {OpC3M1}, {OpC4X0}, {OpC5M1}, {OpC6M1}, {OpC7M1}, - {OpC8X0}, {OpC9M1}, {OpCAX0}, {OpCB}, {OpCCX0}, - {OpCDM1}, {OpCEM1}, {OpCFM1}, {OpD0}, {OpD1M1}, - {OpD2M1}, {OpD3M1}, {OpD4}, {OpD5M1}, {OpD6M1}, - {OpD7M1}, {OpD8}, {OpD9M1}, {OpDAX0}, {OpDB}, - {OpDC}, {OpDDM1}, {OpDEM1}, {OpDFM1}, {OpE0X0}, - {OpE1M1}, {OpE2}, {OpE3M1}, {OpE4X0}, {OpE5M1}, - {OpE6M1}, {OpE7M1}, {OpE8X0}, {OpE9M1}, {OpEA}, - {OpEB}, {OpECX0}, {OpEDM1}, {OpEEM1}, {OpEFM1}, - {OpF0}, {OpF1M1}, {OpF2M1}, {OpF3M1}, {OpF4}, - {OpF5M1}, {OpF6M1}, {OpF7M1}, {OpF8}, {OpF9M1}, - {OpFAX0}, {OpFB}, {OpFC}, {OpFDM1}, {OpFEM1}, - {OpFFM1} + {Op00}, {Op01M1}, {Op02}, {Op03M1}, {Op04M1}, + {Op05M1}, {Op06M1}, {Op07M1}, {Op08}, {Op09M1}, + {Op0AM1}, {Op0B}, {Op0CM1}, {Op0DM1}, {Op0EM1}, + {Op0FM1}, {Op10}, {Op11M1}, {Op12M1}, {Op13M1}, + {Op14M1}, {Op15M1}, {Op16M1}, {Op17M1}, {Op18}, + {Op19M1}, {Op1AM1}, {Op1B}, {Op1CM1}, {Op1DM1}, + {Op1EM1}, {Op1FM1}, {Op20}, {Op21M1}, {Op22}, + {Op23M1}, {Op24M1}, {Op25M1}, {Op26M1}, {Op27M1}, + {Op28}, {Op29M1}, {Op2AM1}, {Op2B}, {Op2CM1}, + {Op2DM1}, {Op2EM1}, {Op2FM1}, {Op30}, {Op31M1}, + {Op32M1}, {Op33M1}, {Op34M1}, {Op35M1}, {Op36M1}, + {Op37M1}, {Op38}, {Op39M1}, {Op3AM1}, {Op3B}, + {Op3CM1}, {Op3DM1}, {Op3EM1}, {Op3FM1}, {Op40}, + {Op41M1}, {Op42}, {Op43M1}, {Op44X0}, {Op45M1}, + {Op46M1}, {Op47M1}, {Op48M1}, {Op49M1}, {Op4AM1}, + {Op4B}, {Op4C}, {Op4DM1}, {Op4EM1}, {Op4FM1}, + {Op50}, {Op51M1}, {Op52M1}, {Op53M1}, {Op54X0}, + {Op55M1}, {Op56M1}, {Op57M1}, {Op58}, {Op59M1}, + {Op5AX0}, {Op5B}, {Op5C}, {Op5DM1}, {Op5EM1}, + {Op5FM1}, {Op60}, {Op61M1}, {Op62}, {Op63M1}, + {Op64M1}, {Op65M1}, {Op66M1}, {Op67M1}, {Op68M1}, + {Op69M1}, {Op6AM1}, {Op6B}, {Op6C}, {Op6DM1}, + {Op6EM1}, {Op6FM1}, {Op70}, {Op71M1}, {Op72M1}, + {Op73M1}, {Op74M1}, {Op75M1}, {Op76M1}, {Op77M1}, + {Op78}, {Op79M1}, {Op7AX0}, {Op7B}, {Op7C}, + {Op7DM1}, {Op7EM1}, {Op7FM1}, {Op80}, {Op81M1}, + {Op82}, {Op83M1}, {Op84X0}, {Op85M1}, {Op86X0}, + {Op87M1}, {Op88X0}, {Op89M1}, {Op8AM1}, {Op8B}, + {Op8CX0}, {Op8DM1}, {Op8EX0}, {Op8FM1}, {Op90}, + {Op91M1}, {Op92M1}, {Op93M1}, {Op94X0}, {Op95M1}, + {Op96X0}, {Op97M1}, {Op98M1}, {Op99M1}, {Op9A}, + {Op9BX0}, {Op9CM1}, {Op9DM1}, {Op9EM1}, {Op9FM1}, + {OpA0X0}, {OpA1M1}, {OpA2X0}, {OpA3M1}, {OpA4X0}, + {OpA5M1}, {OpA6X0}, {OpA7M1}, {OpA8X0}, {OpA9M1}, + {OpAAX0}, {OpAB}, {OpACX0}, {OpADM1}, {OpAEX0}, + {OpAFM1}, {OpB0}, {OpB1M1}, {OpB2M1}, {OpB3M1}, + {OpB4X0}, {OpB5M1}, {OpB6X0}, {OpB7M1}, {OpB8}, + {OpB9M1}, {OpBAX0}, {OpBBX0}, {OpBCX0}, {OpBDM1}, + {OpBEX0}, {OpBFM1}, {OpC0X0}, {OpC1M1}, {OpC2}, + {OpC3M1}, {OpC4X0}, {OpC5M1}, {OpC6M1}, {OpC7M1}, + {OpC8X0}, {OpC9M1}, {OpCAX0}, {OpCB}, {OpCCX0}, + {OpCDM1}, {OpCEM1}, {OpCFM1}, {OpD0}, {OpD1M1}, + {OpD2M1}, {OpD3M1}, {OpD4}, {OpD5M1}, {OpD6M1}, + {OpD7M1}, {OpD8}, {OpD9M1}, {OpDAX0}, {OpDB}, + {OpDC}, {OpDDM1}, {OpDEM1}, {OpDFM1}, {OpE0X0}, + {OpE1M1}, {OpE2}, {OpE3M1}, {OpE4X0}, {OpE5M1}, + {OpE6M1}, {OpE7M1}, {OpE8X0}, {OpE9M1}, {OpEA}, + {OpEB}, {OpECX0}, {OpEDM1}, {OpEEM1}, {OpEFM1}, + {OpF0}, {OpF1M1}, {OpF2M1}, {OpF3M1}, {OpF4}, + {OpF5M1}, {OpF6M1}, {OpF7M1}, {OpF8}, {OpF9M1}, + {OpFAX0}, {OpFB}, {OpFC}, {OpFDM1}, {OpFEM1}, + {OpFFM1} }; SOpcodes S9xOpcodesM0X0[256] = { - {Op00}, {Op01M0}, {Op02}, {Op03M0}, {Op04M0}, - {Op05M0}, {Op06M0}, {Op07M0}, {Op08}, {Op09M0}, - {Op0AM0}, {Op0B}, {Op0CM0}, {Op0DM0}, {Op0EM0}, - {Op0FM0}, {Op10}, {Op11M0}, {Op12M0}, {Op13M0}, - {Op14M0}, {Op15M0}, {Op16M0}, {Op17M0}, {Op18}, - {Op19M0}, {Op1AM0}, {Op1B}, {Op1CM0}, {Op1DM0}, - {Op1EM0}, {Op1FM0}, {Op20}, {Op21M0}, {Op22}, - {Op23M0}, {Op24M0}, {Op25M0}, {Op26M0}, {Op27M0}, - {Op28}, {Op29M0}, {Op2AM0}, {Op2B}, {Op2CM0}, - {Op2DM0}, {Op2EM0}, {Op2FM0}, {Op30}, {Op31M0}, - {Op32M0}, {Op33M0}, {Op34M0}, {Op35M0}, {Op36M0}, - {Op37M0}, {Op38}, {Op39M0}, {Op3AM0}, {Op3B}, - {Op3CM0}, {Op3DM0}, {Op3EM0}, {Op3FM0}, {Op40}, - {Op41M0}, {Op42}, {Op43M0}, {Op44X0}, {Op45M0}, - {Op46M0}, {Op47M0}, {Op48M0}, {Op49M0}, {Op4AM0}, - {Op4B}, {Op4C}, {Op4DM0}, {Op4EM0}, {Op4FM0}, - {Op50}, {Op51M0}, {Op52M0}, {Op53M0}, {Op54X0}, - {Op55M0}, {Op56M0}, {Op57M0}, {Op58}, {Op59M0}, - {Op5AX0}, {Op5B}, {Op5C}, {Op5DM0}, {Op5EM0}, - {Op5FM0}, {Op60}, {Op61M0}, {Op62}, {Op63M0}, - {Op64M0}, {Op65M0}, {Op66M0}, {Op67M0}, {Op68M0}, - {Op69M0}, {Op6AM0}, {Op6B}, {Op6C}, {Op6DM0}, - {Op6EM0}, {Op6FM0}, {Op70}, {Op71M0}, {Op72M0}, - {Op73M0}, {Op74M0}, {Op75M0}, {Op76M0}, {Op77M0}, - {Op78}, {Op79M0}, {Op7AX0}, {Op7B}, {Op7C}, - {Op7DM0}, {Op7EM0}, {Op7FM0}, {Op80}, {Op81M0}, - {Op82}, {Op83M0}, {Op84X0}, {Op85M0}, {Op86X0}, - {Op87M0}, {Op88X0}, {Op89M0}, {Op8AM0}, {Op8B}, - {Op8CX0}, {Op8DM0}, {Op8EX0}, {Op8FM0}, {Op90}, - {Op91M0}, {Op92M0}, {Op93M0}, {Op94X0}, {Op95M0}, - {Op96X0}, {Op97M0}, {Op98M0}, {Op99M0}, {Op9A}, - {Op9BX0}, {Op9CM0}, {Op9DM0}, {Op9EM0}, {Op9FM0}, - {OpA0X0}, {OpA1M0}, {OpA2X0}, {OpA3M0}, {OpA4X0}, - {OpA5M0}, {OpA6X0}, {OpA7M0}, {OpA8X0}, {OpA9M0}, - {OpAAX0}, {OpAB}, {OpACX0}, {OpADM0}, {OpAEX0}, - {OpAFM0}, {OpB0}, {OpB1M0}, {OpB2M0}, {OpB3M0}, - {OpB4X0}, {OpB5M0}, {OpB6X0}, {OpB7M0}, {OpB8}, - {OpB9M0}, {OpBAX0}, {OpBBX0}, {OpBCX0}, {OpBDM0}, - {OpBEX0}, {OpBFM0}, {OpC0X0}, {OpC1M0}, {OpC2}, - {OpC3M0}, {OpC4X0}, {OpC5M0}, {OpC6M0}, {OpC7M0}, - {OpC8X0}, {OpC9M0}, {OpCAX0}, {OpCB}, {OpCCX0}, - {OpCDM0}, {OpCEM0}, {OpCFM0}, {OpD0}, {OpD1M0}, - {OpD2M0}, {OpD3M0}, {OpD4}, {OpD5M0}, {OpD6M0}, - {OpD7M0}, {OpD8}, {OpD9M0}, {OpDAX0}, {OpDB}, - {OpDC}, {OpDDM0}, {OpDEM0}, {OpDFM0}, {OpE0X0}, - {OpE1M0}, {OpE2}, {OpE3M0}, {OpE4X0}, {OpE5M0}, - {OpE6M0}, {OpE7M0}, {OpE8X0}, {OpE9M0}, {OpEA}, - {OpEB}, {OpECX0}, {OpEDM0}, {OpEEM0}, {OpEFM0}, - {OpF0}, {OpF1M0}, {OpF2M0}, {OpF3M0}, {OpF4}, - {OpF5M0}, {OpF6M0}, {OpF7M0}, {OpF8}, {OpF9M0}, - {OpFAX0}, {OpFB}, {OpFC}, {OpFDM0}, {OpFEM0}, - {OpFFM0} + {Op00}, {Op01M0}, {Op02}, {Op03M0}, {Op04M0}, + {Op05M0}, {Op06M0}, {Op07M0}, {Op08}, {Op09M0}, + {Op0AM0}, {Op0B}, {Op0CM0}, {Op0DM0}, {Op0EM0}, + {Op0FM0}, {Op10}, {Op11M0}, {Op12M0}, {Op13M0}, + {Op14M0}, {Op15M0}, {Op16M0}, {Op17M0}, {Op18}, + {Op19M0}, {Op1AM0}, {Op1B}, {Op1CM0}, {Op1DM0}, + {Op1EM0}, {Op1FM0}, {Op20}, {Op21M0}, {Op22}, + {Op23M0}, {Op24M0}, {Op25M0}, {Op26M0}, {Op27M0}, + {Op28}, {Op29M0}, {Op2AM0}, {Op2B}, {Op2CM0}, + {Op2DM0}, {Op2EM0}, {Op2FM0}, {Op30}, {Op31M0}, + {Op32M0}, {Op33M0}, {Op34M0}, {Op35M0}, {Op36M0}, + {Op37M0}, {Op38}, {Op39M0}, {Op3AM0}, {Op3B}, + {Op3CM0}, {Op3DM0}, {Op3EM0}, {Op3FM0}, {Op40}, + {Op41M0}, {Op42}, {Op43M0}, {Op44X0}, {Op45M0}, + {Op46M0}, {Op47M0}, {Op48M0}, {Op49M0}, {Op4AM0}, + {Op4B}, {Op4C}, {Op4DM0}, {Op4EM0}, {Op4FM0}, + {Op50}, {Op51M0}, {Op52M0}, {Op53M0}, {Op54X0}, + {Op55M0}, {Op56M0}, {Op57M0}, {Op58}, {Op59M0}, + {Op5AX0}, {Op5B}, {Op5C}, {Op5DM0}, {Op5EM0}, + {Op5FM0}, {Op60}, {Op61M0}, {Op62}, {Op63M0}, + {Op64M0}, {Op65M0}, {Op66M0}, {Op67M0}, {Op68M0}, + {Op69M0}, {Op6AM0}, {Op6B}, {Op6C}, {Op6DM0}, + {Op6EM0}, {Op6FM0}, {Op70}, {Op71M0}, {Op72M0}, + {Op73M0}, {Op74M0}, {Op75M0}, {Op76M0}, {Op77M0}, + {Op78}, {Op79M0}, {Op7AX0}, {Op7B}, {Op7C}, + {Op7DM0}, {Op7EM0}, {Op7FM0}, {Op80}, {Op81M0}, + {Op82}, {Op83M0}, {Op84X0}, {Op85M0}, {Op86X0}, + {Op87M0}, {Op88X0}, {Op89M0}, {Op8AM0}, {Op8B}, + {Op8CX0}, {Op8DM0}, {Op8EX0}, {Op8FM0}, {Op90}, + {Op91M0}, {Op92M0}, {Op93M0}, {Op94X0}, {Op95M0}, + {Op96X0}, {Op97M0}, {Op98M0}, {Op99M0}, {Op9A}, + {Op9BX0}, {Op9CM0}, {Op9DM0}, {Op9EM0}, {Op9FM0}, + {OpA0X0}, {OpA1M0}, {OpA2X0}, {OpA3M0}, {OpA4X0}, + {OpA5M0}, {OpA6X0}, {OpA7M0}, {OpA8X0}, {OpA9M0}, + {OpAAX0}, {OpAB}, {OpACX0}, {OpADM0}, {OpAEX0}, + {OpAFM0}, {OpB0}, {OpB1M0}, {OpB2M0}, {OpB3M0}, + {OpB4X0}, {OpB5M0}, {OpB6X0}, {OpB7M0}, {OpB8}, + {OpB9M0}, {OpBAX0}, {OpBBX0}, {OpBCX0}, {OpBDM0}, + {OpBEX0}, {OpBFM0}, {OpC0X0}, {OpC1M0}, {OpC2}, + {OpC3M0}, {OpC4X0}, {OpC5M0}, {OpC6M0}, {OpC7M0}, + {OpC8X0}, {OpC9M0}, {OpCAX0}, {OpCB}, {OpCCX0}, + {OpCDM0}, {OpCEM0}, {OpCFM0}, {OpD0}, {OpD1M0}, + {OpD2M0}, {OpD3M0}, {OpD4}, {OpD5M0}, {OpD6M0}, + {OpD7M0}, {OpD8}, {OpD9M0}, {OpDAX0}, {OpDB}, + {OpDC}, {OpDDM0}, {OpDEM0}, {OpDFM0}, {OpE0X0}, + {OpE1M0}, {OpE2}, {OpE3M0}, {OpE4X0}, {OpE5M0}, + {OpE6M0}, {OpE7M0}, {OpE8X0}, {OpE9M0}, {OpEA}, + {OpEB}, {OpECX0}, {OpEDM0}, {OpEEM0}, {OpEFM0}, + {OpF0}, {OpF1M0}, {OpF2M0}, {OpF3M0}, {OpF4}, + {OpF5M0}, {OpF6M0}, {OpF7M0}, {OpF8}, {OpF9M0}, + {OpFAX0}, {OpFB}, {OpFC}, {OpFDM0}, {OpFEM0}, + {OpFFM0} }; SOpcodes S9xOpcodesM0X1[256] = { - {Op00}, {Op01M0}, {Op02}, {Op03M0}, {Op04M0}, - {Op05M0}, {Op06M0}, {Op07M0}, {Op08}, {Op09M0}, - {Op0AM0}, {Op0B}, {Op0CM0}, {Op0DM0}, {Op0EM0}, - {Op0FM0}, {Op10}, {Op11M0}, {Op12M0}, {Op13M0}, - {Op14M0}, {Op15M0}, {Op16M0}, {Op17M0}, {Op18}, - {Op19M0}, {Op1AM0}, {Op1B}, {Op1CM0}, {Op1DM0}, - {Op1EM0}, {Op1FM0}, {Op20}, {Op21M0}, {Op22}, - {Op23M0}, {Op24M0}, {Op25M0}, {Op26M0}, {Op27M0}, - {Op28}, {Op29M0}, {Op2AM0}, {Op2B}, {Op2CM0}, - {Op2DM0}, {Op2EM0}, {Op2FM0}, {Op30}, {Op31M0}, - {Op32M0}, {Op33M0}, {Op34M0}, {Op35M0}, {Op36M0}, - {Op37M0}, {Op38}, {Op39M0}, {Op3AM0}, {Op3B}, - {Op3CM0}, {Op3DM0}, {Op3EM0}, {Op3FM0}, {Op40}, - {Op41M0}, {Op42}, {Op43M0}, {Op44X1}, {Op45M0}, - {Op46M0}, {Op47M0}, {Op48M0}, {Op49M0}, {Op4AM0}, - {Op4B}, {Op4C}, {Op4DM0}, {Op4EM0}, {Op4FM0}, - {Op50}, {Op51M0}, {Op52M0}, {Op53M0}, {Op54X1}, - {Op55M0}, {Op56M0}, {Op57M0}, {Op58}, {Op59M0}, - {Op5AX1}, {Op5B}, {Op5C}, {Op5DM0}, {Op5EM0}, - {Op5FM0}, {Op60}, {Op61M0}, {Op62}, {Op63M0}, - {Op64M0}, {Op65M0}, {Op66M0}, {Op67M0}, {Op68M0}, - {Op69M0}, {Op6AM0}, {Op6B}, {Op6C}, {Op6DM0}, - {Op6EM0}, {Op6FM0}, {Op70}, {Op71M0}, {Op72M0}, - {Op73M0}, {Op74M0}, {Op75M0}, {Op76M0}, {Op77M0}, - {Op78}, {Op79M0}, {Op7AX1}, {Op7B}, {Op7C}, - {Op7DM0}, {Op7EM0}, {Op7FM0}, {Op80}, {Op81M0}, - {Op82}, {Op83M0}, {Op84X1}, {Op85M0}, {Op86X1}, - {Op87M0}, {Op88X1}, {Op89M0}, {Op8AM0}, {Op8B}, - {Op8CX1}, {Op8DM0}, {Op8EX1}, {Op8FM0}, {Op90}, - {Op91M0}, {Op92M0}, {Op93M0}, {Op94X1}, {Op95M0}, - {Op96X1}, {Op97M0}, {Op98M0}, {Op99M0}, {Op9A}, - {Op9BX1}, {Op9CM0}, {Op9DM0}, {Op9EM0}, {Op9FM0}, - {OpA0X1}, {OpA1M0}, {OpA2X1}, {OpA3M0}, {OpA4X1}, - {OpA5M0}, {OpA6X1}, {OpA7M0}, {OpA8X1}, {OpA9M0}, - {OpAAX1}, {OpAB}, {OpACX1}, {OpADM0}, {OpAEX1}, - {OpAFM0}, {OpB0}, {OpB1M0}, {OpB2M0}, {OpB3M0}, - {OpB4X1}, {OpB5M0}, {OpB6X1}, {OpB7M0}, {OpB8}, - {OpB9M0}, {OpBAX1}, {OpBBX1}, {OpBCX1}, {OpBDM0}, - {OpBEX1}, {OpBFM0}, {OpC0X1}, {OpC1M0}, {OpC2}, - {OpC3M0}, {OpC4X1}, {OpC5M0}, {OpC6M0}, {OpC7M0}, - {OpC8X1}, {OpC9M0}, {OpCAX1}, {OpCB}, {OpCCX1}, - {OpCDM0}, {OpCEM0}, {OpCFM0}, {OpD0}, {OpD1M0}, - {OpD2M0}, {OpD3M0}, {OpD4}, {OpD5M0}, {OpD6M0}, - {OpD7M0}, {OpD8}, {OpD9M0}, {OpDAX1}, {OpDB}, - {OpDC}, {OpDDM0}, {OpDEM0}, {OpDFM0}, {OpE0X1}, - {OpE1M0}, {OpE2}, {OpE3M0}, {OpE4X1}, {OpE5M0}, - {OpE6M0}, {OpE7M0}, {OpE8X1}, {OpE9M0}, {OpEA}, - {OpEB}, {OpECX1}, {OpEDM0}, {OpEEM0}, {OpEFM0}, - {OpF0}, {OpF1M0}, {OpF2M0}, {OpF3M0}, {OpF4}, - {OpF5M0}, {OpF6M0}, {OpF7M0}, {OpF8}, {OpF9M0}, - {OpFAX1}, {OpFB}, {OpFC}, {OpFDM0}, {OpFEM0}, - {OpFFM0} + {Op00}, {Op01M0}, {Op02}, {Op03M0}, {Op04M0}, + {Op05M0}, {Op06M0}, {Op07M0}, {Op08}, {Op09M0}, + {Op0AM0}, {Op0B}, {Op0CM0}, {Op0DM0}, {Op0EM0}, + {Op0FM0}, {Op10}, {Op11M0}, {Op12M0}, {Op13M0}, + {Op14M0}, {Op15M0}, {Op16M0}, {Op17M0}, {Op18}, + {Op19M0}, {Op1AM0}, {Op1B}, {Op1CM0}, {Op1DM0}, + {Op1EM0}, {Op1FM0}, {Op20}, {Op21M0}, {Op22}, + {Op23M0}, {Op24M0}, {Op25M0}, {Op26M0}, {Op27M0}, + {Op28}, {Op29M0}, {Op2AM0}, {Op2B}, {Op2CM0}, + {Op2DM0}, {Op2EM0}, {Op2FM0}, {Op30}, {Op31M0}, + {Op32M0}, {Op33M0}, {Op34M0}, {Op35M0}, {Op36M0}, + {Op37M0}, {Op38}, {Op39M0}, {Op3AM0}, {Op3B}, + {Op3CM0}, {Op3DM0}, {Op3EM0}, {Op3FM0}, {Op40}, + {Op41M0}, {Op42}, {Op43M0}, {Op44X1}, {Op45M0}, + {Op46M0}, {Op47M0}, {Op48M0}, {Op49M0}, {Op4AM0}, + {Op4B}, {Op4C}, {Op4DM0}, {Op4EM0}, {Op4FM0}, + {Op50}, {Op51M0}, {Op52M0}, {Op53M0}, {Op54X1}, + {Op55M0}, {Op56M0}, {Op57M0}, {Op58}, {Op59M0}, + {Op5AX1}, {Op5B}, {Op5C}, {Op5DM0}, {Op5EM0}, + {Op5FM0}, {Op60}, {Op61M0}, {Op62}, {Op63M0}, + {Op64M0}, {Op65M0}, {Op66M0}, {Op67M0}, {Op68M0}, + {Op69M0}, {Op6AM0}, {Op6B}, {Op6C}, {Op6DM0}, + {Op6EM0}, {Op6FM0}, {Op70}, {Op71M0}, {Op72M0}, + {Op73M0}, {Op74M0}, {Op75M0}, {Op76M0}, {Op77M0}, + {Op78}, {Op79M0}, {Op7AX1}, {Op7B}, {Op7C}, + {Op7DM0}, {Op7EM0}, {Op7FM0}, {Op80}, {Op81M0}, + {Op82}, {Op83M0}, {Op84X1}, {Op85M0}, {Op86X1}, + {Op87M0}, {Op88X1}, {Op89M0}, {Op8AM0}, {Op8B}, + {Op8CX1}, {Op8DM0}, {Op8EX1}, {Op8FM0}, {Op90}, + {Op91M0}, {Op92M0}, {Op93M0}, {Op94X1}, {Op95M0}, + {Op96X1}, {Op97M0}, {Op98M0}, {Op99M0}, {Op9A}, + {Op9BX1}, {Op9CM0}, {Op9DM0}, {Op9EM0}, {Op9FM0}, + {OpA0X1}, {OpA1M0}, {OpA2X1}, {OpA3M0}, {OpA4X1}, + {OpA5M0}, {OpA6X1}, {OpA7M0}, {OpA8X1}, {OpA9M0}, + {OpAAX1}, {OpAB}, {OpACX1}, {OpADM0}, {OpAEX1}, + {OpAFM0}, {OpB0}, {OpB1M0}, {OpB2M0}, {OpB3M0}, + {OpB4X1}, {OpB5M0}, {OpB6X1}, {OpB7M0}, {OpB8}, + {OpB9M0}, {OpBAX1}, {OpBBX1}, {OpBCX1}, {OpBDM0}, + {OpBEX1}, {OpBFM0}, {OpC0X1}, {OpC1M0}, {OpC2}, + {OpC3M0}, {OpC4X1}, {OpC5M0}, {OpC6M0}, {OpC7M0}, + {OpC8X1}, {OpC9M0}, {OpCAX1}, {OpCB}, {OpCCX1}, + {OpCDM0}, {OpCEM0}, {OpCFM0}, {OpD0}, {OpD1M0}, + {OpD2M0}, {OpD3M0}, {OpD4}, {OpD5M0}, {OpD6M0}, + {OpD7M0}, {OpD8}, {OpD9M0}, {OpDAX1}, {OpDB}, + {OpDC}, {OpDDM0}, {OpDEM0}, {OpDFM0}, {OpE0X1}, + {OpE1M0}, {OpE2}, {OpE3M0}, {OpE4X1}, {OpE5M0}, + {OpE6M0}, {OpE7M0}, {OpE8X1}, {OpE9M0}, {OpEA}, + {OpEB}, {OpECX1}, {OpEDM0}, {OpEEM0}, {OpEFM0}, + {OpF0}, {OpF1M0}, {OpF2M0}, {OpF3M0}, {OpF4}, + {OpF5M0}, {OpF6M0}, {OpF7M0}, {OpF8}, {OpF9M0}, + {OpFAX1}, {OpFB}, {OpFC}, {OpFDM0}, {OpFEM0}, + {OpFFM0} }; diff --git a/source/cpuops.h b/source/cpuops.h index 8b59dbb..fc3696e 100644 --- a/source/cpuops.h +++ b/source/cpuops.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,54 +43,54 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ #ifndef _CPUOPS_H_ #define _CPUOPS_H_ -void S9xOpcode_NMI (); -void S9xOpcode_IRQ (); +void S9xOpcode_NMI(); +void S9xOpcode_IRQ(); #define CHECK_FOR_IRQ() \ if (CPU.IRQActive && !CheckFlag (IRQ) && !Settings.DisableIRQ) \ diff --git a/source/data.c b/source/data.c index 0854ed4..ba52a5d 100644 --- a/source/data.c +++ b/source/data.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,497 +43,790 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ #include "snes9x.h" -uint8 add32_32 [32][32] = { -{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e, - 0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d, - 0x1e,0x1f}, -{ 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e, - 0x1f,0x1f}, -{ 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10, - 0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, - 0x1f,0x1f}, -{ 0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11, - 0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12, - 0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13, - 0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14, - 0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15, - 0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16, - 0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, - 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18, - 0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19, - 0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a, - 0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b, - 0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c, - 0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d, - 0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e, - 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, - 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f, - 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f, - 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f}, -{ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, - 0x1f,0x1f} +uint8 add32_32 [32][32] = +{ + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f + }, + { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, + 0x1f, 0x1f + }, + { + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x1f, 0x1f + }, + { + 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, + 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x1c, 0x1d, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x1d, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + }, + { + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f + } }; -uint8 add32_32_half [32][32] = { -{ 0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07, - 0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e, - 0x0f,0x0f}, -{ 0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07, - 0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f, - 0x0f,0x10}, -{ 0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08, - 0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f, - 0x10,0x10}, -{ 0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08, - 0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10, - 0x10,0x11}, -{ 0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09, - 0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10, - 0x11,0x11}, -{ 0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09, - 0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11, - 0x11,0x12}, -{ 0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a, - 0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11, - 0x12,0x12}, -{ 0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a, - 0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12, - 0x12,0x13}, -{ 0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b, - 0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12, - 0x13,0x13}, -{ 0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b, - 0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13, - 0x13,0x14}, -{ 0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c, - 0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13, - 0x14,0x14}, -{ 0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c, - 0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14, - 0x14,0x15}, -{ 0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d, - 0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14, - 0x15,0x15}, -{ 0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d, - 0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15, - 0x15,0x16}, -{ 0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e, - 0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15, - 0x16,0x16}, -{ 0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e, - 0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16, - 0x16,0x17}, -{ 0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f, - 0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16, - 0x17,0x17}, -{ 0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f, - 0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17, - 0x17,0x18}, -{ 0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10, - 0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17, - 0x18,0x18}, -{ 0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10, - 0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18, - 0x18,0x19}, -{ 0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11, - 0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18, - 0x19,0x19}, -{ 0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11, - 0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19, - 0x19,0x1a}, -{ 0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12, - 0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19, - 0x1a,0x1a}, -{ 0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12, - 0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a, - 0x1a,0x1b}, -{ 0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13, - 0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a, - 0x1b,0x1b}, -{ 0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13, - 0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b, - 0x1b,0x1c}, -{ 0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14, - 0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,0x1b, - 0x1c,0x1c}, -{ 0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14, - 0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,0x1b,0x1c, - 0x1c,0x1d}, -{ 0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15, - 0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,0x1b,0x1c,0x1c, - 0x1d,0x1d}, -{ 0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15, - 0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,0x1b,0x1c,0x1c,0x1d, - 0x1d,0x1e}, -{ 0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16, - 0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,0x1b,0x1c,0x1c,0x1d,0x1d, - 0x1e,0x1e}, -{ 0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16, - 0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,0x1b,0x1c,0x1c,0x1d,0x1d,0x1e, - 0x1e,0x1f} +uint8 add32_32_half [32][32] = +{ + { + 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, + 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, + 0x0f, 0x0f + }, + { + 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, + 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, + 0x0f, 0x10 + }, + { + 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, + 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, + 0x10, 0x10 + }, + { + 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, + 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, + 0x10, 0x11 + }, + { + 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, + 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10, + 0x11, 0x11 + }, + { + 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, + 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x11, + 0x11, 0x12 + }, + { + 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, + 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x11, + 0x12, 0x12 + }, + { + 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, + 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, + 0x12, 0x13 + }, + { + 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, + 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, + 0x13, 0x13 + }, + { + 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, + 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, + 0x13, 0x14 + }, + { + 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, + 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, + 0x14, 0x14 + }, + { + 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, + 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, + 0x14, 0x15 + }, + { + 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, + 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, + 0x15, 0x15 + }, + { + 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, + 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, 0x15, + 0x15, 0x16 + }, + { + 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, + 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, 0x15, 0x15, + 0x16, 0x16 + }, + { + 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, + 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, 0x15, 0x15, 0x16, + 0x16, 0x17 + }, + { + 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, + 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, 0x15, 0x15, 0x16, 0x16, + 0x17, 0x17 + }, + { + 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, + 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, 0x15, 0x15, 0x16, 0x16, 0x17, + 0x17, 0x18 + }, + { + 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, + 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, 0x15, 0x15, 0x16, 0x16, 0x17, 0x17, + 0x18, 0x18 + }, + { + 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10, + 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, 0x15, 0x15, 0x16, 0x16, 0x17, 0x17, 0x18, + 0x18, 0x19 + }, + { + 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x11, + 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, 0x15, 0x15, 0x16, 0x16, 0x17, 0x17, 0x18, 0x18, + 0x19, 0x19 + }, + { + 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x11, + 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, 0x15, 0x15, 0x16, 0x16, 0x17, 0x17, 0x18, 0x18, 0x19, + 0x19, 0x1a + }, + { + 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, + 0x12, 0x13, 0x13, 0x14, 0x14, 0x15, 0x15, 0x16, 0x16, 0x17, 0x17, 0x18, 0x18, 0x19, 0x19, + 0x1a, 0x1a + }, + { + 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, + 0x13, 0x13, 0x14, 0x14, 0x15, 0x15, 0x16, 0x16, 0x17, 0x17, 0x18, 0x18, 0x19, 0x19, 0x1a, + 0x1a, 0x1b + }, + { + 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, + 0x13, 0x14, 0x14, 0x15, 0x15, 0x16, 0x16, 0x17, 0x17, 0x18, 0x18, 0x19, 0x19, 0x1a, 0x1a, + 0x1b, 0x1b + }, + { + 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, + 0x14, 0x14, 0x15, 0x15, 0x16, 0x16, 0x17, 0x17, 0x18, 0x18, 0x19, 0x19, 0x1a, 0x1a, 0x1b, + 0x1b, 0x1c + }, + { + 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, + 0x14, 0x15, 0x15, 0x16, 0x16, 0x17, 0x17, 0x18, 0x18, 0x19, 0x19, 0x1a, 0x1a, 0x1b, 0x1b, + 0x1c, 0x1c + }, + { + 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, + 0x15, 0x15, 0x16, 0x16, 0x17, 0x17, 0x18, 0x18, 0x19, 0x19, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, + 0x1c, 0x1d + }, + { + 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, 0x15, + 0x15, 0x16, 0x16, 0x17, 0x17, 0x18, 0x18, 0x19, 0x19, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1c, + 0x1d, 0x1d + }, + { + 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, 0x15, 0x15, + 0x16, 0x16, 0x17, 0x17, 0x18, 0x18, 0x19, 0x19, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1c, 0x1d, + 0x1d, 0x1e + }, + { + 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, 0x15, 0x15, 0x16, + 0x16, 0x17, 0x17, 0x18, 0x18, 0x19, 0x19, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1c, 0x1d, 0x1d, + 0x1e, 0x1e + }, + { + 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, 0x15, 0x15, 0x16, 0x16, + 0x17, 0x17, 0x18, 0x18, 0x19, 0x19, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1e, + 0x1e, 0x1f + } }; -uint8 sub32_32 [32][32] = { -{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e, - 0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d, - 0x1e,0x1f}, -{ 0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d, - 0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c, - 0x1d,0x1e}, -{ 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c, - 0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b, - 0x1c,0x1d}, -{ 0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b, - 0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a, - 0x1b,0x1c}, -{ 0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a, - 0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19, - 0x1a,0x1b}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, - 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18, - 0x19,0x1a}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08, - 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, - 0x18,0x19}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16, - 0x17,0x18}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06, - 0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15, - 0x16,0x17}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05, - 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14, - 0x15,0x16}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04, - 0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13, - 0x14,0x15}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03, - 0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12, - 0x13,0x14}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02, - 0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11, - 0x12,0x13}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, - 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10, - 0x11,0x12}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, - 0x10,0x11}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e, - 0x0f,0x10}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d, - 0x0e,0x0f}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c, - 0x0d,0x0e}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b, - 0x0c,0x0d}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a, - 0x0b,0x0c}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, - 0x0a,0x0b}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08, - 0x09,0x0a}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0x08,0x09}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06, - 0x07,0x08}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05, - 0x06,0x07}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04, - 0x05,0x06}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03, - 0x04,0x05}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02, - 0x03,0x04}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, - 0x02,0x03}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x02}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x01}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00} +uint8 sub32_32 [32][32] = +{ + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f + }, + { + 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1e + }, + { + 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d + }, + { + 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, + 0x1b, 0x1c + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x1b + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, + 0x13, 0x14 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, + 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, + 0x0b, 0x0c + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, + 0x03, 0x04 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x02, 0x03 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x02 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 + } }; -uint8 sub32_32_half [32][32] = { -{ 0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07, - 0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e, - 0x0f,0x0f}, -{ 0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06, - 0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e, - 0x0e,0x0f}, -{ 0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06, - 0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d, - 0x0e,0x0e}, -{ 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05, - 0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d, - 0x0d,0x0e}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05, - 0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c, - 0x0d,0x0d}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04, - 0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c, - 0x0c,0x0d}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04, - 0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b, - 0x0c,0x0c}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03, - 0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b, - 0x0b,0x0c}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03, - 0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a, - 0x0b,0x0b}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02, - 0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a, - 0x0a,0x0b}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02, - 0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09, - 0x0a,0x0a}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01, - 0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09, - 0x09,0x0a}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, - 0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08, - 0x09,0x09}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08, - 0x08,0x09}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07, - 0x08,0x08}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07, - 0x07,0x08}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06, - 0x07,0x07}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06, - 0x06,0x07}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05, - 0x06,0x06}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05, - 0x05,0x06}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04, - 0x05,0x05}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04, - 0x04,0x05}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03, - 0x04,0x04}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03, - 0x03,0x04}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02, - 0x03,0x03}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02, - 0x02,0x03}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01, - 0x02,0x02}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, - 0x01,0x02}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x01,0x01}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x01}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00} +uint8 sub32_32_half [32][32] = +{ + { + 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, + 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, + 0x0f, 0x0f + }, + { + 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, + 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, + 0x0e, 0x0f + }, + { + 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, + 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, + 0x0e, 0x0e + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, + 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, + 0x0d, 0x0e + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, + 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, + 0x0d, 0x0d + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, + 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, + 0x0c, 0x0d + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, + 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, + 0x0c, 0x0c + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, + 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, + 0x0b, 0x0c + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, + 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, + 0x0b, 0x0b + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, + 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, + 0x0a, 0x0b + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, + 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, + 0x0a, 0x0a + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, + 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, + 0x09, 0x0a + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, + 0x09, 0x09 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, + 0x08, 0x09 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, + 0x08, 0x08 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, + 0x07, 0x08 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, + 0x07, 0x07 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, + 0x06, 0x07 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, + 0x06, 0x06 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, + 0x05, 0x06 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, + 0x05, 0x05 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, + 0x04, 0x05 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, + 0x04, 0x04 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, + 0x03, 0x04 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, + 0x03, 0x03 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, + 0x02, 0x03 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, + 0x02, 0x02 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x01, 0x02 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x01 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 + } }; -uint8 mul_brightness [16][32] = { -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00}, -{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01, - 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x02,0x02, - 0x02,0x02}, -{ 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02, - 0x02,0x02,0x02,0x02,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x04,0x04,0x04, - 0x04,0x04}, -{ 0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x03,0x03, - 0x03,0x03,0x03,0x04,0x04,0x04,0x04,0x04,0x05,0x05,0x05,0x05,0x05,0x06,0x06, - 0x06,0x06}, -{ 0x00,0x00,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x03,0x03,0x03,0x03,0x04, - 0x04,0x04,0x05,0x05,0x05,0x05,0x06,0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x08, - 0x08,0x08}, -{ 0x00,0x00,0x01,0x01,0x01,0x02,0x02,0x02,0x03,0x03,0x03,0x04,0x04,0x04,0x05, - 0x05,0x05,0x06,0x06,0x06,0x07,0x07,0x07,0x08,0x08,0x08,0x09,0x09,0x09,0x0a, - 0x0a,0x0a}, -{ 0x00,0x00,0x01,0x01,0x02,0x02,0x02,0x03,0x03,0x04,0x04,0x04,0x05,0x05,0x06, - 0x06,0x06,0x07,0x07,0x08,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0a,0x0b,0x0b,0x0c, - 0x0c,0x0c}, -{ 0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07, - 0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e, - 0x0e,0x0e}, -{ 0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07, - 0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f, - 0x10,0x11}, -{ 0x00,0x01,0x01,0x02,0x02,0x03,0x04,0x04,0x05,0x05,0x06,0x07,0x07,0x08,0x08, - 0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x10,0x10,0x11,0x11, - 0x12,0x13}, -{ 0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x05,0x06,0x07,0x07,0x08,0x09,0x09, - 0x0a,0x0b,0x0b,0x0c,0x0d,0x0d,0x0e,0x0f,0x0f,0x10,0x11,0x11,0x12,0x13,0x13, - 0x14,0x15}, -{ 0x00,0x01,0x01,0x02,0x03,0x04,0x04,0x05,0x06,0x07,0x07,0x08,0x09,0x0a,0x0a, - 0x0b,0x0c,0x0c,0x0d,0x0e,0x0f,0x0f,0x10,0x11,0x12,0x12,0x13,0x14,0x15,0x15, - 0x16,0x17}, -{ 0x00,0x01,0x02,0x02,0x03,0x04,0x05,0x06,0x06,0x07,0x08,0x09,0x0a,0x0a,0x0b, - 0x0c,0x0d,0x0e,0x0e,0x0f,0x10,0x11,0x12,0x12,0x13,0x14,0x15,0x16,0x16,0x17, - 0x18,0x19}, -{ 0x00,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0a,0x0b,0x0c, - 0x0d,0x0e,0x0f,0x10,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x17,0x18,0x19, - 0x1a,0x1b}, -{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d, - 0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b, - 0x1c,0x1d}, -{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e, - 0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d, - 0x1e,0x1f} +uint8 mul_brightness [16][32] = +{ + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, + 0x04, 0x04 + }, + { + 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, + 0x06, 0x06 + }, + { + 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, + 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, + 0x08, 0x08 + }, + { + 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, + 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, + 0x0a, 0x0a + }, + { + 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x06, + 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, + 0x0c, 0x0c + }, + { + 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, + 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, + 0x0e, 0x0e + }, + { + 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, + 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, + 0x10, 0x11 + }, + { + 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x07, 0x07, 0x08, 0x08, + 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x11, + 0x12, 0x13 + }, + { + 0x00, 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x05, 0x06, 0x07, 0x07, 0x08, 0x09, 0x09, + 0x0a, 0x0b, 0x0b, 0x0c, 0x0d, 0x0d, 0x0e, 0x0f, 0x0f, 0x10, 0x11, 0x11, 0x12, 0x13, 0x13, + 0x14, 0x15 + }, + { + 0x00, 0x01, 0x01, 0x02, 0x03, 0x04, 0x04, 0x05, 0x06, 0x07, 0x07, 0x08, 0x09, 0x0a, 0x0a, + 0x0b, 0x0c, 0x0c, 0x0d, 0x0e, 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x12, 0x13, 0x14, 0x15, 0x15, + 0x16, 0x17 + }, + { + 0x00, 0x01, 0x02, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x12, 0x13, 0x14, 0x15, 0x16, 0x16, 0x17, + 0x18, 0x19 + }, + { + 0x00, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x17, 0x18, 0x19, + 0x1a, 0x1b + }, + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d + }, + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f + } }; diff --git a/source/display.h b/source/display.h index 8b94dd6..d581562 100644 --- a/source/display.h +++ b/source/display.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -91,42 +91,42 @@ #define _DISPLAY_H_ // Routines the port specific code has to implement -void S9xTextMode (); -void S9xGraphicsMode (); -char *S9xParseArgs (char **argv, int argc); -void S9xExtraUsage (); +void S9xTextMode(); +void S9xGraphicsMode(); +char* S9xParseArgs(char** argv, int argc); +void S9xExtraUsage(); #ifdef ACCUMULATE_JOYPAD -void NDSSFCAccumulateJoypad (); +void NDSSFCAccumulateJoypad(); #endif -uint32 S9xReadJoypad (int port); -bool8 S9xReadMousePosition (int which1_0_to_1, int* x, int* y, uint32* buttons); -bool8 S9xReadSuperScopePosition (int* x, int* y, uint32* buttons); - -void S9xUsage (); -void S9xInitDisplay (void); -void S9xDeinitDisplay (); -void S9xInitInputDevices (); -void S9xSetTitle (const char *title); -void S9xPutImage (int width, int height); -void S9xToggleSoundChannel (int channel); -void S9xSetInfoString (const char *string); -int S9xMinCommandLineArgs (); -void S9xNextController (); -bool8 S9xLoadROMImage (const char *string); -const char *S9xSelectFilename (const char *def, const char *dir, - const char *ext, const char *title); - -const char *S9xChooseFilename (bool8 read_only); - -const char *S9xBasename (const char *filename); - -int S9xFStrcmp (FILE *, const char *); -const char *S9xGetHomeDirectory (); -const char *S9xGetSnapshotDirectory (); -const char *S9xGetROMDirectory (); -const char *S9xGetSRAMFilename (); -const char *S9xGetFilename (const char *extension); -const char *S9xGetFilenameInc (const char *); +uint32 S9xReadJoypad(int port); +bool8 S9xReadMousePosition(int which1_0_to_1, int* x, int* y, uint32* buttons); +bool8 S9xReadSuperScopePosition(int* x, int* y, uint32* buttons); + +void S9xUsage(); +void S9xInitDisplay(void); +void S9xDeinitDisplay(); +void S9xInitInputDevices(); +void S9xSetTitle(const char* title); +void S9xPutImage(int width, int height); +void S9xToggleSoundChannel(int channel); +void S9xSetInfoString(const char* string); +int S9xMinCommandLineArgs(); +void S9xNextController(); +bool8 S9xLoadROMImage(const char* string); +const char* S9xSelectFilename(const char* def, const char* dir, + const char* ext, const char* title); + +const char* S9xChooseFilename(bool8 read_only); + +const char* S9xBasename(const char* filename); + +int S9xFStrcmp(FILE*, const char*); +const char* S9xGetHomeDirectory(); +const char* S9xGetSnapshotDirectory(); +const char* S9xGetROMDirectory(); +const char* S9xGetSRAMFilename(); +const char* S9xGetFilename(const char* extension); +const char* S9xGetFilenameInc(const char*); #endif diff --git a/source/dma.c b/source/dma.c index e7de5b4..31814b2 100644 --- a/source/dma.c +++ b/source/dma.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -111,19 +111,19 @@ uint8 buffer[0x10000]; #endif extern int HDMA_ModeByteCounts [8]; -extern uint8 *HDMAMemPointers [8]; -extern uint8 *HDMABasePointers [8]; +extern uint8* HDMAMemPointers [8]; +extern uint8* HDMABasePointers [8]; // #define SETA010_HDMA_FROM_CART #ifdef SETA010_HDMA_FROM_CART -uint32 HDMARawPointers[8]; // Cart address space pointer +uint32 HDMARawPointers[8]; // Cart address space pointer #endif #if defined(__linux__) || defined(__WIN32__) -static int S9xCompareSDD1IndexEntries (const void *p1, const void *p2) +static int S9xCompareSDD1IndexEntries(const void* p1, const void* p2) { - return (*(uint32 *) p1 - *(uint32 *) p2); + return (*(uint32*) p1 - * (uint32*) p2); } #endif @@ -132,979 +132,982 @@ static int S9xCompareSDD1IndexEntries (const void *p1, const void *p2) /* This function preforms the general dma transfer */ /**********************************************************************************************/ -void S9xDoDMA (uint8 Channel) +void S9xDoDMA(uint8 Channel) { - uint8 Work; - - if (Channel > 7 || CPU.InDMA) - return; - - CPU.InDMA = TRUE; - bool8 in_sa1_dma = FALSE; - uint8 *in_sdd1_dma = NULL; - uint8 *spc7110_dma=NULL; - bool s7_wrap=false; - SDMA *d = &DMA[Channel]; - - - int count = d->TransferBytes; - - if (count == 0) - count = 0x10000; - - int inc = d->AAddressFixed ? 0 : (!d->AAddressDecrement ? 1 : -1); - - if((d->ABank==0x7E||d->ABank==0x7F)&&d->BAddress==0x80) - { - d->AAddress+= d->TransferBytes; - //does an invalid DMA actually take time? - // I'd say yes, since 'invalid' is probably just the WRAM chip - // not being able to read and write itself at the same time - CPU.Cycles+=(d->TransferBytes+1)*SLOW_ONE_CYCLE; - goto update_address; - } - switch (d->BAddress) - { - case 0x18: - case 0x19: - if (IPPU.RenderThisFrame) - FLUSH_REDRAW (); - break; - } - if (Settings.SDD1) - { - if (d->AAddressFixed && Memory.FillRAM [0x4801] > 0) - { - // Hacky support for pre-decompressed S-DD1 data - inc = !d->AAddressDecrement ? 1 : -1; - uint32 address = (((d->ABank << 16) | d->AAddress) & 0xfffff) << 4; - - address |= Memory.FillRAM [0x4804 + ((d->ABank - 0xc0) >> 4)]; + uint8 Work; + + if (Channel > 7 || CPU.InDMA) + return; + + CPU.InDMA = TRUE; + bool8 in_sa1_dma = FALSE; + uint8* in_sdd1_dma = NULL; + uint8* spc7110_dma = NULL; + bool s7_wrap = false; + SDMA* d = &DMA[Channel]; + + + int count = d->TransferBytes; + + if (count == 0) + count = 0x10000; + + int inc = d->AAddressFixed ? 0 : (!d->AAddressDecrement ? 1 : -1); + + if ((d->ABank == 0x7E || d->ABank == 0x7F) && d->BAddress == 0x80) + { + d->AAddress += d->TransferBytes; + //does an invalid DMA actually take time? + // I'd say yes, since 'invalid' is probably just the WRAM chip + // not being able to read and write itself at the same time + CPU.Cycles += (d->TransferBytes + 1) * SLOW_ONE_CYCLE; + goto update_address; + } + switch (d->BAddress) + { + case 0x18: + case 0x19: + if (IPPU.RenderThisFrame) + FLUSH_REDRAW(); + break; + } + if (Settings.SDD1) + { + if (d->AAddressFixed && Memory.FillRAM [0x4801] > 0) + { + // Hacky support for pre-decompressed S-DD1 data + inc = !d->AAddressDecrement ? 1 : -1; + uint32 address = (((d->ABank << 16) | d->AAddress) & 0xfffff) << 4; + + address |= Memory.FillRAM [0x4804 + ((d->ABank - 0xc0) >> 4)]; #ifdef SDD1_DECOMP - if(Settings.SDD1Pack) - { - uint8* in_ptr=GetBasePointer(((d->ABank << 16) | d->AAddress)); - in_ptr+=d->AAddress; + if (Settings.SDD1Pack) + { + uint8* in_ptr = GetBasePointer(((d->ABank << 16) | d->AAddress)); + in_ptr += d->AAddress; - SDD1_decompress(buffer,in_ptr,d->TransferBytes); - in_sdd1_dma=buffer; + SDD1_decompress(buffer, in_ptr, d->TransferBytes); + in_sdd1_dma = buffer; #ifdef SDD1_VERIFY - void *ptr = bsearch (&address, Memory.SDD1Index, - Memory.SDD1Entries, 12, S9xCompareSDD1IndexEntries); - if(memcmp(buffer, ptr, d->TransferBytes)) - { - uint8 *p = Memory.SDD1LoggedData; - bool8 found = FALSE; - uint8 SDD1Bank = Memory.FillRAM [0x4804 + ((d->ABank - 0xc0) >> 4)] | 0xf0; - - for (uint32 i = 0; i < Memory.SDD1LoggedDataCount; i++, p += 8) - { - if (*p == d->ABank || - *(p + 1) == (d->AAddress >> 8) && - *(p + 2) == (d->AAddress & 0xff) && - *(p + 3) == (count >> 8) && - *(p + 4) == (count & 0xff) && - *(p + 7) == SDD1Bank) - { - found = TRUE; - } - } - if (!found && Memory.SDD1LoggedDataCount < MEMMAP_MAX_SDD1_LOGGED_ENTRIES) - { - int j=0; - while(ptr[j]==buffer[j]) - j++; - - *p = d->ABank; - *(p + 1) = d->AAddress >> 8; - *(p + 2) = d->AAddress & 0xff; - *(p + 3) = j&0xFF; - *(p + 4) = (j>>8)&0xFF; - *(p + 7) = SDD1Bank; - Memory.SDD1LoggedDataCount += 1; - } - } + void* ptr = bsearch(&address, Memory.SDD1Index, + Memory.SDD1Entries, 12, S9xCompareSDD1IndexEntries); + if (memcmp(buffer, ptr, d->TransferBytes)) + { + uint8* p = Memory.SDD1LoggedData; + bool8 found = FALSE; + uint8 SDD1Bank = Memory.FillRAM [0x4804 + ((d->ABank - 0xc0) >> 4)] | 0xf0; + + for (uint32 i = 0; i < Memory.SDD1LoggedDataCount; i++, p += 8) + { + if (*p == d->ABank || + *(p + 1) == (d->AAddress >> 8) && + *(p + 2) == (d->AAddress & 0xff) && + *(p + 3) == (count >> 8) && + *(p + 4) == (count & 0xff) && + *(p + 7) == SDD1Bank) + found = TRUE; + } + if (!found && Memory.SDD1LoggedDataCount < MEMMAP_MAX_SDD1_LOGGED_ENTRIES) + { + int j = 0; + while (ptr[j] == buffer[j]) + j++; + + *p = d->ABank; + *(p + 1) = d->AAddress >> 8; + *(p + 2) = d->AAddress & 0xff; + *(p + 3) = j & 0xFF; + *(p + 4) = (j >> 8) & 0xFF; + *(p + 7) = SDD1Bank; + Memory.SDD1LoggedDataCount += 1; + } + } #endif - } + } - else - { + else + { #endif #if defined(__linux__) || defined (__WIN32__) - void *ptr = bsearch (&address, Memory.SDD1Index, - Memory.SDD1Entries, 12, S9xCompareSDD1IndexEntries); - if (ptr) - in_sdd1_dma = *(uint32 *) ((uint8 *) ptr + 4) + Memory.SDD1Data; + void* ptr = bsearch(&address, Memory.SDD1Index, + Memory.SDD1Entries, 12, S9xCompareSDD1IndexEntries); + if (ptr) + in_sdd1_dma = *(uint32*)((uint8*) ptr + 4) + Memory.SDD1Data; #else - uint8 *ptr = Memory.SDD1Index; - - uint32 e; - for (e = 0; e < Memory.SDD1Entries; e++, ptr += 12) - { - if (address == *(uint32 *) ptr) - { - in_sdd1_dma = *(uint32 *) (ptr + 4) + Memory.SDD1Data; - break; - } - } + uint8* ptr = Memory.SDD1Index; + + uint32 e; + for (e = 0; e < Memory.SDD1Entries; e++, ptr += 12) + { + if (address == *(uint32*) ptr) + { + in_sdd1_dma = *(uint32*)(ptr + 4) + Memory.SDD1Data; + break; + } + } #endif - - if (!in_sdd1_dma) - { - // No matching decompressed data found. Must be some new - // graphics not encountered before. Log it if it hasn't been - // already. - uint8 *p = Memory.SDD1LoggedData; - bool8 found = FALSE; - uint8 SDD1Bank = Memory.FillRAM [0x4804 + ((d->ABank - 0xc0) >> 4)] | 0xf0; - - uint32 i; - for (i = 0; i < Memory.SDD1LoggedDataCount; i++, p += 8) - { - if (*p == d->ABank || - *(p + 1) == (d->AAddress >> 8) && - *(p + 2) == (d->AAddress & 0xff) && - *(p + 3) == (count >> 8) && - *(p + 4) == (count & 0xff) && - *(p + 7) == SDD1Bank) - { - found = TRUE; - break; - } - } - if (!found && Memory.SDD1LoggedDataCount < MEMMAP_MAX_SDD1_LOGGED_ENTRIES) - { - *p = d->ABank; - *(p + 1) = d->AAddress >> 8; - *(p + 2) = d->AAddress & 0xff; - *(p + 3) = count >> 8; - *(p + 4) = count & 0xff; - *(p + 7) = SDD1Bank; - Memory.SDD1LoggedDataCount += 1; - } - } - } + + if (!in_sdd1_dma) + { + // No matching decompressed data found. Must be some new + // graphics not encountered before. Log it if it hasn't been + // already. + uint8* p = Memory.SDD1LoggedData; + bool8 found = FALSE; + uint8 SDD1Bank = Memory.FillRAM [0x4804 + ((d->ABank - 0xc0) >> 4)] | 0xf0; + + uint32 i; + for (i = 0; i < Memory.SDD1LoggedDataCount; i++, p += 8) + { + if (*p == d->ABank || + *(p + 1) == (d->AAddress >> 8) && + *(p + 2) == (d->AAddress & 0xff) && + *(p + 3) == (count >> 8) && + *(p + 4) == (count & 0xff) && + *(p + 7) == SDD1Bank) + { + found = TRUE; + break; + } + } + if (!found && Memory.SDD1LoggedDataCount < MEMMAP_MAX_SDD1_LOGGED_ENTRIES) + { + *p = d->ABank; + *(p + 1) = d->AAddress >> 8; + *(p + 2) = d->AAddress & 0xff; + *(p + 3) = count >> 8; + *(p + 4) = count & 0xff; + *(p + 7) = SDD1Bank; + Memory.SDD1LoggedDataCount += 1; + } + } + } #ifdef SDD1_DECOMP - } + } #endif - Memory.FillRAM [0x4801] = 0; - } - if(Settings.SPC7110&&(d->AAddress==0x4800||d->ABank==0x50)) - { - uint32 i,j; - i=(s7r.reg4805|(s7r.reg4806<<8)); - i*=s7r.AlignBy; - i+=s7r.bank50Internal; - i%=DECOMP_BUFFER_SIZE; - j=0; - if((i+d->TransferBytes)TransferBytes); - j=DECOMP_BUFFER_SIZE-i; - memcpy(spc7110_dma, &s7r.bank50[i], j); - memcpy(&spc7110_dma[j],s7r.bank50,d->TransferBytes-j); - s7_wrap=true; - } - int icount=s7r.reg4809|(s7r.reg480A<<8); - icount-=d->TransferBytes; - s7r.reg4809=0x00ff&icount; - s7r.reg480A=(0xff00&icount)>>8; - - s7r.bank50Internal+=d->TransferBytes; - s7r.bank50Internal%=DECOMP_BUFFER_SIZE; - inc=1; - d->AAddress-=count; - } - if (d->BAddress == 0x18 && SA1.in_char_dma && (d->ABank & 0xf0) == 0x40) - { - // Perform packed bitmap to PPU character format conversion on the - // data before transmitting it to V-RAM via-DMA. - int num_chars = 1 << ((Memory.FillRAM [0x2231] >> 2) & 7); - int depth = (Memory.FillRAM [0x2231] & 3) == 0 ? 8 : - (Memory.FillRAM [0x2231] & 3) == 1 ? 4 : 2; - - int bytes_per_char = 8 * depth; - int bytes_per_line = depth * num_chars; - int char_line_bytes = bytes_per_char * num_chars; - uint32 addr = (d->AAddress / char_line_bytes) * char_line_bytes; - uint8 *base = GetBasePointer ((d->ABank << 16) + addr) + addr; - uint8 *buffer = &Memory.ROM [MAX_ROM_SIZE - 0x10000]; - uint8 *p = buffer; - uint32 inc = char_line_bytes - (d->AAddress % char_line_bytes); - uint32 char_count = inc / bytes_per_char; - - in_sa1_dma = TRUE; - - //printf ("%08x,", base); fflush (stdout); - //printf ("depth = %d, count = %d, bytes_per_char = %d, bytes_per_line = %d, num_chars = %d, char_line_bytes = %d\n", - //depth, count, bytes_per_char, bytes_per_line, num_chars, char_line_bytes); - int i; - - switch (depth) - { - case 2: - for (i = 0; i < count; i += inc, base += char_line_bytes, - inc = char_line_bytes, char_count = num_chars) - { + Memory.FillRAM [0x4801] = 0; + } + if (Settings.SPC7110 && (d->AAddress == 0x4800 || d->ABank == 0x50)) + { + uint32 i, j; + i = (s7r.reg4805 | (s7r.reg4806 << 8)); + i *= s7r.AlignBy; + i += s7r.bank50Internal; + i %= DECOMP_BUFFER_SIZE; + j = 0; + if ((i + d->TransferBytes) < DECOMP_BUFFER_SIZE) + spc7110_dma = &s7r.bank50[i]; + else + { + spc7110_dma = (uint8*)malloc(d->TransferBytes); + j = DECOMP_BUFFER_SIZE - i; + memcpy(spc7110_dma, &s7r.bank50[i], j); + memcpy(&spc7110_dma[j], s7r.bank50, d->TransferBytes - j); + s7_wrap = true; + } + int icount = s7r.reg4809 | (s7r.reg480A << 8); + icount -= d->TransferBytes; + s7r.reg4809 = 0x00ff & icount; + s7r.reg480A = (0xff00 & icount) >> 8; + + s7r.bank50Internal += d->TransferBytes; + s7r.bank50Internal %= DECOMP_BUFFER_SIZE; + inc = 1; + d->AAddress -= count; + } + if (d->BAddress == 0x18 && SA1.in_char_dma && (d->ABank & 0xf0) == 0x40) + { + // Perform packed bitmap to PPU character format conversion on the + // data before transmitting it to V-RAM via-DMA. + int num_chars = 1 << ((Memory.FillRAM [0x2231] >> 2) & 7); + int depth = (Memory.FillRAM [0x2231] & 3) == 0 ? 8 : + (Memory.FillRAM [0x2231] & 3) == 1 ? 4 : 2; + + int bytes_per_char = 8 * depth; + int bytes_per_line = depth * num_chars; + int char_line_bytes = bytes_per_char * num_chars; + uint32 addr = (d->AAddress / char_line_bytes) * char_line_bytes; + uint8* base = GetBasePointer((d->ABank << 16) + addr) + addr; + uint8* buffer = &Memory.ROM [MAX_ROM_SIZE - 0x10000]; + uint8* p = buffer; + uint32 inc = char_line_bytes - (d->AAddress % char_line_bytes); + uint32 char_count = inc / bytes_per_char; + + in_sa1_dma = TRUE; + + //printf ("%08x,", base); fflush (stdout); + //printf ("depth = %d, count = %d, bytes_per_char = %d, bytes_per_line = %d, num_chars = %d, char_line_bytes = %d\n", + //depth, count, bytes_per_char, bytes_per_line, num_chars, char_line_bytes); + int i; + + switch (depth) + { + case 2: + for (i = 0; i < count; i += inc, base += char_line_bytes, + inc = char_line_bytes, char_count = num_chars) + { uint32 j; - uint8 *line = base + (num_chars - char_count) * 2; + uint8* line = base + (num_chars - char_count) * 2; for (j = 0; j < char_count && p - buffer < count; - j++, line += 2) - { - int b,l; - uint8 *q = line; + j++, line += 2) + { + int b, l; + uint8* q = line; for (l = 0; l < 8; l++, q += bytes_per_line) - { + { for (b = 0; b < 2; b++) - { - uint8 r = *(q + b); - *(p + 0) = (*(p + 0) << 1) | ((r >> 0) & 1); - *(p + 1) = (*(p + 1) << 1) | ((r >> 1) & 1); - *(p + 0) = (*(p + 0) << 1) | ((r >> 2) & 1); - *(p + 1) = (*(p + 1) << 1) | ((r >> 3) & 1); - *(p + 0) = (*(p + 0) << 1) | ((r >> 4) & 1); - *(p + 1) = (*(p + 1) << 1) | ((r >> 5) & 1); - *(p + 0) = (*(p + 0) << 1) | ((r >> 6) & 1); - *(p + 1) = (*(p + 1) << 1) | ((r >> 7) & 1); - } - p += 2; - } - } - } - break; - case 4: - for (i = 0; i < count; i += inc, base += char_line_bytes, - inc = char_line_bytes, char_count = num_chars) - { + { + uint8 r = *(q + b); + *(p + 0) = (*(p + 0) << 1) | ((r >> 0) & 1); + *(p + 1) = (*(p + 1) << 1) | ((r >> 1) & 1); + *(p + 0) = (*(p + 0) << 1) | ((r >> 2) & 1); + *(p + 1) = (*(p + 1) << 1) | ((r >> 3) & 1); + *(p + 0) = (*(p + 0) << 1) | ((r >> 4) & 1); + *(p + 1) = (*(p + 1) << 1) | ((r >> 5) & 1); + *(p + 0) = (*(p + 0) << 1) | ((r >> 6) & 1); + *(p + 1) = (*(p + 1) << 1) | ((r >> 7) & 1); + } + p += 2; + } + } + } + break; + case 4: + for (i = 0; i < count; i += inc, base += char_line_bytes, + inc = char_line_bytes, char_count = num_chars) + { uint32 j; - uint8 *line = base + (num_chars - char_count) * 4; + uint8* line = base + (num_chars - char_count) * 4; for (j = 0; j < char_count && p - buffer < count; - j++, line += 4) - { - uint8 *q = line; - int b,l; + j++, line += 4) + { + uint8* q = line; + int b, l; for (l = 0; l < 8; l++, q += bytes_per_line) - { + { for (b = 0; b < 4; b++) - { - uint8 r = *(q + b); - *(p + 0) = (*(p + 0) << 1) | ((r >> 0) & 1); - *(p + 1) = (*(p + 1) << 1) | ((r >> 1) & 1); - *(p + 16) = (*(p + 16) << 1) | ((r >> 2) & 1); - *(p + 17) = (*(p + 17) << 1) | ((r >> 3) & 1); - *(p + 0) = (*(p + 0) << 1) | ((r >> 4) & 1); - *(p + 1) = (*(p + 1) << 1) | ((r >> 5) & 1); - *(p + 16) = (*(p + 16) << 1) | ((r >> 6) & 1); - *(p + 17) = (*(p + 17) << 1) | ((r >> 7) & 1); - } - p += 2; - } - p += 32 - 16; - } - } - break; - case 8: - for (i = 0; i < count; i += inc, base += char_line_bytes, - inc = char_line_bytes, char_count = num_chars) - { - uint8 *line = base + (num_chars - char_count) * 8; + { + uint8 r = *(q + b); + *(p + 0) = (*(p + 0) << 1) | ((r >> 0) & 1); + *(p + 1) = (*(p + 1) << 1) | ((r >> 1) & 1); + *(p + 16) = (*(p + 16) << 1) | ((r >> 2) & 1); + *(p + 17) = (*(p + 17) << 1) | ((r >> 3) & 1); + *(p + 0) = (*(p + 0) << 1) | ((r >> 4) & 1); + *(p + 1) = (*(p + 1) << 1) | ((r >> 5) & 1); + *(p + 16) = (*(p + 16) << 1) | ((r >> 6) & 1); + *(p + 17) = (*(p + 17) << 1) | ((r >> 7) & 1); + } + p += 2; + } + p += 32 - 16; + } + } + break; + case 8: + for (i = 0; i < count; i += inc, base += char_line_bytes, + inc = char_line_bytes, char_count = num_chars) + { + uint8* line = base + (num_chars - char_count) * 8; uint32 j; for (j = 0; j < char_count && p - buffer < count; - j++, line += 8) - { - uint8 *q = line; - int b,l; + j++, line += 8) + { + uint8* q = line; + int b, l; for (l = 0; l < 8; l++, q += bytes_per_line) - { + { for (b = 0; b < 8; b++) - { - uint8 r = *(q + b); - *(p + 0) = (*(p + 0) << 1) | ((r >> 0) & 1); - *(p + 1) = (*(p + 1) << 1) | ((r >> 1) & 1); - *(p + 16) = (*(p + 16) << 1) | ((r >> 2) & 1); - *(p + 17) = (*(p + 17) << 1) | ((r >> 3) & 1); - *(p + 32) = (*(p + 32) << 1) | ((r >> 4) & 1); - *(p + 33) = (*(p + 33) << 1) | ((r >> 5) & 1); - *(p + 48) = (*(p + 48) << 1) | ((r >> 6) & 1); - *(p + 49) = (*(p + 49) << 1) | ((r >> 7) & 1); - } - p += 2; - } - p += 64 - 16; - } - } - break; - } - } - - if (!d->TransferDirection) - { - /* XXX: DMA is potentially broken here for cases where we DMA across - * XXX: memmap boundries. A possible solution would be to re-call - * XXX: GetBasePointer whenever we cross a boundry, and when - * XXX: GetBasePointer returns (0) to take the 'slow path' and use - * XXX: S9xGetByte instead of *base. GetBasePointer() would want to - * XXX: return (0) for MAP_PPU and whatever else is a register range - * XXX: rather than a RAM/ROM block, and we'd want to detect MAP_PPU - * XXX: (or specifically, Address Bus B addresses $2100-$21FF in - * XXX: banks $00-$3F) specially and treat it as MAP_NONE (since - * XXX: PPU->PPU transfers don't work). - */ - - //reflects extra cycle used by DMA - CPU.Cycles += SLOW_ONE_CYCLE * (count+1); - - uint8 *base = GetBasePointer ((d->ABank << 16) + d->AAddress); - uint16 p = d->AAddress; - - if (!base) - base = Memory.ROM; - - if (in_sa1_dma) - { + { + uint8 r = *(q + b); + *(p + 0) = (*(p + 0) << 1) | ((r >> 0) & 1); + *(p + 1) = (*(p + 1) << 1) | ((r >> 1) & 1); + *(p + 16) = (*(p + 16) << 1) | ((r >> 2) & 1); + *(p + 17) = (*(p + 17) << 1) | ((r >> 3) & 1); + *(p + 32) = (*(p + 32) << 1) | ((r >> 4) & 1); + *(p + 33) = (*(p + 33) << 1) | ((r >> 5) & 1); + *(p + 48) = (*(p + 48) << 1) | ((r >> 6) & 1); + *(p + 49) = (*(p + 49) << 1) | ((r >> 7) & 1); + } + p += 2; + } + p += 64 - 16; + } + } + break; + } + } + + if (!d->TransferDirection) + { + /* XXX: DMA is potentially broken here for cases where we DMA across + * XXX: memmap boundries. A possible solution would be to re-call + * XXX: GetBasePointer whenever we cross a boundry, and when + * XXX: GetBasePointer returns (0) to take the 'slow path' and use + * XXX: S9xGetByte instead of *base. GetBasePointer() would want to + * XXX: return (0) for MAP_PPU and whatever else is a register range + * XXX: rather than a RAM/ROM block, and we'd want to detect MAP_PPU + * XXX: (or specifically, Address Bus B addresses $2100-$21FF in + * XXX: banks $00-$3F) specially and treat it as MAP_NONE (since + * XXX: PPU->PPU transfers don't work). + */ + + //reflects extra cycle used by DMA + CPU.Cycles += SLOW_ONE_CYCLE * (count + 1); + + uint8* base = GetBasePointer((d->ABank << 16) + d->AAddress); + uint16 p = d->AAddress; + + if (!base) + base = Memory.ROM; + + if (in_sa1_dma) + { base = &Memory.ROM [MAX_ROM_SIZE - 0x10000]; - p = 0; - } - - if (in_sdd1_dma) - { - base = in_sdd1_dma; - p = 0; - } - if(spc7110_dma) - { - base=spc7110_dma; - p = 0; - } - if (inc > 0) - d->AAddress += count; - else - if (inc < 0) - d->AAddress -= count; - - if (d->TransferMode == 0 || d->TransferMode == 2 || d->TransferMode == 6) - { - switch (d->BAddress) - { - case 0x04: - do - { - Work = *(base + p); - REGISTER_2104(Work); - p += inc; - CHECK_SOUND(); - } while (--count > 0); - break; - case 0x18: + p = 0; + } + + if (in_sdd1_dma) + { + base = in_sdd1_dma; + p = 0; + } + if (spc7110_dma) + { + base = spc7110_dma; + p = 0; + } + if (inc > 0) + d->AAddress += count; + else if (inc < 0) + d->AAddress -= count; + + if (d->TransferMode == 0 || d->TransferMode == 2 || d->TransferMode == 6) + { + switch (d->BAddress) + { + case 0x04: + do + { + Work = *(base + p); + REGISTER_2104(Work); + p += inc; + CHECK_SOUND(); + } + while (--count > 0); + break; + case 0x18: #ifndef CORRECT_VRAM_READS - IPPU.FirstVRAMRead = TRUE; + IPPU.FirstVRAMRead = TRUE; #endif - if (!PPU.VMA.FullGraphicCount) - { - do - { - Work = *(base + p); - REGISTER_2118_linear(Work); - p += inc; - CHECK_SOUND(); - } while (--count > 0); - } - else - { - do - { - Work = *(base + p); - REGISTER_2118_tile(Work); - p += inc; - CHECK_SOUND(); - } while (--count > 0); - } - break; - case 0x19: + if (!PPU.VMA.FullGraphicCount) + { + do + { + Work = *(base + p); + REGISTER_2118_linear(Work); + p += inc; + CHECK_SOUND(); + } + while (--count > 0); + } + else + { + do + { + Work = *(base + p); + REGISTER_2118_tile(Work); + p += inc; + CHECK_SOUND(); + } + while (--count > 0); + } + break; + case 0x19: #ifndef CORRECT_VRAM_READS - IPPU.FirstVRAMRead = TRUE; + IPPU.FirstVRAMRead = TRUE; #endif - if (!PPU.VMA.FullGraphicCount) - { - do - { - Work = *(base + p); - REGISTER_2119_linear(Work); - p += inc; - CHECK_SOUND(); - } while (--count > 0); - } - else - { - do - { - Work = *(base + p); - REGISTER_2119_tile(Work); - p += inc; - CHECK_SOUND(); - } while (--count > 0); - } - break; - case 0x22: - do - { - Work = *(base + p); - REGISTER_2122(Work); - p += inc; - CHECK_SOUND(); - } while (--count > 0); - break; - case 0x80: - do - { - Work = *(base + p); - REGISTER_2180(Work); - p += inc; - CHECK_SOUND(); - } while (--count > 0); - break; - default: - do - { - Work = *(base + p); - S9xSetPPU (Work, 0x2100 + d->BAddress); - p += inc; - CHECK_SOUND(); - } while (--count > 0); - break; - } - } - else - if (d->TransferMode == 1 || d->TransferMode == 5) - { - if (d->BAddress == 0x18) - { - // Write to V-RAM + if (!PPU.VMA.FullGraphicCount) + { + do + { + Work = *(base + p); + REGISTER_2119_linear(Work); + p += inc; + CHECK_SOUND(); + } + while (--count > 0); + } + else + { + do + { + Work = *(base + p); + REGISTER_2119_tile(Work); + p += inc; + CHECK_SOUND(); + } + while (--count > 0); + } + break; + case 0x22: + do + { + Work = *(base + p); + REGISTER_2122(Work); + p += inc; + CHECK_SOUND(); + } + while (--count > 0); + break; + case 0x80: + do + { + Work = *(base + p); + REGISTER_2180(Work); + p += inc; + CHECK_SOUND(); + } + while (--count > 0); + break; + default: + do + { + Work = *(base + p); + S9xSetPPU(Work, 0x2100 + d->BAddress); + p += inc; + CHECK_SOUND(); + } + while (--count > 0); + break; + } + } + else if (d->TransferMode == 1 || d->TransferMode == 5) + { + if (d->BAddress == 0x18) + { + // Write to V-RAM #ifndef CORRECT_VRAM_READS - IPPU.FirstVRAMRead = TRUE; + IPPU.FirstVRAMRead = TRUE; #endif - if (!PPU.VMA.FullGraphicCount) - { - while (count > 1) - { - Work = *(base + p); - REGISTER_2118_linear(Work); - p += inc; - - Work = *(base + p); - REGISTER_2119_linear(Work); - p += inc; - CHECK_SOUND(); - count -= 2; - } - if (count == 1) - { - Work = *(base + p); - REGISTER_2118_linear(Work); - p += inc; - } - } - else - { - while (count > 1) - { - Work = *(base + p); - REGISTER_2118_tile(Work); - p += inc; - - Work = *(base + p); - REGISTER_2119_tile(Work); - p += inc; - CHECK_SOUND(); - count -= 2; - } - if (count == 1) - { - Work = *(base + p); - REGISTER_2118_tile(Work); - p += inc; - } - } - } - else - { - // DMA mode 1 general case - while (count > 1) - { - Work = *(base + p); - S9xSetPPU (Work, 0x2100 + d->BAddress); - p += inc; - - Work = *(base + p); - S9xSetPPU (Work, 0x2101 + d->BAddress); - p += inc; - CHECK_SOUND(); - count -= 2; - } - if (count == 1) - { - Work = *(base + p); - S9xSetPPU (Work, 0x2100 + d->BAddress); - p += inc; - } - } - } - else - if (d->TransferMode == 3 || d->TransferMode == 7) - { - do - { - Work = *(base + p); - S9xSetPPU (Work, 0x2100 + d->BAddress); - p += inc; - if (count <= 1) - break; - - Work = *(base + p); - S9xSetPPU (Work, 0x2100 + d->BAddress); - p += inc; - if (count <= 2) - break; - - Work = *(base + p); - S9xSetPPU (Work, 0x2101 + d->BAddress); - p += inc; - if (count <= 3) - break; - - Work = *(base + p); - S9xSetPPU (Work, 0x2101 + d->BAddress); - p += inc; - CHECK_SOUND(); - count -= 4; - } while (count > 0); - } - else - if (d->TransferMode == 4) - { - do - { - Work = *(base + p); - S9xSetPPU (Work, 0x2100 + d->BAddress); - p += inc; - if (count <= 1) - break; - - Work = *(base + p); - S9xSetPPU (Work, 0x2101 + d->BAddress); - p += inc; - if (count <= 2) - break; - - Work = *(base + p); - S9xSetPPU (Work, 0x2102 + d->BAddress); - p += inc; - if (count <= 3) - break; - - Work = *(base + p); - S9xSetPPU (Work, 0x2103 + d->BAddress); - p += inc; - CHECK_SOUND(); - count -= 4; - } while (count > 0); - } - } - else - { - /* XXX: DMA is potentially broken here for cases where the dest is - * XXX: in the Address Bus B range. Note that this bad dest may not - * XXX: cover the whole range of the DMA though, if we transfer - * XXX: 65536 bytes only 256 of them may be Address Bus B. - */ - do - { - switch (d->TransferMode) - { - case 0: - case 2: - case 6: - Work = S9xGetPPU (0x2100 + d->BAddress); - S9xSetByte (Work, (d->ABank << 16) + d->AAddress); - d->AAddress += inc; - --count; - break; - - case 1: - case 5: - Work = S9xGetPPU (0x2100 + d->BAddress); - S9xSetByte (Work, (d->ABank << 16) + d->AAddress); - d->AAddress += inc; - if (!--count) - break; - - Work = S9xGetPPU (0x2101 + d->BAddress); - S9xSetByte (Work, (d->ABank << 16) + d->AAddress); - d->AAddress += inc; - count--; - break; - - case 3: - case 7: - Work = S9xGetPPU (0x2100 + d->BAddress); - S9xSetByte (Work, (d->ABank << 16) + d->AAddress); - d->AAddress += inc; - if (!--count) - break; - - Work = S9xGetPPU (0x2100 + d->BAddress); - S9xSetByte (Work, (d->ABank << 16) + d->AAddress); - d->AAddress += inc; - if (!--count) - break; - - Work = S9xGetPPU (0x2101 + d->BAddress); - S9xSetByte (Work, (d->ABank << 16) + d->AAddress); - d->AAddress += inc; - if (!--count) - break; - - Work = S9xGetPPU (0x2101 + d->BAddress); - S9xSetByte (Work, (d->ABank << 16) + d->AAddress); - d->AAddress += inc; - count--; - break; - - case 4: - Work = S9xGetPPU (0x2100 + d->BAddress); - S9xSetByte (Work, (d->ABank << 16) + d->AAddress); - d->AAddress += inc; - if (!--count) - break; - - Work = S9xGetPPU (0x2101 + d->BAddress); - S9xSetByte (Work, (d->ABank << 16) + d->AAddress); - d->AAddress += inc; - if (!--count) - break; - - Work = S9xGetPPU (0x2102 + d->BAddress); - S9xSetByte (Work, (d->ABank << 16) + d->AAddress); - d->AAddress += inc; - if (!--count) - break; - - Work = S9xGetPPU (0x2103 + d->BAddress); - S9xSetByte (Work, (d->ABank << 16) + d->AAddress); - d->AAddress += inc; - count--; - break; - - default: - count = 0; - break; - } - CHECK_SOUND(); - } while (count); - } - + if (!PPU.VMA.FullGraphicCount) + { + while (count > 1) + { + Work = *(base + p); + REGISTER_2118_linear(Work); + p += inc; + + Work = *(base + p); + REGISTER_2119_linear(Work); + p += inc; + CHECK_SOUND(); + count -= 2; + } + if (count == 1) + { + Work = *(base + p); + REGISTER_2118_linear(Work); + p += inc; + } + } + else + { + while (count > 1) + { + Work = *(base + p); + REGISTER_2118_tile(Work); + p += inc; + + Work = *(base + p); + REGISTER_2119_tile(Work); + p += inc; + CHECK_SOUND(); + count -= 2; + } + if (count == 1) + { + Work = *(base + p); + REGISTER_2118_tile(Work); + p += inc; + } + } + } + else + { + // DMA mode 1 general case + while (count > 1) + { + Work = *(base + p); + S9xSetPPU(Work, 0x2100 + d->BAddress); + p += inc; + + Work = *(base + p); + S9xSetPPU(Work, 0x2101 + d->BAddress); + p += inc; + CHECK_SOUND(); + count -= 2; + } + if (count == 1) + { + Work = *(base + p); + S9xSetPPU(Work, 0x2100 + d->BAddress); + p += inc; + } + } + } + else if (d->TransferMode == 3 || d->TransferMode == 7) + { + do + { + Work = *(base + p); + S9xSetPPU(Work, 0x2100 + d->BAddress); + p += inc; + if (count <= 1) + break; + + Work = *(base + p); + S9xSetPPU(Work, 0x2100 + d->BAddress); + p += inc; + if (count <= 2) + break; + + Work = *(base + p); + S9xSetPPU(Work, 0x2101 + d->BAddress); + p += inc; + if (count <= 3) + break; + + Work = *(base + p); + S9xSetPPU(Work, 0x2101 + d->BAddress); + p += inc; + CHECK_SOUND(); + count -= 4; + } + while (count > 0); + } + else if (d->TransferMode == 4) + { + do + { + Work = *(base + p); + S9xSetPPU(Work, 0x2100 + d->BAddress); + p += inc; + if (count <= 1) + break; + + Work = *(base + p); + S9xSetPPU(Work, 0x2101 + d->BAddress); + p += inc; + if (count <= 2) + break; + + Work = *(base + p); + S9xSetPPU(Work, 0x2102 + d->BAddress); + p += inc; + if (count <= 3) + break; + + Work = *(base + p); + S9xSetPPU(Work, 0x2103 + d->BAddress); + p += inc; + CHECK_SOUND(); + count -= 4; + } + while (count > 0); + } + } + else + { + /* XXX: DMA is potentially broken here for cases where the dest is + * XXX: in the Address Bus B range. Note that this bad dest may not + * XXX: cover the whole range of the DMA though, if we transfer + * XXX: 65536 bytes only 256 of them may be Address Bus B. + */ + do + { + switch (d->TransferMode) + { + case 0: + case 2: + case 6: + Work = S9xGetPPU(0x2100 + d->BAddress); + S9xSetByte(Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + --count; + break; + + case 1: + case 5: + Work = S9xGetPPU(0x2100 + d->BAddress); + S9xSetByte(Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + if (!--count) + break; + + Work = S9xGetPPU(0x2101 + d->BAddress); + S9xSetByte(Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + count--; + break; + + case 3: + case 7: + Work = S9xGetPPU(0x2100 + d->BAddress); + S9xSetByte(Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + if (!--count) + break; + + Work = S9xGetPPU(0x2100 + d->BAddress); + S9xSetByte(Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + if (!--count) + break; + + Work = S9xGetPPU(0x2101 + d->BAddress); + S9xSetByte(Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + if (!--count) + break; + + Work = S9xGetPPU(0x2101 + d->BAddress); + S9xSetByte(Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + count--; + break; + + case 4: + Work = S9xGetPPU(0x2100 + d->BAddress); + S9xSetByte(Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + if (!--count) + break; + + Work = S9xGetPPU(0x2101 + d->BAddress); + S9xSetByte(Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + if (!--count) + break; + + Work = S9xGetPPU(0x2102 + d->BAddress); + S9xSetByte(Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + if (!--count) + break; + + Work = S9xGetPPU(0x2103 + d->BAddress); + S9xSetByte(Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + count--; + break; + + default: + count = 0; + break; + } + CHECK_SOUND(); + } + while (count); + } + #ifdef SPC700_C - IAPU.APUExecuting = Settings.APUEnabled; - APU_EXECUTE (); + IAPU.APUExecuting = Settings.APUEnabled; + APU_EXECUTE(); #endif - if (Settings.SuperFX) - while (CPU.Cycles > CPU.NextEvent) - S9xDoHBlankProcessing_SFX (); - else /* if (!Settings.SuperFX) */ - while (CPU.Cycles > CPU.NextEvent) - S9xDoHBlankProcessing_NoSFX (); - - if(Settings.SPC7110&&spc7110_dma) - { - if(spc7110_dma&&s7_wrap) + if (Settings.SuperFX) + while (CPU.Cycles > CPU.NextEvent) + S9xDoHBlankProcessing_SFX(); + else /* if (!Settings.SuperFX) */ + while (CPU.Cycles > CPU.NextEvent) + S9xDoHBlankProcessing_NoSFX(); + + if (Settings.SPC7110 && spc7110_dma) + { + if (spc7110_dma && s7_wrap) free(spc7110_dma); - } + } update_address: - // Super Punch-Out requires that the A-BUS address be updated after the - // DMA transfer. - Memory.FillRAM[0x4302 + (Channel << 4)] = (uint8) d->AAddress; - Memory.FillRAM[0x4303 + (Channel << 4)] = d->AAddress >> 8; - - // Secret of the Mana requires that the DMA bytes transfer count be set to - // zero when DMA has completed. - Memory.FillRAM [0x4305 + (Channel << 4)] = 0; - Memory.FillRAM [0x4306 + (Channel << 4)] = 0; - - DMA[Channel].IndirectAddress = 0; - d->TransferBytes = 0; - - CPU.InDMA = FALSE; + // Super Punch-Out requires that the A-BUS address be updated after the + // DMA transfer. + Memory.FillRAM[0x4302 + (Channel << 4)] = (uint8) d->AAddress; + Memory.FillRAM[0x4303 + (Channel << 4)] = d->AAddress >> 8; + + // Secret of the Mana requires that the DMA bytes transfer count be set to + // zero when DMA has completed. + Memory.FillRAM [0x4305 + (Channel << 4)] = 0; + Memory.FillRAM [0x4306 + (Channel << 4)] = 0; + + DMA[Channel].IndirectAddress = 0; + d->TransferBytes = 0; + + CPU.InDMA = FALSE; } -void S9xStartHDMA () +void S9xStartHDMA() { - if (Settings.DisableHDMA) - IPPU.HDMA = 0; - else - missing.hdma_this_frame = IPPU.HDMA = Memory.FillRAM [0x420c]; - - //per anomie timing post - if(IPPU.HDMA!=0) - CPU.Cycles+=ONE_CYCLE*3; - - IPPU.HDMAStarted = TRUE; - - uint8 i; - for (i = 0; i < 8; i++) - { - if (IPPU.HDMA & (1 << i)) - { - CPU.Cycles+=SLOW_ONE_CYCLE ; - DMA [i].LineCount = 0; - DMA [i].FirstLine = TRUE; - DMA [i].Address = DMA [i].AAddress; - if(DMA[i].HDMAIndirectAddressing) - CPU.Cycles+=(SLOW_ONE_CYCLE <<2); - } - HDMAMemPointers [i] = NULL; + if (Settings.DisableHDMA) + IPPU.HDMA = 0; + else + missing.hdma_this_frame = IPPU.HDMA = Memory.FillRAM [0x420c]; + + //per anomie timing post + if (IPPU.HDMA != 0) + CPU.Cycles += ONE_CYCLE * 3; + + IPPU.HDMAStarted = TRUE; + + uint8 i; + for (i = 0; i < 8; i++) + { + if (IPPU.HDMA & (1 << i)) + { + CPU.Cycles += SLOW_ONE_CYCLE ; + DMA [i].LineCount = 0; + DMA [i].FirstLine = TRUE; + DMA [i].Address = DMA [i].AAddress; + if (DMA[i].HDMAIndirectAddressing) + CPU.Cycles += (SLOW_ONE_CYCLE << 2); + } + HDMAMemPointers [i] = NULL; #ifdef SETA010_HDMA_FROM_CART - HDMARawPointers [i] = 0; + HDMARawPointers [i] = 0; #endif - } + } } -uint8 S9xDoHDMA (uint8 byte) +uint8 S9xDoHDMA(uint8 byte) { - SDMA *p = &DMA [0]; - - int d = 0; + SDMA* p = &DMA [0]; + + int d = 0; - CPU.InDMA = TRUE; - CPU.Cycles+=ONE_CYCLE*3; + CPU.InDMA = TRUE; + CPU.Cycles += ONE_CYCLE * 3; uint8 mask; for (mask = 1; mask; mask <<= 1, p++, d++) - { - if (byte & mask) - { - if (!p->LineCount) - { - //remember, InDMA is set. - //Get/Set incur no charges! - CPU.Cycles+=SLOW_ONE_CYCLE; - uint8 line = S9xGetByte ((p->ABank << 16) + p->Address); - if (line == 0x80) - { - p->Repeat = TRUE; - p->LineCount = 128; - } - else - { - p->Repeat = !(line & 0x80); - p->LineCount = line & 0x7f; - } - - // Disable H-DMA'ing into V-RAM (register 2118) for Hook - /* XXX: instead of p->BAddress == 0x18, make S9xSetPPU fail - * XXX: writes to $2118/9 when appropriate - */ + { + if (byte & mask) + { + if (!p->LineCount) + { + //remember, InDMA is set. + //Get/Set incur no charges! + CPU.Cycles += SLOW_ONE_CYCLE; + uint8 line = S9xGetByte((p->ABank << 16) + p->Address); + if (line == 0x80) + { + p->Repeat = TRUE; + p->LineCount = 128; + } + else + { + p->Repeat = !(line & 0x80); + p->LineCount = line & 0x7f; + } + + // Disable H-DMA'ing into V-RAM (register 2118) for Hook + /* XXX: instead of p->BAddress == 0x18, make S9xSetPPU fail + * XXX: writes to $2118/9 when appropriate + */ #ifdef SETA010_HDMA_FROM_CART - if (!p->LineCount) + if (!p->LineCount) #else - if (!p->LineCount || p->BAddress == 0x18) + if (!p->LineCount || p->BAddress == 0x18) #endif - { - byte &= ~mask; - p->IndirectAddress += HDMAMemPointers [d] - HDMABasePointers [d]; - Memory.FillRAM [0x4305 + (d << 4)] = (uint8) p->IndirectAddress; - Memory.FillRAM [0x4306 + (d << 4)] = p->IndirectAddress >> 8; - continue; - } - - p->Address++; - p->FirstLine = 1; - if (p->HDMAIndirectAddressing) - { - p->IndirectBank = Memory.FillRAM [0x4307 + (d << 4)]; - //again, no cycle charges while InDMA is set! - CPU.Cycles+=SLOW_ONE_CYCLE<<2; - p->IndirectAddress = S9xGetWord ((p->ABank << 16) + p->Address); - p->Address += 2; - } - else - { - p->IndirectBank = p->ABank; - p->IndirectAddress = p->Address; - } - HDMABasePointers [d] = HDMAMemPointers [d] = - S9xGetMemPointer ((p->IndirectBank << 16) + p->IndirectAddress); + { + byte &= ~mask; + p->IndirectAddress += HDMAMemPointers [d] - HDMABasePointers [d]; + Memory.FillRAM [0x4305 + (d << 4)] = (uint8) p->IndirectAddress; + Memory.FillRAM [0x4306 + (d << 4)] = p->IndirectAddress >> 8; + continue; + } + + p->Address++; + p->FirstLine = 1; + if (p->HDMAIndirectAddressing) + { + p->IndirectBank = Memory.FillRAM [0x4307 + (d << 4)]; + //again, no cycle charges while InDMA is set! + CPU.Cycles += SLOW_ONE_CYCLE << 2; + p->IndirectAddress = S9xGetWord((p->ABank << 16) + p->Address); + p->Address += 2; + } + else + { + p->IndirectBank = p->ABank; + p->IndirectAddress = p->Address; + } + HDMABasePointers [d] = HDMAMemPointers [d] = + S9xGetMemPointer((p->IndirectBank << 16) + p->IndirectAddress); #ifdef SETA010_HDMA_FROM_CART - HDMARawPointers [d] = (p->IndirectBank << 16) + p->IndirectAddress; + HDMARawPointers [d] = (p->IndirectBank << 16) + p->IndirectAddress; #endif - } - else - { - CPU.Cycles += SLOW_ONE_CYCLE; - } - - if (!HDMAMemPointers [d]) - { - if (!p->HDMAIndirectAddressing) - { - p->IndirectBank = p->ABank; - p->IndirectAddress = p->Address; - } + } + else + CPU.Cycles += SLOW_ONE_CYCLE; + + if (!HDMAMemPointers [d]) + { + if (!p->HDMAIndirectAddressing) + { + p->IndirectBank = p->ABank; + p->IndirectAddress = p->Address; + } #ifdef SETA010_HDMA_FROM_CART - HDMARawPointers [d] = (p->IndirectBank << 16) + p->IndirectAddress; + HDMARawPointers [d] = (p->IndirectBank << 16) + p->IndirectAddress; #endif - if (!(HDMABasePointers [d] = HDMAMemPointers [d] = - S9xGetMemPointer ((p->IndirectBank << 16) + p->IndirectAddress))) - { - /* XXX: Instead of this, goto a slow path that first - * XXX: verifies src!=Address Bus B, then uses - * XXX: S9xGetByte(). Or make S9xGetByte return OpenBus - * XXX: (probably?) for Address Bus B while inDMA. - */ - byte &= ~mask; - continue; - } - // Uncommenting the following line breaks Punchout - it starts - // H-DMA during the frame. - //p->FirstLine = TRUE; - } - if (p->Repeat && !p->FirstLine) - { - p->LineCount--; - continue; - } - - if (p->BAddress == 0x04){ - if(SNESGameFixes.Uniracers){ - PPU.OAMAddr = 0x10c; - PPU.OAMFlip=0; - } - } - - switch (p->TransferMode) - { - case 0: - CPU.Cycles += SLOW_ONE_CYCLE; + if (!(HDMABasePointers [d] = HDMAMemPointers [d] = + S9xGetMemPointer((p->IndirectBank << 16) + p->IndirectAddress))) + { + /* XXX: Instead of this, goto a slow path that first + * XXX: verifies src!=Address Bus B, then uses + * XXX: S9xGetByte(). Or make S9xGetByte return OpenBus + * XXX: (probably?) for Address Bus B while inDMA. + */ + byte &= ~mask; + continue; + } + // Uncommenting the following line breaks Punchout - it starts + // H-DMA during the frame. + //p->FirstLine = TRUE; + } + if (p->Repeat && !p->FirstLine) + { + p->LineCount--; + continue; + } + + if (p->BAddress == 0x04) + { + if (SNESGameFixes.Uniracers) + { + PPU.OAMAddr = 0x10c; + PPU.OAMFlip = 0; + } + } + + switch (p->TransferMode) + { + case 0: + CPU.Cycles += SLOW_ONE_CYCLE; #ifdef SETA010_HDMA_FROM_CART - S9xSetPPU (S9xGetByte (HDMARawPointers [d]++), 0x2100 + p->BAddress); - HDMAMemPointers [d]++; + S9xSetPPU(S9xGetByte(HDMARawPointers [d]++), 0x2100 + p->BAddress); + HDMAMemPointers [d]++; #else - S9xSetPPU (*HDMAMemPointers [d]++, 0x2100 + p->BAddress); + S9xSetPPU(*HDMAMemPointers [d]++, 0x2100 + p->BAddress); #endif - break; - case 5: - CPU.Cycles += 2*SLOW_ONE_CYCLE; + break; + case 5: + CPU.Cycles += 2 * SLOW_ONE_CYCLE; #ifdef SETA010_HDMA_FROM_CART - S9xSetPPU (S9xGetByte (HDMARawPointers [d]), 0x2100 + p->BAddress); - S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 1), 0x2101 + p->BAddress); - HDMARawPointers [d] += 2; + S9xSetPPU(S9xGetByte(HDMARawPointers [d]), 0x2100 + p->BAddress); + S9xSetPPU(S9xGetByte(HDMARawPointers [d] + 1), 0x2101 + p->BAddress); + HDMARawPointers [d] += 2; #else - S9xSetPPU (*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); - S9xSetPPU (*(HDMAMemPointers [d] + 1), 0x2101 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 1), 0x2101 + p->BAddress); #endif - HDMAMemPointers [d] += 2; - /* fall through */ - case 1: - CPU.Cycles += 2*SLOW_ONE_CYCLE; + HDMAMemPointers [d] += 2; + /* fall through */ + case 1: + CPU.Cycles += 2 * SLOW_ONE_CYCLE; #ifdef SETA010_HDMA_FROM_CART - S9xSetPPU (S9xGetByte (HDMARawPointers [d]), 0x2100 + p->BAddress); - S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 1), 0x2101 + p->BAddress); - HDMARawPointers [d] += 2; + S9xSetPPU(S9xGetByte(HDMARawPointers [d]), 0x2100 + p->BAddress); + S9xSetPPU(S9xGetByte(HDMARawPointers [d] + 1), 0x2101 + p->BAddress); + HDMARawPointers [d] += 2; #else - S9xSetPPU (*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); - S9xSetPPU (*(HDMAMemPointers [d] + 1), 0x2101 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 1), 0x2101 + p->BAddress); #endif - HDMAMemPointers [d] += 2; - break; - case 2: - case 6: - CPU.Cycles += 2*SLOW_ONE_CYCLE; + HDMAMemPointers [d] += 2; + break; + case 2: + case 6: + CPU.Cycles += 2 * SLOW_ONE_CYCLE; #ifdef SETA010_HDMA_FROM_CART - S9xSetPPU (S9xGetByte (HDMARawPointers [d]), 0x2100 + p->BAddress); - S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 1), 0x2100 + p->BAddress); - HDMARawPointers [d] += 2; + S9xSetPPU(S9xGetByte(HDMARawPointers [d]), 0x2100 + p->BAddress); + S9xSetPPU(S9xGetByte(HDMARawPointers [d] + 1), 0x2100 + p->BAddress); + HDMARawPointers [d] += 2; #else - S9xSetPPU (*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); - S9xSetPPU (*(HDMAMemPointers [d] + 1), 0x2100 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 1), 0x2100 + p->BAddress); #endif - HDMAMemPointers [d] += 2; - break; - case 3: - case 7: - CPU.Cycles += 4*SLOW_ONE_CYCLE; + HDMAMemPointers [d] += 2; + break; + case 3: + case 7: + CPU.Cycles += 4 * SLOW_ONE_CYCLE; #ifdef SETA010_HDMA_FROM_CART - S9xSetPPU (S9xGetByte (HDMARawPointers [d]), 0x2100 + p->BAddress); - S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 1), 0x2100 + p->BAddress); - S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 2), 0x2101 + p->BAddress); - S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 3), 0x2101 + p->BAddress); - HDMARawPointers [d] += 4; + S9xSetPPU(S9xGetByte(HDMARawPointers [d]), 0x2100 + p->BAddress); + S9xSetPPU(S9xGetByte(HDMARawPointers [d] + 1), 0x2100 + p->BAddress); + S9xSetPPU(S9xGetByte(HDMARawPointers [d] + 2), 0x2101 + p->BAddress); + S9xSetPPU(S9xGetByte(HDMARawPointers [d] + 3), 0x2101 + p->BAddress); + HDMARawPointers [d] += 4; #else - S9xSetPPU (*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); - S9xSetPPU (*(HDMAMemPointers [d] + 1), 0x2100 + p->BAddress); - S9xSetPPU (*(HDMAMemPointers [d] + 2), 0x2101 + p->BAddress); - S9xSetPPU (*(HDMAMemPointers [d] + 3), 0x2101 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 1), 0x2100 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 2), 0x2101 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 3), 0x2101 + p->BAddress); #endif - HDMAMemPointers [d] += 4; - break; - case 4: - CPU.Cycles += 4*SLOW_ONE_CYCLE; + HDMAMemPointers [d] += 4; + break; + case 4: + CPU.Cycles += 4 * SLOW_ONE_CYCLE; #ifdef SETA010_HDMA_FROM_CART - S9xSetPPU (S9xGetByte (HDMARawPointers [d]), 0x2100 + p->BAddress); - S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 1), 0x2101 + p->BAddress); - S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 2), 0x2102 + p->BAddress); - S9xSetPPU (S9xGetByte (HDMARawPointers [d] + 3), 0x2103 + p->BAddress); - HDMARawPointers [d] += 4; + S9xSetPPU(S9xGetByte(HDMARawPointers [d]), 0x2100 + p->BAddress); + S9xSetPPU(S9xGetByte(HDMARawPointers [d] + 1), 0x2101 + p->BAddress); + S9xSetPPU(S9xGetByte(HDMARawPointers [d] + 2), 0x2102 + p->BAddress); + S9xSetPPU(S9xGetByte(HDMARawPointers [d] + 3), 0x2103 + p->BAddress); + HDMARawPointers [d] += 4; #else - S9xSetPPU (*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); - S9xSetPPU (*(HDMAMemPointers [d] + 1), 0x2101 + p->BAddress); - S9xSetPPU (*(HDMAMemPointers [d] + 2), 0x2102 + p->BAddress); - S9xSetPPU (*(HDMAMemPointers [d] + 3), 0x2103 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 1), 0x2101 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 2), 0x2102 + p->BAddress); + S9xSetPPU(*(HDMAMemPointers [d] + 3), 0x2103 + p->BAddress); #endif - HDMAMemPointers [d] += 4; - break; - } - if (!p->HDMAIndirectAddressing) - p->Address += HDMA_ModeByteCounts [p->TransferMode]; - p->IndirectAddress += HDMA_ModeByteCounts [p->TransferMode]; - /* XXX: Check for p->IndirectAddress crossing a mapping boundry, - * XXX: and invalidate HDMAMemPointers[d] - */ - p->FirstLine = FALSE; - p->LineCount--; - } - } - CPU.InDMA=FALSE; - return (byte); + HDMAMemPointers [d] += 4; + break; + } + if (!p->HDMAIndirectAddressing) + p->Address += HDMA_ModeByteCounts [p->TransferMode]; + p->IndirectAddress += HDMA_ModeByteCounts [p->TransferMode]; + /* XXX: Check for p->IndirectAddress crossing a mapping boundry, + * XXX: and invalidate HDMAMemPointers[d] + */ + p->FirstLine = FALSE; + p->LineCount--; + } + } + CPU.InDMA = FALSE; + return (byte); } -void S9xResetDMA () +void S9xResetDMA() { - int c,d; - for (d = 0; d < 8; d++) - { - DMA [d].TransferDirection = FALSE; - DMA [d].HDMAIndirectAddressing = FALSE; - DMA [d].AAddressFixed = TRUE; - DMA [d].AAddressDecrement = FALSE; - DMA [d].TransferMode = 0xff; - DMA [d].ABank = 0xff; - DMA [d].AAddress = 0xffff; - DMA [d].Address = 0xffff; - DMA [d].BAddress = 0xff; - DMA [d].TransferBytes = 0xffff; - } - for (c = 0x4300; c < 0x4380; c += 0x10) - { - for (d = c; d < c + 12; d++) - Memory.FillRAM [d] = 0xff; - - Memory.FillRAM [c + 0xf] = 0xff; - } + int c, d; + for (d = 0; d < 8; d++) + { + DMA [d].TransferDirection = FALSE; + DMA [d].HDMAIndirectAddressing = FALSE; + DMA [d].AAddressFixed = TRUE; + DMA [d].AAddressDecrement = FALSE; + DMA [d].TransferMode = 0xff; + DMA [d].ABank = 0xff; + DMA [d].AAddress = 0xffff; + DMA [d].Address = 0xffff; + DMA [d].BAddress = 0xff; + DMA [d].TransferBytes = 0xffff; + } + for (c = 0x4300; c < 0x4380; c += 0x10) + { + for (d = c; d < c + 12; d++) + Memory.FillRAM [d] = 0xff; + + Memory.FillRAM [c + 0xf] = 0xff; + } } diff --git a/source/dma.h b/source/dma.h index 8628774..2d0b687 100644 --- a/source/dma.h +++ b/source/dma.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -90,10 +90,10 @@ #ifndef _DMA_H_ #define _DMA_H_ -void S9xResetDMA (void); -uint8 S9xDoHDMA (uint8); -void S9xStartHDMA (); -void S9xDoDMA (uint8); +void S9xResetDMA(void); +uint8 S9xDoHDMA(uint8); +void S9xStartHDMA(); +void S9xDoDMA(uint8); #endif diff --git a/source/dsp1.c b/source/dsp1.c index d017eef..053631a 100644 --- a/source/dsp1.c +++ b/source/dsp1.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -95,1349 +95,1460 @@ #include "dsp1emu.c" #include "dsp2emu.c" -void (*SetDSP)(uint8, uint16)=&DSP1SetByte; -uint8 (*GetDSP)(uint16)=&DSP1GetByte; +void (*SetDSP)(uint8, uint16) = &DSP1SetByte; +uint8(*GetDSP)(uint16) = &DSP1GetByte; -void S9xInitDSP1 () +void S9xInitDSP1() { - static bool8 init = FALSE; - - if (!init) - { - InitDSP (); - init = TRUE; - } + static bool8 init = FALSE; + + if (!init) + { + InitDSP(); + init = TRUE; + } } -void S9xResetDSP1 () +void S9xResetDSP1() { - S9xInitDSP1 (); - - DSP1.waiting4command = TRUE; - DSP1.in_count = 0; - DSP1.out_count = 0; - DSP1.in_index = 0; - DSP1.out_index = 0; - DSP1.first_parameter = TRUE; + S9xInitDSP1(); + + DSP1.waiting4command = TRUE; + DSP1.in_count = 0; + DSP1.out_count = 0; + DSP1.in_index = 0; + DSP1.out_index = 0; + DSP1.first_parameter = TRUE; } -uint8 S9xGetDSP (uint16 address) +uint8 S9xGetDSP(uint16 address) { - uint8 t; - - t=(*GetDSP)(address); - //DSP1GetByte(address); - return (t); + uint8 t; + + t = (*GetDSP)(address); + //DSP1GetByte(address); + return (t); } -void S9xSetDSP (uint8 byte, uint16 address) +void S9xSetDSP(uint8 byte, uint16 address) { - (*SetDSP)(byte, address); - //DSP1SetByte(byte, address); + (*SetDSP)(byte, address); + //DSP1SetByte(byte, address); } void DSP1SetByte(uint8 byte, uint16 address) { - if( (address & 0xf000) == 0x6000 || (address & 0x7fff) < 0x4000 ) - { -// if ((address & 1) == 0) -// { - if((DSP1.command==0x0A||DSP1.command==0x1A)&&DSP1.out_count!=0) - { - DSP1.out_count--; - DSP1.out_index++; - return; - } - else if (DSP1.waiting4command) - { - DSP1.command = byte; - DSP1.in_index = 0; - DSP1.waiting4command = FALSE; - DSP1.first_parameter = TRUE; -// printf("Op%02X\n",byte); - // Mario Kart uses 0x00, 0x02, 0x06, 0x0c, 0x28, 0x0a - switch (byte) - { - case 0x00: DSP1.in_count = 2; break; - case 0x30: - case 0x10: DSP1.in_count = 2; break; - case 0x20: DSP1.in_count = 2; break; - case 0x24: - case 0x04: DSP1.in_count = 2; break; - case 0x08: DSP1.in_count = 3; break; - case 0x18: DSP1.in_count = 4; break; - case 0x28: DSP1.in_count = 3; break; - case 0x38: DSP1.in_count = 4; break; - case 0x2c: - case 0x0c: DSP1.in_count = 3; break; - case 0x3c: - case 0x1c: DSP1.in_count = 6; break; - case 0x32: - case 0x22: - case 0x12: - case 0x02: DSP1.in_count = 7; break; - case 0x0a: DSP1.in_count = 1; break; - case 0x3a: - case 0x2a: - case 0x1a: - DSP1. command =0x1a; - DSP1.in_count = 1; break; - case 0x16: - case 0x26: - case 0x36: - case 0x06: DSP1.in_count = 3; break; - case 0x1e: - case 0x2e: - case 0x3e: - case 0x0e: DSP1.in_count = 2; break; - case 0x05: - case 0x35: - case 0x31: - case 0x01: DSP1.in_count = 4; break; - case 0x15: - case 0x11: DSP1.in_count = 4; break; - case 0x25: - case 0x21: DSP1.in_count = 4; break; - case 0x09: - case 0x39: - case 0x3d: - case 0x0d: DSP1.in_count = 3; break; - case 0x19: - case 0x1d: DSP1.in_count = 3; break; - case 0x29: - case 0x2d: DSP1.in_count = 3; break; - case 0x33: - case 0x03: DSP1.in_count = 3; break; - case 0x13: DSP1.in_count = 3; break; - case 0x23: DSP1.in_count = 3; break; - case 0x3b: - case 0x0b: DSP1.in_count = 3; break; - case 0x1b: DSP1.in_count = 3; break; - case 0x2b: DSP1.in_count = 3; break; - case 0x34: - case 0x14: DSP1.in_count = 6; break; - case 0x07: - case 0x0f: DSP1.in_count = 1; break; - case 0x27: - case 0x2F: DSP1.in_count=1; break; - case 0x17: - case 0x37: - case 0x3F: - DSP1.command=0x1f; - case 0x1f: DSP1.in_count = 1; break; - // case 0x80: DSP1.in_count = 2; break; - default: - //printf("Op%02X\n",byte); - case 0x80: - DSP1.in_count = 0; - DSP1.waiting4command = TRUE; - DSP1.first_parameter = TRUE; - break; - } - DSP1.in_count<<=1; - } - else - { - DSP1.parameters [DSP1.in_index] = byte; - DSP1.first_parameter = FALSE; - DSP1.in_index++; - } - - if (DSP1.waiting4command || - (DSP1.first_parameter && byte == 0x80)) - { - DSP1.waiting4command = TRUE; - DSP1.first_parameter = FALSE; - } - else if(DSP1.first_parameter && (DSP1.in_count != 0 || (DSP1.in_count==0&&DSP1.in_index==0))) - { - } -// else if (DSP1.first_parameter) -// { -// } - else - { - if (DSP1.in_count) - { - //DSP1.parameters [DSP1.in_index] |= (byte << 8); - if (--DSP1.in_count == 0) - { - // Actually execute the command - DSP1.waiting4command = TRUE; - DSP1.out_index = 0; - switch (DSP1.command) - { - case 0x1f: - DSP1.out_count=2048; - break; - case 0x00: // Multiple - Op00Multiplicand = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op00Multiplier = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - - DSPOp00 (); - - DSP1.out_count = 2; - DSP1.output [0] = Op00Result&0xFF; - DSP1.output [1] = (Op00Result>>8)&0xFF; - break; - - case 0x20: // Multiple - Op20Multiplicand = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op20Multiplier = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - - DSPOp20 (); - - DSP1.out_count = 2; - DSP1.output [0] = Op20Result&0xFF; - DSP1.output [1] = (Op20Result>>8)&0xFF; - break; - - case 0x30: - case 0x10: // Inverse - Op10Coefficient = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op10Exponent = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - - DSPOp10 (); - - DSP1.out_count = 4; - DSP1.output [0] = (uint8) (((int16) Op10CoefficientR)&0xFF); - DSP1.output [1] = (uint8) ((((int16) Op10CoefficientR)>>8)&0xFF); - DSP1.output [2] = (uint8) (((int16) Op10ExponentR)&0xff); - DSP1.output [3] = (uint8) ((((int16) Op10ExponentR)>>8)&0xff); - break; - - case 0x24: - case 0x04: // Sin and Cos of angle - Op04Angle = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op04Radius = (uint16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - - DSPOp04 (); - - DSP1.out_count = 4; - DSP1.output [0] = (uint8) (Op04Sin&0xFF); - DSP1.output [1] = (uint8) ((Op04Sin>>8)&0xFF); - DSP1.output [2] = (uint8) (Op04Cos&0xFF); - DSP1.output [3] = (uint8) ((Op04Cos>>8)&0xFF); - break; - - case 0x08: // Radius - Op08X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op08Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - Op08Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); - - DSPOp08 (); - - DSP1.out_count = 4; - DSP1.output [0] = (uint8) (((int16) Op08Ll)&0xFF); - DSP1.output [1] = (uint8) ((((int16) Op08Ll)>>8)&0xFF); - DSP1.output [2] = (uint8) (((int16) Op08Lh)&0xFF); - DSP1.output [3] = (uint8) ((((int16) Op08Lh)>>8)&0xFF); - break; - - case 0x18: // Range - - Op18X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op18Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - Op18Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); - Op18R = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8)); - - DSPOp18 (); - - DSP1.out_count = 2; - DSP1.output [0] = (uint8) (Op18D&0xFF); - DSP1.output [1] = (uint8) ((Op18D>>8)&0xFF); - break; - - case 0x38: // Range - - Op38X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op38Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - Op38Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); - Op38R = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8)); - - DSPOp38 (); - - DSP1.out_count = 2; - DSP1.output [0] = (uint8) (Op38D&0xFF); - DSP1.output [1] = (uint8) ((Op38D>>8)&0xFF); - break; - - case 0x28: // Distance (vector length) - Op28X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op28Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - Op28Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); - - DSPOp28 (); - - DSP1.out_count = 2; - DSP1.output [0] = (uint8) (Op28R&0xFF); - DSP1.output [1] = (uint8) ((Op28R>>8)&0xFF); - break; - - case 0x2c: - case 0x0c: // Rotate (2D rotate) - Op0CA = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op0CX1 = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - Op0CY1 = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); - - DSPOp0C (); - - DSP1.out_count = 4; - DSP1.output [0] = (uint8) (Op0CX2&0xFF); - DSP1.output [1] = (uint8) ((Op0CX2>>8)&0xFF); - DSP1.output [2] = (uint8) (Op0CY2&0xFF); - DSP1.output [3] = (uint8) ((Op0CY2>>8)&0xFF); - break; - - case 0x3c: - case 0x1c: // Polar (3D rotate) - Op1CZ = (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - //MK: reversed X and Y on neviksti and John's advice. - Op1CY = (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - Op1CX = (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); - Op1CXBR = (DSP1.parameters [6]|(DSP1.parameters[7]<<8)); - Op1CYBR = (DSP1.parameters [8]|(DSP1.parameters[9]<<8)); - Op1CZBR = (DSP1.parameters [10]|(DSP1.parameters[11]<<8)); - - DSPOp1C (); - - DSP1.out_count = 6; - DSP1.output [0] = (uint8) (Op1CXAR&0xFF); - DSP1.output [1] = (uint8) ((Op1CXAR>>8)&0xFF); - DSP1.output [2] = (uint8) (Op1CYAR&0xFF); - DSP1.output [3] = (uint8) ((Op1CYAR>>8)&0xFF); - DSP1.output [4] = (uint8) (Op1CZAR&0xFF); - DSP1.output [5] = (uint8) ((Op1CZAR>>8)&0xFF); - break; - - case 0x32: - case 0x22: - case 0x12: - case 0x02: // Parameter (Projection) - Op02FX = (short)(DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op02FY = (short)(DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - Op02FZ = (short)(DSP1.parameters [4]|(DSP1.parameters[5]<<8)); - Op02LFE = (short)(DSP1.parameters [6]|(DSP1.parameters[7]<<8)); - Op02LES = (short)(DSP1.parameters [8]|(DSP1.parameters[9]<<8)); - Op02AAS = (unsigned short)(DSP1.parameters [10]|(DSP1.parameters[11]<<8)); - Op02AZS = (unsigned short)(DSP1.parameters [12]|(DSP1.parameters[13]<<8)); - - DSPOp02 (); - - DSP1.out_count = 8; - DSP1.output [0] = (uint8) (Op02VOF&0xFF); - DSP1.output [1] = (uint8) ((Op02VOF>>8)&0xFF); - DSP1.output [2] = (uint8) (Op02VVA&0xFF); - DSP1.output [3] = (uint8) ((Op02VVA>>8)&0xFF); - DSP1.output [4] = (uint8) (Op02CX&0xFF); - DSP1.output [5] = (uint8) ((Op02CX>>8)&0xFF); - DSP1.output [6] = (uint8) (Op02CY&0xFF); - DSP1.output [7] = (uint8) ((Op02CY>>8)&0xFF); - break; - - case 0x3a: //1a Mirror - case 0x2a: //1a Mirror - case 0x1a: // Raster mode 7 matrix data - case 0x0a: - Op0AVS = (short)(DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - - DSPOp0A (); - - DSP1.out_count = 8; - DSP1.output [0] = (uint8) (Op0AA&0xFF); - DSP1.output [2] = (uint8) (Op0AB&0xFF); - DSP1.output [4] = (uint8) (Op0AC&0xFF); - DSP1.output [6] = (uint8) (Op0AD&0xFF); - DSP1.output [1] = (uint8) ((Op0AA>>8)&0xFF); - DSP1.output [3] = (uint8) ((Op0AB>>8)&0xFF); - DSP1.output [5] = (uint8) ((Op0AC>>8)&0xFF); - DSP1.output [7] = (uint8) ((Op0AD>>8)&0xFF); - DSP1.in_index=0; - break; - - case 0x16: - case 0x26: - case 0x36: - case 0x06: // Project object - Op06X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op06Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - Op06Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); - - DSPOp06 (); - - DSP1.out_count = 6; - DSP1.output [0] = (uint8) (Op06H&0xff); - DSP1.output [1] = (uint8) ((Op06H>>8)&0xFF); - DSP1.output [2] = (uint8) (Op06V&0xFF); - DSP1.output [3] = (uint8) ((Op06V>>8)&0xFF); - DSP1.output [4] = (uint8) (Op06S&0xFF); - DSP1.output [5] = (uint8) ((Op06S>>8)&0xFF); - break; - - case 0x1e: - case 0x2e: - case 0x3e: - case 0x0e: // Target - Op0EH = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op0EV = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - - DSPOp0E (); - - DSP1.out_count = 4; - DSP1.output [0] = (uint8) (Op0EX&0xFF); - DSP1.output [1] = (uint8) ((Op0EX>>8)&0xFF); - DSP1.output [2] = (uint8) (Op0EY&0xFF); - DSP1.output [3] = (uint8) ((Op0EY>>8)&0xFF); - break; - - // Extra commands used by Pilot Wings - case 0x05: - case 0x35: - case 0x31: - case 0x01: // Set attitude matrix A - Op01m = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op01Zr = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - Op01Yr = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); - Op01Xr = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8)); - - DSPOp01 (); - break; - - case 0x15: - case 0x11: // Set attitude matrix B - Op11m = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op11Zr = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - Op11Yr = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); - Op11Xr = (int16) (DSP1.parameters [7]|(DSP1.parameters[7]<<8)); - - DSPOp11 (); - break; - - case 0x25: - case 0x21: // Set attitude matrix C - Op21m = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op21Zr = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - Op21Yr = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); - Op21Xr = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8)); - - DSPOp21 (); - break; - - case 0x09: - case 0x39: - case 0x3d: - case 0x0d: // Objective matrix A - Op0DX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op0DY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - Op0DZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); - - DSPOp0D (); - - DSP1.out_count = 6; - DSP1.output [0] = (uint8) (Op0DF&0xFF); - DSP1.output [1] = (uint8) ((Op0DF>>8)&0xFF); - DSP1.output [2] = (uint8) (Op0DL&0xFF); - DSP1.output [3] = (uint8) ((Op0DL>>8)&0xFF); - DSP1.output [4] = (uint8) (Op0DU&0xFF); - DSP1.output [5] = (uint8) ((Op0DU>>8)&0xFF); - break; - - case 0x19: - case 0x1d: // Objective matrix B - Op1DX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op1DY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - Op1DZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); - - DSPOp1D (); - - DSP1.out_count = 6; - DSP1.output [0] = (uint8) (Op1DF&0xFF); - DSP1.output [1] = (uint8) ((Op1DF>>8)&0xFF); - DSP1.output [2] = (uint8) (Op1DL&0xFF); - DSP1.output [3] = (uint8) ((Op1DL>>8)&0xFF); - DSP1.output [4] = (uint8) (Op1DU&0xFF); - DSP1.output [5] = (uint8) ((Op1DU>>8)&0xFF); - break; - - case 0x29: - case 0x2d: // Objective matrix C - Op2DX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op2DY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - Op2DZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); - - DSPOp2D (); - - DSP1.out_count = 6; - DSP1.output [0] = (uint8) (Op2DF&0xFF); - DSP1.output [1] = (uint8) ((Op2DF>>8)&0xFF); - DSP1.output [2] = (uint8) (Op2DL&0xFF); - DSP1.output [3] = (uint8) ((Op2DL>>8)&0xFF); - DSP1.output [4] = (uint8) (Op2DU&0xFF); - DSP1.output [5] = (uint8) ((Op2DU>>8)&0xFF); - break; - - case 0x33: - case 0x03: // Subjective matrix A - Op03F = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op03L = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - Op03U = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); - - DSPOp03 (); - - DSP1.out_count = 6; - DSP1.output [0] = (uint8) (Op03X&0xFF); - DSP1.output [1] = (uint8) ((Op03X>>8)&0xFF); - DSP1.output [2] = (uint8) (Op03Y&0xFF); - DSP1.output [3] = (uint8) ((Op03Y>>8)&0xFF); - DSP1.output [4] = (uint8) (Op03Z&0xFF); - DSP1.output [5] = (uint8) ((Op03Z>>8)&0xFF); - break; - - case 0x13: // Subjective matrix B - Op13F = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op13L = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - Op13U = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); - - DSPOp13 (); - - DSP1.out_count = 6; - DSP1.output [0] = (uint8) (Op13X&0xFF); - DSP1.output [1] = (uint8) ((Op13X>>8)&0xFF); - DSP1.output [2] = (uint8) (Op13Y&0xFF); - DSP1.output [3] = (uint8) ((Op13Y>>8)&0xFF); - DSP1.output [4] = (uint8) (Op13Z&0xFF); - DSP1.output [5] = (uint8) ((Op13Z>>8)&0xFF); - break; - - case 0x23: // Subjective matrix C - Op23F = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op23L = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - Op23U = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); - - DSPOp23 (); - - DSP1.out_count = 6; - DSP1.output [0] = (uint8) (Op23X&0xFF); - DSP1.output [1] = (uint8) ((Op23X>>8)&0xFF); - DSP1.output [2] = (uint8) (Op23Y&0xFF); - DSP1.output [3] = (uint8) ((Op23Y>>8)&0xFF); - DSP1.output [4] = (uint8) (Op23Z&0xFF); - DSP1.output [5] = (uint8) ((Op23Z>>8)&0xFF); - break; - - case 0x3b: - case 0x0b: - Op0BX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op0BY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - Op0BZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); - - DSPOp0B (); - - DSP1.out_count = 2; - DSP1.output [0] = (uint8) (Op0BS&0xFF); - DSP1.output [1] = (uint8) ((Op0BS>>8)&0xFF); - break; - - case 0x1b: - Op1BX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op1BY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - Op1BZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); - - DSPOp1B (); - - DSP1.out_count = 2; - DSP1.output [0] = (uint8) (Op1BS&0xFF); - DSP1.output [1] = (uint8) ((Op1BS>>8)&0xFF); - break; - - case 0x2b: - Op2BX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op2BY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - Op2BZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); - - DSPOp2B (); - - DSP1.out_count = 2; - DSP1.output [0] = (uint8) (Op2BS&0xFF); - DSP1.output [1] = (uint8) ((Op2BS>>8)&0xFF); - break; - - case 0x34: - case 0x14: - Op14Zr = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - Op14Xr = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); - Op14Yr = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); - Op14U = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8)); - Op14F = (int16) (DSP1.parameters [8]|(DSP1.parameters[9]<<8)); - Op14L = (int16) (DSP1.parameters [10]|(DSP1.parameters[11]<<8)); - - DSPOp14 (); - - DSP1.out_count = 6; - DSP1.output [0] = (uint8) (Op14Zrr&0xFF); - DSP1.output [1] = (uint8) ((Op14Zrr>>8)&0xFF); - DSP1.output [2] = (uint8) (Op14Xrr&0xFF); - DSP1.output [3] = (uint8) ((Op14Xrr>>8)&0xFF); - DSP1.output [4] = (uint8) (Op14Yrr&0xFF); - DSP1.output [5] = (uint8) ((Op14Yrr>>8)&0xFF); - break; - - case 0x27: - case 0x2F: - Op2FUnknown = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - - DSPOp2F (); - - DSP1.out_count = 2; - DSP1.output [0] = (uint8)(Op2FSize&0xFF); - DSP1.output [1] = (uint8)((Op2FSize>>8)&0xFF); - break; - - - case 0x07: - case 0x0F: - Op0FRamsize = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); - - DSPOp0F (); - - DSP1.out_count = 2; - DSP1.output [0] = (uint8)(Op0FPass&0xFF); - DSP1.output [1] = (uint8)((Op0FPass>>8)&0xFF); - break; - - default: - break; - } - } - } - } - } + if ((address & 0xf000) == 0x6000 || (address & 0x7fff) < 0x4000) + { + // if ((address & 1) == 0) + // { + if ((DSP1.command == 0x0A || DSP1.command == 0x1A) && DSP1.out_count != 0) + { + DSP1.out_count--; + DSP1.out_index++; + return; + } + else if (DSP1.waiting4command) + { + DSP1.command = byte; + DSP1.in_index = 0; + DSP1.waiting4command = FALSE; + DSP1.first_parameter = TRUE; + // printf("Op%02X\n",byte); + // Mario Kart uses 0x00, 0x02, 0x06, 0x0c, 0x28, 0x0a + switch (byte) + { + case 0x00: + DSP1.in_count = 2; + break; + case 0x30: + case 0x10: + DSP1.in_count = 2; + break; + case 0x20: + DSP1.in_count = 2; + break; + case 0x24: + case 0x04: + DSP1.in_count = 2; + break; + case 0x08: + DSP1.in_count = 3; + break; + case 0x18: + DSP1.in_count = 4; + break; + case 0x28: + DSP1.in_count = 3; + break; + case 0x38: + DSP1.in_count = 4; + break; + case 0x2c: + case 0x0c: + DSP1.in_count = 3; + break; + case 0x3c: + case 0x1c: + DSP1.in_count = 6; + break; + case 0x32: + case 0x22: + case 0x12: + case 0x02: + DSP1.in_count = 7; + break; + case 0x0a: + DSP1.in_count = 1; + break; + case 0x3a: + case 0x2a: + case 0x1a: + DSP1. command = 0x1a; + DSP1.in_count = 1; + break; + case 0x16: + case 0x26: + case 0x36: + case 0x06: + DSP1.in_count = 3; + break; + case 0x1e: + case 0x2e: + case 0x3e: + case 0x0e: + DSP1.in_count = 2; + break; + case 0x05: + case 0x35: + case 0x31: + case 0x01: + DSP1.in_count = 4; + break; + case 0x15: + case 0x11: + DSP1.in_count = 4; + break; + case 0x25: + case 0x21: + DSP1.in_count = 4; + break; + case 0x09: + case 0x39: + case 0x3d: + case 0x0d: + DSP1.in_count = 3; + break; + case 0x19: + case 0x1d: + DSP1.in_count = 3; + break; + case 0x29: + case 0x2d: + DSP1.in_count = 3; + break; + case 0x33: + case 0x03: + DSP1.in_count = 3; + break; + case 0x13: + DSP1.in_count = 3; + break; + case 0x23: + DSP1.in_count = 3; + break; + case 0x3b: + case 0x0b: + DSP1.in_count = 3; + break; + case 0x1b: + DSP1.in_count = 3; + break; + case 0x2b: + DSP1.in_count = 3; + break; + case 0x34: + case 0x14: + DSP1.in_count = 6; + break; + case 0x07: + case 0x0f: + DSP1.in_count = 1; + break; + case 0x27: + case 0x2F: + DSP1.in_count = 1; + break; + case 0x17: + case 0x37: + case 0x3F: + DSP1.command = 0x1f; + case 0x1f: + DSP1.in_count = 1; + break; + // case 0x80: DSP1.in_count = 2; break; + default: + //printf("Op%02X\n",byte); + case 0x80: + DSP1.in_count = 0; + DSP1.waiting4command = TRUE; + DSP1.first_parameter = TRUE; + break; + } + DSP1.in_count <<= 1; + } + else + { + DSP1.parameters [DSP1.in_index] = byte; + DSP1.first_parameter = FALSE; + DSP1.in_index++; + } + + if (DSP1.waiting4command || + (DSP1.first_parameter && byte == 0x80)) + { + DSP1.waiting4command = TRUE; + DSP1.first_parameter = FALSE; + } + else if (DSP1.first_parameter && (DSP1.in_count != 0 || (DSP1.in_count == 0 + && DSP1.in_index == 0))) + { + } + // else if (DSP1.first_parameter) + // { + // } + else + { + if (DSP1.in_count) + { + //DSP1.parameters [DSP1.in_index] |= (byte << 8); + if (--DSP1.in_count == 0) + { + // Actually execute the command + DSP1.waiting4command = TRUE; + DSP1.out_index = 0; + switch (DSP1.command) + { + case 0x1f: + DSP1.out_count = 2048; + break; + case 0x00: // Multiple + Op00Multiplicand = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op00Multiplier = (int16)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + + DSPOp00(); + + DSP1.out_count = 2; + DSP1.output [0] = Op00Result & 0xFF; + DSP1.output [1] = (Op00Result >> 8) & 0xFF; + break; + + case 0x20: // Multiple + Op20Multiplicand = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op20Multiplier = (int16)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + + DSPOp20(); + + DSP1.out_count = 2; + DSP1.output [0] = Op20Result & 0xFF; + DSP1.output [1] = (Op20Result >> 8) & 0xFF; + break; + + case 0x30: + case 0x10: // Inverse + Op10Coefficient = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op10Exponent = (int16)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + + DSPOp10(); + + DSP1.out_count = 4; + DSP1.output [0] = (uint8)(((int16) Op10CoefficientR) & 0xFF); + DSP1.output [1] = (uint8)((((int16) Op10CoefficientR) >> 8) & 0xFF); + DSP1.output [2] = (uint8)(((int16) Op10ExponentR) & 0xff); + DSP1.output [3] = (uint8)((((int16) Op10ExponentR) >> 8) & 0xff); + break; + + case 0x24: + case 0x04: // Sin and Cos of angle + Op04Angle = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op04Radius = (uint16)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + + DSPOp04(); + + DSP1.out_count = 4; + DSP1.output [0] = (uint8)(Op04Sin & 0xFF); + DSP1.output [1] = (uint8)((Op04Sin >> 8) & 0xFF); + DSP1.output [2] = (uint8)(Op04Cos & 0xFF); + DSP1.output [3] = (uint8)((Op04Cos >> 8) & 0xFF); + break; + + case 0x08: // Radius + Op08X = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op08Y = (int16)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + Op08Z = (int16)(DSP1.parameters [4] | (DSP1.parameters[5] << 8)); + + DSPOp08(); + + DSP1.out_count = 4; + DSP1.output [0] = (uint8)(((int16) Op08Ll) & 0xFF); + DSP1.output [1] = (uint8)((((int16) Op08Ll) >> 8) & 0xFF); + DSP1.output [2] = (uint8)(((int16) Op08Lh) & 0xFF); + DSP1.output [3] = (uint8)((((int16) Op08Lh) >> 8) & 0xFF); + break; + + case 0x18: // Range + + Op18X = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op18Y = (int16)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + Op18Z = (int16)(DSP1.parameters [4] | (DSP1.parameters[5] << 8)); + Op18R = (int16)(DSP1.parameters [6] | (DSP1.parameters[7] << 8)); + + DSPOp18(); + + DSP1.out_count = 2; + DSP1.output [0] = (uint8)(Op18D & 0xFF); + DSP1.output [1] = (uint8)((Op18D >> 8) & 0xFF); + break; + + case 0x38: // Range + + Op38X = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op38Y = (int16)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + Op38Z = (int16)(DSP1.parameters [4] | (DSP1.parameters[5] << 8)); + Op38R = (int16)(DSP1.parameters [6] | (DSP1.parameters[7] << 8)); + + DSPOp38(); + + DSP1.out_count = 2; + DSP1.output [0] = (uint8)(Op38D & 0xFF); + DSP1.output [1] = (uint8)((Op38D >> 8) & 0xFF); + break; + + case 0x28: // Distance (vector length) + Op28X = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op28Y = (int16)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + Op28Z = (int16)(DSP1.parameters [4] | (DSP1.parameters[5] << 8)); + + DSPOp28(); + + DSP1.out_count = 2; + DSP1.output [0] = (uint8)(Op28R & 0xFF); + DSP1.output [1] = (uint8)((Op28R >> 8) & 0xFF); + break; + + case 0x2c: + case 0x0c: // Rotate (2D rotate) + Op0CA = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op0CX1 = (int16)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + Op0CY1 = (int16)(DSP1.parameters [4] | (DSP1.parameters[5] << 8)); + + DSPOp0C(); + + DSP1.out_count = 4; + DSP1.output [0] = (uint8)(Op0CX2 & 0xFF); + DSP1.output [1] = (uint8)((Op0CX2 >> 8) & 0xFF); + DSP1.output [2] = (uint8)(Op0CY2 & 0xFF); + DSP1.output [3] = (uint8)((Op0CY2 >> 8) & 0xFF); + break; + + case 0x3c: + case 0x1c: // Polar (3D rotate) + Op1CZ = (DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + //MK: reversed X and Y on neviksti and John's advice. + Op1CY = (DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + Op1CX = (DSP1.parameters [4] | (DSP1.parameters[5] << 8)); + Op1CXBR = (DSP1.parameters [6] | (DSP1.parameters[7] << 8)); + Op1CYBR = (DSP1.parameters [8] | (DSP1.parameters[9] << 8)); + Op1CZBR = (DSP1.parameters [10] | (DSP1.parameters[11] << 8)); + + DSPOp1C(); + + DSP1.out_count = 6; + DSP1.output [0] = (uint8)(Op1CXAR & 0xFF); + DSP1.output [1] = (uint8)((Op1CXAR >> 8) & 0xFF); + DSP1.output [2] = (uint8)(Op1CYAR & 0xFF); + DSP1.output [3] = (uint8)((Op1CYAR >> 8) & 0xFF); + DSP1.output [4] = (uint8)(Op1CZAR & 0xFF); + DSP1.output [5] = (uint8)((Op1CZAR >> 8) & 0xFF); + break; + + case 0x32: + case 0x22: + case 0x12: + case 0x02: // Parameter (Projection) + Op02FX = (short)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op02FY = (short)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + Op02FZ = (short)(DSP1.parameters [4] | (DSP1.parameters[5] << 8)); + Op02LFE = (short)(DSP1.parameters [6] | (DSP1.parameters[7] << 8)); + Op02LES = (short)(DSP1.parameters [8] | (DSP1.parameters[9] << 8)); + Op02AAS = (unsigned short)(DSP1.parameters [10] | (DSP1.parameters[11] << 8)); + Op02AZS = (unsigned short)(DSP1.parameters [12] | (DSP1.parameters[13] << 8)); + + DSPOp02(); + + DSP1.out_count = 8; + DSP1.output [0] = (uint8)(Op02VOF & 0xFF); + DSP1.output [1] = (uint8)((Op02VOF >> 8) & 0xFF); + DSP1.output [2] = (uint8)(Op02VVA & 0xFF); + DSP1.output [3] = (uint8)((Op02VVA >> 8) & 0xFF); + DSP1.output [4] = (uint8)(Op02CX & 0xFF); + DSP1.output [5] = (uint8)((Op02CX >> 8) & 0xFF); + DSP1.output [6] = (uint8)(Op02CY & 0xFF); + DSP1.output [7] = (uint8)((Op02CY >> 8) & 0xFF); + break; + + case 0x3a: //1a Mirror + case 0x2a: //1a Mirror + case 0x1a: // Raster mode 7 matrix data + case 0x0a: + Op0AVS = (short)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + + DSPOp0A(); + + DSP1.out_count = 8; + DSP1.output [0] = (uint8)(Op0AA & 0xFF); + DSP1.output [2] = (uint8)(Op0AB & 0xFF); + DSP1.output [4] = (uint8)(Op0AC & 0xFF); + DSP1.output [6] = (uint8)(Op0AD & 0xFF); + DSP1.output [1] = (uint8)((Op0AA >> 8) & 0xFF); + DSP1.output [3] = (uint8)((Op0AB >> 8) & 0xFF); + DSP1.output [5] = (uint8)((Op0AC >> 8) & 0xFF); + DSP1.output [7] = (uint8)((Op0AD >> 8) & 0xFF); + DSP1.in_index = 0; + break; + + case 0x16: + case 0x26: + case 0x36: + case 0x06: // Project object + Op06X = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op06Y = (int16)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + Op06Z = (int16)(DSP1.parameters [4] | (DSP1.parameters[5] << 8)); + + DSPOp06(); + + DSP1.out_count = 6; + DSP1.output [0] = (uint8)(Op06H & 0xff); + DSP1.output [1] = (uint8)((Op06H >> 8) & 0xFF); + DSP1.output [2] = (uint8)(Op06V & 0xFF); + DSP1.output [3] = (uint8)((Op06V >> 8) & 0xFF); + DSP1.output [4] = (uint8)(Op06S & 0xFF); + DSP1.output [5] = (uint8)((Op06S >> 8) & 0xFF); + break; + + case 0x1e: + case 0x2e: + case 0x3e: + case 0x0e: // Target + Op0EH = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op0EV = (int16)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + + DSPOp0E(); + + DSP1.out_count = 4; + DSP1.output [0] = (uint8)(Op0EX & 0xFF); + DSP1.output [1] = (uint8)((Op0EX >> 8) & 0xFF); + DSP1.output [2] = (uint8)(Op0EY & 0xFF); + DSP1.output [3] = (uint8)((Op0EY >> 8) & 0xFF); + break; + + // Extra commands used by Pilot Wings + case 0x05: + case 0x35: + case 0x31: + case 0x01: // Set attitude matrix A + Op01m = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op01Zr = (int16)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + Op01Yr = (int16)(DSP1.parameters [4] | (DSP1.parameters[5] << 8)); + Op01Xr = (int16)(DSP1.parameters [6] | (DSP1.parameters[7] << 8)); + + DSPOp01(); + break; + + case 0x15: + case 0x11: // Set attitude matrix B + Op11m = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op11Zr = (int16)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + Op11Yr = (int16)(DSP1.parameters [4] | (DSP1.parameters[5] << 8)); + Op11Xr = (int16)(DSP1.parameters [7] | (DSP1.parameters[7] << 8)); + + DSPOp11(); + break; + + case 0x25: + case 0x21: // Set attitude matrix C + Op21m = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op21Zr = (int16)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + Op21Yr = (int16)(DSP1.parameters [4] | (DSP1.parameters[5] << 8)); + Op21Xr = (int16)(DSP1.parameters [6] | (DSP1.parameters[7] << 8)); + + DSPOp21(); + break; + + case 0x09: + case 0x39: + case 0x3d: + case 0x0d: // Objective matrix A + Op0DX = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op0DY = (int16)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + Op0DZ = (int16)(DSP1.parameters [4] | (DSP1.parameters[5] << 8)); + + DSPOp0D(); + + DSP1.out_count = 6; + DSP1.output [0] = (uint8)(Op0DF & 0xFF); + DSP1.output [1] = (uint8)((Op0DF >> 8) & 0xFF); + DSP1.output [2] = (uint8)(Op0DL & 0xFF); + DSP1.output [3] = (uint8)((Op0DL >> 8) & 0xFF); + DSP1.output [4] = (uint8)(Op0DU & 0xFF); + DSP1.output [5] = (uint8)((Op0DU >> 8) & 0xFF); + break; + + case 0x19: + case 0x1d: // Objective matrix B + Op1DX = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op1DY = (int16)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + Op1DZ = (int16)(DSP1.parameters [4] | (DSP1.parameters[5] << 8)); + + DSPOp1D(); + + DSP1.out_count = 6; + DSP1.output [0] = (uint8)(Op1DF & 0xFF); + DSP1.output [1] = (uint8)((Op1DF >> 8) & 0xFF); + DSP1.output [2] = (uint8)(Op1DL & 0xFF); + DSP1.output [3] = (uint8)((Op1DL >> 8) & 0xFF); + DSP1.output [4] = (uint8)(Op1DU & 0xFF); + DSP1.output [5] = (uint8)((Op1DU >> 8) & 0xFF); + break; + + case 0x29: + case 0x2d: // Objective matrix C + Op2DX = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op2DY = (int16)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + Op2DZ = (int16)(DSP1.parameters [4] | (DSP1.parameters[5] << 8)); + + DSPOp2D(); + + DSP1.out_count = 6; + DSP1.output [0] = (uint8)(Op2DF & 0xFF); + DSP1.output [1] = (uint8)((Op2DF >> 8) & 0xFF); + DSP1.output [2] = (uint8)(Op2DL & 0xFF); + DSP1.output [3] = (uint8)((Op2DL >> 8) & 0xFF); + DSP1.output [4] = (uint8)(Op2DU & 0xFF); + DSP1.output [5] = (uint8)((Op2DU >> 8) & 0xFF); + break; + + case 0x33: + case 0x03: // Subjective matrix A + Op03F = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op03L = (int16)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + Op03U = (int16)(DSP1.parameters [4] | (DSP1.parameters[5] << 8)); + + DSPOp03(); + + DSP1.out_count = 6; + DSP1.output [0] = (uint8)(Op03X & 0xFF); + DSP1.output [1] = (uint8)((Op03X >> 8) & 0xFF); + DSP1.output [2] = (uint8)(Op03Y & 0xFF); + DSP1.output [3] = (uint8)((Op03Y >> 8) & 0xFF); + DSP1.output [4] = (uint8)(Op03Z & 0xFF); + DSP1.output [5] = (uint8)((Op03Z >> 8) & 0xFF); + break; + + case 0x13: // Subjective matrix B + Op13F = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op13L = (int16)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + Op13U = (int16)(DSP1.parameters [4] | (DSP1.parameters[5] << 8)); + + DSPOp13(); + + DSP1.out_count = 6; + DSP1.output [0] = (uint8)(Op13X & 0xFF); + DSP1.output [1] = (uint8)((Op13X >> 8) & 0xFF); + DSP1.output [2] = (uint8)(Op13Y & 0xFF); + DSP1.output [3] = (uint8)((Op13Y >> 8) & 0xFF); + DSP1.output [4] = (uint8)(Op13Z & 0xFF); + DSP1.output [5] = (uint8)((Op13Z >> 8) & 0xFF); + break; + + case 0x23: // Subjective matrix C + Op23F = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op23L = (int16)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + Op23U = (int16)(DSP1.parameters [4] | (DSP1.parameters[5] << 8)); + + DSPOp23(); + + DSP1.out_count = 6; + DSP1.output [0] = (uint8)(Op23X & 0xFF); + DSP1.output [1] = (uint8)((Op23X >> 8) & 0xFF); + DSP1.output [2] = (uint8)(Op23Y & 0xFF); + DSP1.output [3] = (uint8)((Op23Y >> 8) & 0xFF); + DSP1.output [4] = (uint8)(Op23Z & 0xFF); + DSP1.output [5] = (uint8)((Op23Z >> 8) & 0xFF); + break; + + case 0x3b: + case 0x0b: + Op0BX = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op0BY = (int16)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + Op0BZ = (int16)(DSP1.parameters [4] | (DSP1.parameters[5] << 8)); + + DSPOp0B(); + + DSP1.out_count = 2; + DSP1.output [0] = (uint8)(Op0BS & 0xFF); + DSP1.output [1] = (uint8)((Op0BS >> 8) & 0xFF); + break; + + case 0x1b: + Op1BX = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op1BY = (int16)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + Op1BZ = (int16)(DSP1.parameters [4] | (DSP1.parameters[5] << 8)); + + DSPOp1B(); + + DSP1.out_count = 2; + DSP1.output [0] = (uint8)(Op1BS & 0xFF); + DSP1.output [1] = (uint8)((Op1BS >> 8) & 0xFF); + break; + + case 0x2b: + Op2BX = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op2BY = (int16)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + Op2BZ = (int16)(DSP1.parameters [4] | (DSP1.parameters[5] << 8)); + + DSPOp2B(); + + DSP1.out_count = 2; + DSP1.output [0] = (uint8)(Op2BS & 0xFF); + DSP1.output [1] = (uint8)((Op2BS >> 8) & 0xFF); + break; + + case 0x34: + case 0x14: + Op14Zr = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + Op14Xr = (int16)(DSP1.parameters [2] | (DSP1.parameters[3] << 8)); + Op14Yr = (int16)(DSP1.parameters [4] | (DSP1.parameters[5] << 8)); + Op14U = (int16)(DSP1.parameters [6] | (DSP1.parameters[7] << 8)); + Op14F = (int16)(DSP1.parameters [8] | (DSP1.parameters[9] << 8)); + Op14L = (int16)(DSP1.parameters [10] | (DSP1.parameters[11] << 8)); + + DSPOp14(); + + DSP1.out_count = 6; + DSP1.output [0] = (uint8)(Op14Zrr & 0xFF); + DSP1.output [1] = (uint8)((Op14Zrr >> 8) & 0xFF); + DSP1.output [2] = (uint8)(Op14Xrr & 0xFF); + DSP1.output [3] = (uint8)((Op14Xrr >> 8) & 0xFF); + DSP1.output [4] = (uint8)(Op14Yrr & 0xFF); + DSP1.output [5] = (uint8)((Op14Yrr >> 8) & 0xFF); + break; + + case 0x27: + case 0x2F: + Op2FUnknown = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + + DSPOp2F(); + + DSP1.out_count = 2; + DSP1.output [0] = (uint8)(Op2FSize & 0xFF); + DSP1.output [1] = (uint8)((Op2FSize >> 8) & 0xFF); + break; + + + case 0x07: + case 0x0F: + Op0FRamsize = (int16)(DSP1.parameters [0] | (DSP1.parameters[1] << 8)); + + DSPOp0F(); + + DSP1.out_count = 2; + DSP1.output [0] = (uint8)(Op0FPass & 0xFF); + DSP1.output [1] = (uint8)((Op0FPass >> 8) & 0xFF); + break; + + default: + break; + } + } + } + } + } } uint8 DSP1GetByte(uint16 address) { - uint8 t; - if ((address & 0xf000) == 0x6000 || -// (address >= 0x8000 && address < 0xc000)) - (address&0x7fff) < 0x4000) - { - if (DSP1.out_count) - { - //if ((address & 1) == 0) - t = (uint8) DSP1.output [DSP1.out_index]; - //else - //{ - // t = (uint8) (DSP1.output [DSP1.out_index] >> 8); - DSP1.out_index++; - if (--DSP1.out_count == 0) - { - if (DSP1.command == 0x1a || DSP1.command == 0x0a) - { - DSPOp0A (); - DSP1.out_count = 8; - DSP1.out_index = 0; - DSP1.output [0] = (Op0AA&0xFF); - DSP1.output [1] = (Op0AA>>8)&0xFF; - DSP1.output [2] = (Op0AB&0xFF); - DSP1.output [3] = (Op0AB>>8)&0xFF; - DSP1.output [4] = (Op0AC&0xFF); - DSP1.output [5] = (Op0AC>>8)&0xFF; - DSP1.output [6] = (Op0AD&0xFF); - DSP1.output [7] = (Op0AD>>8)&0xFF; - } - if(DSP1.command==0x1f) - { - if((DSP1.out_index%2)!=0) - { - t=(uint8)DSP1ROM[DSP1.out_index>>1]; - } - else - { - t=DSP1ROM[DSP1.out_index>>1]>>8; - } - } - } - DSP1.waiting4command = TRUE; - //} - } - else - { - // Top Gear 3000 requires this value.... - // if(4==Settings.DSPVersion) - t = 0xff; - //Ballz3d requires this one: - // else t = 0x00; - } - } - else t = 0x80; - return t; + uint8 t; + if ((address & 0xf000) == 0x6000 || + // (address >= 0x8000 && address < 0xc000)) + (address & 0x7fff) < 0x4000) + { + if (DSP1.out_count) + { + //if ((address & 1) == 0) + t = (uint8) DSP1.output [DSP1.out_index]; + //else + //{ + // t = (uint8) (DSP1.output [DSP1.out_index] >> 8); + DSP1.out_index++; + if (--DSP1.out_count == 0) + { + if (DSP1.command == 0x1a || DSP1.command == 0x0a) + { + DSPOp0A(); + DSP1.out_count = 8; + DSP1.out_index = 0; + DSP1.output [0] = (Op0AA & 0xFF); + DSP1.output [1] = (Op0AA >> 8) & 0xFF; + DSP1.output [2] = (Op0AB & 0xFF); + DSP1.output [3] = (Op0AB >> 8) & 0xFF; + DSP1.output [4] = (Op0AC & 0xFF); + DSP1.output [5] = (Op0AC >> 8) & 0xFF; + DSP1.output [6] = (Op0AD & 0xFF); + DSP1.output [7] = (Op0AD >> 8) & 0xFF; + } + if (DSP1.command == 0x1f) + { + if ((DSP1.out_index % 2) != 0) + t = (uint8)DSP1ROM[DSP1.out_index >> 1]; + else + t = DSP1ROM[DSP1.out_index >> 1] >> 8; + } + } + DSP1.waiting4command = TRUE; + //} + } + else + { + // Top Gear 3000 requires this value.... + // if(4==Settings.DSPVersion) + t = 0xff; + //Ballz3d requires this one: + // else t = 0x00; + } + } + else t = 0x80; + return t; } void DSP2SetByte(uint8 byte, uint16 address) { - if ((address & 0xf000) == 0x6000 || - (address >= 0x8000 && address < 0xc000)) - { - if (DSP1.waiting4command) - { - DSP1.command = byte; - DSP1.in_index = 0; - DSP1.waiting4command = FALSE; -// DSP1.first_parameter = TRUE; -// printf("Op%02X\n",byte); - switch (byte) - { - case 0x01:DSP1.in_count=32;break; - case 0x03:DSP1.in_count=1;break; - case 0x05:DSP1.in_count=1;break; - case 0x09:DSP1.in_count=4;break; - case 0x06:DSP1.in_count=1;break; - case 0x0D:DSP1.in_count=2;break; - default: - printf("Op%02X\n",byte); - case 0x0f:DSP1.in_count=0;break; - } - } - else - { - DSP1.parameters [DSP1.in_index] = byte; -// DSP1.first_parameter = FALSE; - DSP1.in_index++; - } - - if (DSP1.in_count==DSP1.in_index) - { - //DSP1.parameters [DSP1.in_index] |= (byte << 8); - // Actually execute the command - DSP1.waiting4command = TRUE; - DSP1.out_index = 0; - switch (DSP1.command) - { - case 0x0D: - if(DSP2Op0DHasLen) - { - DSP2Op0DHasLen=false; - DSP1.out_count=DSP2Op0DOutLen; - //execute Op5 - DSP2_Op0D(); - } - else - { - DSP2Op0DInLen=DSP1.parameters[0]; - DSP2Op0DOutLen=DSP1.parameters[1]; - DSP1.in_index=0; - DSP1.in_count=(DSP2Op0DInLen+1)>>1; - DSP2Op0DHasLen=true; - if(byte) - DSP1.waiting4command=false; - } - break; - case 0x06: - if(DSP2Op06HasLen) - { - DSP2Op06HasLen=false; - DSP1.out_count=DSP2Op06Len; - //execute Op5 - DSP2_Op06(); - } - else - { - DSP2Op06Len=DSP1.parameters[0]; - DSP1.in_index=0; - DSP1.in_count=DSP2Op06Len; - DSP2Op06HasLen=true; - if(byte) - DSP1.waiting4command=false; - } - break; - case 0x01: - DSP1.out_count=32; - DSP2_Op01(); - break; - case 0x09: - // Multiply - don't yet know if this is signed or unsigned - DSP2Op09Word1 = DSP1.parameters[0] | (DSP1.parameters[1]<<8); - DSP2Op09Word2 = DSP1.parameters[2] | (DSP1.parameters[3]<<8); - DSP1.out_count=4; + if ((address & 0xf000) == 0x6000 || + (address >= 0x8000 && address < 0xc000)) + { + if (DSP1.waiting4command) + { + DSP1.command = byte; + DSP1.in_index = 0; + DSP1.waiting4command = FALSE; + // DSP1.first_parameter = TRUE; + // printf("Op%02X\n",byte); + switch (byte) + { + case 0x01: + DSP1.in_count = 32; + break; + case 0x03: + DSP1.in_count = 1; + break; + case 0x05: + DSP1.in_count = 1; + break; + case 0x09: + DSP1.in_count = 4; + break; + case 0x06: + DSP1.in_count = 1; + break; + case 0x0D: + DSP1.in_count = 2; + break; + default: + printf("Op%02X\n", byte); + case 0x0f: + DSP1.in_count = 0; + break; + } + } + else + { + DSP1.parameters [DSP1.in_index] = byte; + // DSP1.first_parameter = FALSE; + DSP1.in_index++; + } + + if (DSP1.in_count == DSP1.in_index) + { + //DSP1.parameters [DSP1.in_index] |= (byte << 8); + // Actually execute the command + DSP1.waiting4command = TRUE; + DSP1.out_index = 0; + switch (DSP1.command) + { + case 0x0D: + if (DSP2Op0DHasLen) + { + DSP2Op0DHasLen = false; + DSP1.out_count = DSP2Op0DOutLen; + //execute Op5 + DSP2_Op0D(); + } + else + { + DSP2Op0DInLen = DSP1.parameters[0]; + DSP2Op0DOutLen = DSP1.parameters[1]; + DSP1.in_index = 0; + DSP1.in_count = (DSP2Op0DInLen + 1) >> 1; + DSP2Op0DHasLen = true; + if (byte) + DSP1.waiting4command = false; + } + break; + case 0x06: + if (DSP2Op06HasLen) + { + DSP2Op06HasLen = false; + DSP1.out_count = DSP2Op06Len; + //execute Op5 + DSP2_Op06(); + } + else + { + DSP2Op06Len = DSP1.parameters[0]; + DSP1.in_index = 0; + DSP1.in_count = DSP2Op06Len; + DSP2Op06HasLen = true; + if (byte) + DSP1.waiting4command = false; + } + break; + case 0x01: + DSP1.out_count = 32; + DSP2_Op01(); + break; + case 0x09: + // Multiply - don't yet know if this is signed or unsigned + DSP2Op09Word1 = DSP1.parameters[0] | (DSP1.parameters[1] << 8); + DSP2Op09Word2 = DSP1.parameters[2] | (DSP1.parameters[3] << 8); + DSP1.out_count = 4; #ifdef FAST_LSB_WORD_ACCESS - *(uint32 *)DSP1.output = DSP2Op09Word1 * DSP2Op09Word2; + *(uint32*)DSP1.output = DSP2Op09Word1 * DSP2Op09Word2; #else - uint32 temp; - temp=DSP2Op09Word1 * DSP2Op09Word2; - DSP1.output[0]=temp&0xFF; - DSP1.output[1]=(temp>>8)&0xFF; - DSP1.output[2]=(temp>>16)&0xFF; - DSP1.output[3]=(temp>>24)&0xFF; + uint32 temp; + temp = DSP2Op09Word1 * DSP2Op09Word2; + DSP1.output[0] = temp & 0xFF; + DSP1.output[1] = (temp >> 8) & 0xFF; + DSP1.output[2] = (temp >> 16) & 0xFF; + DSP1.output[3] = (temp >> 24) & 0xFF; #endif - break; - case 0x05: - if(DSP2Op05HasLen) - { - DSP2Op05HasLen=false; - DSP1.out_count=DSP2Op05Len; - //execute Op5 - DSP2_Op05(); - } - else - { - DSP2Op05Len=DSP1.parameters[0]; - DSP1.in_index=0; - DSP1.in_count=2*DSP2Op05Len; - DSP2Op05HasLen=true; - if(byte) - DSP1.waiting4command=false; - } - break; - - case 0x03: - DSP2Op05Transparent= DSP1.parameters[0]; - //DSP2Op03(); - break; - case 0x0f: - default: - break; - } - } - } + break; + case 0x05: + if (DSP2Op05HasLen) + { + DSP2Op05HasLen = false; + DSP1.out_count = DSP2Op05Len; + //execute Op5 + DSP2_Op05(); + } + else + { + DSP2Op05Len = DSP1.parameters[0]; + DSP1.in_index = 0; + DSP1.in_count = 2 * DSP2Op05Len; + DSP2Op05HasLen = true; + if (byte) + DSP1.waiting4command = false; + } + break; + + case 0x03: + DSP2Op05Transparent = DSP1.parameters[0]; + //DSP2Op03(); + break; + case 0x0f: + default: + break; + } + } + } } uint8 DSP2GetByte(uint16 address) { - uint8 t; - if ((address & 0xf000) == 0x6000 || - (address >= 0x8000 && address < 0xc000)) - { - if (DSP1.out_count) - { - t = (uint8) DSP1.output [DSP1.out_index]; - DSP1.out_index++; - if(DSP1.out_count==DSP1.out_index) - DSP1.out_count=0; - } - else - { - t = 0xff; - } - } - else t = 0x80; - return t; + uint8 t; + if ((address & 0xf000) == 0x6000 || + (address >= 0x8000 && address < 0xc000)) + { + if (DSP1.out_count) + { + t = (uint8) DSP1.output [DSP1.out_index]; + DSP1.out_index++; + if (DSP1.out_count == DSP1.out_index) + DSP1.out_count = 0; + } + else + t = 0xff; + } + else t = 0x80; + return t; } //Disable non-working chips? #ifdef DSP_DUMMY_LOOPS -//static const uint16 DSP1ROM[1024] from SNES9X v1.53 -uint16 Dsp3Rom[1024] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, - 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, - 0x4000, 0x7fff, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, - 0x0100, 0x0080, 0x0040, 0x0020, 0x0001, 0x0008, 0x0004, 0x0002, - 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8000, 0xffe5, 0x0100, 0x7fff, 0x7f02, 0x7e08, - 0x7d12, 0x7c1f, 0x7b30, 0x7a45, 0x795d, 0x7878, 0x7797, 0x76ba, - 0x75df, 0x7507, 0x7433, 0x7361, 0x7293, 0x71c7, 0x70fe, 0x7038, - 0x6f75, 0x6eb4, 0x6df6, 0x6d3a, 0x6c81, 0x6bca, 0x6b16, 0x6a64, - 0x69b4, 0x6907, 0x685b, 0x67b2, 0x670b, 0x6666, 0x65c4, 0x6523, - 0x6484, 0x63e7, 0x634c, 0x62b3, 0x621c, 0x6186, 0x60f2, 0x6060, - 0x5fd0, 0x5f41, 0x5eb5, 0x5e29, 0x5d9f, 0x5d17, 0x5c91, 0x5c0c, - 0x5b88, 0x5b06, 0x5a85, 0x5a06, 0x5988, 0x590b, 0x5890, 0x5816, - 0x579d, 0x5726, 0x56b0, 0x563b, 0x55c8, 0x5555, 0x54e4, 0x5474, - 0x5405, 0x5398, 0x532b, 0x52bf, 0x5255, 0x51ec, 0x5183, 0x511c, - 0x50b6, 0x5050, 0x4fec, 0x4f89, 0x4f26, 0x4ec5, 0x4e64, 0x4e05, - 0x4da6, 0x4d48, 0x4cec, 0x4c90, 0x4c34, 0x4bda, 0x4b81, 0x4b28, - 0x4ad0, 0x4a79, 0x4a23, 0x49cd, 0x4979, 0x4925, 0x48d1, 0x487f, - 0x482d, 0x47dc, 0x478c, 0x473c, 0x46ed, 0x469f, 0x4651, 0x4604, - 0x45b8, 0x456c, 0x4521, 0x44d7, 0x448d, 0x4444, 0x43fc, 0x43b4, - 0x436d, 0x4326, 0x42e0, 0x429a, 0x4255, 0x4211, 0x41cd, 0x4189, - 0x4146, 0x4104, 0x40c2, 0x4081, 0x4040, 0x3fff, 0x41f7, 0x43e1, - 0x45bd, 0x478d, 0x4951, 0x4b0b, 0x4cbb, 0x4e61, 0x4fff, 0x5194, - 0x5322, 0x54a9, 0x5628, 0x57a2, 0x5914, 0x5a81, 0x5be9, 0x5d4a, - 0x5ea7, 0x5fff, 0x6152, 0x62a0, 0x63ea, 0x6530, 0x6672, 0x67b0, - 0x68ea, 0x6a20, 0x6b53, 0x6c83, 0x6daf, 0x6ed9, 0x6fff, 0x7122, - 0x7242, 0x735f, 0x747a, 0x7592, 0x76a7, 0x77ba, 0x78cb, 0x79d9, - 0x7ae5, 0x7bee, 0x7cf5, 0x7dfa, 0x7efe, 0x7fff, 0x0000, 0x0324, - 0x0647, 0x096a, 0x0c8b, 0x0fab, 0x12c8, 0x15e2, 0x18f8, 0x1c0b, - 0x1f19, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, 0x30fb, 0x33de, - 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, 0x471c, 0x49b4, - 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, 0x5a82, 0x5cb4, - 0x5ed7, 0x60ec, 0x62f2, 0x64e8, 0x66cf, 0x68a6, 0x6a6d, 0x6c24, - 0x6dca, 0x6f5f, 0x70e2, 0x7255, 0x73b5, 0x7504, 0x7641, 0x776c, - 0x7884, 0x798a, 0x7a7d, 0x7b5d, 0x7c29, 0x7ce3, 0x7d8a, 0x7e1d, - 0x7e9d, 0x7f09, 0x7f62, 0x7fa7, 0x7fd8, 0x7ff6, 0x7fff, 0x7ff6, - 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, 0x7d8a, 0x7ce3, - 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, 0x7641, 0x7504, - 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, 0x6a6d, 0x68a6, - 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, 0x5a82, 0x5842, - 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, 0x471c, 0x447a, - 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, 0x30fb, 0x2e11, - 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, 0x18f8, 0x15e2, - 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, 0x7fff, 0x7ff6, - 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, 0x7d8a, 0x7ce3, - 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, 0x7641, 0x7504, - 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, 0x6a6d, 0x68a6, - 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, 0x5a82, 0x5842, - 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, 0x471c, 0x447a, - 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, 0x30fb, 0x2e11, - 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, 0x18f8, 0x15e2, - 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, 0x0000, 0xfcdc, - 0xf9b9, 0xf696, 0xf375, 0xf055, 0xed38, 0xea1e, 0xe708, 0xe3f5, - 0xe0e7, 0xdddd, 0xdad8, 0xd7da, 0xd4e1, 0xd1ef, 0xcf05, 0xcc22, - 0xc946, 0xc674, 0xc3aa, 0xc0e9, 0xbe32, 0xbb86, 0xb8e4, 0xb64c, - 0xb3c1, 0xb141, 0xaecd, 0xac65, 0xaa0b, 0xa7be, 0xa57e, 0xa34c, - 0xa129, 0x9f14, 0x9d0e, 0x9b18, 0x9931, 0x975a, 0x9593, 0x93dc, - 0x9236, 0x90a1, 0x8f1e, 0x8dab, 0x8c4b, 0x8afc, 0x89bf, 0x8894, - 0x877c, 0x8676, 0x8583, 0x84a3, 0x83d7, 0x831d, 0x8276, 0x81e3, - 0x8163, 0x80f7, 0x809e, 0x8059, 0x8028, 0x800a, 0x6488, 0x0080, - 0x03ff, 0x0116, 0x0002, 0x0080, 0x4000, 0x3fd7, 0x3faf, 0x3f86, - 0x3f5d, 0x3f34, 0x3f0c, 0x3ee3, 0x3eba, 0x3e91, 0x3e68, 0x3e40, - 0x3e17, 0x3dee, 0x3dc5, 0x3d9c, 0x3d74, 0x3d4b, 0x3d22, 0x3cf9, - 0x3cd0, 0x3ca7, 0x3c7f, 0x3c56, 0x3c2d, 0x3c04, 0x3bdb, 0x3bb2, - 0x3b89, 0x3b60, 0x3b37, 0x3b0e, 0x3ae5, 0x3abc, 0x3a93, 0x3a69, - 0x3a40, 0x3a17, 0x39ee, 0x39c5, 0x399c, 0x3972, 0x3949, 0x3920, - 0x38f6, 0x38cd, 0x38a4, 0x387a, 0x3851, 0x3827, 0x37fe, 0x37d4, - 0x37aa, 0x3781, 0x3757, 0x372d, 0x3704, 0x36da, 0x36b0, 0x3686, - 0x365c, 0x3632, 0x3609, 0x35df, 0x35b4, 0x358a, 0x3560, 0x3536, - 0x350c, 0x34e1, 0x34b7, 0x348d, 0x3462, 0x3438, 0x340d, 0x33e3, - 0x33b8, 0x338d, 0x3363, 0x3338, 0x330d, 0x32e2, 0x32b7, 0x328c, - 0x3261, 0x3236, 0x320b, 0x31df, 0x31b4, 0x3188, 0x315d, 0x3131, - 0x3106, 0x30da, 0x30ae, 0x3083, 0x3057, 0x302b, 0x2fff, 0x2fd2, - 0x2fa6, 0x2f7a, 0x2f4d, 0x2f21, 0x2ef4, 0x2ec8, 0x2e9b, 0x2e6e, - 0x2e41, 0x2e14, 0x2de7, 0x2dba, 0x2d8d, 0x2d60, 0x2d32, 0x2d05, - 0x2cd7, 0x2ca9, 0x2c7b, 0x2c4d, 0x2c1f, 0x2bf1, 0x2bc3, 0x2b94, - 0x2b66, 0x2b37, 0x2b09, 0x2ada, 0x2aab, 0x2a7c, 0x2a4c, 0x2a1d, - 0x29ed, 0x29be, 0x298e, 0x295e, 0x292e, 0x28fe, 0x28ce, 0x289d, - 0x286d, 0x283c, 0x280b, 0x27da, 0x27a9, 0x2777, 0x2746, 0x2714, - 0x26e2, 0x26b0, 0x267e, 0x264c, 0x2619, 0x25e7, 0x25b4, 0x2581, - 0x254d, 0x251a, 0x24e6, 0x24b2, 0x247e, 0x244a, 0x2415, 0x23e1, - 0x23ac, 0x2376, 0x2341, 0x230b, 0x22d6, 0x229f, 0x2269, 0x2232, - 0x21fc, 0x21c4, 0x218d, 0x2155, 0x211d, 0x20e5, 0x20ad, 0x2074, - 0x203b, 0x2001, 0x1fc7, 0x1f8d, 0x1f53, 0x1f18, 0x1edd, 0x1ea1, - 0x1e66, 0x1e29, 0x1ded, 0x1db0, 0x1d72, 0x1d35, 0x1cf6, 0x1cb8, - 0x1c79, 0x1c39, 0x1bf9, 0x1bb8, 0x1b77, 0x1b36, 0x1af4, 0x1ab1, - 0x1a6e, 0x1a2a, 0x19e6, 0x19a1, 0x195c, 0x1915, 0x18ce, 0x1887, - 0x183f, 0x17f5, 0x17ac, 0x1761, 0x1715, 0x16c9, 0x167c, 0x162e, - 0x15df, 0x158e, 0x153d, 0x14eb, 0x1497, 0x1442, 0x13ec, 0x1395, - 0x133c, 0x12e2, 0x1286, 0x1228, 0x11c9, 0x1167, 0x1104, 0x109e, - 0x1036, 0x0fcc, 0x0f5f, 0x0eef, 0x0e7b, 0x0e04, 0x0d89, 0x0d0a, - 0x0c86, 0x0bfd, 0x0b6d, 0x0ad6, 0x0a36, 0x098d, 0x08d7, 0x0811, - 0x0736, 0x063e, 0x0519, 0x039a, 0x0000, 0x7fff, 0x0100, 0x0080, - 0x021d, 0x00c8, 0x00ce, 0x0048, 0x0a26, 0x277a, 0x00ce, 0x6488, - 0x14ac, 0x0001, 0x00f9, 0x00fc, 0x00ff, 0x00fc, 0x00f9, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff +//static const uint16 DSP1ROM[1024] from SNES9X v1.53 +uint16 Dsp3Rom[1024] = +{ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, + 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, + 0x4000, 0x7fff, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, + 0x0100, 0x0080, 0x0040, 0x0020, 0x0001, 0x0008, 0x0004, 0x0002, + 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8000, 0xffe5, 0x0100, 0x7fff, 0x7f02, 0x7e08, + 0x7d12, 0x7c1f, 0x7b30, 0x7a45, 0x795d, 0x7878, 0x7797, 0x76ba, + 0x75df, 0x7507, 0x7433, 0x7361, 0x7293, 0x71c7, 0x70fe, 0x7038, + 0x6f75, 0x6eb4, 0x6df6, 0x6d3a, 0x6c81, 0x6bca, 0x6b16, 0x6a64, + 0x69b4, 0x6907, 0x685b, 0x67b2, 0x670b, 0x6666, 0x65c4, 0x6523, + 0x6484, 0x63e7, 0x634c, 0x62b3, 0x621c, 0x6186, 0x60f2, 0x6060, + 0x5fd0, 0x5f41, 0x5eb5, 0x5e29, 0x5d9f, 0x5d17, 0x5c91, 0x5c0c, + 0x5b88, 0x5b06, 0x5a85, 0x5a06, 0x5988, 0x590b, 0x5890, 0x5816, + 0x579d, 0x5726, 0x56b0, 0x563b, 0x55c8, 0x5555, 0x54e4, 0x5474, + 0x5405, 0x5398, 0x532b, 0x52bf, 0x5255, 0x51ec, 0x5183, 0x511c, + 0x50b6, 0x5050, 0x4fec, 0x4f89, 0x4f26, 0x4ec5, 0x4e64, 0x4e05, + 0x4da6, 0x4d48, 0x4cec, 0x4c90, 0x4c34, 0x4bda, 0x4b81, 0x4b28, + 0x4ad0, 0x4a79, 0x4a23, 0x49cd, 0x4979, 0x4925, 0x48d1, 0x487f, + 0x482d, 0x47dc, 0x478c, 0x473c, 0x46ed, 0x469f, 0x4651, 0x4604, + 0x45b8, 0x456c, 0x4521, 0x44d7, 0x448d, 0x4444, 0x43fc, 0x43b4, + 0x436d, 0x4326, 0x42e0, 0x429a, 0x4255, 0x4211, 0x41cd, 0x4189, + 0x4146, 0x4104, 0x40c2, 0x4081, 0x4040, 0x3fff, 0x41f7, 0x43e1, + 0x45bd, 0x478d, 0x4951, 0x4b0b, 0x4cbb, 0x4e61, 0x4fff, 0x5194, + 0x5322, 0x54a9, 0x5628, 0x57a2, 0x5914, 0x5a81, 0x5be9, 0x5d4a, + 0x5ea7, 0x5fff, 0x6152, 0x62a0, 0x63ea, 0x6530, 0x6672, 0x67b0, + 0x68ea, 0x6a20, 0x6b53, 0x6c83, 0x6daf, 0x6ed9, 0x6fff, 0x7122, + 0x7242, 0x735f, 0x747a, 0x7592, 0x76a7, 0x77ba, 0x78cb, 0x79d9, + 0x7ae5, 0x7bee, 0x7cf5, 0x7dfa, 0x7efe, 0x7fff, 0x0000, 0x0324, + 0x0647, 0x096a, 0x0c8b, 0x0fab, 0x12c8, 0x15e2, 0x18f8, 0x1c0b, + 0x1f19, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, 0x30fb, 0x33de, + 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, 0x471c, 0x49b4, + 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, 0x5a82, 0x5cb4, + 0x5ed7, 0x60ec, 0x62f2, 0x64e8, 0x66cf, 0x68a6, 0x6a6d, 0x6c24, + 0x6dca, 0x6f5f, 0x70e2, 0x7255, 0x73b5, 0x7504, 0x7641, 0x776c, + 0x7884, 0x798a, 0x7a7d, 0x7b5d, 0x7c29, 0x7ce3, 0x7d8a, 0x7e1d, + 0x7e9d, 0x7f09, 0x7f62, 0x7fa7, 0x7fd8, 0x7ff6, 0x7fff, 0x7ff6, + 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, 0x7d8a, 0x7ce3, + 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, 0x7641, 0x7504, + 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, 0x6a6d, 0x68a6, + 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, 0x5a82, 0x5842, + 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, 0x471c, 0x447a, + 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, 0x30fb, 0x2e11, + 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, 0x18f8, 0x15e2, + 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, 0x7fff, 0x7ff6, + 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, 0x7d8a, 0x7ce3, + 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, 0x7641, 0x7504, + 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, 0x6a6d, 0x68a6, + 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, 0x5a82, 0x5842, + 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, 0x471c, 0x447a, + 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, 0x30fb, 0x2e11, + 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, 0x18f8, 0x15e2, + 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, 0x0000, 0xfcdc, + 0xf9b9, 0xf696, 0xf375, 0xf055, 0xed38, 0xea1e, 0xe708, 0xe3f5, + 0xe0e7, 0xdddd, 0xdad8, 0xd7da, 0xd4e1, 0xd1ef, 0xcf05, 0xcc22, + 0xc946, 0xc674, 0xc3aa, 0xc0e9, 0xbe32, 0xbb86, 0xb8e4, 0xb64c, + 0xb3c1, 0xb141, 0xaecd, 0xac65, 0xaa0b, 0xa7be, 0xa57e, 0xa34c, + 0xa129, 0x9f14, 0x9d0e, 0x9b18, 0x9931, 0x975a, 0x9593, 0x93dc, + 0x9236, 0x90a1, 0x8f1e, 0x8dab, 0x8c4b, 0x8afc, 0x89bf, 0x8894, + 0x877c, 0x8676, 0x8583, 0x84a3, 0x83d7, 0x831d, 0x8276, 0x81e3, + 0x8163, 0x80f7, 0x809e, 0x8059, 0x8028, 0x800a, 0x6488, 0x0080, + 0x03ff, 0x0116, 0x0002, 0x0080, 0x4000, 0x3fd7, 0x3faf, 0x3f86, + 0x3f5d, 0x3f34, 0x3f0c, 0x3ee3, 0x3eba, 0x3e91, 0x3e68, 0x3e40, + 0x3e17, 0x3dee, 0x3dc5, 0x3d9c, 0x3d74, 0x3d4b, 0x3d22, 0x3cf9, + 0x3cd0, 0x3ca7, 0x3c7f, 0x3c56, 0x3c2d, 0x3c04, 0x3bdb, 0x3bb2, + 0x3b89, 0x3b60, 0x3b37, 0x3b0e, 0x3ae5, 0x3abc, 0x3a93, 0x3a69, + 0x3a40, 0x3a17, 0x39ee, 0x39c5, 0x399c, 0x3972, 0x3949, 0x3920, + 0x38f6, 0x38cd, 0x38a4, 0x387a, 0x3851, 0x3827, 0x37fe, 0x37d4, + 0x37aa, 0x3781, 0x3757, 0x372d, 0x3704, 0x36da, 0x36b0, 0x3686, + 0x365c, 0x3632, 0x3609, 0x35df, 0x35b4, 0x358a, 0x3560, 0x3536, + 0x350c, 0x34e1, 0x34b7, 0x348d, 0x3462, 0x3438, 0x340d, 0x33e3, + 0x33b8, 0x338d, 0x3363, 0x3338, 0x330d, 0x32e2, 0x32b7, 0x328c, + 0x3261, 0x3236, 0x320b, 0x31df, 0x31b4, 0x3188, 0x315d, 0x3131, + 0x3106, 0x30da, 0x30ae, 0x3083, 0x3057, 0x302b, 0x2fff, 0x2fd2, + 0x2fa6, 0x2f7a, 0x2f4d, 0x2f21, 0x2ef4, 0x2ec8, 0x2e9b, 0x2e6e, + 0x2e41, 0x2e14, 0x2de7, 0x2dba, 0x2d8d, 0x2d60, 0x2d32, 0x2d05, + 0x2cd7, 0x2ca9, 0x2c7b, 0x2c4d, 0x2c1f, 0x2bf1, 0x2bc3, 0x2b94, + 0x2b66, 0x2b37, 0x2b09, 0x2ada, 0x2aab, 0x2a7c, 0x2a4c, 0x2a1d, + 0x29ed, 0x29be, 0x298e, 0x295e, 0x292e, 0x28fe, 0x28ce, 0x289d, + 0x286d, 0x283c, 0x280b, 0x27da, 0x27a9, 0x2777, 0x2746, 0x2714, + 0x26e2, 0x26b0, 0x267e, 0x264c, 0x2619, 0x25e7, 0x25b4, 0x2581, + 0x254d, 0x251a, 0x24e6, 0x24b2, 0x247e, 0x244a, 0x2415, 0x23e1, + 0x23ac, 0x2376, 0x2341, 0x230b, 0x22d6, 0x229f, 0x2269, 0x2232, + 0x21fc, 0x21c4, 0x218d, 0x2155, 0x211d, 0x20e5, 0x20ad, 0x2074, + 0x203b, 0x2001, 0x1fc7, 0x1f8d, 0x1f53, 0x1f18, 0x1edd, 0x1ea1, + 0x1e66, 0x1e29, 0x1ded, 0x1db0, 0x1d72, 0x1d35, 0x1cf6, 0x1cb8, + 0x1c79, 0x1c39, 0x1bf9, 0x1bb8, 0x1b77, 0x1b36, 0x1af4, 0x1ab1, + 0x1a6e, 0x1a2a, 0x19e6, 0x19a1, 0x195c, 0x1915, 0x18ce, 0x1887, + 0x183f, 0x17f5, 0x17ac, 0x1761, 0x1715, 0x16c9, 0x167c, 0x162e, + 0x15df, 0x158e, 0x153d, 0x14eb, 0x1497, 0x1442, 0x13ec, 0x1395, + 0x133c, 0x12e2, 0x1286, 0x1228, 0x11c9, 0x1167, 0x1104, 0x109e, + 0x1036, 0x0fcc, 0x0f5f, 0x0eef, 0x0e7b, 0x0e04, 0x0d89, 0x0d0a, + 0x0c86, 0x0bfd, 0x0b6d, 0x0ad6, 0x0a36, 0x098d, 0x08d7, 0x0811, + 0x0736, 0x063e, 0x0519, 0x039a, 0x0000, 0x7fff, 0x0100, 0x0080, + 0x021d, 0x00c8, 0x00ce, 0x0048, 0x0a26, 0x277a, 0x00ce, 0x6488, + 0x14ac, 0x0001, 0x00f9, 0x00fc, 0x00ff, 0x00fc, 0x00f9, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff }; void DSP3SetByte(uint8 byte, uint16 address) { - if ((address & 0xf000) == 0x6000 || - (address >= 0x8000 && address < 0xc000)) - { - if (DSP1.waiting4command) - { - DSP1.command = byte; - DSP1.in_index = 0; - DSP1.waiting4command = FALSE; -// DSP1.first_parameter = TRUE; -// printf("Op%02X\n",byte); - switch (byte) - { - case 0x2F:DSP1.in_count=2;break; - case 0x1F:DSP1.in_count=2;break; - case 0x0F:DSP1.in_count=2;break; - case 0x38:DSP1.in_count=4;break; - default: -// printf("Op%02X\n",byte); - break; - } - } - else - { - DSP1.parameters [DSP1.in_index] = byte; -// DSP1.first_parameter = FALSE; - DSP1.in_index++; - } - - if (DSP1.in_count==DSP1.in_index) - { - //DSP1.parameters [DSP1.in_index] |= (byte << 8); - // Actually execute the command - DSP1.waiting4command = TRUE; - DSP1.out_index = 0; - switch (DSP1.command) - { - case 0x2F:DSP1.out_count=2;break; - case 0x1F:DSP1.out_count=2048;break; - case 0x0F:DSP1.out_count=2; - DSP1.output[0]=0; - DSP1.output[1]=0; - break; - case 0x38: - { - DSP1.out_count=2; - // 176B - DSP1.output[0]=0; - DSP1.output[1]=0x80; - - break; - } - default: - break; - } - } - } + if ((address & 0xf000) == 0x6000 || + (address >= 0x8000 && address < 0xc000)) + { + if (DSP1.waiting4command) + { + DSP1.command = byte; + DSP1.in_index = 0; + DSP1.waiting4command = FALSE; + // DSP1.first_parameter = TRUE; + // printf("Op%02X\n",byte); + switch (byte) + { + case 0x2F: + DSP1.in_count = 2; + break; + case 0x1F: + DSP1.in_count = 2; + break; + case 0x0F: + DSP1.in_count = 2; + break; + case 0x38: + DSP1.in_count = 4; + break; + default: + // printf("Op%02X\n",byte); + break; + } + } + else + { + DSP1.parameters [DSP1.in_index] = byte; + // DSP1.first_parameter = FALSE; + DSP1.in_index++; + } + + if (DSP1.in_count == DSP1.in_index) + { + //DSP1.parameters [DSP1.in_index] |= (byte << 8); + // Actually execute the command + DSP1.waiting4command = TRUE; + DSP1.out_index = 0; + switch (DSP1.command) + { + case 0x2F: + DSP1.out_count = 2; + break; + case 0x1F: + DSP1.out_count = 2048; + break; + case 0x0F: + DSP1.out_count = 2; + DSP1.output[0] = 0; + DSP1.output[1] = 0; + break; + case 0x38: + { + DSP1.out_count = 2; + // 176B + DSP1.output[0] = 0; + DSP1.output[1] = 0x80; + + break; + } + default: + break; + } + } + } } uint8 DSP3GetByte(uint16 address) { - uint8 t; - if ((address & 0xf000) == 0x6000 || - (address >= 0x8000 && address < 0xc000)) - { - if(DSP1.command==0x38&&DSP1.out_index==1) - { - t=4; - } - - if (DSP1.out_count) - { - if(DSP1.command==0x1f) - { - if((DSP1.out_index%2)!=0) - { - t=(uint8)Dsp3Rom[DSP1.out_index>>1]; - } - else - { - t=Dsp3Rom[DSP1.out_index>>1]>>8; - } -// t=Dsp3Rom[DSP1.out_index]; - DSP1.out_index++; - } - else - { - t = (uint8) DSP1.output [DSP1.out_index]; - DSP1.out_index++; - DSP1.out_index%=512; - if(DSP1.out_count==DSP1.out_index) - DSP1.out_count=0; - } - } - else - { - t = 0xff; - } - } - else - { - t = 0x80; -/* if(DSP1.command=0x38&&DSP1.out_count==0) - { - t=0xC0; - static int Op38c; - if(Op38c==14) - { - Op38c=0; - t=0x80; - DSP1.in_count=4; - } - Op38c++; - }*/ - } - return t; + uint8 t; + if ((address & 0xf000) == 0x6000 || + (address >= 0x8000 && address < 0xc000)) + { + if (DSP1.command == 0x38 && DSP1.out_index == 1) + t = 4; + + if (DSP1.out_count) + { + if (DSP1.command == 0x1f) + { + if ((DSP1.out_index % 2) != 0) + t = (uint8)Dsp3Rom[DSP1.out_index >> 1]; + else + t = Dsp3Rom[DSP1.out_index >> 1] >> 8; + // t=Dsp3Rom[DSP1.out_index]; + DSP1.out_index++; + } + else + { + t = (uint8) DSP1.output [DSP1.out_index]; + DSP1.out_index++; + DSP1.out_index %= 512; + if (DSP1.out_count == DSP1.out_index) + DSP1.out_count = 0; + } + } + else + t = 0xff; + } + else + { + t = 0x80; + /* if(DSP1.command=0x38&&DSP1.out_count==0) + { + t=0xC0; + static int Op38c; + if(Op38c==14) + { + Op38c=0; + t=0x80; + DSP1.in_count=4; + } + Op38c++; + }*/ + } + return t; } #endif typedef struct { - bool8 waiting4command; - bool8 half_command; - uint16 command; - uint32 in_count; - uint32 in_index; - uint32 out_count; - uint32 out_index; - uint8 parameters [512]; - uint8 output [512]; -}SDSP4; + bool8 waiting4command; + bool8 half_command; + uint16 command; + uint32 in_count; + uint32 in_index; + uint32 out_count; + uint32 out_index; + uint8 parameters [512]; + uint8 output [512]; +} SDSP4; SDSP4 DSP4; #include "dsp4emu.c" -bool DSP4_init=FALSE; +bool DSP4_init = FALSE; void DSP4SetByte(uint8 byte, uint16 address) { - if(!DSP4_init) - { - // bootup - DSP4.waiting4command=1; - DSP4_init=TRUE; - } - - if ((address & 0xf000) == 0x6000 || - (address >= 0x8000 && address < 0xc000)) - { - if(DSP4.out_index>16); - } - break; - - // unknown: horizontal mapping command - case 0x0011: - { - int16 a,b,c,d,m; - - a = DSP4_READ_WORD(6); - b = DSP4_READ_WORD(4); - c = DSP4_READ_WORD(2); - d = DSP4_READ_WORD(0); - - m = DSP4_UnknownOP11(a,b,c,d); - - DSP4.out_count = 2; - DSP4_WRITE_WORD(0,m); - break; - } - - // track projection - case 0x0001: DSP4_Op01(); break; - - // track projection (pass 2) - case 0x0007: DSP4_Op07(); break; - - // zone projections (fuel/repair/lap/teleport/...) - case 0x0008: DSP4_Op08(); break; - - // sprite transformation - case 0x0009: DSP4_Op09(); break; - - // fast track projection - case 0x000D: DSP4_Op0D(); break; - - // internal memory management (01) - case 0x0003: - { - // reset op09 data - op09_mode = 0; - break; - } - - // internal memory management (06) - case 0x0005: - { - // clear OAM tables - op06_index = 0; - op06_offset = 0; - int lcv; - for(lcv=0; lcv<32; lcv++ ) - op06_OAM[lcv] = 0; - break; - } - - // internal memory management (0D) - case 0x000E: - { - // reset op09 data - op09_mode = 1; - break; - } - - // sprite OAM post-table data - case 0x0006: - { - DSP4.out_count = 32; - int lcv; - for(lcv=0; lcv<32; lcv++ ) - DSP4.output[lcv] = op06_OAM[lcv]; - } - break; - - // unknown - case 0x000A: - { - int16 in1a = DSP4_READ_WORD(0); - int16 in2a = DSP4_READ_WORD(2); - int16 in3a = DSP4_READ_WORD(4); - int16 out1a,out2a; - - out1a=(short)0xff40; - out2a=(short)0x00c0; - - DSP4.out_count=8; - - DSP4_WRITE_WORD(0,out1a); - DSP4_WRITE_WORD(2,out2a); - DSP4_WRITE_WORD(4,out1a); - DSP4_WRITE_WORD(6,out2a); - } - break; - - // render player positions around track - case 0x000B: - { - int16 sp_x = DSP4_READ_WORD(0); - int16 sp_y = DSP4_READ_WORD(2); - int16 oam = DSP4_READ_WORD(4); - - // Only allow 1p/1p-split to yield output (???) - if(!op09_mode) - { - // yield OAM output - DSP4.out_count = 6; - DSP4_WRITE_WORD(0,1); - - // pack OAM data: x,y,name,attr - DSP4.output[2] = sp_x & 0xff; - DSP4.output[3] = sp_y & 0xff; - DSP4_WRITE_WORD(4,oam); - - // OAM: size,msb data - DSP4_Op06(0,0); - } - // 4p mode - else - { - // no OAM available - DSP4.out_count=0; - DSP4_WRITE_WORD(0,0); - } - } - break; - - default: break; - } - } - } + if (!DSP4_init) + { + // bootup + DSP4.waiting4command = 1; + DSP4_init = TRUE; + } + + if ((address & 0xf000) == 0x6000 || + (address >= 0x8000 && address < 0xc000)) + { + if (DSP4.out_index < DSP4.out_count) + { + DSP4.out_index++; + return; + } + + if (DSP4.waiting4command) + { + if (DSP4.half_command) + { + DSP4.command |= (byte << 8); + DSP4.in_index = 0; + DSP4.waiting4command = FALSE; + // DSP4.first_parameter = TRUE; + DSP4.half_command = 0; + DSP4.out_count = 0; + DSP4.out_index = 0; + DSP4_Logic = 0; + + switch (DSP4.command) + { + case 0x0000: + DSP4.in_count = 4; + break; + case 0x0001: + DSP4.in_count = 36; + break; + case 0x0003: + DSP4.in_count = 0; + break; + case 0x0005: + DSP4.in_count = 0; + break; + case 0x0006: + DSP4.in_count = 0; + break; + case 0x0007: + DSP4.in_count = 22; + break; + case 0x0008: + DSP4.in_count = 72; + break; + case 0x0009: + DSP4.in_count = 14; + break; + case 0x000A: + DSP4.in_count = 6; + break; + case 0x000B: + DSP4.in_count = 6; + break; + case 0x000D: + DSP4.in_count = 34; + break; + case 0x000E: + DSP4.in_count = 0; + break; + case 0x0011: + DSP4.in_count = 8; + break; + default: + DSP4.waiting4command = TRUE; + //printf("(line %d) Unknown Op%02X\n",line,DSP4.command); + break; + } + } + else + { + DSP4.command = byte; + DSP4.half_command = 1; + } + } + else + { + DSP4.parameters [DSP4.in_index] = byte; + // DSP4.first_parameter = FALSE; + DSP4.in_index++; + } + + if (!DSP4.waiting4command && DSP4.in_count == DSP4.in_index) + { + //DSP4.parameters [DSP4.in_index] |= (byte << 8); + // Actually execute the command + DSP4.waiting4command = TRUE; + DSP4.out_index = 0; + DSP4.in_index = 0; + switch (DSP4.command) + { + // 16-bit multiplication + case 0x0000: + { + int16 multiplier, multiplicand; + int product; + + multiplier = DSP4_READ_WORD(0); + multiplicand = DSP4_READ_WORD(2); + + product = DSP4_Multiply(multiplicand, multiplier); + + DSP4.out_count = 4; + DSP4_WRITE_WORD(0, product); + DSP4_WRITE_WORD(2, product >> 16); + } + break; + + // unknown: horizontal mapping command + case 0x0011: + { + int16 a, b, c, d, m; + + a = DSP4_READ_WORD(6); + b = DSP4_READ_WORD(4); + c = DSP4_READ_WORD(2); + d = DSP4_READ_WORD(0); + + m = DSP4_UnknownOP11(a, b, c, d); + + DSP4.out_count = 2; + DSP4_WRITE_WORD(0, m); + break; + } + + // track projection + case 0x0001: + DSP4_Op01(); + break; + + // track projection (pass 2) + case 0x0007: + DSP4_Op07(); + break; + + // zone projections (fuel/repair/lap/teleport/...) + case 0x0008: + DSP4_Op08(); + break; + + // sprite transformation + case 0x0009: + DSP4_Op09(); + break; + + // fast track projection + case 0x000D: + DSP4_Op0D(); + break; + + // internal memory management (01) + case 0x0003: + { + // reset op09 data + op09_mode = 0; + break; + } + + // internal memory management (06) + case 0x0005: + { + // clear OAM tables + op06_index = 0; + op06_offset = 0; + int lcv; + for (lcv = 0; lcv < 32; lcv++) + op06_OAM[lcv] = 0; + break; + } + + // internal memory management (0D) + case 0x000E: + { + // reset op09 data + op09_mode = 1; + break; + } + + // sprite OAM post-table data + case 0x0006: + { + DSP4.out_count = 32; + int lcv; + for (lcv = 0; lcv < 32; lcv++) + DSP4.output[lcv] = op06_OAM[lcv]; + } + break; + + // unknown + case 0x000A: + { + int16 in1a = DSP4_READ_WORD(0); + int16 in2a = DSP4_READ_WORD(2); + int16 in3a = DSP4_READ_WORD(4); + int16 out1a, out2a; + + out1a = (short)0xff40; + out2a = (short)0x00c0; + + DSP4.out_count = 8; + + DSP4_WRITE_WORD(0, out1a); + DSP4_WRITE_WORD(2, out2a); + DSP4_WRITE_WORD(4, out1a); + DSP4_WRITE_WORD(6, out2a); + } + break; + + // render player positions around track + case 0x000B: + { + int16 sp_x = DSP4_READ_WORD(0); + int16 sp_y = DSP4_READ_WORD(2); + int16 oam = DSP4_READ_WORD(4); + + // Only allow 1p/1p-split to yield output (???) + if (!op09_mode) + { + // yield OAM output + DSP4.out_count = 6; + DSP4_WRITE_WORD(0, 1); + + // pack OAM data: x,y,name,attr + DSP4.output[2] = sp_x & 0xff; + DSP4.output[3] = sp_y & 0xff; + DSP4_WRITE_WORD(4, oam); + + // OAM: size,msb data + DSP4_Op06(0, 0); + } + // 4p mode + else + { + // no OAM available + DSP4.out_count = 0; + DSP4_WRITE_WORD(0, 0); + } + } + break; + + default: + break; + } + } + } } uint8 DSP4GetByte(uint16 address) { - uint8 t; - if ((address & 0xf000) == 0x6000 || - (address >= 0x8000 && address < 0xc000)) - { - if (DSP4.out_count) - { - t = (uint8) DSP4.output [DSP4.out_index]; - DSP4.out_index++; - if(DSP4.out_count==DSP4.out_index) - DSP4.out_count=0; - } - else - t = 0xff; - } - else - { - t = 0x80; - } - - return t; + uint8 t; + if ((address & 0xf000) == 0x6000 || + (address >= 0x8000 && address < 0xc000)) + { + if (DSP4.out_count) + { + t = (uint8) DSP4.output [DSP4.out_index]; + DSP4.out_index++; + if (DSP4.out_count == DSP4.out_index) + DSP4.out_count = 0; + } + else + t = 0xff; + } + else + t = 0x80; + + return t; } diff --git a/source/dsp1.h b/source/dsp1.h index a2c5f1b..5eba950 100644 --- a/source/dsp1.h +++ b/source/dsp1.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -91,7 +91,7 @@ #define _DSP1_H_ extern void (*SetDSP)(uint8, uint16); -extern uint8 (*GetDSP)(uint16); +extern uint8(*GetDSP)(uint16); void DSP1SetByte(uint8 byte, uint16 address); uint8 DSP1GetByte(uint16 address); @@ -105,22 +105,23 @@ uint8 DSP3GetByte(uint16 address); void DSP4SetByte(uint8 byte, uint16 address); uint8 DSP4GetByte(uint16 address); -typedef struct{ - bool8 waiting4command; - bool8 first_parameter; - uint8 command; - uint32 in_count; - uint32 in_index; - uint32 out_count; - uint32 out_index; - uint8 parameters [512]; -//output was 512 for DSP-2 work, updated to reflect current thinking on DSP-3 - uint8 output [512]; -}SDSP1; - -void S9xResetDSP1 (); -uint8 S9xGetDSP (uint16 Address); -void S9xSetDSP (uint8 Byte, uint16 Address); +typedef struct +{ + bool8 waiting4command; + bool8 first_parameter; + uint8 command; + uint32 in_count; + uint32 in_index; + uint32 out_count; + uint32 out_index; + uint8 parameters [512]; + //output was 512 for DSP-2 work, updated to reflect current thinking on DSP-3 + uint8 output [512]; +} SDSP1; + +void S9xResetDSP1(); +uint8 S9xGetDSP(uint16 Address); +void S9xSetDSP(uint8 Byte, uint16 Address); extern SDSP1 DSP1; //extern struct SDSP1 DSP1; diff --git a/source/dsp1emu.c b/source/dsp1emu.c index 6b4172a..8bf3617 100644 --- a/source/dsp1emu.c +++ b/source/dsp1emu.c @@ -38,172 +38,174 @@ #ifdef DebugDSP1 -FILE * LogFile = NULL; +FILE* LogFile = NULL; -void Log_Message (char *Message, ...) +void Log_Message(char* Message, ...) { - char Msg[400]; - va_list ap; + char Msg[400]; + va_list ap; - va_start(ap,Message); - vsprintf(Msg,Message,ap ); + va_start(ap, Message); + vsprintf(Msg, Message, ap); va_end(ap); - - strcat(Msg,"\r\n\0"); - fwrite(Msg,strlen(Msg),1,LogFile); - fflush (LogFile); + + strcat(Msg, "\r\n\0"); + fwrite(Msg, strlen(Msg), 1, LogFile); + fflush(LogFile); } -void Start_Log (void) +void Start_Log(void) { - char LogFileName[255]; -// [4/15/2001] char *p; + char LogFileName[255]; + // [4/15/2001] char *p; + + strcpy(LogFileName, "dsp1emu.log\0"); - strcpy(LogFileName,"dsp1emu.log\0"); - - LogFile = fopen(LogFileName,"wb"); + LogFile = fopen(LogFileName, "wb"); } -void Stop_Log (void) +void Stop_Log(void) { if (LogFile) { fclose(LogFile); LogFile = NULL; - } + } } #endif -const unsigned short DSP1ROM[1024] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, - 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, - 0x4000, 0x7fff, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, - 0x0100, 0x0080, 0x0040, 0x0020, 0x0001, 0x0008, 0x0004, 0x0002, - 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8000, 0xffe5, 0x0100, 0x7fff, 0x7f02, 0x7e08, - 0x7d12, 0x7c1f, 0x7b30, 0x7a45, 0x795d, 0x7878, 0x7797, 0x76ba, - 0x75df, 0x7507, 0x7433, 0x7361, 0x7293, 0x71c7, 0x70fe, 0x7038, - 0x6f75, 0x6eb4, 0x6df6, 0x6d3a, 0x6c81, 0x6bca, 0x6b16, 0x6a64, - 0x69b4, 0x6907, 0x685b, 0x67b2, 0x670b, 0x6666, 0x65c4, 0x6523, - 0x6484, 0x63e7, 0x634c, 0x62b3, 0x621c, 0x6186, 0x60f2, 0x6060, - 0x5fd0, 0x5f41, 0x5eb5, 0x5e29, 0x5d9f, 0x5d17, 0x5c91, 0x5c0c, - 0x5b88, 0x5b06, 0x5a85, 0x5a06, 0x5988, 0x590b, 0x5890, 0x5816, - 0x579d, 0x5726, 0x56b0, 0x563b, 0x55c8, 0x5555, 0x54e4, 0x5474, - 0x5405, 0x5398, 0x532b, 0x52bf, 0x5255, 0x51ec, 0x5183, 0x511c, - 0x50b6, 0x5050, 0x4fec, 0x4f89, 0x4f26, 0x4ec5, 0x4e64, 0x4e05, - 0x4da6, 0x4d48, 0x4cec, 0x4c90, 0x4c34, 0x4bda, 0x4b81, 0x4b28, - 0x4ad0, 0x4a79, 0x4a23, 0x49cd, 0x4979, 0x4925, 0x48d1, 0x487f, - 0x482d, 0x47dc, 0x478c, 0x473c, 0x46ed, 0x469f, 0x4651, 0x4604, - 0x45b8, 0x456c, 0x4521, 0x44d7, 0x448d, 0x4444, 0x43fc, 0x43b4, - 0x436d, 0x4326, 0x42e0, 0x429a, 0x4255, 0x4211, 0x41cd, 0x4189, - 0x4146, 0x4104, 0x40c2, 0x4081, 0x4040, 0x3fff, 0x41f7, 0x43e1, - 0x45bd, 0x478d, 0x4951, 0x4b0b, 0x4cbb, 0x4e61, 0x4fff, 0x5194, - 0x5322, 0x54a9, 0x5628, 0x57a2, 0x5914, 0x5a81, 0x5be9, 0x5d4a, - 0x5ea7, 0x5fff, 0x6152, 0x62a0, 0x63ea, 0x6530, 0x6672, 0x67b0, - 0x68ea, 0x6a20, 0x6b53, 0x6c83, 0x6daf, 0x6ed9, 0x6fff, 0x7122, - 0x7242, 0x735f, 0x747a, 0x7592, 0x76a7, 0x77ba, 0x78cb, 0x79d9, - 0x7ae5, 0x7bee, 0x7cf5, 0x7dfa, 0x7efe, 0x7fff, 0x0000, 0x0324, - 0x0647, 0x096a, 0x0c8b, 0x0fab, 0x12c8, 0x15e2, 0x18f8, 0x1c0b, - 0x1f19, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, 0x30fb, 0x33de, - 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, 0x471c, 0x49b4, - 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, 0x5a82, 0x5cb4, - 0x5ed7, 0x60ec, 0x62f2, 0x64e8, 0x66cf, 0x68a6, 0x6a6d, 0x6c24, - 0x6dca, 0x6f5f, 0x70e2, 0x7255, 0x73b5, 0x7504, 0x7641, 0x776c, - 0x7884, 0x798a, 0x7a7d, 0x7b5d, 0x7c29, 0x7ce3, 0x7d8a, 0x7e1d, - 0x7e9d, 0x7f09, 0x7f62, 0x7fa7, 0x7fd8, 0x7ff6, 0x7fff, 0x7ff6, - 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, 0x7d8a, 0x7ce3, - 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, 0x7641, 0x7504, - 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, 0x6a6d, 0x68a6, - 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, 0x5a82, 0x5842, - 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, 0x471c, 0x447a, - 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, 0x30fb, 0x2e11, - 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, 0x18f8, 0x15e2, - 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, 0x7fff, 0x7ff6, - 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, 0x7d8a, 0x7ce3, - 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, 0x7641, 0x7504, - 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, 0x6a6d, 0x68a6, - 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, 0x5a82, 0x5842, - 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, 0x471c, 0x447a, - 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, 0x30fb, 0x2e11, - 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, 0x18f8, 0x15e2, - 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, 0x0000, 0xfcdc, - 0xf9b9, 0xf696, 0xf375, 0xf055, 0xed38, 0xea1e, 0xe708, 0xe3f5, - 0xe0e7, 0xdddd, 0xdad8, 0xd7da, 0xd4e1, 0xd1ef, 0xcf05, 0xcc22, - 0xc946, 0xc674, 0xc3aa, 0xc0e9, 0xbe32, 0xbb86, 0xb8e4, 0xb64c, - 0xb3c1, 0xb141, 0xaecd, 0xac65, 0xaa0b, 0xa7be, 0xa57e, 0xa34c, - 0xa129, 0x9f14, 0x9d0e, 0x9b18, 0x9931, 0x975a, 0x9593, 0x93dc, - 0x9236, 0x90a1, 0x8f1e, 0x8dab, 0x8c4b, 0x8afc, 0x89bf, 0x8894, - 0x877c, 0x8676, 0x8583, 0x84a3, 0x83d7, 0x831d, 0x8276, 0x81e3, - 0x8163, 0x80f7, 0x809e, 0x8059, 0x8028, 0x800a, 0x6488, 0x0080, - 0x03ff, 0x0116, 0x0002, 0x0080, 0x4000, 0x3fd7, 0x3faf, 0x3f86, - 0x3f5d, 0x3f34, 0x3f0c, 0x3ee3, 0x3eba, 0x3e91, 0x3e68, 0x3e40, - 0x3e17, 0x3dee, 0x3dc5, 0x3d9c, 0x3d74, 0x3d4b, 0x3d22, 0x3cf9, - 0x3cd0, 0x3ca7, 0x3c7f, 0x3c56, 0x3c2d, 0x3c04, 0x3bdb, 0x3bb2, - 0x3b89, 0x3b60, 0x3b37, 0x3b0e, 0x3ae5, 0x3abc, 0x3a93, 0x3a69, - 0x3a40, 0x3a17, 0x39ee, 0x39c5, 0x399c, 0x3972, 0x3949, 0x3920, - 0x38f6, 0x38cd, 0x38a4, 0x387a, 0x3851, 0x3827, 0x37fe, 0x37d4, - 0x37aa, 0x3781, 0x3757, 0x372d, 0x3704, 0x36da, 0x36b0, 0x3686, - 0x365c, 0x3632, 0x3609, 0x35df, 0x35b4, 0x358a, 0x3560, 0x3536, - 0x350c, 0x34e1, 0x34b7, 0x348d, 0x3462, 0x3438, 0x340d, 0x33e3, - 0x33b8, 0x338d, 0x3363, 0x3338, 0x330d, 0x32e2, 0x32b7, 0x328c, - 0x3261, 0x3236, 0x320b, 0x31df, 0x31b4, 0x3188, 0x315d, 0x3131, - 0x3106, 0x30da, 0x30ae, 0x3083, 0x3057, 0x302b, 0x2fff, 0x2fd2, - 0x2fa6, 0x2f7a, 0x2f4d, 0x2f21, 0x2ef4, 0x2ec8, 0x2e9b, 0x2e6e, - 0x2e41, 0x2e14, 0x2de7, 0x2dba, 0x2d8d, 0x2d60, 0x2d32, 0x2d05, - 0x2cd7, 0x2ca9, 0x2c7b, 0x2c4d, 0x2c1f, 0x2bf1, 0x2bc3, 0x2b94, - 0x2b66, 0x2b37, 0x2b09, 0x2ada, 0x2aab, 0x2a7c, 0x2a4c, 0x2a1d, - 0x29ed, 0x29be, 0x298e, 0x295e, 0x292e, 0x28fe, 0x28ce, 0x289d, - 0x286d, 0x283c, 0x280b, 0x27da, 0x27a9, 0x2777, 0x2746, 0x2714, - 0x26e2, 0x26b0, 0x267e, 0x264c, 0x2619, 0x25e7, 0x25b4, 0x2581, - 0x254d, 0x251a, 0x24e6, 0x24b2, 0x247e, 0x244a, 0x2415, 0x23e1, - 0x23ac, 0x2376, 0x2341, 0x230b, 0x22d6, 0x229f, 0x2269, 0x2232, - 0x21fc, 0x21c4, 0x218d, 0x2155, 0x211d, 0x20e5, 0x20ad, 0x2074, - 0x203b, 0x2001, 0x1fc7, 0x1f8d, 0x1f53, 0x1f18, 0x1edd, 0x1ea1, - 0x1e66, 0x1e29, 0x1ded, 0x1db0, 0x1d72, 0x1d35, 0x1cf6, 0x1cb8, - 0x1c79, 0x1c39, 0x1bf9, 0x1bb8, 0x1b77, 0x1b36, 0x1af4, 0x1ab1, - 0x1a6e, 0x1a2a, 0x19e6, 0x19a1, 0x195c, 0x1915, 0x18ce, 0x1887, - 0x183f, 0x17f5, 0x17ac, 0x1761, 0x1715, 0x16c9, 0x167c, 0x162e, - 0x15df, 0x158e, 0x153d, 0x14eb, 0x1497, 0x1442, 0x13ec, 0x1395, - 0x133c, 0x12e2, 0x1286, 0x1228, 0x11c9, 0x1167, 0x1104, 0x109e, - 0x1036, 0x0fcc, 0x0f5f, 0x0eef, 0x0e7b, 0x0e04, 0x0d89, 0x0d0a, - 0x0c86, 0x0bfd, 0x0b6d, 0x0ad6, 0x0a36, 0x098d, 0x08d7, 0x0811, - 0x0736, 0x063e, 0x0519, 0x039a, 0x0000, 0x7fff, 0x0100, 0x0080, - 0x021d, 0x00c8, 0x00ce, 0x0048, 0x0a26, 0x277a, 0x00ce, 0x6488, - 0x14ac, 0x0001, 0x00f9, 0x00fc, 0x00ff, 0x00fc, 0x00f9, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}; +const unsigned short DSP1ROM[1024] = +{ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, + 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, + 0x4000, 0x7fff, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, + 0x0100, 0x0080, 0x0040, 0x0020, 0x0001, 0x0008, 0x0004, 0x0002, + 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8000, 0xffe5, 0x0100, 0x7fff, 0x7f02, 0x7e08, + 0x7d12, 0x7c1f, 0x7b30, 0x7a45, 0x795d, 0x7878, 0x7797, 0x76ba, + 0x75df, 0x7507, 0x7433, 0x7361, 0x7293, 0x71c7, 0x70fe, 0x7038, + 0x6f75, 0x6eb4, 0x6df6, 0x6d3a, 0x6c81, 0x6bca, 0x6b16, 0x6a64, + 0x69b4, 0x6907, 0x685b, 0x67b2, 0x670b, 0x6666, 0x65c4, 0x6523, + 0x6484, 0x63e7, 0x634c, 0x62b3, 0x621c, 0x6186, 0x60f2, 0x6060, + 0x5fd0, 0x5f41, 0x5eb5, 0x5e29, 0x5d9f, 0x5d17, 0x5c91, 0x5c0c, + 0x5b88, 0x5b06, 0x5a85, 0x5a06, 0x5988, 0x590b, 0x5890, 0x5816, + 0x579d, 0x5726, 0x56b0, 0x563b, 0x55c8, 0x5555, 0x54e4, 0x5474, + 0x5405, 0x5398, 0x532b, 0x52bf, 0x5255, 0x51ec, 0x5183, 0x511c, + 0x50b6, 0x5050, 0x4fec, 0x4f89, 0x4f26, 0x4ec5, 0x4e64, 0x4e05, + 0x4da6, 0x4d48, 0x4cec, 0x4c90, 0x4c34, 0x4bda, 0x4b81, 0x4b28, + 0x4ad0, 0x4a79, 0x4a23, 0x49cd, 0x4979, 0x4925, 0x48d1, 0x487f, + 0x482d, 0x47dc, 0x478c, 0x473c, 0x46ed, 0x469f, 0x4651, 0x4604, + 0x45b8, 0x456c, 0x4521, 0x44d7, 0x448d, 0x4444, 0x43fc, 0x43b4, + 0x436d, 0x4326, 0x42e0, 0x429a, 0x4255, 0x4211, 0x41cd, 0x4189, + 0x4146, 0x4104, 0x40c2, 0x4081, 0x4040, 0x3fff, 0x41f7, 0x43e1, + 0x45bd, 0x478d, 0x4951, 0x4b0b, 0x4cbb, 0x4e61, 0x4fff, 0x5194, + 0x5322, 0x54a9, 0x5628, 0x57a2, 0x5914, 0x5a81, 0x5be9, 0x5d4a, + 0x5ea7, 0x5fff, 0x6152, 0x62a0, 0x63ea, 0x6530, 0x6672, 0x67b0, + 0x68ea, 0x6a20, 0x6b53, 0x6c83, 0x6daf, 0x6ed9, 0x6fff, 0x7122, + 0x7242, 0x735f, 0x747a, 0x7592, 0x76a7, 0x77ba, 0x78cb, 0x79d9, + 0x7ae5, 0x7bee, 0x7cf5, 0x7dfa, 0x7efe, 0x7fff, 0x0000, 0x0324, + 0x0647, 0x096a, 0x0c8b, 0x0fab, 0x12c8, 0x15e2, 0x18f8, 0x1c0b, + 0x1f19, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, 0x30fb, 0x33de, + 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, 0x471c, 0x49b4, + 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, 0x5a82, 0x5cb4, + 0x5ed7, 0x60ec, 0x62f2, 0x64e8, 0x66cf, 0x68a6, 0x6a6d, 0x6c24, + 0x6dca, 0x6f5f, 0x70e2, 0x7255, 0x73b5, 0x7504, 0x7641, 0x776c, + 0x7884, 0x798a, 0x7a7d, 0x7b5d, 0x7c29, 0x7ce3, 0x7d8a, 0x7e1d, + 0x7e9d, 0x7f09, 0x7f62, 0x7fa7, 0x7fd8, 0x7ff6, 0x7fff, 0x7ff6, + 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, 0x7d8a, 0x7ce3, + 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, 0x7641, 0x7504, + 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, 0x6a6d, 0x68a6, + 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, 0x5a82, 0x5842, + 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, 0x471c, 0x447a, + 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, 0x30fb, 0x2e11, + 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, 0x18f8, 0x15e2, + 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, 0x7fff, 0x7ff6, + 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, 0x7d8a, 0x7ce3, + 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, 0x7641, 0x7504, + 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, 0x6a6d, 0x68a6, + 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, 0x5a82, 0x5842, + 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, 0x471c, 0x447a, + 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, 0x30fb, 0x2e11, + 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, 0x18f8, 0x15e2, + 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, 0x0000, 0xfcdc, + 0xf9b9, 0xf696, 0xf375, 0xf055, 0xed38, 0xea1e, 0xe708, 0xe3f5, + 0xe0e7, 0xdddd, 0xdad8, 0xd7da, 0xd4e1, 0xd1ef, 0xcf05, 0xcc22, + 0xc946, 0xc674, 0xc3aa, 0xc0e9, 0xbe32, 0xbb86, 0xb8e4, 0xb64c, + 0xb3c1, 0xb141, 0xaecd, 0xac65, 0xaa0b, 0xa7be, 0xa57e, 0xa34c, + 0xa129, 0x9f14, 0x9d0e, 0x9b18, 0x9931, 0x975a, 0x9593, 0x93dc, + 0x9236, 0x90a1, 0x8f1e, 0x8dab, 0x8c4b, 0x8afc, 0x89bf, 0x8894, + 0x877c, 0x8676, 0x8583, 0x84a3, 0x83d7, 0x831d, 0x8276, 0x81e3, + 0x8163, 0x80f7, 0x809e, 0x8059, 0x8028, 0x800a, 0x6488, 0x0080, + 0x03ff, 0x0116, 0x0002, 0x0080, 0x4000, 0x3fd7, 0x3faf, 0x3f86, + 0x3f5d, 0x3f34, 0x3f0c, 0x3ee3, 0x3eba, 0x3e91, 0x3e68, 0x3e40, + 0x3e17, 0x3dee, 0x3dc5, 0x3d9c, 0x3d74, 0x3d4b, 0x3d22, 0x3cf9, + 0x3cd0, 0x3ca7, 0x3c7f, 0x3c56, 0x3c2d, 0x3c04, 0x3bdb, 0x3bb2, + 0x3b89, 0x3b60, 0x3b37, 0x3b0e, 0x3ae5, 0x3abc, 0x3a93, 0x3a69, + 0x3a40, 0x3a17, 0x39ee, 0x39c5, 0x399c, 0x3972, 0x3949, 0x3920, + 0x38f6, 0x38cd, 0x38a4, 0x387a, 0x3851, 0x3827, 0x37fe, 0x37d4, + 0x37aa, 0x3781, 0x3757, 0x372d, 0x3704, 0x36da, 0x36b0, 0x3686, + 0x365c, 0x3632, 0x3609, 0x35df, 0x35b4, 0x358a, 0x3560, 0x3536, + 0x350c, 0x34e1, 0x34b7, 0x348d, 0x3462, 0x3438, 0x340d, 0x33e3, + 0x33b8, 0x338d, 0x3363, 0x3338, 0x330d, 0x32e2, 0x32b7, 0x328c, + 0x3261, 0x3236, 0x320b, 0x31df, 0x31b4, 0x3188, 0x315d, 0x3131, + 0x3106, 0x30da, 0x30ae, 0x3083, 0x3057, 0x302b, 0x2fff, 0x2fd2, + 0x2fa6, 0x2f7a, 0x2f4d, 0x2f21, 0x2ef4, 0x2ec8, 0x2e9b, 0x2e6e, + 0x2e41, 0x2e14, 0x2de7, 0x2dba, 0x2d8d, 0x2d60, 0x2d32, 0x2d05, + 0x2cd7, 0x2ca9, 0x2c7b, 0x2c4d, 0x2c1f, 0x2bf1, 0x2bc3, 0x2b94, + 0x2b66, 0x2b37, 0x2b09, 0x2ada, 0x2aab, 0x2a7c, 0x2a4c, 0x2a1d, + 0x29ed, 0x29be, 0x298e, 0x295e, 0x292e, 0x28fe, 0x28ce, 0x289d, + 0x286d, 0x283c, 0x280b, 0x27da, 0x27a9, 0x2777, 0x2746, 0x2714, + 0x26e2, 0x26b0, 0x267e, 0x264c, 0x2619, 0x25e7, 0x25b4, 0x2581, + 0x254d, 0x251a, 0x24e6, 0x24b2, 0x247e, 0x244a, 0x2415, 0x23e1, + 0x23ac, 0x2376, 0x2341, 0x230b, 0x22d6, 0x229f, 0x2269, 0x2232, + 0x21fc, 0x21c4, 0x218d, 0x2155, 0x211d, 0x20e5, 0x20ad, 0x2074, + 0x203b, 0x2001, 0x1fc7, 0x1f8d, 0x1f53, 0x1f18, 0x1edd, 0x1ea1, + 0x1e66, 0x1e29, 0x1ded, 0x1db0, 0x1d72, 0x1d35, 0x1cf6, 0x1cb8, + 0x1c79, 0x1c39, 0x1bf9, 0x1bb8, 0x1b77, 0x1b36, 0x1af4, 0x1ab1, + 0x1a6e, 0x1a2a, 0x19e6, 0x19a1, 0x195c, 0x1915, 0x18ce, 0x1887, + 0x183f, 0x17f5, 0x17ac, 0x1761, 0x1715, 0x16c9, 0x167c, 0x162e, + 0x15df, 0x158e, 0x153d, 0x14eb, 0x1497, 0x1442, 0x13ec, 0x1395, + 0x133c, 0x12e2, 0x1286, 0x1228, 0x11c9, 0x1167, 0x1104, 0x109e, + 0x1036, 0x0fcc, 0x0f5f, 0x0eef, 0x0e7b, 0x0e04, 0x0d89, 0x0d0a, + 0x0c86, 0x0bfd, 0x0b6d, 0x0ad6, 0x0a36, 0x098d, 0x08d7, 0x0811, + 0x0736, 0x063e, 0x0519, 0x039a, 0x0000, 0x7fff, 0x0100, 0x0080, + 0x021d, 0x00c8, 0x00ce, 0x0048, 0x0a26, 0x277a, 0x00ce, 0x6488, + 0x14ac, 0x0001, 0x00f9, 0x00fc, 0x00ff, 0x00fc, 0x00f9, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff +}; /***************************************************************************\ * Math tables * @@ -223,10 +225,10 @@ double SinTable2[INCR]; double Atan(double x) { - if ((x>=1) || (x<=1)) - return (x/(1+0.28*x*x)); - else - return (PI/2 - Atan(1/x)); + if ((x >= 1) || (x <= 1)) + return (x / (1 + 0.28 * x * x)); + else + return (PI / 2 - Atan(1 / x)); } #ifdef __ZSNES__ @@ -242,79 +244,80 @@ short C4WFY2Val; short C4WFDist; short C4WFScale; double tanval; -double c4x,c4y,c4z; -double c4x2,c4y2,c4z2; +double c4x, c4y, c4z; +double c4x2, c4y2, c4z2; void C4TransfWireFrame() { - c4x=(double)C4WFXVal; - c4y=(double)C4WFYVal; - c4z=(double)C4WFZVal-0x95; - - // Rotate X - tanval=-(double)C4WFX2Val*PI*2/128; - c4y2=c4y*cos(tanval)-c4z*sin(tanval); - c4z2=c4y*sin(tanval)+c4z*cos(tanval); - - // Rotate Y - tanval=-(double)C4WFY2Val*PI*2/128; - c4x2=c4x*cos(tanval)+c4z2*sin(tanval); - c4z=c4x*-sin(tanval)+c4z2*cos(tanval); - - // Rotate Z - tanval=-(double)C4WFDist*PI*2/128; - c4x=c4x2*cos(tanval)-c4y2*sin(tanval); - c4y=c4x2*sin(tanval)+c4y2*cos(tanval); - - // Scale - C4WFXVal=(short)(c4x*C4WFScale/(0x90*(c4z+0x95))*0x95); - C4WFYVal=(short)(c4y*C4WFScale/(0x90*(c4z+0x95))*0x95); + c4x = (double)C4WFXVal; + c4y = (double)C4WFYVal; + c4z = (double)C4WFZVal - 0x95; + + // Rotate X + tanval = -(double)C4WFX2Val * PI * 2 / 128; + c4y2 = c4y * cos(tanval) - c4z * sin(tanval); + c4z2 = c4y * sin(tanval) + c4z * cos(tanval); + + // Rotate Y + tanval = -(double)C4WFY2Val * PI * 2 / 128; + c4x2 = c4x * cos(tanval) + c4z2 * sin(tanval); + c4z = c4x * -sin(tanval) + c4z2 * cos(tanval); + + // Rotate Z + tanval = -(double)C4WFDist * PI * 2 / 128; + c4x = c4x2 * cos(tanval) - c4y2 * sin(tanval); + c4y = c4x2 * sin(tanval) + c4y2 * cos(tanval); + + // Scale + C4WFXVal = (short)(c4x * C4WFScale / (0x90 * (c4z + 0x95)) * 0x95); + C4WFYVal = (short)(c4y * C4WFScale / (0x90 * (c4z + 0x95)) * 0x95); } void C4TransfWireFrame2() { - c4x=(double)C4WFXVal; - c4y=(double)C4WFYVal; - c4z=(double)C4WFZVal; - - // Rotate X - tanval=-(double)C4WFX2Val*PI*2/128; - c4y2=c4y*cos(tanval)-c4z*sin(tanval); - c4z2=c4y*sin(tanval)+c4z*cos(tanval); - - // Rotate Y - tanval=-(double)C4WFY2Val*PI*2/128; - c4x2=c4x*cos(tanval)+c4z2*sin(tanval); - c4z=c4x*-sin(tanval)+c4z2*cos(tanval); - - // Rotate Z - tanval=-(double)C4WFDist*PI*2/128; - c4x=c4x2*cos(tanval)-c4y2*sin(tanval); - c4y=c4x2*sin(tanval)+c4y2*cos(tanval); - - // Scale - C4WFXVal=(short)(c4x*C4WFScale/0x100); - C4WFYVal=(short)(c4y*C4WFScale/0x100); + c4x = (double)C4WFXVal; + c4y = (double)C4WFYVal; + c4z = (double)C4WFZVal; + + // Rotate X + tanval = -(double)C4WFX2Val * PI * 2 / 128; + c4y2 = c4y * cos(tanval) - c4z * sin(tanval); + c4z2 = c4y * sin(tanval) + c4z * cos(tanval); + + // Rotate Y + tanval = -(double)C4WFY2Val * PI * 2 / 128; + c4x2 = c4x * cos(tanval) + c4z2 * sin(tanval); + c4z = c4x * -sin(tanval) + c4z2 * cos(tanval); + + // Rotate Z + tanval = -(double)C4WFDist * PI * 2 / 128; + c4x = c4x2 * cos(tanval) - c4y2 * sin(tanval); + c4y = c4x2 * sin(tanval) + c4y2 * cos(tanval); + + // Scale + C4WFXVal = (short)(c4x * C4WFScale / 0x100); + C4WFYVal = (short)(c4y * C4WFScale / 0x100); } void C4CalcWireFrame() { - C4WFXVal=C4WFX2Val-C4WFXVal; - C4WFYVal=C4WFY2Val-C4WFYVal; - if (abs(C4WFXVal)>abs(C4WFYVal)){ - C4WFDist=abs(C4WFXVal)+1; - C4WFYVal=(256*(long)C4WFYVal)/abs(C4WFXVal); - if (C4WFXVal<0) C4WFXVal=-256; - else C4WFXVal=256; - } - else - if (C4WFYVal!=0) { - C4WFDist=abs(C4WFYVal)+1; - C4WFXVal=(256*(long)C4WFXVal)/abs(C4WFYVal); - if (C4WFYVal<0) C4WFYVal=-256; - else C4WFYVal=256; - } - else C4WFDist=0; + C4WFXVal = C4WFX2Val - C4WFXVal; + C4WFYVal = C4WFY2Val - C4WFYVal; + if (abs(C4WFXVal) > abs(C4WFYVal)) + { + C4WFDist = abs(C4WFXVal) + 1; + C4WFYVal = (256 * (long)C4WFYVal) / abs(C4WFXVal); + if (C4WFXVal < 0) C4WFXVal = -256; + else C4WFXVal = 256; + } + else if (C4WFYVal != 0) + { + C4WFDist = abs(C4WFYVal) + 1; + C4WFXVal = (256 * (long)C4WFXVal) / abs(C4WFYVal); + if (C4WFYVal < 0) C4WFYVal = -256; + else C4WFYVal = 256; + } + else C4WFDist = 0; } short C41FXVal; @@ -325,33 +328,35 @@ short C41FDistVal; void C4Op1F() { - if (C41FXVal == 0) { - if (C41FYVal>0) C41FAngleRes=0x80; - else C41FAngleRes=0x180; - } - else { - tanval = ((double)C41FYVal)/((double)C41FXVal); - C41FAngleRes=(short)(atan(tanval)/(PI*2)*512); - C41FAngleRes=C41FAngleRes; - if (C41FXVal<0) C41FAngleRes+=0x100; - C41FAngleRes&=0x1FF; - } + if (C41FXVal == 0) + { + if (C41FYVal > 0) C41FAngleRes = 0x80; + else C41FAngleRes = 0x180; + } + else + { + tanval = ((double)C41FYVal) / ((double)C41FXVal); + C41FAngleRes = (short)(atan(tanval) / (PI * 2) * 512); + C41FAngleRes = C41FAngleRes; + if (C41FXVal < 0) C41FAngleRes += 0x100; + C41FAngleRes &= 0x1FF; + } } void C4Op15() { - tanval=sqrt(((double)C41FYVal)*((double)C41FYVal)+((double)C41FXVal)* - ((double)C41FXVal)); - C41FDist=(short)tanval; + tanval = sqrt(((double)C41FYVal) * ((double)C41FYVal) + ((double)C41FXVal) * + ((double)C41FXVal)); + C41FDist = (short)tanval; } void C4Op0D() { - tanval=sqrt(((double)C41FYVal)*((double)C41FYVal)+((double)C41FXVal)* - ((double)C41FXVal)); - tanval=(double)C41FDistVal/tanval; - C41FYVal=(short)(((double)C41FYVal*tanval)*0.99); - C41FXVal=(short)(((double)C41FXVal*tanval)*0.98); + tanval = sqrt(((double)C41FYVal) * ((double)C41FYVal) + ((double)C41FXVal) * + ((double)C41FXVal)); + tanval = (double)C41FDistVal / tanval; + C41FYVal = (short)(((double)C41FYVal * tanval) * 0.99); + C41FXVal = (short)(((double)C41FXVal * tanval) * 0.98); } #endif @@ -362,14 +367,15 @@ void C4Op0D() void InitDSP(void) { #ifdef __OPT__ - unsigned int i; - for (i=0; i> 15; + Op00Result = Op00Multiplicand * Op00Multiplier >> 15; - #ifdef DebugDSP1 - Log_Message("OP00 MULT %d*%d/32768=%d",Op00Multiplicand,Op00Multiplier,Op00Result); - #endif +#ifdef DebugDSP1 + Log_Message("OP00 MULT %d*%d/32768=%d", Op00Multiplicand, Op00Multiplier, + Op00Result); +#endif } short Op20Multiplicand; @@ -393,12 +400,13 @@ short Op20Result; void DSPOp20() { - Op20Result= Op20Multiplicand * Op20Multiplier >> 15; + Op20Result = Op20Multiplicand * Op20Multiplier >> 15; Op20Result++; - #ifdef DebugDSP1 - Log_Message("OP20 MULT %d*%d/32768=%d",Op20Multiplicand,Op20Multiplier,Op20Result); - #endif +#ifdef DebugDSP1 + Log_Message("OP20 MULT %d*%d/32768=%d", Op20Multiplicand, Op20Multiplier, + Op20Result); +#endif } signed short Op10Coefficient; @@ -406,61 +414,65 @@ signed short Op10Exponent; signed short Op10CoefficientR; signed short Op10ExponentR; -void DSP1_Inverse(short Coefficient, short Exponent, short *iCoefficient, short *iExponent) +void DSP1_Inverse(short Coefficient, short Exponent, short* iCoefficient, + short* iExponent) { - // Step One: Division by Zero - if (Coefficient == 0x0000) - { - *iCoefficient = 0x7fff; - *iExponent = 0x002f; - } - else - { - short Sign = 1; - - // Step Two: Remove Sign - if (Coefficient < 0) - { - if (Coefficient < -32767) Coefficient = -32767; - Coefficient = -Coefficient; - Sign = -1; - } - - // Step Three: Normalize - while (Coefficient < 0x4000) - { - Coefficient <<= 1; - Exponent--; - } - - // Step Four: Special Case - if (Coefficient == 0x4000) - if (Sign == 1) *iCoefficient = 0x7fff; - else { - *iCoefficient = -0x4000; - Exponent--; - } - else { - // Step Five: Initial Guess - short i = DSP1ROM[((Coefficient - 0x4000) >> 7) + 0x0065]; - - // Step Six: Iterate "estimated" Newton's Method - i = (i + (-i * (Coefficient * i >> 15) >> 15)) << 1; - i = (i + (-i * (Coefficient * i >> 15) >> 15)) << 1; - - *iCoefficient = i * Sign; - } - - *iExponent = 1 - Exponent; - } + // Step One: Division by Zero + if (Coefficient == 0x0000) + { + *iCoefficient = 0x7fff; + *iExponent = 0x002f; + } + else + { + short Sign = 1; + + // Step Two: Remove Sign + if (Coefficient < 0) + { + if (Coefficient < -32767) Coefficient = -32767; + Coefficient = -Coefficient; + Sign = -1; + } + + // Step Three: Normalize + while (Coefficient < 0x4000) + { + Coefficient <<= 1; + Exponent--; + } + + // Step Four: Special Case + if (Coefficient == 0x4000) + if (Sign == 1) *iCoefficient = 0x7fff; + else + { + *iCoefficient = -0x4000; + Exponent--; + } + else + { + // Step Five: Initial Guess + short i = DSP1ROM[((Coefficient - 0x4000) >> 7) + 0x0065]; + + // Step Six: Iterate "estimated" Newton's Method + i = (i + (-i * (Coefficient * i >> 15) >> 15)) << 1; + i = (i + (-i * (Coefficient * i >> 15) >> 15)) << 1; + + *iCoefficient = i * Sign; + } + + *iExponent = 1 - Exponent; + } } void DSPOp10() { - DSP1_Inverse(Op10Coefficient, Op10Exponent, &Op10CoefficientR, &Op10ExponentR); - #ifdef DebugDSP1 - Log_Message("OP10 INV %d*2^%d = %d*2^%d", Op10Coefficient, Op10Exponent, Op10CoefficientR, Op10ExponentR); - #endif + DSP1_Inverse(Op10Coefficient, Op10Exponent, &Op10CoefficientR, &Op10ExponentR); +#ifdef DebugDSP1 + Log_Message("OP10 INV %d*2^%d = %d*2^%d", Op10Coefficient, Op10Exponent, + Op10CoefficientR, Op10ExponentR); +#endif } short Op04Angle; @@ -468,185 +480,203 @@ short Op04Radius; short Op04Sin; short Op04Cos; -const short DSP1_MulTable[256] = { - 0x0000, 0x0003, 0x0006, 0x0009, 0x000c, 0x000f, 0x0012, 0x0015, - 0x0019, 0x001c, 0x001f, 0x0022, 0x0025, 0x0028, 0x002b, 0x002f, - 0x0032, 0x0035, 0x0038, 0x003b, 0x003e, 0x0041, 0x0045, 0x0048, - 0x004b, 0x004e, 0x0051, 0x0054, 0x0057, 0x005b, 0x005e, 0x0061, - 0x0064, 0x0067, 0x006a, 0x006d, 0x0071, 0x0074, 0x0077, 0x007a, - 0x007d, 0x0080, 0x0083, 0x0087, 0x008a, 0x008d, 0x0090, 0x0093, - 0x0096, 0x0099, 0x009d, 0x00a0, 0x00a3, 0x00a6, 0x00a9, 0x00ac, - 0x00af, 0x00b3, 0x00b6, 0x00b9, 0x00bc, 0x00bf, 0x00c2, 0x00c5, - 0x00c9, 0x00cc, 0x00cf, 0x00d2, 0x00d5, 0x00d8, 0x00db, 0x00df, - 0x00e2, 0x00e5, 0x00e8, 0x00eb, 0x00ee, 0x00f1, 0x00f5, 0x00f8, - 0x00fb, 0x00fe, 0x0101, 0x0104, 0x0107, 0x010b, 0x010e, 0x0111, - 0x0114, 0x0117, 0x011a, 0x011d, 0x0121, 0x0124, 0x0127, 0x012a, - 0x012d, 0x0130, 0x0133, 0x0137, 0x013a, 0x013d, 0x0140, 0x0143, - 0x0146, 0x0149, 0x014d, 0x0150, 0x0153, 0x0156, 0x0159, 0x015c, - 0x015f, 0x0163, 0x0166, 0x0169, 0x016c, 0x016f, 0x0172, 0x0175, - 0x0178, 0x017c, 0x017f, 0x0182, 0x0185, 0x0188, 0x018b, 0x018e, - 0x0192, 0x0195, 0x0198, 0x019b, 0x019e, 0x01a1, 0x01a4, 0x01a8, - 0x01ab, 0x01ae, 0x01b1, 0x01b4, 0x01b7, 0x01ba, 0x01be, 0x01c1, - 0x01c4, 0x01c7, 0x01ca, 0x01cd, 0x01d0, 0x01d4, 0x01d7, 0x01da, - 0x01dd, 0x01e0, 0x01e3, 0x01e6, 0x01ea, 0x01ed, 0x01f0, 0x01f3, - 0x01f6, 0x01f9, 0x01fc, 0x0200, 0x0203, 0x0206, 0x0209, 0x020c, - 0x020f, 0x0212, 0x0216, 0x0219, 0x021c, 0x021f, 0x0222, 0x0225, - 0x0228, 0x022c, 0x022f, 0x0232, 0x0235, 0x0238, 0x023b, 0x023e, - 0x0242, 0x0245, 0x0248, 0x024b, 0x024e, 0x0251, 0x0254, 0x0258, - 0x025b, 0x025e, 0x0261, 0x0264, 0x0267, 0x026a, 0x026e, 0x0271, - 0x0274, 0x0277, 0x027a, 0x027d, 0x0280, 0x0284, 0x0287, 0x028a, - 0x028d, 0x0290, 0x0293, 0x0296, 0x029a, 0x029d, 0x02a0, 0x02a3, - 0x02a6, 0x02a9, 0x02ac, 0x02b0, 0x02b3, 0x02b6, 0x02b9, 0x02bc, - 0x02bf, 0x02c2, 0x02c6, 0x02c9, 0x02cc, 0x02cf, 0x02d2, 0x02d5, - 0x02d8, 0x02db, 0x02df, 0x02e2, 0x02e5, 0x02e8, 0x02eb, 0x02ee, - 0x02f1, 0x02f5, 0x02f8, 0x02fb, 0x02fe, 0x0301, 0x0304, 0x0307, - 0x030b, 0x030e, 0x0311, 0x0314, 0x0317, 0x031a, 0x031d, 0x0321}; - -const short DSP1_SinTable[256] = { - 0x0000, 0x0324, 0x0647, 0x096a, 0x0c8b, 0x0fab, 0x12c8, 0x15e2, - 0x18f8, 0x1c0b, 0x1f19, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, - 0x30fb, 0x33de, 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, - 0x471c, 0x49b4, 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, - 0x5a82, 0x5cb4, 0x5ed7, 0x60ec, 0x62f2, 0x64e8, 0x66cf, 0x68a6, - 0x6a6d, 0x6c24, 0x6dca, 0x6f5f, 0x70e2, 0x7255, 0x73b5, 0x7504, - 0x7641, 0x776c, 0x7884, 0x798a, 0x7a7d, 0x7b5d, 0x7c29, 0x7ce3, - 0x7d8a, 0x7e1d, 0x7e9d, 0x7f09, 0x7f62, 0x7fa7, 0x7fd8, 0x7ff6, - 0x7fff, 0x7ff6, 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, - 0x7d8a, 0x7ce3, 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, - 0x7641, 0x7504, 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, - 0x6a6d, 0x68a6, 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, - 0x5a82, 0x5842, 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, - 0x471c, 0x447a, 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, - 0x30fb, 0x2e11, 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, - 0x18f8, 0x15e2, 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, - -0x0000, -0x0324, -0x0647, -0x096a, -0x0c8b, -0x0fab, -0x12c8, -0x15e2, - -0x18f8, -0x1c0b, -0x1f19, -0x2223, -0x2528, -0x2826, -0x2b1f, -0x2e11, - -0x30fb, -0x33de, -0x36ba, -0x398c, -0x3c56, -0x3f17, -0x41ce, -0x447a, - -0x471c, -0x49b4, -0x4c3f, -0x4ebf, -0x5133, -0x539b, -0x55f5, -0x5842, - -0x5a82, -0x5cb4, -0x5ed7, -0x60ec, -0x62f2, -0x64e8, -0x66cf, -0x68a6, - -0x6a6d, -0x6c24, -0x6dca, -0x6f5f, -0x70e2, -0x7255, -0x73b5, -0x7504, - -0x7641, -0x776c, -0x7884, -0x798a, -0x7a7d, -0x7b5d, -0x7c29, -0x7ce3, - -0x7d8a, -0x7e1d, -0x7e9d, -0x7f09, -0x7f62, -0x7fa7, -0x7fd8, -0x7ff6, - -0x7fff, -0x7ff6, -0x7fd8, -0x7fa7, -0x7f62, -0x7f09, -0x7e9d, -0x7e1d, - -0x7d8a, -0x7ce3, -0x7c29, -0x7b5d, -0x7a7d, -0x798a, -0x7884, -0x776c, - -0x7641, -0x7504, -0x73b5, -0x7255, -0x70e2, -0x6f5f, -0x6dca, -0x6c24, - -0x6a6d, -0x68a6, -0x66cf, -0x64e8, -0x62f2, -0x60ec, -0x5ed7, -0x5cb4, - -0x5a82, -0x5842, -0x55f5, -0x539b, -0x5133, -0x4ebf, -0x4c3f, -0x49b4, - -0x471c, -0x447a, -0x41ce, -0x3f17, -0x3c56, -0x398c, -0x36ba, -0x33de, - -0x30fb, -0x2e11, -0x2b1f, -0x2826, -0x2528, -0x2223, -0x1f19, -0x1c0b, - -0x18f8, -0x15e2, -0x12c8, -0x0fab, -0x0c8b, -0x096a, -0x0647, -0x0324}; +const short DSP1_MulTable[256] = +{ + 0x0000, 0x0003, 0x0006, 0x0009, 0x000c, 0x000f, 0x0012, 0x0015, + 0x0019, 0x001c, 0x001f, 0x0022, 0x0025, 0x0028, 0x002b, 0x002f, + 0x0032, 0x0035, 0x0038, 0x003b, 0x003e, 0x0041, 0x0045, 0x0048, + 0x004b, 0x004e, 0x0051, 0x0054, 0x0057, 0x005b, 0x005e, 0x0061, + 0x0064, 0x0067, 0x006a, 0x006d, 0x0071, 0x0074, 0x0077, 0x007a, + 0x007d, 0x0080, 0x0083, 0x0087, 0x008a, 0x008d, 0x0090, 0x0093, + 0x0096, 0x0099, 0x009d, 0x00a0, 0x00a3, 0x00a6, 0x00a9, 0x00ac, + 0x00af, 0x00b3, 0x00b6, 0x00b9, 0x00bc, 0x00bf, 0x00c2, 0x00c5, + 0x00c9, 0x00cc, 0x00cf, 0x00d2, 0x00d5, 0x00d8, 0x00db, 0x00df, + 0x00e2, 0x00e5, 0x00e8, 0x00eb, 0x00ee, 0x00f1, 0x00f5, 0x00f8, + 0x00fb, 0x00fe, 0x0101, 0x0104, 0x0107, 0x010b, 0x010e, 0x0111, + 0x0114, 0x0117, 0x011a, 0x011d, 0x0121, 0x0124, 0x0127, 0x012a, + 0x012d, 0x0130, 0x0133, 0x0137, 0x013a, 0x013d, 0x0140, 0x0143, + 0x0146, 0x0149, 0x014d, 0x0150, 0x0153, 0x0156, 0x0159, 0x015c, + 0x015f, 0x0163, 0x0166, 0x0169, 0x016c, 0x016f, 0x0172, 0x0175, + 0x0178, 0x017c, 0x017f, 0x0182, 0x0185, 0x0188, 0x018b, 0x018e, + 0x0192, 0x0195, 0x0198, 0x019b, 0x019e, 0x01a1, 0x01a4, 0x01a8, + 0x01ab, 0x01ae, 0x01b1, 0x01b4, 0x01b7, 0x01ba, 0x01be, 0x01c1, + 0x01c4, 0x01c7, 0x01ca, 0x01cd, 0x01d0, 0x01d4, 0x01d7, 0x01da, + 0x01dd, 0x01e0, 0x01e3, 0x01e6, 0x01ea, 0x01ed, 0x01f0, 0x01f3, + 0x01f6, 0x01f9, 0x01fc, 0x0200, 0x0203, 0x0206, 0x0209, 0x020c, + 0x020f, 0x0212, 0x0216, 0x0219, 0x021c, 0x021f, 0x0222, 0x0225, + 0x0228, 0x022c, 0x022f, 0x0232, 0x0235, 0x0238, 0x023b, 0x023e, + 0x0242, 0x0245, 0x0248, 0x024b, 0x024e, 0x0251, 0x0254, 0x0258, + 0x025b, 0x025e, 0x0261, 0x0264, 0x0267, 0x026a, 0x026e, 0x0271, + 0x0274, 0x0277, 0x027a, 0x027d, 0x0280, 0x0284, 0x0287, 0x028a, + 0x028d, 0x0290, 0x0293, 0x0296, 0x029a, 0x029d, 0x02a0, 0x02a3, + 0x02a6, 0x02a9, 0x02ac, 0x02b0, 0x02b3, 0x02b6, 0x02b9, 0x02bc, + 0x02bf, 0x02c2, 0x02c6, 0x02c9, 0x02cc, 0x02cf, 0x02d2, 0x02d5, + 0x02d8, 0x02db, 0x02df, 0x02e2, 0x02e5, 0x02e8, 0x02eb, 0x02ee, + 0x02f1, 0x02f5, 0x02f8, 0x02fb, 0x02fe, 0x0301, 0x0304, 0x0307, + 0x030b, 0x030e, 0x0311, 0x0314, 0x0317, 0x031a, 0x031d, 0x0321 +}; + +const short DSP1_SinTable[256] = +{ + 0x0000, 0x0324, 0x0647, 0x096a, 0x0c8b, 0x0fab, 0x12c8, 0x15e2, + 0x18f8, 0x1c0b, 0x1f19, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, + 0x30fb, 0x33de, 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, + 0x471c, 0x49b4, 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, + 0x5a82, 0x5cb4, 0x5ed7, 0x60ec, 0x62f2, 0x64e8, 0x66cf, 0x68a6, + 0x6a6d, 0x6c24, 0x6dca, 0x6f5f, 0x70e2, 0x7255, 0x73b5, 0x7504, + 0x7641, 0x776c, 0x7884, 0x798a, 0x7a7d, 0x7b5d, 0x7c29, 0x7ce3, + 0x7d8a, 0x7e1d, 0x7e9d, 0x7f09, 0x7f62, 0x7fa7, 0x7fd8, 0x7ff6, + 0x7fff, 0x7ff6, 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, + 0x7d8a, 0x7ce3, 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, + 0x7641, 0x7504, 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, + 0x6a6d, 0x68a6, 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, + 0x5a82, 0x5842, 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, + 0x471c, 0x447a, 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, + 0x30fb, 0x2e11, 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, + 0x18f8, 0x15e2, 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, + -0x0000, -0x0324, -0x0647, -0x096a, -0x0c8b, -0x0fab, -0x12c8, -0x15e2, + -0x18f8, -0x1c0b, -0x1f19, -0x2223, -0x2528, -0x2826, -0x2b1f, -0x2e11, + -0x30fb, -0x33de, -0x36ba, -0x398c, -0x3c56, -0x3f17, -0x41ce, -0x447a, + -0x471c, -0x49b4, -0x4c3f, -0x4ebf, -0x5133, -0x539b, -0x55f5, -0x5842, + -0x5a82, -0x5cb4, -0x5ed7, -0x60ec, -0x62f2, -0x64e8, -0x66cf, -0x68a6, + -0x6a6d, -0x6c24, -0x6dca, -0x6f5f, -0x70e2, -0x7255, -0x73b5, -0x7504, + -0x7641, -0x776c, -0x7884, -0x798a, -0x7a7d, -0x7b5d, -0x7c29, -0x7ce3, + -0x7d8a, -0x7e1d, -0x7e9d, -0x7f09, -0x7f62, -0x7fa7, -0x7fd8, -0x7ff6, + -0x7fff, -0x7ff6, -0x7fd8, -0x7fa7, -0x7f62, -0x7f09, -0x7e9d, -0x7e1d, + -0x7d8a, -0x7ce3, -0x7c29, -0x7b5d, -0x7a7d, -0x798a, -0x7884, -0x776c, + -0x7641, -0x7504, -0x73b5, -0x7255, -0x70e2, -0x6f5f, -0x6dca, -0x6c24, + -0x6a6d, -0x68a6, -0x66cf, -0x64e8, -0x62f2, -0x60ec, -0x5ed7, -0x5cb4, + -0x5a82, -0x5842, -0x55f5, -0x539b, -0x5133, -0x4ebf, -0x4c3f, -0x49b4, + -0x471c, -0x447a, -0x41ce, -0x3f17, -0x3c56, -0x398c, -0x36ba, -0x33de, + -0x30fb, -0x2e11, -0x2b1f, -0x2826, -0x2528, -0x2223, -0x1f19, -0x1c0b, + -0x18f8, -0x15e2, -0x12c8, -0x0fab, -0x0c8b, -0x096a, -0x0647, -0x0324 +}; short DSP1_Sin(short Angle) { - if (Angle < 0) { - if (Angle == -32768) return 0; - return -DSP1_Sin(-Angle); - } - int S = DSP1_SinTable[Angle >> 8] + (DSP1_MulTable[Angle & 0xff] * DSP1_SinTable[0x40 + (Angle >> 8)] >> 15); - if (S > 32767) S = 32767; - return (short) S; + if (Angle < 0) + { + if (Angle == -32768) return 0; + return -DSP1_Sin(-Angle); + } + int S = DSP1_SinTable[Angle >> 8] + (DSP1_MulTable[Angle & 0xff] * + DSP1_SinTable[0x40 + (Angle >> 8)] >> 15); + if (S > 32767) S = 32767; + return (short) S; } short DSP1_Cos(short Angle) { - if (Angle < 0) { - if (Angle == -32768) return -32768; - Angle = -Angle; - } - int S = DSP1_SinTable[0x40 + (Angle >> 8)] - (DSP1_MulTable[Angle & 0xff] * DSP1_SinTable[Angle >> 8] >> 15); - if (S < -32768) S = -32767; - return (short) S; + if (Angle < 0) + { + if (Angle == -32768) return -32768; + Angle = -Angle; + } + int S = DSP1_SinTable[0x40 + (Angle >> 8)] - (DSP1_MulTable[Angle & 0xff] * + DSP1_SinTable[Angle >> 8] >> 15); + if (S < -32768) S = -32767; + return (short) S; } -void DSP1_Normalize(short m, short *Coefficient, short *Exponent) +void DSP1_Normalize(short m, short* Coefficient, short* Exponent) { - short i = 0x4000; - short e = 0; - - if (m < 0) - while ((m & i) && i) { - i >>= 1; - e++; - } - else - while (!(m & i) && i) { - i >>= 1; - e++; - } - - if (e > 0) - *Coefficient = m * DSP1ROM[0x21 + e] << 1; - else - *Coefficient = m; - - *Exponent -= e; + short i = 0x4000; + short e = 0; + + if (m < 0) + while ((m & i) && i) + { + i >>= 1; + e++; + } + else + while (!(m & i) && i) + { + i >>= 1; + e++; + } + + if (e > 0) + *Coefficient = m * DSP1ROM[0x21 + e] << 1; + else + *Coefficient = m; + + *Exponent -= e; } -void DSP1_NormalizeDouble(int Product, short *Coefficient, short *Exponent) +void DSP1_NormalizeDouble(int Product, short* Coefficient, short* Exponent) { - short n = Product & 0x7fff; - short m = Product >> 15; - short i = 0x4000; - short e = 0; - - if (m < 0) - while ((m & i) && i) { - i >>= 1; - e++; - } - else - while (!(m & i) && i) { - i >>= 1; - e++; - } - - if (e > 0) - { - *Coefficient = m * DSP1ROM[0x0021 + e] << 1; - - if (e < 15) - *Coefficient += n * DSP1ROM[0x0040 - e] >> 15; - else - { - i = 0x4000; - - if (m < 0) - while ((n & i) && i) { - i >>= 1; - e++; - } - else - while (!(n & i) && i) { - i >>= 1; - e++; - } - - if (e > 15) - *Coefficient = n * DSP1ROM[0x0012 + e] << 1; - else - *Coefficient += n; - } - } - else - *Coefficient = m; - - *Exponent = e; + short n = Product & 0x7fff; + short m = Product >> 15; + short i = 0x4000; + short e = 0; + + if (m < 0) + while ((m & i) && i) + { + i >>= 1; + e++; + } + else + while (!(m & i) && i) + { + i >>= 1; + e++; + } + + if (e > 0) + { + *Coefficient = m * DSP1ROM[0x0021 + e] << 1; + + if (e < 15) + *Coefficient += n * DSP1ROM[0x0040 - e] >> 15; + else + { + i = 0x4000; + + if (m < 0) + while ((n & i) && i) + { + i >>= 1; + e++; + } + else + while (!(n & i) && i) + { + i >>= 1; + e++; + } + + if (e > 15) + *Coefficient = n * DSP1ROM[0x0012 + e] << 1; + else + *Coefficient += n; + } + } + else + *Coefficient = m; + + *Exponent = e; } short DSP1_Truncate(short C, short E) { - if (E > 0) { - if (C > 0) return 32767; else if (C < 0) return -32767; - } else { - if (E < 0) return C * DSP1ROM[0x0031 + E] >> 15; - } - return C; + if (E > 0) + { + if (C > 0) return 32767; + else if (C < 0) return -32767; + } + else + { + if (E < 0) return C * DSP1ROM[0x0031 + E] >> 15; + } + return C; } void DSPOp04() { - Op04Sin = DSP1_Sin(Op04Angle) * Op04Radius >> 15; - Op04Cos = DSP1_Cos(Op04Angle) * Op04Radius >> 15; + Op04Sin = DSP1_Sin(Op04Angle) * Op04Radius >> 15; + Op04Cos = DSP1_Cos(Op04Angle) * Op04Radius >> 15; } short Op0CA; @@ -657,8 +687,8 @@ short Op0CY2; void DSPOp0C() { - Op0CX2 = (Op0CY1 * DSP1_Sin(Op0CA) >> 15) + (Op0CX1 * DSP1_Cos(Op0CA) >> 15); - Op0CY2 = (Op0CY1 * DSP1_Cos(Op0CA) >> 15) - (Op0CX1 * DSP1_Sin(Op0CA) >> 15); + Op0CX2 = (Op0CY1 * DSP1_Sin(Op0CA) >> 15) + (Op0CX1 * DSP1_Cos(Op0CA) >> 15); + Op0CY2 = (Op0CY1 * DSP1_Cos(Op0CA) >> 15) - (Op0CX1 * DSP1_Sin(Op0CA) >> 15); } short CentreX; @@ -675,124 +705,133 @@ short SinAzs; short CosAzs; // Clipped Zenith angle -short SinAZS; +short SinAZS; short CosAZS; short SecAZS_C1; short SecAZS_E1; short SecAZS_C2; short SecAZS_E2; -const short MaxAZS_Exp[16] = { - 0x38b4, 0x38b7, 0x38ba, 0x38be, 0x38c0, 0x38c4, 0x38c7, 0x38ca, - 0x38ce, 0x38d0, 0x38d4, 0x38d7, 0x38da, 0x38dd, 0x38e0, 0x38e4 +const short MaxAZS_Exp[16] = +{ + 0x38b4, 0x38b7, 0x38ba, 0x38be, 0x38c0, 0x38c4, 0x38c7, 0x38ca, + 0x38ce, 0x38d0, 0x38d4, 0x38d7, 0x38da, 0x38dd, 0x38e0, 0x38e4 }; -void DSP1_Parameter(short Fx, short Fy, short Fz, short Lfe, short Les, short Aas, short Azs, short *Vof, short *Vva, short *Cx, short *Cy) +void DSP1_Parameter(short Fx, short Fy, short Fz, short Lfe, short Les, + short Aas, short Azs, short* Vof, short* Vva, short* Cx, short* Cy) { - short CSec, C, E; + short CSec, C, E; - // Copy Zenith angle for clipping - short AZS = Azs; + // Copy Zenith angle for clipping + short AZS = Azs; - // Store Sin and Cos of Azimuth and Zenith angles - SinAas = DSP1_Sin(Aas); - CosAas = DSP1_Cos(Aas); - SinAzs = DSP1_Sin(Azs); - CosAzs = DSP1_Cos(Azs); + // Store Sin and Cos of Azimuth and Zenith angles + SinAas = DSP1_Sin(Aas); + CosAas = DSP1_Cos(Aas); + SinAzs = DSP1_Sin(Azs); + CosAzs = DSP1_Cos(Azs); - // Center of Projection - CentreX = Fx + (Lfe * (SinAzs * -SinAas >> 15) >> 15); - CentreY = Fy + (Lfe * (SinAzs * CosAas >> 15) >> 15); + // Center of Projection + CentreX = Fx + (Lfe * (SinAzs * -SinAas >> 15) >> 15); + CentreY = Fy + (Lfe * (SinAzs * CosAas >> 15) >> 15); - E = 0; - DSP1_Normalize(Fz + (Lfe * (CosAzs * 0x7fff >> 15) >> 15), &C, &E); + E = 0; + DSP1_Normalize(Fz + (Lfe * (CosAzs * 0x7fff >> 15) >> 15), &C, &E); - VPlane_C = C; - VPlane_E = E; + VPlane_C = C; + VPlane_E = E; - // Determine clip boundary and clip Zenith angle if necessary - short MaxAZS = MaxAZS_Exp[-E]; + // Determine clip boundary and clip Zenith angle if necessary + short MaxAZS = MaxAZS_Exp[-E]; - if (AZS < 0) { - MaxAZS = -MaxAZS; - if (AZS < MaxAZS + 1) AZS = MaxAZS + 1; - } else { - if (AZS > MaxAZS) AZS = MaxAZS; - } + if (AZS < 0) + { + MaxAZS = -MaxAZS; + if (AZS < MaxAZS + 1) AZS = MaxAZS + 1; + } + else + { + if (AZS > MaxAZS) AZS = MaxAZS; + } - // Store Sin and Cos of clipped Zenith angle - SinAZS = DSP1_Sin(AZS); - CosAZS = DSP1_Cos(AZS); + // Store Sin and Cos of clipped Zenith angle + SinAZS = DSP1_Sin(AZS); + CosAZS = DSP1_Cos(AZS); - DSP1_Inverse(CosAZS, 0, &SecAZS_C1, &SecAZS_E1); - DSP1_Normalize(C * SecAZS_C1 >> 15, &C, &E); - E += SecAZS_E1; + DSP1_Inverse(CosAZS, 0, &SecAZS_C1, &SecAZS_E1); + DSP1_Normalize(C * SecAZS_C1 >> 15, &C, &E); + E += SecAZS_E1; - C = DSP1_Truncate(C, E) * SinAZS >> 15; + C = DSP1_Truncate(C, E) * SinAZS >> 15; - CentreX += C * SinAas >> 15; - CentreY -= C * CosAas >> 15; + CentreX += C * SinAas >> 15; + CentreY -= C * CosAas >> 15; - *Cx = CentreX; - *Cy = CentreY; + *Cx = CentreX; + *Cy = CentreY; - // Raster number of imaginary center and horizontal line - *Vof = 0; + // Raster number of imaginary center and horizontal line + *Vof = 0; - if ((Azs != AZS) || (Azs == MaxAZS)) - { - if (Azs == -32768) Azs = -32767; + if ((Azs != AZS) || (Azs == MaxAZS)) + { + if (Azs == -32768) Azs = -32767; - C = Azs - MaxAZS; - if (C >= 0) C--; - short Aux = ~(C << 2); + C = Azs - MaxAZS; + if (C >= 0) C--; + short Aux = ~(C << 2); - C = Aux * DSP1ROM[0x0328] >> 15; - C = (C * Aux >> 15) + DSP1ROM[0x0327]; - *Vof -= (C * Aux >> 15) * Les >> 15; + C = Aux * DSP1ROM[0x0328] >> 15; + C = (C * Aux >> 15) + DSP1ROM[0x0327]; + *Vof -= (C * Aux >> 15) * Les >> 15; - C = Aux * Aux >> 15; - Aux = (C * DSP1ROM[0x0324] >> 15) + DSP1ROM[0x0325]; - CosAZS += (C * Aux >> 15) * CosAZS >> 15; - } + C = Aux * Aux >> 15; + Aux = (C * DSP1ROM[0x0324] >> 15) + DSP1ROM[0x0325]; + CosAZS += (C * Aux >> 15) * CosAZS >> 15; + } - VOffset = Les * CosAZS >> 15; + VOffset = Les * CosAZS >> 15; - DSP1_Inverse(SinAZS, 0, &CSec, &E); - DSP1_Normalize(VOffset, &C, &E); - DSP1_Normalize(C * CSec >> 15, &C, &E); + DSP1_Inverse(SinAZS, 0, &CSec, &E); + DSP1_Normalize(VOffset, &C, &E); + DSP1_Normalize(C * CSec >> 15, &C, &E); - if (C == -32768) { C >>= 1; E++; } + if (C == -32768) + { + C >>= 1; + E++; + } - *Vva = DSP1_Truncate(-C, E); + *Vva = DSP1_Truncate(-C, E); - // Store Sec of clipped Zenith angle - DSP1_Inverse(CosAZS, 0, &SecAZS_C2, &SecAZS_E2); + // Store Sec of clipped Zenith angle + DSP1_Inverse(CosAZS, 0, &SecAZS_C2, &SecAZS_E2); } -void DSP1_Raster(short Vs, short *An, short *Bn, short *Cn, short *Dn) +void DSP1_Raster(short Vs, short* An, short* Bn, short* Cn, short* Dn) { - short C, E, C1, E1; + short C, E, C1, E1; - DSP1_Inverse((Vs * SinAzs >> 15) + VOffset, 7, &C, &E); - E += VPlane_E; + DSP1_Inverse((Vs * SinAzs >> 15) + VOffset, 7, &C, &E); + E += VPlane_E; - C1 = C * VPlane_C >> 15; - E1 = E + SecAZS_E2; + C1 = C * VPlane_C >> 15; + E1 = E + SecAZS_E2; - DSP1_Normalize(C1, &C, &E); + DSP1_Normalize(C1, &C, &E); - C = DSP1_Truncate(C, E); + C = DSP1_Truncate(C, E); - *An = C * CosAas >> 15; - *Cn = C * SinAas >> 15; + *An = C * CosAas >> 15; + *Cn = C * SinAas >> 15; - DSP1_Normalize(C1 * SecAZS_C2 >> 15, &C, &E1); + DSP1_Normalize(C1 * SecAZS_C2 >> 15, &C, &E1); - C = DSP1_Truncate(C, E1); + C = DSP1_Truncate(C, E1); - *Bn = C * -SinAas >> 15; - *Dn = C * CosAas >> 15; + *Bn = C * -SinAas >> 15; + *Dn = C * CosAas >> 15; } short Op02FX; @@ -809,7 +848,8 @@ short Op02CY; void DSPOp02() { - DSP1_Parameter(Op02FX, Op02FY, Op02FZ, Op02LFE, Op02LES, Op02AAS, Op02AZS, &Op02VOF, &Op02VVA, &Op02CX, &Op02CY); + DSP1_Parameter(Op02FX, Op02FY, Op02FZ, Op02LFE, Op02LES, Op02AAS, Op02AZS, + &Op02VOF, &Op02VVA, &Op02CX, &Op02CY); } short Op0AVS; @@ -820,8 +860,8 @@ short Op0AD; void DSPOp0A() { - DSP1_Raster(Op0AVS, &Op0AA, &Op0AB, &Op0AC, &Op0AD); - Op0AVS++; + DSP1_Raster(Op0AVS, &Op0AA, &Op0AB, &Op0AC, &Op0AD); + Op0AVS++; } short Op06X; @@ -847,119 +887,119 @@ int tanval2; #ifdef __OPT06__ void DSPOp06() { - ObjPX=Op06X-Op02FX; - ObjPY=Op06Y-Op02FY; - ObjPZ=Op06Z-Op02FZ; + ObjPX = Op06X - Op02FX; + ObjPY = Op06Y - Op02FY; + ObjPZ = Op06Z - Op02FZ; // rotate around Z - tanval2 = Angle(-Op02AAS+32768); -// tanval2 = (-Op02AAS+32768)/(65536/INCR); - ObjPX1=(ObjPX*Cos(tanval2)+ObjPY*-Sin(tanval2)); - ObjPY1=(ObjPX*Sin(tanval2)+ObjPY*Cos(tanval2)); - ObjPZ1=ObjPZ; + tanval2 = Angle(-Op02AAS + 32768); + // tanval2 = (-Op02AAS+32768)/(65536/INCR); + ObjPX1 = (ObjPX * Cos(tanval2) + ObjPY * -Sin(tanval2)); + ObjPY1 = (ObjPX * Sin(tanval2) + ObjPY * Cos(tanval2)); + ObjPZ1 = ObjPZ; // rotate around X -// tanval2 = (-Op02AZS/(65536/INCR)) & 1023; + // tanval2 = (-Op02AZS/(65536/INCR)) & 1023; tanval2 = Angle(-Op02AZS); -// tanval2 = (-Op02AZS)/256; - ObjPX2=ObjPX1; - ObjPY2=(ObjPY1*Cos(tanval2)+ObjPZ1*-Sin(tanval2)); - ObjPZ2=(ObjPY1*Sin(tanval2)+ObjPZ1*Cos(tanval2)); + // tanval2 = (-Op02AZS)/256; + ObjPX2 = ObjPX1; + ObjPY2 = (ObjPY1 * Cos(tanval2) + ObjPZ1 * -Sin(tanval2)); + ObjPZ2 = (ObjPY1 * Sin(tanval2) + ObjPZ1 * Cos(tanval2)); - #ifdef debug06 - Log_Message("ObjPX2: %f ObjPY2: %f ObjPZ2: %f\n",ObjPX2,ObjPY2,ObjPZ2); - #endif +#ifdef debug06 + Log_Message("ObjPX2: %f ObjPY2: %f ObjPZ2: %f\n", ObjPX2, ObjPY2, ObjPZ2); +#endif - ObjPZ2=ObjPZ2-Op02LFE; + ObjPZ2 = ObjPZ2 - Op02LFE; - if (ObjPZ2<0) + if (ObjPZ2 < 0) { double d; - Op06H=(short)(-ObjPX2*Op02LES/-(ObjPZ2)); //-ObjPX2*256/-ObjPZ2; - Op06V=(short)(-ObjPY2*Op02LES/-(ObjPZ2)); //-ObjPY2*256/-ObjPZ2; - d=(double)Op02LES; - d*=256.0; - d/=(-ObjPZ2); - if(d>65535.0) - d=65535.0; - else if(d<0.0) - d=0.0; - Op06S=(unsigned short)d; - //Op06S=(unsigned short)(256*(double)Op02LES/-ObjPZ2); + Op06H = (short)(-ObjPX2 * Op02LES / -(ObjPZ2)); //-ObjPX2*256/-ObjPZ2; + Op06V = (short)(-ObjPY2 * Op02LES / -(ObjPZ2)); //-ObjPY2*256/-ObjPZ2; + d = (double)Op02LES; + d *= 256.0; + d /= (-ObjPZ2); + if (d > 65535.0) + d = 65535.0; + else if (d < 0.0) + d = 0.0; + Op06S = (unsigned short)d; + //Op06S=(unsigned short)(256*(double)Op02LES/-ObjPZ2); //Op06S=(unsigned short)((double)(256.0*((double)Op02LES)/(-ObjPZ2))); } else { - Op06H=0; - Op06V=14*16; - Op06S=0xFFFF; + Op06H = 0; + Op06V = 14 * 16; + Op06S = 0xFFFF; } - #ifdef DebugDSP1 - Log_Message("OP06 X:%d Y:%d Z:%d",Op06X,Op06Y,Op06Z); - Log_Message("OP06 H:%d V:%d S:%d",Op06H,Op06V,Op06S); - #endif +#ifdef DebugDSP1 + Log_Message("OP06 X:%d Y:%d Z:%d", Op06X, Op06Y, Op06Z); + Log_Message("OP06 H:%d V:%d S:%d", Op06H, Op06V, Op06S); +#endif } #else void DSPOp06() { - ObjPX=Op06X-Op02FX; - ObjPY=Op06Y-Op02FY; - ObjPZ=Op06Z-Op02FZ; + ObjPX = Op06X - Op02FX; + ObjPY = Op06Y - Op02FY; + ObjPZ = Op06Z - Op02FZ; // rotate around Z - tanval = (-Op02AAS+32768)/65536.0*6.2832; - ObjPX1=(ObjPX*cos(tanval)+ObjPY*-sin(tanval)); - ObjPY1=(ObjPX*sin(tanval)+ObjPY*cos(tanval)); - ObjPZ1=ObjPZ; + tanval = (-Op02AAS + 32768) / 65536.0 * 6.2832; + ObjPX1 = (ObjPX * cos(tanval) + ObjPY * -sin(tanval)); + ObjPY1 = (ObjPX * sin(tanval) + ObjPY * cos(tanval)); + ObjPZ1 = ObjPZ; - #ifdef debug06 +#ifdef debug06 Log_Message("Angle : %f", tanval); - Log_Message("ObjPX1: %f ObjPY1: %f ObjPZ1: %f\n",ObjPX1,ObjPY1,ObjPZ1); + Log_Message("ObjPX1: %f ObjPY1: %f ObjPZ1: %f\n", ObjPX1, ObjPY1, ObjPZ1); Log_Message("cos(tanval) : %f sin(tanval) : %f", cos(tanval), sin(tanval)); - #endif +#endif // rotate around X - tanval = (-Op02AZS)/65536.0*6.2832; - ObjPX2=ObjPX1; - ObjPY2=(ObjPY1*cos(tanval)+ObjPZ1*-sin(tanval)); - ObjPZ2=(ObjPY1*sin(tanval)+ObjPZ1*cos(tanval)); + tanval = (-Op02AZS) / 65536.0 * 6.2832; + ObjPX2 = ObjPX1; + ObjPY2 = (ObjPY1 * cos(tanval) + ObjPZ1 * -sin(tanval)); + ObjPZ2 = (ObjPY1 * sin(tanval) + ObjPZ1 * cos(tanval)); - #ifdef debug06 - Log_Message("ObjPX2: %f ObjPY2: %f ObjPZ2: %f\n",ObjPX2,ObjPY2,ObjPZ2); - #endif +#ifdef debug06 + Log_Message("ObjPX2: %f ObjPY2: %f ObjPZ2: %f\n", ObjPX2, ObjPY2, ObjPZ2); +#endif - ObjPZ2=ObjPZ2-Op02LFE; + ObjPZ2 = ObjPZ2 - Op02LFE; - if (ObjPZ2<0) + if (ObjPZ2 < 0) { - Op06H=(short)(-ObjPX2*Op02LES/-(ObjPZ2)); //-ObjPX2*256/-ObjPZ2; - Op06V=(short)(-ObjPY2*Op02LES/-(ObjPZ2)); //-ObjPY2*256/-ObjPZ2; - double d=(double)Op02LES; - d*=256.0; - d/=(-ObjPZ2); - if(d>65535.0) - d=65535.0; - else if(d<0.0) - d=0.0; - Op06S=(unsigned short)d; -// Op06S=(unsigned short)(256*(double)Op02LES/-ObjPZ2); + Op06H = (short)(-ObjPX2 * Op02LES / -(ObjPZ2)); //-ObjPX2*256/-ObjPZ2; + Op06V = (short)(-ObjPY2 * Op02LES / -(ObjPZ2)); //-ObjPY2*256/-ObjPZ2; + double d = (double)Op02LES; + d *= 256.0; + d /= (-ObjPZ2); + if (d > 65535.0) + d = 65535.0; + else if (d < 0.0) + d = 0.0; + Op06S = (unsigned short)d; + // Op06S=(unsigned short)(256*(double)Op02LES/-ObjPZ2); } else { - Op06H=0; - Op06V=14*16; - Op06S=0xFFFF; + Op06H = 0; + Op06V = 14 * 16; + Op06S = 0xFFFF; } - #ifdef DebugDSP1 - Log_Message("OP06 X:%d Y:%d Z:%d",Op06X,Op06Y,Op06Z); - Log_Message("OP06 H:%d V:%d S:%d",Op06H,Op06V,Op06S); - #endif +#ifdef DebugDSP1 + Log_Message("OP06 X:%d Y:%d Z:%d", Op06X, Op06Y, Op06Z); + Log_Message("OP06 H:%d V:%d S:%d", Op06H, Op06V, Op06S); +#endif } -#endif +#endif short matrixC[3][3]; @@ -981,74 +1021,86 @@ short Op21Yr; void DSPOp01() { - short SinAz = DSP1_Sin(Op01Zr); - short CosAz = DSP1_Cos(Op01Zr); - short SinAy = DSP1_Sin(Op01Yr); - short CosAy = DSP1_Cos(Op01Yr); - short SinAx = DSP1_Sin(Op01Xr); - short CosAx = DSP1_Cos(Op01Xr); - - Op01m >>= 1; - - matrixA[0][0] = (Op01m * CosAz >> 15) * CosAy >> 15; - matrixA[0][1] = -((Op01m * SinAz >> 15) * CosAy >> 15); - matrixA[0][2] = Op01m * SinAy >> 15; - - matrixA[1][0] = ((Op01m * SinAz >> 15) * CosAx >> 15) + (((Op01m * CosAz >> 15) * SinAx >> 15) * SinAy >> 15); - matrixA[1][1] = ((Op01m * CosAz >> 15) * CosAx >> 15) - (((Op01m * SinAz >> 15) * SinAx >> 15) * SinAy >> 15); - matrixA[1][2] = -((Op01m * SinAx >> 15) * CosAy >> 15); - - matrixA[2][0] = ((Op01m * SinAz >> 15) * SinAx >> 15) - (((Op01m * CosAz >> 15) * CosAx >> 15) * SinAy >> 15); - matrixA[2][1] = ((Op01m * CosAz >> 15) * SinAx >> 15) + (((Op01m * SinAz >> 15) * CosAx >> 15) * SinAy >> 15); - matrixA[2][2] = (Op01m * CosAx >> 15) * CosAy >> 15; + short SinAz = DSP1_Sin(Op01Zr); + short CosAz = DSP1_Cos(Op01Zr); + short SinAy = DSP1_Sin(Op01Yr); + short CosAy = DSP1_Cos(Op01Yr); + short SinAx = DSP1_Sin(Op01Xr); + short CosAx = DSP1_Cos(Op01Xr); + + Op01m >>= 1; + + matrixA[0][0] = (Op01m * CosAz >> 15) * CosAy >> 15; + matrixA[0][1] = -((Op01m * SinAz >> 15) * CosAy >> 15); + matrixA[0][2] = Op01m * SinAy >> 15; + + matrixA[1][0] = ((Op01m * SinAz >> 15) * CosAx >> 15) + ((( + Op01m * CosAz >> 15) * SinAx >> 15) * SinAy >> 15); + matrixA[1][1] = ((Op01m * CosAz >> 15) * CosAx >> 15) - ((( + Op01m * SinAz >> 15) * SinAx >> 15) * SinAy >> 15); + matrixA[1][2] = -((Op01m * SinAx >> 15) * CosAy >> 15); + + matrixA[2][0] = ((Op01m * SinAz >> 15) * SinAx >> 15) - ((( + Op01m * CosAz >> 15) * CosAx >> 15) * SinAy >> 15); + matrixA[2][1] = ((Op01m * CosAz >> 15) * SinAx >> 15) + ((( + Op01m * SinAz >> 15) * CosAx >> 15) * SinAy >> 15); + matrixA[2][2] = (Op01m * CosAx >> 15) * CosAy >> 15; } void DSPOp11() { - short SinAz = DSP1_Sin(Op11Zr); - short CosAz = DSP1_Cos(Op11Zr); - short SinAy = DSP1_Sin(Op11Yr); - short CosAy = DSP1_Cos(Op11Yr); - short SinAx = DSP1_Sin(Op11Xr); - short CosAx = DSP1_Cos(Op11Xr); - - Op11m >>= 1; - - matrixB[0][0] = (Op11m * CosAz >> 15) * CosAy >> 15; - matrixB[0][1] = -((Op11m * SinAz >> 15) * CosAy >> 15); - matrixB[0][2] = Op11m * SinAy >> 15; - - matrixB[1][0] = ((Op11m * SinAz >> 15) * CosAx >> 15) + (((Op11m * CosAz >> 15) * SinAx >> 15) * SinAy >> 15); - matrixB[1][1] = ((Op11m * CosAz >> 15) * CosAx >> 15) - (((Op11m * SinAz >> 15) * SinAx >> 15) * SinAy >> 15); - matrixB[1][2] = -((Op11m * SinAx >> 15) * CosAy >> 15); - - matrixB[2][0] = ((Op11m * SinAz >> 15) * SinAx >> 15) - (((Op11m * CosAz >> 15) * CosAx >> 15) * SinAy >> 15); - matrixB[2][1] = ((Op11m * CosAz >> 15) * SinAx >> 15) + (((Op11m * SinAz >> 15) * CosAx >> 15) * SinAy >> 15); - matrixB[2][2] = (Op11m * CosAx >> 15) * CosAy >> 15; + short SinAz = DSP1_Sin(Op11Zr); + short CosAz = DSP1_Cos(Op11Zr); + short SinAy = DSP1_Sin(Op11Yr); + short CosAy = DSP1_Cos(Op11Yr); + short SinAx = DSP1_Sin(Op11Xr); + short CosAx = DSP1_Cos(Op11Xr); + + Op11m >>= 1; + + matrixB[0][0] = (Op11m * CosAz >> 15) * CosAy >> 15; + matrixB[0][1] = -((Op11m * SinAz >> 15) * CosAy >> 15); + matrixB[0][2] = Op11m * SinAy >> 15; + + matrixB[1][0] = ((Op11m * SinAz >> 15) * CosAx >> 15) + ((( + Op11m * CosAz >> 15) * SinAx >> 15) * SinAy >> 15); + matrixB[1][1] = ((Op11m * CosAz >> 15) * CosAx >> 15) - ((( + Op11m * SinAz >> 15) * SinAx >> 15) * SinAy >> 15); + matrixB[1][2] = -((Op11m * SinAx >> 15) * CosAy >> 15); + + matrixB[2][0] = ((Op11m * SinAz >> 15) * SinAx >> 15) - ((( + Op11m * CosAz >> 15) * CosAx >> 15) * SinAy >> 15); + matrixB[2][1] = ((Op11m * CosAz >> 15) * SinAx >> 15) + ((( + Op11m * SinAz >> 15) * CosAx >> 15) * SinAy >> 15); + matrixB[2][2] = (Op11m * CosAx >> 15) * CosAy >> 15; } void DSPOp21() { - short SinAz = DSP1_Sin(Op21Zr); - short CosAz = DSP1_Cos(Op21Zr); - short SinAy = DSP1_Sin(Op21Yr); - short CosAy = DSP1_Cos(Op21Yr); - short SinAx = DSP1_Sin(Op21Xr); - short CosAx = DSP1_Cos(Op21Xr); - - Op21m >>= 1; - - matrixC[0][0] = (Op21m * CosAz >> 15) * CosAy >> 15; - matrixC[0][1] = -((Op21m * SinAz >> 15) * CosAy >> 15); - matrixC[0][2] = Op21m * SinAy >> 15; - - matrixC[1][0] = ((Op21m * SinAz >> 15) * CosAx >> 15) + (((Op21m * CosAz >> 15) * SinAx >> 15) * SinAy >> 15); - matrixC[1][1] = ((Op21m * CosAz >> 15) * CosAx >> 15) - (((Op21m * SinAz >> 15) * SinAx >> 15) * SinAy >> 15); - matrixC[1][2] = -((Op21m * SinAx >> 15) * CosAy >> 15); - - matrixC[2][0] = ((Op21m * SinAz >> 15) * SinAx >> 15) - (((Op21m * CosAz >> 15) * CosAx >> 15) * SinAy >> 15); - matrixC[2][1] = ((Op21m * CosAz >> 15) * SinAx >> 15) + (((Op21m * SinAz >> 15) * CosAx >> 15) * SinAy >> 15); - matrixC[2][2] = (Op21m * CosAx >> 15) * CosAy >> 15; + short SinAz = DSP1_Sin(Op21Zr); + short CosAz = DSP1_Cos(Op21Zr); + short SinAy = DSP1_Sin(Op21Yr); + short CosAy = DSP1_Cos(Op21Yr); + short SinAx = DSP1_Sin(Op21Xr); + short CosAx = DSP1_Cos(Op21Xr); + + Op21m >>= 1; + + matrixC[0][0] = (Op21m * CosAz >> 15) * CosAy >> 15; + matrixC[0][1] = -((Op21m * SinAz >> 15) * CosAy >> 15); + matrixC[0][2] = Op21m * SinAy >> 15; + + matrixC[1][0] = ((Op21m * SinAz >> 15) * CosAx >> 15) + ((( + Op21m * CosAz >> 15) * SinAx >> 15) * SinAy >> 15); + matrixC[1][1] = ((Op21m * CosAz >> 15) * CosAx >> 15) - ((( + Op21m * SinAz >> 15) * SinAx >> 15) * SinAy >> 15); + matrixC[1][2] = -((Op21m * SinAx >> 15) * CosAy >> 15); + + matrixC[2][0] = ((Op21m * SinAz >> 15) * SinAx >> 15) - ((( + Op21m * CosAz >> 15) * CosAx >> 15) * SinAy >> 15); + matrixC[2][1] = ((Op21m * CosAz >> 15) * SinAx >> 15) + ((( + Op21m * SinAz >> 15) * CosAx >> 15) * SinAy >> 15); + matrixC[2][2] = (Op21m * CosAx >> 15) * CosAy >> 15; } short Op0DX; @@ -1072,35 +1124,47 @@ short Op2DU; void DSPOp0D() { - Op0DF = (Op0DX * matrixA[0][0] >> 15) + (Op0DY * matrixA[0][1] >> 15) + (Op0DZ * matrixA[0][2] >> 15); - Op0DL = (Op0DX * matrixA[1][0] >> 15) + (Op0DY * matrixA[1][1] >> 15) + (Op0DZ * matrixA[1][2] >> 15); - Op0DU = (Op0DX * matrixA[2][0] >> 15) + (Op0DY * matrixA[2][1] >> 15) + (Op0DZ * matrixA[2][2] >> 15); + Op0DF = (Op0DX * matrixA[0][0] >> 15) + (Op0DY * matrixA[0][1] >> 15) + + (Op0DZ * matrixA[0][2] >> 15); + Op0DL = (Op0DX * matrixA[1][0] >> 15) + (Op0DY * matrixA[1][1] >> 15) + + (Op0DZ * matrixA[1][2] >> 15); + Op0DU = (Op0DX * matrixA[2][0] >> 15) + (Op0DY * matrixA[2][1] >> 15) + + (Op0DZ * matrixA[2][2] >> 15); - #ifdef DebugDSP1 - Log_Message("OP0D X: %d Y: %d Z: %d / F: %d L: %d U: %d",Op0DX,Op0DY,Op0DZ,Op0DF,Op0DL,Op0DU); - #endif +#ifdef DebugDSP1 + Log_Message("OP0D X: %d Y: %d Z: %d / F: %d L: %d U: %d", Op0DX, Op0DY, Op0DZ, + Op0DF, Op0DL, Op0DU); +#endif } void DSPOp1D() { - Op1DF = (Op1DX * matrixB[0][0] >> 15) + (Op1DY * matrixB[0][1] >> 15) + (Op1DZ * matrixB[0][2] >> 15); - Op1DL = (Op1DX * matrixB[1][0] >> 15) + (Op1DY * matrixB[1][1] >> 15) + (Op1DZ * matrixB[1][2] >> 15); - Op1DU = (Op1DX * matrixB[2][0] >> 15) + (Op1DY * matrixB[2][1] >> 15) + (Op1DZ * matrixB[2][2] >> 15); + Op1DF = (Op1DX * matrixB[0][0] >> 15) + (Op1DY * matrixB[0][1] >> 15) + + (Op1DZ * matrixB[0][2] >> 15); + Op1DL = (Op1DX * matrixB[1][0] >> 15) + (Op1DY * matrixB[1][1] >> 15) + + (Op1DZ * matrixB[1][2] >> 15); + Op1DU = (Op1DX * matrixB[2][0] >> 15) + (Op1DY * matrixB[2][1] >> 15) + + (Op1DZ * matrixB[2][2] >> 15); - #ifdef DebugDSP1 - Log_Message("OP1D X: %d Y: %d Z: %d / F: %d L: %d U: %d",Op1DX,Op1DY,Op1DZ,Op1DF,Op1DL,Op1DU); - #endif +#ifdef DebugDSP1 + Log_Message("OP1D X: %d Y: %d Z: %d / F: %d L: %d U: %d", Op1DX, Op1DY, Op1DZ, + Op1DF, Op1DL, Op1DU); +#endif } void DSPOp2D() { - Op2DF = (Op2DX * matrixC[0][0] >> 15) + (Op2DY * matrixC[0][1] >> 15) + (Op2DZ * matrixC[0][2] >> 15); - Op2DL = (Op2DX * matrixC[1][0] >> 15) + (Op2DY * matrixC[1][1] >> 15) + (Op2DZ * matrixC[1][2] >> 15); - Op2DU = (Op2DX * matrixC[2][0] >> 15) + (Op2DY * matrixC[2][1] >> 15) + (Op2DZ * matrixC[2][2] >> 15); + Op2DF = (Op2DX * matrixC[0][0] >> 15) + (Op2DY * matrixC[0][1] >> 15) + + (Op2DZ * matrixC[0][2] >> 15); + Op2DL = (Op2DX * matrixC[1][0] >> 15) + (Op2DY * matrixC[1][1] >> 15) + + (Op2DZ * matrixC[1][2] >> 15); + Op2DU = (Op2DX * matrixC[2][0] >> 15) + (Op2DY * matrixC[2][1] >> 15) + + (Op2DZ * matrixC[2][2] >> 15); - #ifdef DebugDSP1 - Log_Message("OP2D X: %d Y: %d Z: %d / F: %d L: %d U: %d",Op2DX,Op2DY,Op2DZ,Op2DF,Op2DL,Op2DU); - #endif +#ifdef DebugDSP1 + Log_Message("OP2D X: %d Y: %d Z: %d / F: %d L: %d U: %d", Op2DX, Op2DY, Op2DZ, + Op2DF, Op2DL, Op2DU); +#endif } short Op03F; @@ -1124,35 +1188,47 @@ short Op23Z; void DSPOp03() { - Op03X = (Op03F * matrixA[0][0] >> 15) + (Op03L * matrixA[1][0] >> 15) + (Op03U * matrixA[2][0] >> 15); - Op03Y = (Op03F * matrixA[0][1] >> 15) + (Op03L * matrixA[1][1] >> 15) + (Op03U * matrixA[2][1] >> 15); - Op03Z = (Op03F * matrixA[0][2] >> 15) + (Op03L * matrixA[1][2] >> 15) + (Op03U * matrixA[2][2] >> 15); + Op03X = (Op03F * matrixA[0][0] >> 15) + (Op03L * matrixA[1][0] >> 15) + + (Op03U * matrixA[2][0] >> 15); + Op03Y = (Op03F * matrixA[0][1] >> 15) + (Op03L * matrixA[1][1] >> 15) + + (Op03U * matrixA[2][1] >> 15); + Op03Z = (Op03F * matrixA[0][2] >> 15) + (Op03L * matrixA[1][2] >> 15) + + (Op03U * matrixA[2][2] >> 15); - #ifdef DebugDSP1 - Log_Message("OP03 F: %d L: %d U: %d / X: %d Y: %d Z: %d",Op03F,Op03L,Op03U,Op03X,Op03Y,Op03Z); - #endif +#ifdef DebugDSP1 + Log_Message("OP03 F: %d L: %d U: %d / X: %d Y: %d Z: %d", Op03F, Op03L, Op03U, + Op03X, Op03Y, Op03Z); +#endif } void DSPOp13() { - Op13X = (Op13F * matrixB[0][0] >> 15) + (Op13L * matrixB[1][0] >> 15) + (Op13U * matrixB[2][0] >> 15); - Op13Y = (Op13F * matrixB[0][1] >> 15) + (Op13L * matrixB[1][1] >> 15) + (Op13U * matrixB[2][1] >> 15); - Op13Z = (Op13F * matrixB[0][2] >> 15) + (Op13L * matrixB[1][2] >> 15) + (Op13U * matrixB[2][2] >> 15); + Op13X = (Op13F * matrixB[0][0] >> 15) + (Op13L * matrixB[1][0] >> 15) + + (Op13U * matrixB[2][0] >> 15); + Op13Y = (Op13F * matrixB[0][1] >> 15) + (Op13L * matrixB[1][1] >> 15) + + (Op13U * matrixB[2][1] >> 15); + Op13Z = (Op13F * matrixB[0][2] >> 15) + (Op13L * matrixB[1][2] >> 15) + + (Op13U * matrixB[2][2] >> 15); - #ifdef DebugDSP1 - Log_Message("OP13 F: %d L: %d U: %d / X: %d Y: %d Z: %d",Op13F,Op13L,Op13U,Op13X,Op13Y,Op13Z); - #endif +#ifdef DebugDSP1 + Log_Message("OP13 F: %d L: %d U: %d / X: %d Y: %d Z: %d", Op13F, Op13L, Op13U, + Op13X, Op13Y, Op13Z); +#endif } void DSPOp23() { - Op23X = (Op23F * matrixC[0][0] >> 15) + (Op23L * matrixC[1][0] >> 15) + (Op23U * matrixC[2][0] >> 15); - Op23Y = (Op23F * matrixC[0][1] >> 15) + (Op23L * matrixC[1][1] >> 15) + (Op23U * matrixC[2][1] >> 15); - Op23Z = (Op23F * matrixC[0][2] >> 15) + (Op23L * matrixC[1][2] >> 15) + (Op23U * matrixC[2][2] >> 15); + Op23X = (Op23F * matrixC[0][0] >> 15) + (Op23L * matrixC[1][0] >> 15) + + (Op23U * matrixC[2][0] >> 15); + Op23Y = (Op23F * matrixC[0][1] >> 15) + (Op23L * matrixC[1][1] >> 15) + + (Op23U * matrixC[2][1] >> 15); + Op23Z = (Op23F * matrixC[0][2] >> 15) + (Op23L * matrixC[1][2] >> 15) + + (Op23U * matrixC[2][2] >> 15); - #ifdef DebugDSP1 - Log_Message("OP23 F: %d L: %d U: %d / X: %d Y: %d Z: %d",Op23F,Op23L,Op23U,Op23X,Op23Y,Op23Z); - #endif +#ifdef DebugDSP1 + Log_Message("OP23 F: %d L: %d U: %d / X: %d Y: %d Z: %d", Op23F, Op23L, Op23U, + Op23X, Op23Y, Op23Z); +#endif } short Op14Zr; @@ -1167,63 +1243,66 @@ short Op14Yrr; void DSPOp14() { - short CSec, ESec, CTan, CSin, C, E; - - DSP1_Inverse(DSP1_Cos(Op14Xr), 0, &CSec, &ESec); - - // Rotation Around Z - DSP1_NormalizeDouble(Op14U * DSP1_Cos(Op14Yr) - Op14F * DSP1_Sin(Op14Yr), &C, &E); - - E = ESec - E; - - DSP1_Normalize(C * CSec >> 15, &C, &E); - - Op14Zrr = Op14Zr + DSP1_Truncate(C, E); - - // Rotation Around X - Op14Xrr = Op14Xr + (Op14U * DSP1_Sin(Op14Yr) >> 15) + (Op14F * DSP1_Cos(Op14Yr) >> 15); - - // Rotation Around Y - DSP1_NormalizeDouble(Op14U * DSP1_Cos(Op14Yr) + Op14F * DSP1_Sin(Op14Yr), &C, &E); - - E = ESec - E; - - DSP1_Normalize(DSP1_Sin(Op14Xr), &CSin, &E); - - CTan = CSec * CSin >> 15; - - DSP1_Normalize(-(C * CTan >> 15), &C, &E); - - Op14Yrr = Op14Yr + DSP1_Truncate(C, E) + Op14L; + short CSec, ESec, CTan, CSin, C, E; + + DSP1_Inverse(DSP1_Cos(Op14Xr), 0, &CSec, &ESec); + + // Rotation Around Z + DSP1_NormalizeDouble(Op14U * DSP1_Cos(Op14Yr) - Op14F * DSP1_Sin(Op14Yr), &C, + &E); + + E = ESec - E; + + DSP1_Normalize(C * CSec >> 15, &C, &E); + + Op14Zrr = Op14Zr + DSP1_Truncate(C, E); + + // Rotation Around X + Op14Xrr = Op14Xr + (Op14U * DSP1_Sin(Op14Yr) >> 15) + (Op14F * DSP1_Cos( + Op14Yr) >> 15); + + // Rotation Around Y + DSP1_NormalizeDouble(Op14U * DSP1_Cos(Op14Yr) + Op14F * DSP1_Sin(Op14Yr), &C, + &E); + + E = ESec - E; + + DSP1_Normalize(DSP1_Sin(Op14Xr), &CSin, &E); + + CTan = CSec * CSin >> 15; + + DSP1_Normalize(-(C * CTan >> 15), &C, &E); + + Op14Yrr = Op14Yr + DSP1_Truncate(C, E) + Op14L; } -void DSP1_Target(short H, short V, short *X, short *Y) +void DSP1_Target(short H, short V, short* X, short* Y) { - short C, E, C1, E1; + short C, E, C1, E1; - DSP1_Inverse((V * SinAzs >> 15) + VOffset, 8, &C, &E); - E += VPlane_E; + DSP1_Inverse((V * SinAzs >> 15) + VOffset, 8, &C, &E); + E += VPlane_E; - C1 = C * VPlane_C >> 15; - E1 = E + SecAZS_E1; + C1 = C * VPlane_C >> 15; + E1 = E + SecAZS_E1; - H <<= 8; + H <<= 8; - DSP1_Normalize(C1, &C, &E); + DSP1_Normalize(C1, &C, &E); - C = DSP1_Truncate(C, E) * H >> 15; + C = DSP1_Truncate(C, E) * H >> 15; - *X = CentreX + (C * CosAas >> 15); - *Y = CentreY - (C * SinAas >> 15); + *X = CentreX + (C * CosAas >> 15); + *Y = CentreY - (C * SinAas >> 15); - V <<= 8; + V <<= 8; - DSP1_Normalize(C1 * SecAZS_C1 >> 15, &C, &E1); + DSP1_Normalize(C1 * SecAZS_C1 >> 15, &C, &E1); - C = DSP1_Truncate(C, E1) * V >> 15; + C = DSP1_Truncate(C, E1) * V >> 15; - *X += C * -SinAas >> 15; - *Y += C * CosAas >> 15; + *X += C * -SinAas >> 15; + *Y += C * CosAas >> 15; } short Op0EH; @@ -1233,7 +1312,7 @@ short Op0EY; void DSPOp0E() { - DSP1_Target(Op0EH, Op0EV, &Op0EX, &Op0EY); + DSP1_Target(Op0EH, Op0EV, &Op0EX, &Op0EY); } short Op0BX; @@ -1251,67 +1330,71 @@ short Op2BS; void DSPOp0B() { - Op0BS = (Op0BX * matrixA[0][0] + Op0BY * matrixA[0][1] + Op0BZ * matrixA[0][2]) >> 15; + Op0BS = (Op0BX * matrixA[0][0] + Op0BY * matrixA[0][1] + Op0BZ * matrixA[0][2]) + >> 15; - #ifdef DebugDSP1 - Log_Message("OP0B"); - #endif +#ifdef DebugDSP1 + Log_Message("OP0B"); +#endif } void DSPOp1B() -{ - Op1BS = (Op1BX * matrixB[0][0] + Op1BY * matrixB[0][1] + Op1BZ * matrixB[0][2]) >> 15; +{ + Op1BS = (Op1BX * matrixB[0][0] + Op1BY * matrixB[0][1] + Op1BZ * matrixB[0][2]) + >> 15; - #ifdef DebugDSP1 - Log_Message("OP1B X: %d Y: %d Z: %d S: %d",Op1BX,Op1BY,Op1BZ,Op1BS); - Log_Message(" MX: %d MY: %d MZ: %d Scale: %d",(short)(matrixB[0][0]*100),(short)(matrixB[0][1]*100),(short)(matrixB[0][2]*100),(short)(sc2*100)); - #endif +#ifdef DebugDSP1 + Log_Message("OP1B X: %d Y: %d Z: %d S: %d", Op1BX, Op1BY, Op1BZ, Op1BS); + Log_Message(" MX: %d MY: %d MZ: %d Scale: %d", (short)(matrixB[0][0] * 100), + (short)(matrixB[0][1] * 100), (short)(matrixB[0][2] * 100), (short)(sc2 * 100)); +#endif } void DSPOp2B() { - Op2BS = (Op2BX * matrixC[0][0] + Op2BY * matrixC[0][1] + Op2BZ * matrixC[0][2]) >> 15; + Op2BS = (Op2BX * matrixC[0][0] + Op2BY * matrixC[0][1] + Op2BZ * matrixC[0][2]) + >> 15; - #ifdef DebugDSP1 - Log_Message("OP2B"); - #endif +#ifdef DebugDSP1 + Log_Message("OP2B"); +#endif } -short Op08X,Op08Y,Op08Z,Op08Ll,Op08Lh; +short Op08X, Op08Y, Op08Z, Op08Ll, Op08Lh; void DSPOp08() { - int Op08Size = (Op08X * Op08X + Op08Y * Op08Y + Op08Z * Op08Z) << 1; - Op08Ll = Op08Size & 0xffff; - Op08Lh = (Op08Size >> 16) & 0xffff; - - #ifdef DebugDSP1 - Log_Message("OP08 %d,%d,%d",Op08X,Op08Y,Op08Z); - Log_Message("OP08 ((Op08X^2)+(Op08Y^2)+(Op08X^2))=%x",Op08Size ); - #endif + int Op08Size = (Op08X * Op08X + Op08Y * Op08Y + Op08Z * Op08Z) << 1; + Op08Ll = Op08Size & 0xffff; + Op08Lh = (Op08Size >> 16) & 0xffff; + +#ifdef DebugDSP1 + Log_Message("OP08 %d,%d,%d", Op08X, Op08Y, Op08Z); + Log_Message("OP08 ((Op08X^2)+(Op08Y^2)+(Op08X^2))=%x", Op08Size); +#endif } -short Op18X,Op18Y,Op18Z,Op18R,Op18D; +short Op18X, Op18Y, Op18Z, Op18R, Op18D; void DSPOp18() { Op18D = (Op18X * Op18X + Op18Y * Op18Y + Op18Z * Op18Z - Op18R * Op18R) >> 15; - #ifdef DebugDSP1 - Log_Message("Op18 X: %d Y: %d Z: %d R: %D DIFF %d",Op18X,Op18Y,Op38Z,Op18D); - #endif +#ifdef DebugDSP1 + Log_Message("Op18 X: %d Y: %d Z: %d R: %D DIFF %d", Op18X, Op18Y, Op38Z, Op18D); +#endif } -short Op38X,Op38Y,Op38Z,Op38R,Op38D; +short Op38X, Op38Y, Op38Z, Op38R, Op38D; void DSPOp38() { Op38D = (Op38X * Op38X + Op38Y * Op38Y + Op38Z * Op38Z - Op38R * Op38R) >> 15; Op38D++; - #ifdef DebugDSP1 - Log_Message("OP38 X: %d Y: %d Z: %d R: %D DIFF %d",Op38X,Op38Y,Op38Z,Op38D); - #endif +#ifdef DebugDSP1 + Log_Message("OP38 X: %d Y: %d Z: %d R: %D DIFF %d", Op38X, Op38Y, Op38Z, Op38D); +#endif } short Op28X; @@ -1321,32 +1404,32 @@ short Op28R; void DSPOp28() { - int Radius = Op28X * Op28X + Op28Y * Op28Y + Op28Z * Op28Z; + int Radius = Op28X * Op28X + Op28Y * Op28Y + Op28Z * Op28Z; - if (Radius == 0) Op28R = 0; - else - { - short C, E; - DSP1_NormalizeDouble(Radius, &C, &E); - if (E & 1) C = C * 0x4000 >> 15; + if (Radius == 0) Op28R = 0; + else + { + short C, E; + DSP1_NormalizeDouble(Radius, &C, &E); + if (E & 1) C = C * 0x4000 >> 15; - short Pos = C * 0x0040 >> 15; + short Pos = C * 0x0040 >> 15; - short Node1 = DSP1ROM[0x00d5 + Pos]; - short Node2 = DSP1ROM[0x00d6 + Pos]; + short Node1 = DSP1ROM[0x00d5 + Pos]; + short Node2 = DSP1ROM[0x00d6 + Pos]; - Op28R = ((Node2 - Node1) * (C & 0x1ff) >> 9) + Node1; - Op28R >>= (E >> 1); - } + Op28R = ((Node2 - Node1) * (C & 0x1ff) >> 9) + Node1; + Op28R >>= (E >> 1); + } - #ifdef DebugDSP1 - Log_Message("OP28 X:%d Y:%d Z:%d",Op28X,Op28Y,Op28Z); - Log_Message("OP28 Vector Length %d",Op28R); - #endif +#ifdef DebugDSP1 + Log_Message("OP28 X:%d Y:%d Z:%d", Op28X, Op28Y, Op28Z); + Log_Message("OP28 Vector Length %d", Op28R); +#endif } -short Op1CX,Op1CY,Op1CZ; -short Op1CXBR,Op1CYBR,Op1CZBR,Op1CXAR,Op1CYAR,Op1CZAR; +short Op1CX, Op1CY, Op1CZ; +short Op1CXBR, Op1CYBR, Op1CZBR, Op1CXAR, Op1CYAR, Op1CZAR; short Op1CX1; short Op1CY1; short Op1CZ1; @@ -1356,24 +1439,27 @@ short Op1CZ2; void DSPOp1C() { - // Rotate Around Op1CZ1 - Op1CX1 = (Op1CYBR * DSP1_Sin(Op1CZ) >> 15) + (Op1CXBR * DSP1_Cos(Op1CZ) >> 15); - Op1CY1 = (Op1CYBR * DSP1_Cos(Op1CZ) >> 15) - (Op1CXBR * DSP1_Sin(Op1CZ) >> 15); - Op1CXBR = Op1CX1; Op1CYBR = Op1CY1; - - // Rotate Around Op1CY1 - Op1CZ1 = (Op1CXBR * DSP1_Sin(Op1CY) >> 15) + (Op1CZBR * DSP1_Cos(Op1CY) >> 15); - Op1CX1 = (Op1CXBR * DSP1_Cos(Op1CY) >> 15) - (Op1CZBR * DSP1_Sin(Op1CY) >> 15); - Op1CXAR = Op1CX1; Op1CZBR = Op1CZ1; - - // Rotate Around Op1CX1 - Op1CY1 = (Op1CZBR * DSP1_Sin(Op1CX) >> 15) + (Op1CYBR * DSP1_Cos(Op1CX) >> 15); - Op1CZ1 = (Op1CZBR * DSP1_Cos(Op1CX) >> 15) - (Op1CYBR * DSP1_Sin(Op1CX) >> 15); - Op1CYAR = Op1CY1; Op1CZAR = Op1CZ1; - - #ifdef DebugDSP1 - Log_Message("OP1C Apply Matrix CX:%d CY:%d CZ",Op1CXAR,Op1CYAR,Op1CZAR); - #endif + // Rotate Around Op1CZ1 + Op1CX1 = (Op1CYBR * DSP1_Sin(Op1CZ) >> 15) + (Op1CXBR * DSP1_Cos(Op1CZ) >> 15); + Op1CY1 = (Op1CYBR * DSP1_Cos(Op1CZ) >> 15) - (Op1CXBR * DSP1_Sin(Op1CZ) >> 15); + Op1CXBR = Op1CX1; + Op1CYBR = Op1CY1; + + // Rotate Around Op1CY1 + Op1CZ1 = (Op1CXBR * DSP1_Sin(Op1CY) >> 15) + (Op1CZBR * DSP1_Cos(Op1CY) >> 15); + Op1CX1 = (Op1CXBR * DSP1_Cos(Op1CY) >> 15) - (Op1CZBR * DSP1_Sin(Op1CY) >> 15); + Op1CXAR = Op1CX1; + Op1CZBR = Op1CZ1; + + // Rotate Around Op1CX1 + Op1CY1 = (Op1CZBR * DSP1_Sin(Op1CX) >> 15) + (Op1CYBR * DSP1_Cos(Op1CX) >> 15); + Op1CZ1 = (Op1CZBR * DSP1_Cos(Op1CX) >> 15) - (Op1CYBR * DSP1_Sin(Op1CX) >> 15); + Op1CYAR = Op1CY1; + Op1CZAR = Op1CZ1; + +#ifdef DebugDSP1 + Log_Message("OP1C Apply Matrix CX:%d CY:%d CZ", Op1CXAR, Op1CYAR, Op1CZAR); +#endif } unsigned short Op0FRamsize; @@ -1383,9 +1469,9 @@ void DSPOp0F() { Op0FPass = 0x0000; - #ifdef DebugDSP1 - Log_Message("OP0F RAM Test Pass:%d", Op0FPass); - #endif +#ifdef DebugDSP1 + Log_Message("OP0F RAM Test Pass:%d", Op0FPass); +#endif } short Op2FUnknown; @@ -1393,5 +1479,5 @@ short Op2FSize; void DSPOp2F() { - Op2FSize=0x100; + Op2FSize = 0x100; } diff --git a/source/dsp2emu.c b/source/dsp2emu.c index 7b74c3b..8e31d04 100644 --- a/source/dsp2emu.c +++ b/source/dsp2emu.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,182 +43,180 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ -uint16 DSP2Op09Word1=0; -uint16 DSP2Op09Word2=0; -bool DSP2Op05HasLen=false; -int DSP2Op05Len=0; -bool DSP2Op06HasLen=false; -int DSP2Op06Len=0; -uint8 DSP2Op05Transparent=0; +uint16 DSP2Op09Word1 = 0; +uint16 DSP2Op09Word2 = 0; +bool DSP2Op05HasLen = false; +int DSP2Op05Len = 0; +bool DSP2Op06HasLen = false; +int DSP2Op06Len = 0; +uint8 DSP2Op05Transparent = 0; -void DSP2_Op05 () +void DSP2_Op05() { - uint8 color; - // Overlay bitmap with transparency. - // Input: - // - // Bitmap 1: i[0] <=> i[size-1] - // Bitmap 2: i[size] <=> i[2*size-1] - // - // Output: - // - // Bitmap 3: o[0] <=> o[size-1] - // - // Processing: - // - // Process all 4-bit pixels (nibbles) in the bitmap - // - // if ( BM2_pixel == transparent_color ) - // pixelout = BM1_pixel - // else - // pixelout = BM2_pixel - - // The max size bitmap is limited to 255 because the size parameter is a byte - // I think size=0 is an error. The behavior of the chip on size=0 is to - // return the last value written to DR if you read DR on Op05 with - // size = 0. I don't think it's worth implementing this quirk unless it's - // proven necessary. - - int n; - unsigned char c1; - unsigned char c2; - unsigned char *p1 = DSP1.parameters; - unsigned char *p2 = &DSP1.parameters[DSP2Op05Len]; - unsigned char *p3 = DSP1.output; - - color = DSP2Op05Transparent&0x0f; - - for( n = 0; n < DSP2Op05Len; n++ ) - { - c1 = *p1++; - c2 = *p2++; - *p3++ = ( ((c2 >> 4) == color ) ? c1 & 0xf0: c2 & 0xf0 ) | - ( ((c2 & 0x0f)==color) ? c1 & 0x0f: c2 & 0x0f ); - } + uint8 color; + // Overlay bitmap with transparency. + // Input: + // + // Bitmap 1: i[0] <=> i[size-1] + // Bitmap 2: i[size] <=> i[2*size-1] + // + // Output: + // + // Bitmap 3: o[0] <=> o[size-1] + // + // Processing: + // + // Process all 4-bit pixels (nibbles) in the bitmap + // + // if ( BM2_pixel == transparent_color ) + // pixelout = BM1_pixel + // else + // pixelout = BM2_pixel + + // The max size bitmap is limited to 255 because the size parameter is a byte + // I think size=0 is an error. The behavior of the chip on size=0 is to + // return the last value written to DR if you read DR on Op05 with + // size = 0. I don't think it's worth implementing this quirk unless it's + // proven necessary. + + int n; + unsigned char c1; + unsigned char c2; + unsigned char* p1 = DSP1.parameters; + unsigned char* p2 = &DSP1.parameters[DSP2Op05Len]; + unsigned char* p3 = DSP1.output; + + color = DSP2Op05Transparent & 0x0f; + + for (n = 0; n < DSP2Op05Len; n++) + { + c1 = *p1++; + c2 = *p2++; + *p3++ = (((c2 >> 4) == color) ? c1 & 0xf0 : c2 & 0xf0) | + (((c2 & 0x0f) == color) ? c1 & 0x0f : c2 & 0x0f); + } } -void DSP2_Op01 () +void DSP2_Op01() { - // Op01 size is always 32 bytes input and output. - // The hardware does strange things if you vary the size. - - int j; - unsigned char c0, c1, c2, c3; - unsigned char *p1 = DSP1.parameters; - unsigned char *p2a = DSP1.output; - unsigned char *p2b = &DSP1.output[16]; // halfway - - // Process 8 blocks of 4 bytes each - - for ( j = 0; j < 8; j++ ) - { - c0 = *p1++; - c1 = *p1++; - c2 = *p1++; - c3 = *p1++; - - *p2a++ = (c0 & 0x10) << 3 | - (c0 & 0x01) << 6 | - (c1 & 0x10) << 1 | - (c1 & 0x01) << 4 | - (c2 & 0x10) >> 1 | - (c2 & 0x01) << 2 | - (c3 & 0x10) >> 3 | - (c3 & 0x01); - - *p2a++ = (c0 & 0x20) << 2 | - (c0 & 0x02) << 5 | - (c1 & 0x20) | - (c1 & 0x02) << 3 | - (c2 & 0x20) >> 2 | - (c2 & 0x02) << 1 | - (c3 & 0x20) >> 4 | - (c3 & 0x02) >> 1; - - *p2b++ = (c0 & 0x40) << 1 | - (c0 & 0x04) << 4 | - (c1 & 0x40) >> 1 | - (c1 & 0x04) << 2 | - (c2 & 0x40) >> 3 | - (c2 & 0x04) | - (c3 & 0x40) >> 5 | - (c3 & 0x04) >> 2; - - - *p2b++ = (c0 & 0x80) | - (c0 & 0x08) << 3 | - (c1 & 0x80) >> 2 | - (c1 & 0x08) << 1 | - (c2 & 0x80) >> 4 | - (c2 & 0x08) >> 1 | - (c3 & 0x80) >> 6 | - (c3 & 0x08) >> 3; - } - return; + // Op01 size is always 32 bytes input and output. + // The hardware does strange things if you vary the size. + + int j; + unsigned char c0, c1, c2, c3; + unsigned char* p1 = DSP1.parameters; + unsigned char* p2a = DSP1.output; + unsigned char* p2b = &DSP1.output[16]; // halfway + + // Process 8 blocks of 4 bytes each + + for (j = 0; j < 8; j++) + { + c0 = *p1++; + c1 = *p1++; + c2 = *p1++; + c3 = *p1++; + + *p2a++ = (c0 & 0x10) << 3 | + (c0 & 0x01) << 6 | + (c1 & 0x10) << 1 | + (c1 & 0x01) << 4 | + (c2 & 0x10) >> 1 | + (c2 & 0x01) << 2 | + (c3 & 0x10) >> 3 | + (c3 & 0x01); + + *p2a++ = (c0 & 0x20) << 2 | + (c0 & 0x02) << 5 | + (c1 & 0x20) | + (c1 & 0x02) << 3 | + (c2 & 0x20) >> 2 | + (c2 & 0x02) << 1 | + (c3 & 0x20) >> 4 | + (c3 & 0x02) >> 1; + + *p2b++ = (c0 & 0x40) << 1 | + (c0 & 0x04) << 4 | + (c1 & 0x40) >> 1 | + (c1 & 0x04) << 2 | + (c2 & 0x40) >> 3 | + (c2 & 0x04) | + (c3 & 0x40) >> 5 | + (c3 & 0x04) >> 2; + + + *p2b++ = (c0 & 0x80) | + (c0 & 0x08) << 3 | + (c1 & 0x80) >> 2 | + (c1 & 0x08) << 1 | + (c2 & 0x80) >> 4 | + (c2 & 0x08) >> 1 | + (c3 & 0x80) >> 6 | + (c3 & 0x08) >> 3; + } + return; } -void DSP2_Op06 () +void DSP2_Op06() { - // Input: - // size - // bitmap + // Input: + // size + // bitmap - int i, j; + int i, j; - for ( i = 0, j = DSP2Op06Len - 1; i < DSP2Op06Len; i++, j-- ) - { - DSP1.output[j] = (DSP1.parameters[i] << 4) | (DSP1.parameters[i] >> 4); - } + for (i = 0, j = DSP2Op06Len - 1; i < DSP2Op06Len; i++, j--) + DSP1.output[j] = (DSP1.parameters[i] << 4) | (DSP1.parameters[i] >> 4); } -bool DSP2Op0DHasLen=false; -int DSP2Op0DOutLen=0; -int DSP2Op0DInLen=0; +bool DSP2Op0DHasLen = false; +int DSP2Op0DOutLen = 0; +int DSP2Op0DInLen = 0; #ifndef DSP2_BIT_ACCURRATE_CODE @@ -226,116 +224,116 @@ int DSP2Op0DInLen=0; void DSP2_Op0D() { - // Overload's algorithm - use this unless doing hardware testing - - // One note: the HW can do odd byte scaling but since we divide - // by two to get the count of bytes this won't work well for - // odd byte scaling (in any of the current algorithm implementations). - // So far I haven't seen Dungeon Master use it. - // If it does we can adjust the parameters and code to work with it - - int i; - int pixel_offset; - uint8 pixelarray[512]; - - for(i=0; i>1] >> 4; - else - pixelarray[i] = DSP1.parameters[pixel_offset>>1] & 0x0f; - } - - for ( i=0; i < DSP2Op0DOutLen; i++ ) - DSP1.output[i] = ( pixelarray[i<<1] << 4 ) | pixelarray[(i<<1)+1]; + // Overload's algorithm - use this unless doing hardware testing + + // One note: the HW can do odd byte scaling but since we divide + // by two to get the count of bytes this won't work well for + // odd byte scaling (in any of the current algorithm implementations). + // So far I haven't seen Dungeon Master use it. + // If it does we can adjust the parameters and code to work with it + + int i; + int pixel_offset; + uint8 pixelarray[512]; + + for (i = 0; i < DSP2Op0DOutLen * 2; i++) + { + pixel_offset = (i * DSP2Op0DInLen) / DSP2Op0DOutLen; + if ((pixel_offset & 1) == 0) + pixelarray[i] = DSP1.parameters[pixel_offset >> 1] >> 4; + else + pixelarray[i] = DSP1.parameters[pixel_offset >> 1] & 0x0f; + } + + for (i = 0; i < DSP2Op0DOutLen; i++) + DSP1.output[i] = (pixelarray[i << 1] << 4) | pixelarray[(i << 1) + 1]; } #else void DSP2_Op0D() { - // Bit accurate hardware algorithm - uses fixed point math - // This should match the DSP2 Op0D output exactly - // I wouldn't recommend using this unless you're doing hardware debug. - // In some situations it has small visual artifacts that - // are not readily apparent on a TV screen but show up clearly - // on a monitor. Use Overload's scaling instead. - // This is for hardware verification testing. - // - // One note: the HW can do odd byte scaling but since we divide - // by two to get the count of bytes this won't work well for - // odd byte scaling (in any of the current algorithm implementations). - // So far I haven't seen Dungeon Master use it. - // If it does we can adjust the parameters and code to work with it - - - uint32 multiplier; // Any size int >= 32-bits - uint32 pixloc; // match size of multiplier - int i, j; - uint8 pixelarray[512]; - - if (DSP2Op0DInLen <= DSP2Op0DOutLen) - multiplier = 0x10000; // In our self defined fixed point 0x10000 == 1 - else - multiplier = (DSP2Op0DInLen << 17) / ((DSP2Op0DOutLen<<1) + 1); - - pixloc = 0; - for ( i=0; i < DSP2Op0DOutLen * 2; i++ ) - { - j = pixloc >> 16; - - if ( j & 1 ) - pixelarray[i] = DSP1.parameters[j>>1] & 0x0f; - else - pixelarray[i] = (DSP1.parameters[j>>1] & 0xf0) >> 4; - - pixloc += multiplier; - } - - for ( i=0; i < DSP2Op0DOutLen; i++ ) - DSP1.output[i] = ( pixelarray[i<<1] << 4 ) | pixelarray[(i<<1)+1]; + // Bit accurate hardware algorithm - uses fixed point math + // This should match the DSP2 Op0D output exactly + // I wouldn't recommend using this unless you're doing hardware debug. + // In some situations it has small visual artifacts that + // are not readily apparent on a TV screen but show up clearly + // on a monitor. Use Overload's scaling instead. + // This is for hardware verification testing. + // + // One note: the HW can do odd byte scaling but since we divide + // by two to get the count of bytes this won't work well for + // odd byte scaling (in any of the current algorithm implementations). + // So far I haven't seen Dungeon Master use it. + // If it does we can adjust the parameters and code to work with it + + + uint32 multiplier; // Any size int >= 32-bits + uint32 pixloc; // match size of multiplier + int i, j; + uint8 pixelarray[512]; + + if (DSP2Op0DInLen <= DSP2Op0DOutLen) + multiplier = 0x10000; // In our self defined fixed point 0x10000 == 1 + else + multiplier = (DSP2Op0DInLen << 17) / ((DSP2Op0DOutLen << 1) + 1); + + pixloc = 0; + for (i = 0; i < DSP2Op0DOutLen * 2; i++) + { + j = pixloc >> 16; + + if (j & 1) + pixelarray[i] = DSP1.parameters[j >> 1] & 0x0f; + else + pixelarray[i] = (DSP1.parameters[j >> 1] & 0xf0) >> 4; + + pixloc += multiplier; + } + + for (i = 0; i < DSP2Op0DOutLen; i++) + DSP1.output[i] = (pixelarray[i << 1] << 4) | pixelarray[(i << 1) + 1]; } #endif -#if 0 // Probably no reason to use this code - it's not quite bit accurate and it doesn't look as good as Overload's algorithm +#if 0 // Probably no reason to use this code - it's not quite bit accurate and it doesn't look as good as Overload's algorithm void DSP2_Op0D() { - // Float implementation of Neviksti's algorithm - // This is the right algorithm to match the DSP2 bits but the precision - // of the PC float does not match the precision of the fixed point math - // on the DSP2 causing occasional one off data mismatches (which should - // be no problem because its just a one pixel difference in a scaled image - // to be displayed). - - float multiplier; - float pixloc; - int i, j; - uint8 pixelarray[512]; - - if (DSP2Op0DInLen <= DSP2Op0DOutLen) - multiplier = (float) 1.0; - else - multiplier = (float) ((DSP2Op0DInLen * 2.0) / (DSP2Op0DOutLen * 2.0 + 1.0)); - - pixloc = 0.0; - for ( i=0; i < DSP2Op0DOutLen * 2; i++ ) - { - // j = (int)(i * multiplier); - j = (int) pixloc; - - if ( j & 1 ) - pixelarray[i] = DSP1.parameters[j>>1] & 0x0f; - else - pixelarray[i] = (DSP1.parameters[j>>1] & 0xf0) >> 4; - - pixloc += multiplier; // use an add in the loop instead of multiply to increase loop speed - } - - for ( i=0; i < DSP2Op0DOutLen; i++ ) - DSP1.output[i] = ( pixelarray[i<<1] << 4 ) | pixelarray[(i<<1)+1]; + // Float implementation of Neviksti's algorithm + // This is the right algorithm to match the DSP2 bits but the precision + // of the PC float does not match the precision of the fixed point math + // on the DSP2 causing occasional one off data mismatches (which should + // be no problem because its just a one pixel difference in a scaled image + // to be displayed). + + float multiplier; + float pixloc; + int i, j; + uint8 pixelarray[512]; + + if (DSP2Op0DInLen <= DSP2Op0DOutLen) + multiplier = (float) 1.0; + else + multiplier = (float)((DSP2Op0DInLen * 2.0) / (DSP2Op0DOutLen * 2.0 + 1.0)); + + pixloc = 0.0; + for (i = 0; i < DSP2Op0DOutLen * 2; i++) + { + // j = (int)(i * multiplier); + j = (int) pixloc; + + if (j & 1) + pixelarray[i] = DSP1.parameters[j >> 1] & 0x0f; + else + pixelarray[i] = (DSP1.parameters[j >> 1] & 0xf0) >> 4; + + pixloc += multiplier; // use an add in the loop instead of multiply to increase loop speed + } + + for (i = 0; i < DSP2Op0DOutLen; i++) + DSP1.output[i] = (pixelarray[i << 1] << 4) | pixelarray[(i << 1) + 1]; } #endif diff --git a/source/dsp4.h b/source/dsp4.h index 2e7e711..a214db6 100644 --- a/source/dsp4.h +++ b/source/dsp4.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -91,84 +91,84 @@ #define _DSP4_H_ // debug -int block; // current block number +int block; // current block number extern int c; // op control -int8 DSP4_Logic; // controls op flow +int8 DSP4_Logic; // controls op flow // projection format -const int16 PLANE_START = 0x7fff; // starting distance +const int16 PLANE_START = 0x7fff; // starting distance -int16 view_plane; // viewer location -int16 far_plane; // next milestone into screen -int16 segments; // # raster segments to draw -int16 raster; // current raster line +int16 view_plane; // viewer location +int16 far_plane; // next milestone into screen +int16 segments; // # raster segments to draw +int16 raster; // current raster line -int16 project_x; // current x-position -int16 project_y; // current y-position +int16 project_x; // current x-position +int16 project_y; // current y-position -int16 project_centerx; // x-target of projection -int16 project_centery; // y-target of projection +int16 project_centerx; // x-target of projection +int16 project_centery; // y-target of projection -int16 project_x1; // current x-distance -int16 project_x1low; // lower 16-bits -int16 project_y1; // current y-distance -int16 project_y1low; // lower 16-bits +int16 project_x1; // current x-distance +int16 project_x1low; // lower 16-bits +int16 project_y1; // current y-distance +int16 project_y1low; // lower 16-bits -int16 project_x2; // next projected x-distance -int16 project_y2; // next projected y-distance +int16 project_x2; // next projected x-distance +int16 project_y2; // next projected y-distance -int16 project_pitchx; // delta center -int16 project_pitchxlow; // lower 16-bits -int16 project_pitchy; // delta center -int16 project_pitchylow; // lower 16-bits +int16 project_pitchx; // delta center +int16 project_pitchxlow; // lower 16-bits +int16 project_pitchy; // delta center +int16 project_pitchylow; // lower 16-bits -int16 project_focalx; // x-point of projection at viewer plane -int16 project_focaly; // y-point of projection at viewer plane +int16 project_focalx; // x-point of projection at viewer plane +int16 project_focaly; // y-point of projection at viewer plane -int16 project_ptr; // data structure pointer +int16 project_ptr; // data structure pointer // render window -int16 center_x; // x-center of viewport -int16 center_y; // y-center of viewport -int16 viewport_left; // x-left of viewport -int16 viewport_right; // x-right of viewport -int16 viewport_top; // y-top of viewport -int16 viewport_bottom; // y-bottom of viewport +int16 center_x; // x-center of viewport +int16 center_y; // y-center of viewport +int16 viewport_left; // x-left of viewport +int16 viewport_right; // x-right of viewport +int16 viewport_top; // y-top of viewport +int16 viewport_bottom; // y-bottom of viewport // sprite structure -int16 sprite_x; // projected x-pos of sprite -int16 sprite_y; // projected y-pos of sprite -int16 sprite_offset; // data pointer offset -int8 sprite_type; // vehicle, terrain -bool8 sprite_size; // sprite size: 8x8 or 16x16 +int16 sprite_x; // projected x-pos of sprite +int16 sprite_y; // projected y-pos of sprite +int16 sprite_offset; // data pointer offset +int8 sprite_type; // vehicle, terrain +bool8 sprite_size; // sprite size: 8x8 or 16x16 // path strips -int16 path_clipRight[4]; // value to clip to for x>b -int16 path_clipLeft[4]; // value to clip to for xb +int16 path_clipLeft[4]; // value to clip to for x> 2) & 0xf000) | ((B * 0x0155 >> 6) & 0x0f00) | - ((C * 0x0155 >> 10) & 0x00f0) | ((D * 0x0155 >> 14) & 0x000f); + ((C * 0x0155 >> 10) & 0x00f0) | ((D * 0x0155 >> 14) & 0x000f); } ////////////////////////////////////////////////////////////// @@ -119,17 +119,17 @@ short DSP4_UnknownOP11(short A, short B, short C, short D) void DSP4_Op06(bool8 size, bool8 msb) { - // save post-oam table data for future retrieval - op06_OAM[op06_index] |= (msb<<(op06_offset+0)); - op06_OAM[op06_index] |= (size<<(op06_offset+1)); - op06_offset += 2; - - if(op06_offset==8) - { - // move to next byte in buffer - op06_offset=0; - op06_index++; - } + // save post-oam table data for future retrieval + op06_OAM[op06_index] |= (msb << (op06_offset + 0)); + op06_OAM[op06_index] |= (size << (op06_offset + 1)); + op06_offset += 2; + + if (op06_offset == 8) + { + // move to next byte in buffer + op06_offset = 0; + op06_index++; + } } #if OP==0x0001 @@ -138,209 +138,217 @@ void DSP4_Op06(bool8 size, bool8 msb) void DSP4_Op01() { - uint16 command; - - DSP4.waiting4command = FALSE; - - // op flow control - switch(DSP4_Logic) { - case 1: goto resume1; break; - case 2: goto resume2; break; - } - - //////////////////////////////////////////////////// - // process initial inputs - - // sort inputs - // 0x00 = DSP4_READ_WORD(0x00); - project_focaly = DSP4_READ_WORD(0x02); - raster = DSP4_READ_WORD(0x04); - viewport_top = DSP4_READ_WORD(0x06); - project_y = DSP4_READ_WORD(0x08); - viewport_bottom = DSP4_READ_WORD(0x0a); - project_x1low = DSP4_READ_WORD(0x0c); - project_focalx = DSP4_READ_WORD(0x0e); - project_centerx = DSP4_READ_WORD(0x10); - project_ptr = DSP4_READ_WORD(0x12); - // (envelope?) 0xc0 = DSP4_READ_WORD(0x14); - project_pitchylow = DSP4_READ_WORD(0x16); - project_pitchy = DSP4_READ_WORD(0x18); - project_pitchxlow = DSP4_READ_WORD(0x1a); - project_pitchx = DSP4_READ_WORD(0x1c); - far_plane = DSP4_READ_WORD(0x1e); - // ? = DSP4_READ_WORD(0x20); - project_y1low = DSP4_READ_WORD(0x22); - - // pre-compute - view_plane = PLANE_START; - - // find starting projection points - project_x1 = project_focalx; - project_y -= viewport_bottom; - project_x = project_centerx + project_x1; - - // multi-op storage - multi_index1 = 0; - multi_index2 = 0; - - // debug - block=0; - - //////////////////////////////////////////////////// - // command check - - do { - // scan next command - DSP4.in_count = 2; - - DSP4_WAIT(1) resume1: - - // inspect input - command = DSP4_READ_WORD(0); - - // check for termination - if(command == 0x8000) break; - - // already have 2 bytes in queue - DSP4.in_index = 2; - DSP4.in_count = 8; + uint16 command; + + DSP4.waiting4command = FALSE; + + // op flow control + switch (DSP4_Logic) + { + case 1: + goto resume1; + break; + case 2: + goto resume2; + break; + } + + //////////////////////////////////////////////////// + // process initial inputs + + // sort inputs + // 0x00 = DSP4_READ_WORD(0x00); + project_focaly = DSP4_READ_WORD(0x02); + raster = DSP4_READ_WORD(0x04); + viewport_top = DSP4_READ_WORD(0x06); + project_y = DSP4_READ_WORD(0x08); + viewport_bottom = DSP4_READ_WORD(0x0a); + project_x1low = DSP4_READ_WORD(0x0c); + project_focalx = DSP4_READ_WORD(0x0e); + project_centerx = DSP4_READ_WORD(0x10); + project_ptr = DSP4_READ_WORD(0x12); + // (envelope?) 0xc0 = DSP4_READ_WORD(0x14); + project_pitchylow = DSP4_READ_WORD(0x16); + project_pitchy = DSP4_READ_WORD(0x18); + project_pitchxlow = DSP4_READ_WORD(0x1a); + project_pitchx = DSP4_READ_WORD(0x1c); + far_plane = DSP4_READ_WORD(0x1e); + // ? = DSP4_READ_WORD(0x20); + project_y1low = DSP4_READ_WORD(0x22); + + // pre-compute + view_plane = PLANE_START; + + // find starting projection points + project_x1 = project_focalx; + project_y -= viewport_bottom; + project_x = project_centerx + project_x1; + + // multi-op storage + multi_index1 = 0; + multi_index2 = 0; + + // debug + block = 0; + + //////////////////////////////////////////////////// + // command check + + do + { + // scan next command + DSP4.in_count = 2; + +DSP4_WAIT(1) resume1: + + // inspect input + command = DSP4_READ_WORD(0); + + // check for termination + if (command == 0x8000) break; + + // already have 2 bytes in queue + DSP4.in_index = 2; + DSP4.in_count = 8; DSP4_WAIT(2) //////////////////////////////////////////////////// - // process one iteration of projection + // process one iteration of projection - // inspect inputs + // inspect inputs int16 plane; - int16 index, lcv; + int16 index, lcv; int16 py_dy, px_dx; - int16 y_out, x_out; + int16 y_out, x_out; - resume2: +resume2: plane = DSP4_READ_WORD(0); - py_dy=0; - px_dx=0; - - // ignore invalid data - if((uint16) plane == 0x8001) continue; - - // one-time init - if(far_plane) - { - // setup final parameters - project_focalx += plane; - project_x1 = project_focalx; - project_y1 = project_focaly; - plane = far_plane; - far_plane = 0; - } - - // use proportional triangles to project new coords - project_x2 = project_focalx * plane / view_plane; - project_y2 = project_focaly * plane / view_plane; - - // quadratic regression (rough) - if(project_focaly>=-0x0f) - py_dy = (short) (project_focaly * project_focaly * -0.20533553 - - 1.08330005 * project_focaly - 69.61094639); - else - py_dy = (short) (project_focaly * project_focaly * -0.000657035759 - - 1.07629051 * project_focaly - 65.69315963); - - // approximate # of raster lines - segments = abs(project_y2-project_y1); - - // prevent overdraw - if(project_y2>=raster) segments=0; - else raster=project_y2; - - // don't draw outside the window - if(project_y20) - { - // interpolate between projected points - px_dx = ((project_x2-project_x1)<<8)/segments; - } - - // debug - ++block; + py_dy = 0; + px_dx = 0; + + // ignore invalid data + if ((uint16) plane == 0x8001) continue; + + // one-time init + if (far_plane) + { + // setup final parameters + project_focalx += plane; + project_x1 = project_focalx; + project_y1 = project_focaly; + plane = far_plane; + far_plane = 0; + } + + // use proportional triangles to project new coords + project_x2 = project_focalx * plane / view_plane; + project_y2 = project_focaly * plane / view_plane; + + // quadratic regression (rough) + if (project_focaly >= -0x0f) + py_dy = (short)(project_focaly * project_focaly * -0.20533553 + - 1.08330005 * project_focaly - 69.61094639); + else + py_dy = (short)(project_focaly * project_focaly * -0.000657035759 + - 1.07629051 * project_focaly - 65.69315963); + + // approximate # of raster lines + segments = abs(project_y2 - project_y1); + + // prevent overdraw + if (project_y2 >= raster) segments = 0; + else raster = project_y2; + + // don't draw outside the window + if (project_y2 < viewport_top) segments = 0; + + // project new positions + if (segments > 0) + { + // interpolate between projected points + px_dx = ((project_x2 - project_x1) << 8) / segments; + } + + // debug + ++block; #ifdef PRINT - printf("(line %d) Op01 check %02X, plane %04X, focal_y %04X, y2 %04X\n",c,(uint16)segments,(uint16)(plane),(uint16)project_focaly,(uint16)project_y2); + printf("(line %d) Op01 check %02X, plane %04X, focal_y %04X, y2 %04X\n", c, + (uint16)segments, (uint16)(plane), (uint16)project_focaly, (uint16)project_y2); #endif - // prepare output - DSP4.out_count=8+2+6*segments; + // prepare output + DSP4.out_count = 8 + 2 + 6 * segments; + + // pre-block data + DSP4_WRITE_WORD(0, project_focalx); + DSP4_WRITE_WORD(2, project_x2); + DSP4_WRITE_WORD(4, project_focaly); + DSP4_WRITE_WORD(6, project_y2); + DSP4_WRITE_WORD(8, segments); - // pre-block data - DSP4_WRITE_WORD(0,project_focalx); - DSP4_WRITE_WORD(2,project_x2); - DSP4_WRITE_WORD(4,project_focaly); - DSP4_WRITE_WORD(6,project_y2); - DSP4_WRITE_WORD(8,segments); - #if 0 - DSP4_WRITE_WORD(0,-1); - DSP4_WRITE_WORD(2,-1); - DSP4_WRITE_WORD(4,-1); - DSP4_WRITE_WORD(6,-1); - DSP4_WRITE_WORD(8,-1); + DSP4_WRITE_WORD(0, -1); + DSP4_WRITE_WORD(2, -1); + DSP4_WRITE_WORD(4, -1); + DSP4_WRITE_WORD(6, -1); + DSP4_WRITE_WORD(8, -1); #endif - index=10; + index = 10; - // iterate through each point - for( lcv=0; lcv>8); - x_out = project_x+((px_dx*lcv)>>8); + // iterate through each point + for (lcv = 0; lcv < segments; lcv++) + { + // step through the projected line + y_out = project_y + ((py_dy * lcv) >> 8); + x_out = project_x + ((px_dx * lcv) >> 8); #if 0 - project_ptr=-1; - y_out=-1; - x_out=-1; + project_ptr = -1; + y_out = -1; + x_out = -1; #endif - // data - DSP4_WRITE_WORD(index+0,project_ptr); - DSP4_WRITE_WORD(index+2,y_out); - DSP4_WRITE_WORD(index+4,x_out); - index += 6; - - // post-update - project_ptr -= 4; - } - - // post-update - project_y += ((py_dy*lcv)>>8); - project_x += ((px_dx*lcv)>>8); - - // new positions - if(segments>0) - { - project_x1 = project_x2; - project_y1 = project_y2; - - // multi-op storage - multi_focaly[multi_index2++] = project_focaly; - multi_farplane[1] = plane; - multi_raster[1] = project_y1-1; - } - - // update projection points - project_pitchy += (int8)DSP4.parameters[3]; - project_pitchx += (int8)DSP4.parameters[5]; - - project_focaly += project_pitchy; - project_focalx += project_pitchx; - } while (1); - - // terminate op - DSP4.waiting4command = TRUE; - DSP4.out_count = 0; + // data + DSP4_WRITE_WORD(index + 0, project_ptr); + DSP4_WRITE_WORD(index + 2, y_out); + DSP4_WRITE_WORD(index + 4, x_out); + index += 6; + + // post-update + project_ptr -= 4; + } + + // post-update + project_y += ((py_dy * lcv) >> 8); + project_x += ((px_dx * lcv) >> 8); + + // new positions + if (segments > 0) + { + project_x1 = project_x2; + project_y1 = project_y2; + + // multi-op storage + multi_focaly[multi_index2++] = project_focaly; + multi_farplane[1] = plane; + multi_raster[1] = project_y1 - 1; + } + + // update projection points + project_pitchy += (int8)DSP4.parameters[3]; + project_pitchx += (int8)DSP4.parameters[5]; + + project_focaly += project_pitchy; + project_focalx += project_pitchx; + } + while (1); + + // terminate op + DSP4.waiting4command = TRUE; + DSP4.out_count = 0; } #undef PRINT @@ -351,179 +359,187 @@ void DSP4_Op01() void DSP4_Op07() { - uint16 command; - - DSP4.waiting4command = FALSE; - - // op flow control - switch(DSP4_Logic) { - case 1: goto resume1; break; - case 2: goto resume2; break; - } - - //////////////////////////////////////////////////// - // sort inputs - - // 0x00 = DSP4_READ_WORD(0x00); - project_focaly = DSP4_READ_WORD(0x02); - raster = DSP4_READ_WORD(0x04); - viewport_top = DSP4_READ_WORD(0x06); - project_y = DSP4_READ_WORD(0x08); - viewport_bottom = DSP4_READ_WORD(0x0a); - project_x1low = DSP4_READ_WORD(0x0c); - project_x1 = DSP4_READ_WORD(0x0e); - project_centerx = DSP4_READ_WORD(0x10); - project_ptr = DSP4_READ_WORD(0x12); - // (envelope?) 0xc0 = DSP4_READ_WORD(0x14); - - // pre-compute - view_plane = PLANE_START; - - // find projection targets - project_y1 = project_focaly; - project_y -= viewport_bottom; - project_x = project_centerx + project_x1; - - // multi-op storage - multi_index2 = 0; - - // debug - block=0; + uint16 command; + + DSP4.waiting4command = FALSE; + + // op flow control + switch (DSP4_Logic) + { + case 1: + goto resume1; + break; + case 2: + goto resume2; + break; + } + + //////////////////////////////////////////////////// + // sort inputs + + // 0x00 = DSP4_READ_WORD(0x00); + project_focaly = DSP4_READ_WORD(0x02); + raster = DSP4_READ_WORD(0x04); + viewport_top = DSP4_READ_WORD(0x06); + project_y = DSP4_READ_WORD(0x08); + viewport_bottom = DSP4_READ_WORD(0x0a); + project_x1low = DSP4_READ_WORD(0x0c); + project_x1 = DSP4_READ_WORD(0x0e); + project_centerx = DSP4_READ_WORD(0x10); + project_ptr = DSP4_READ_WORD(0x12); + // (envelope?) 0xc0 = DSP4_READ_WORD(0x14); + + // pre-compute + view_plane = PLANE_START; + + // find projection targets + project_y1 = project_focaly; + project_y -= viewport_bottom; + project_x = project_centerx + project_x1; + + // multi-op storage + multi_index2 = 0; + + // debug + block = 0; #ifdef PRINT - printf("(line %d) Op07 data %04X\n",c,(uint16)project_y1); + printf("(line %d) Op07 data %04X\n", c, (uint16)project_y1); #endif - //////////////////////////////////////////////////// - // command check + //////////////////////////////////////////////////// + // command check - do { - // scan next command - DSP4.in_count = 2; + do + { + // scan next command + DSP4.in_count = 2; - DSP4_WAIT(1) resume1: +DSP4_WAIT(1) resume1: - // inspect input - command = DSP4_READ_WORD(0); + // inspect input + command = DSP4_READ_WORD(0); - // check for opcode termination - if(command == 0x8000) break; + // check for opcode termination + if (command == 0x8000) break; - // already have 2 bytes in queue - DSP4.in_index = 2; - DSP4.in_count = 12; + // already have 2 bytes in queue + DSP4.in_index = 2; + DSP4.in_count = 12; DSP4_WAIT(2) - //////////////////////////////////////////////////// - // process one loop of projection + //////////////////////////////////////////////////// + // process one loop of projection - int16 plane; - int16 index,lcv; - int16 y_out,x_out; - int16 py_dy,px_dx; + int16 plane; + int16 index, lcv; + int16 y_out, x_out; + int16 py_dy, px_dx; - resume2: - py_dy=0; - px_dx=0; +resume2: + py_dy = 0; + px_dx = 0; - // debug - ++block; + // debug + ++block; - // inspect inputs - plane = DSP4_READ_WORD(0); - project_y2 = DSP4_READ_WORD(2); - // ? = DSP4_READ_WORD(4); - project_x2 = DSP4_READ_WORD(6); + // inspect inputs + plane = DSP4_READ_WORD(0); + project_y2 = DSP4_READ_WORD(2); + // ? = DSP4_READ_WORD(4); + project_x2 = DSP4_READ_WORD(6); - // ignore invalid data - if((uint16) plane == 0x8001) continue; + // ignore invalid data + if ((uint16) plane == 0x8001) continue; - // multi-op storage - project_focaly = multi_focaly[multi_index2]; + // multi-op storage + project_focaly = multi_focaly[multi_index2]; - // quadratic regression (rough) - if(project_focaly>=-0x0f) - py_dy = (short) (project_focaly * project_focaly * -0.20533553 - - 1.08330005 * project_focaly - 69.61094639); - else - py_dy = (short) (project_focaly * project_focaly * -0.000657035759 - - 1.07629051 * project_focaly - 65.69315963); + // quadratic regression (rough) + if (project_focaly >= -0x0f) + py_dy = (short)(project_focaly * project_focaly * -0.20533553 + - 1.08330005 * project_focaly - 69.61094639); + else + py_dy = (short)(project_focaly * project_focaly * -0.000657035759 + - 1.07629051 * project_focaly - 65.69315963); - // approximate # of raster lines - segments = abs(project_y2-project_y1); + // approximate # of raster lines + segments = abs(project_y2 - project_y1); - // prevent overdraw - if(project_y2>=raster) segments=0; - else raster=project_y2; + // prevent overdraw + if (project_y2 >= raster) segments = 0; + else raster = project_y2; - // don't draw outside the window - if(project_y20) - { - // interpolate between projected points - px_dx = ((project_x2-project_x1)<<8)/segments; - } + // project new positions + if (segments > 0) + { + // interpolate between projected points + px_dx = ((project_x2 - project_x1) << 8) / segments; + } #ifdef PRINT - printf("(line %d) Op07 block %d, loc %04X, out %02X, project_x2 %04X\n",c,block,plane,segments,(uint16)project_x2); + printf("(line %d) Op07 block %d, loc %04X, out %02X, project_x2 %04X\n", c, + block, plane, segments, (uint16)project_x2); #endif - // prepare pre-output - DSP4.out_count=4+2+6*segments; + // prepare pre-output + DSP4.out_count = 4 + 2 + 6 * segments; - DSP4_WRITE_WORD(0,project_x2); - DSP4_WRITE_WORD(2,project_y2); - DSP4_WRITE_WORD(4,segments); + DSP4_WRITE_WORD(0, project_x2); + DSP4_WRITE_WORD(2, project_y2); + DSP4_WRITE_WORD(4, segments); #if 0 - DSP4_WRITE_WORD(0,-1); - DSP4_WRITE_WORD(2,-1); - DSP4_WRITE_WORD(4,-1); + DSP4_WRITE_WORD(0, -1); + DSP4_WRITE_WORD(2, -1); + DSP4_WRITE_WORD(4, -1); #endif - index=6; - for( lcv=0; lcv>8); - x_out = project_x+((px_dx*lcv)>>8); + index = 6; + for (lcv = 0; lcv < segments; lcv++) + { + // pre-compute + y_out = project_y + ((py_dy * lcv) >> 8); + x_out = project_x + ((px_dx * lcv) >> 8); #if 0 - project_ptr = -1; - //y_out = -1; - x_out = -1; + project_ptr = -1; + //y_out = -1; + x_out = -1; #endif - // data - DSP4_WRITE_WORD(index+0,project_ptr); - DSP4_WRITE_WORD(index+2,y_out); - DSP4_WRITE_WORD(index+4,x_out); - index += 6; - - // post-update - project_ptr -= 4; - } - - // update internal variables - project_y += ((py_dy*lcv)>>8); - project_x += ((px_dx*lcv)>>8); - - // new positions - if(segments>0) - { - project_x1 = project_x2; - project_y1 = project_y2; - - // multi-op storage - multi_index2++; - } - } while(1); - - DSP4.waiting4command = TRUE; - DSP4.out_count = 0; + // data + DSP4_WRITE_WORD(index + 0, project_ptr); + DSP4_WRITE_WORD(index + 2, y_out); + DSP4_WRITE_WORD(index + 4, x_out); + index += 6; + + // post-update + project_ptr -= 4; + } + + // update internal variables + project_y += ((py_dy * lcv) >> 8); + project_x += ((px_dx * lcv) >> 8); + + // new positions + if (segments > 0) + { + project_x1 = project_x2; + project_y1 = project_y2; + + // multi-op storage + multi_index2++; + } + } + while (1); + + DSP4.waiting4command = TRUE; + DSP4.out_count = 0; } #undef PRINT @@ -534,346 +550,358 @@ void DSP4_Op07() void DSP4_Op08() { - uint16 command; + uint16 command; + + DSP4.waiting4command = FALSE; - DSP4.waiting4command = FALSE; + // op flow control + switch (DSP4_Logic) + { + case 1: + goto resume1; + break; + case 2: + goto resume2; + break; + } - // op flow control - switch(DSP4_Logic) { - case 1: goto resume1; break; - case 2: goto resume2; break; - } + //////////////////////////////////////////////////// + // process initial inputs - //////////////////////////////////////////////////// - // process initial inputs + // clip values + path_clipRight[0] = DSP4_READ_WORD(0x00); + path_clipRight[1] = DSP4_READ_WORD(0x02); + path_clipRight[2] = DSP4_READ_WORD(0x04); + path_clipRight[3] = DSP4_READ_WORD(0x06); - // clip values - path_clipRight[0] = DSP4_READ_WORD(0x00); - path_clipRight[1] = DSP4_READ_WORD(0x02); - path_clipRight[2] = DSP4_READ_WORD(0x04); - path_clipRight[3] = DSP4_READ_WORD(0x06); + path_clipLeft[0] = DSP4_READ_WORD(0x08); + path_clipLeft[1] = DSP4_READ_WORD(0x0a); + path_clipLeft[2] = DSP4_READ_WORD(0x0c); + path_clipLeft[3] = DSP4_READ_WORD(0x0e); - path_clipLeft[0] = DSP4_READ_WORD(0x08); - path_clipLeft[1] = DSP4_READ_WORD(0x0a); - path_clipLeft[2] = DSP4_READ_WORD(0x0c); - path_clipLeft[3] = DSP4_READ_WORD(0x0e); + // unknown (constant) + // unknown (constant) - // unknown (constant) - // unknown (constant) + // path positions + path_pos[0] = DSP4_READ_WORD(0x20); + path_pos[1] = DSP4_READ_WORD(0x22); + path_pos[2] = DSP4_READ_WORD(0x24); + path_pos[3] = DSP4_READ_WORD(0x26); - // path positions - path_pos[0] = DSP4_READ_WORD(0x20); - path_pos[1] = DSP4_READ_WORD(0x22); - path_pos[2] = DSP4_READ_WORD(0x24); - path_pos[3] = DSP4_READ_WORD(0x26); + // data locations + path_ptr[0] = DSP4_READ_WORD(0x28); + path_ptr[1] = DSP4_READ_WORD(0x2a); + path_ptr[2] = DSP4_READ_WORD(0x2c); + path_ptr[3] = DSP4_READ_WORD(0x2e); - // data locations - path_ptr[0] = DSP4_READ_WORD(0x28); - path_ptr[1] = DSP4_READ_WORD(0x2a); - path_ptr[2] = DSP4_READ_WORD(0x2c); - path_ptr[3] = DSP4_READ_WORD(0x2e); + // project_y1 lines + path_raster[0] = DSP4_READ_WORD(0x30); + path_raster[1] = DSP4_READ_WORD(0x32); + path_raster[2] = DSP4_READ_WORD(0x34); + path_raster[3] = DSP4_READ_WORD(0x36); - // project_y1 lines - path_raster[0] = DSP4_READ_WORD(0x30); - path_raster[1] = DSP4_READ_WORD(0x32); - path_raster[2] = DSP4_READ_WORD(0x34); - path_raster[3] = DSP4_READ_WORD(0x36); + // viewport_top + path_top[0] = DSP4_READ_WORD(0x38); + path_top[1] = DSP4_READ_WORD(0x3a); + path_top[2] = DSP4_READ_WORD(0x3c); + path_top[3] = DSP4_READ_WORD(0x3e); - // viewport_top - path_top[0] = DSP4_READ_WORD(0x38); - path_top[1] = DSP4_READ_WORD(0x3a); - path_top[2] = DSP4_READ_WORD(0x3c); - path_top[3] = DSP4_READ_WORD(0x3e); + // unknown (constants) - // unknown (constants) + view_plane = PLANE_START; - view_plane = PLANE_START; + // debug + block = 0; - // debug - block=0; + //////////////////////////////////////////////////// + // command check - //////////////////////////////////////////////////// - // command check + do + { + // scan next command + DSP4.in_count = 2; - do { - // scan next command - DSP4.in_count = 2; +DSP4_WAIT(1) resume1: - DSP4_WAIT(1) resume1: - - // inspect input - command = DSP4_READ_WORD(0); + // inspect input + command = DSP4_READ_WORD(0); - // terminate op - if(command == 0x8000) break; + // terminate op + if (command == 0x8000) break; - // already have 2 bytes in queue - DSP4.in_index = 2; - DSP4.in_count = 18; + // already have 2 bytes in queue + DSP4.in_index = 2; + DSP4.in_count = 18; - DSP4_WAIT(2) resume2: +DSP4_WAIT(2) resume2: - //////////////////////////////////////////////////// - // projection begins + //////////////////////////////////////////////////// + // projection begins - // debug - ++block; + // debug + ++block; - // used in envelope shaping - int16 x1_final; - int16 x2_final; + // used in envelope shaping + int16 x1_final; + int16 x2_final; - // look at guidelines - int16 plane = DSP4_READ_WORD(0x00); - int16 x_left = DSP4_READ_WORD(0x02); - int16 y_left = DSP4_READ_WORD(0x04); - int16 x_right = DSP4_READ_WORD(0x06); - int16 y_right = DSP4_READ_WORD(0x08); + // look at guidelines + int16 plane = DSP4_READ_WORD(0x00); + int16 x_left = DSP4_READ_WORD(0x02); + int16 y_left = DSP4_READ_WORD(0x04); + int16 x_right = DSP4_READ_WORD(0x06); + int16 y_right = DSP4_READ_WORD(0x08); - // envelope guidelines (one frame only) - int16 envelope1 = DSP4_READ_WORD(0x0a); - int16 envelope2 = DSP4_READ_WORD(0x0c); + // envelope guidelines (one frame only) + int16 envelope1 = DSP4_READ_WORD(0x0a); + int16 envelope2 = DSP4_READ_WORD(0x0c); - // ignore invalid data - if((uint16) plane == 0x8001) continue; - - // first init - if(plane == 0x7fff) - { - int pos1,pos2; + // ignore invalid data + if ((uint16) plane == 0x8001) continue; - // initialize projection - path_x[0] = x_left; - path_x[1] = x_right; + // first init + if (plane == 0x7fff) + { + int pos1, pos2; - path_y[0] = y_left; - path_y[1] = y_right; - - // update coordinates - path_pos[0]-=x_left; - path_pos[1]-=x_left; - path_pos[2]-=x_right; - path_pos[3]-=x_right; + // initialize projection + path_x[0] = x_left; + path_x[1] = x_right; - pos1 = path_pos[0]+envelope1; - pos2 = path_pos[1]+envelope2; + path_y[0] = y_left; + path_y[1] = y_right; - // clip offscreen data - if(pos1path_clipRight[0]) pos1 = path_clipRight[0]; - if(pos2path_clipRight[1]) pos2 = path_clipRight[1]; + // update coordinates + path_pos[0] -= x_left; + path_pos[1] -= x_left; + path_pos[2] -= x_right; + path_pos[3] -= x_right; + + pos1 = path_pos[0] + envelope1; + pos2 = path_pos[1] + envelope2; + + // clip offscreen data + if (pos1 < path_clipLeft[0]) pos1 = path_clipLeft[0]; + if (pos1 > path_clipRight[0]) pos1 = path_clipRight[0]; + if (pos2 < path_clipLeft[1]) pos2 = path_clipLeft[1]; + if (pos2 > path_clipRight[1]) pos2 = path_clipRight[1]; #if 0 - pos1=-1; - //pos2=-1; + pos1 = -1; + //pos2=-1; #endif - path_plane[0] = plane; - path_plane[1] = plane; + path_plane[0] = plane; + path_plane[1] = plane; - // initial output - DSP4.out_count = 2; - DSP4.output[0]=pos1&0xFF; - DSP4.output[1]=pos2&0xFF; + // initial output + DSP4.out_count = 2; + DSP4.output[0] = pos1 & 0xFF; + DSP4.output[1] = pos2 & 0xFF; #ifdef PRINT - printf("(line %d) Op08 x_left %04X\n",c,(uint16)x_left); + printf("(line %d) Op08 x_left %04X\n", c, (uint16)x_left); #endif - } - // proceed with projection - else - { - int16 index=0, lcv; - int16 left_inc=0,right_inc=0; - int16 dx1=0,dx2=0,dx3,dx4; + } + // proceed with projection + else + { + int16 index = 0, lcv; + int16 left_inc = 0, right_inc = 0; + int16 dx1 = 0, dx2 = 0, dx3, dx4; - // # segments to traverse - segments = abs(y_left - path_y[0]); + // # segments to traverse + segments = abs(y_left - path_y[0]); - // prevent overdraw - if(y_left>=path_raster[0]) segments=0; - else path_raster[0]=y_left; + // prevent overdraw + if (y_left >= path_raster[0]) segments = 0; + else path_raster[0] = y_left; - // don't draw outside the window - if(path_raster[0]0) - { - // use previous data - dx1 = (envelope1 * path_plane[0] / view_plane); - dx2 = (envelope2 * path_plane[0] / view_plane); + // proceed if visibility rules apply + if (segments > 0) + { + // use previous data + dx1 = (envelope1 * path_plane[0] / view_plane); + dx2 = (envelope2 * path_plane[0] / view_plane); - // use temporary envelope pitch (this frame only) - dx3 = (envelope1 * plane / view_plane); - dx4 = (envelope2 * plane / view_plane); + // use temporary envelope pitch (this frame only) + dx3 = (envelope1 * plane / view_plane); + dx4 = (envelope2 * plane / view_plane); - // project new shapes (left side) - x1_final = x_left+dx1; - x2_final = path_x[0]+dx3; + // project new shapes (left side) + x1_final = x_left + dx1; + x2_final = path_x[0] + dx3; - // interpolate between projected points with shaping - left_inc = ((x2_final-x1_final)<<8)/segments; + // interpolate between projected points with shaping + left_inc = ((x2_final - x1_final) << 8) / segments; - // project new shapes (right side) - x1_final = x_left+dx2; - x2_final = path_x[0]+dx4; + // project new shapes (right side) + x1_final = x_left + dx2; + x2_final = path_x[0] + dx4; - // interpolate between projected points with shaping - right_inc = ((x2_final-x1_final)<<8)/segments; + // interpolate between projected points with shaping + right_inc = ((x2_final - x1_final) << 8) / segments; - path_plane[0] = plane; - } + path_plane[0] = plane; + } #ifdef PRINT - printf("(line %d) Op08 block %d, out %02X, raster %02X\n",c,block,segments,(uint16)y_left); + printf("(line %d) Op08 block %d, out %02X, raster %02X\n", c, block, segments, + (uint16)y_left); #endif - // zone 1 - DSP4.out_count = (2+4*segments); - DSP4_WRITE_WORD(index,segments); index+=2; + // zone 1 + DSP4.out_count = (2 + 4 * segments); + DSP4_WRITE_WORD(index, segments); + index += 2; - for( lcv=1; lcv<=segments; lcv++ ) - { - int16 pos1,pos2; + for (lcv = 1; lcv <= segments; lcv++) + { + int16 pos1, pos2; - // pre-compute - pos1 = path_pos[0]+((left_inc*lcv)>>8)+dx1; - pos2 = path_pos[1]+((right_inc*lcv)>>8)+dx2; + // pre-compute + pos1 = path_pos[0] + ((left_inc * lcv) >> 8) + dx1; + pos2 = path_pos[1] + ((right_inc * lcv) >> 8) + dx2; - // clip offscreen data - if(pos1path_clipRight[0]) pos1 = path_clipRight[0]; - if(pos2path_clipRight[1]) pos2 = path_clipRight[1]; + // clip offscreen data + if (pos1 < path_clipLeft[0]) pos1 = path_clipLeft[0]; + if (pos1 > path_clipRight[0]) pos1 = path_clipRight[0]; + if (pos2 < path_clipLeft[1]) pos2 = path_clipLeft[1]; + if (pos2 > path_clipRight[1]) pos2 = path_clipRight[1]; #if 0 - if(pos1==0x00ff) pos1=0; - if(pos2==0x00ff) pos2=0; - path_ptr[0] = -1; - pos1 = -1; - pos2 = -1; + if (pos1 == 0x00ff) pos1 = 0; + if (pos2 == 0x00ff) pos2 = 0; + path_ptr[0] = -1; + pos1 = -1; + pos2 = -1; #endif - // data - DSP4_WRITE_WORD(index,path_ptr[0]); index+=2; - DSP4.output[index++]=pos1&0xFF; - DSP4.output[index++]=pos2&0xFF; - - // post-update - path_ptr[0] -= 4; - path_ptr[1] -= 4; - } - lcv--; - - if(segments>0) - { - // project points w/out the envelopes - int16 inc = ((path_x[0]-x_left)<<8)/segments; - - // post-store - path_pos[0] += ((inc*lcv)>>8); - path_pos[1] += ((inc*lcv)>>8); - - path_x[0] = x_left; - path_y[0] = y_left; - } - - ////////////////////////////////////////////// - // zone 2 - segments = abs(y_right - path_y[1]); - - // prevent overdraw - if(y_right>=path_raster[2]) segments=0; - else path_raster[2]=y_right; - - // don't draw outside the window - if(path_raster[2]0) - { - // use previous data - dx1 = (envelope1 * path_plane[1] / view_plane); - dx2 = (envelope2 * path_plane[1] / view_plane); - - // use temporary envelope pitch (this frame only) - dx3 = (envelope1 * plane / view_plane); - dx4 = (envelope2 * plane / view_plane); - - // project new shapes (left side) - x1_final = x_left+dx1; - x2_final = path_x[1]+dx3; - - // interpolate between projected points with shaping - left_inc = ((x2_final-x1_final)<<8)/segments; - - // project new shapes (right side) - x1_final = x_left+dx2; - x2_final = path_x[1]+dx4; - - // interpolate between projected points with shaping - right_inc = ((x2_final-x1_final)<<8)/segments; - - path_plane[1] = plane; - } - - // write out results - DSP4.out_count += (2+4*segments); - DSP4_WRITE_WORD(index,segments); index+=2; - - for( lcv=1; lcv<=segments; lcv++ ) - { - int16 pos1,pos2; - - // pre-compute - pos1 = path_pos[2]+((left_inc*lcv)>>8)+dx1; - pos2 = path_pos[3]+((right_inc*lcv)>>8)+dx2; - - // clip offscreen data - if(pos1path_clipRight[2]) pos1 = path_clipRight[2]; - if(pos2path_clipRight[3]) pos2 = path_clipRight[3]; + // data + DSP4_WRITE_WORD(index, path_ptr[0]); + index += 2; + DSP4.output[index++] = pos1 & 0xFF; + DSP4.output[index++] = pos2 & 0xFF; + + // post-update + path_ptr[0] -= 4; + path_ptr[1] -= 4; + } + lcv--; + + if (segments > 0) + { + // project points w/out the envelopes + int16 inc = ((path_x[0] - x_left) << 8) / segments; + + // post-store + path_pos[0] += ((inc * lcv) >> 8); + path_pos[1] += ((inc * lcv) >> 8); + + path_x[0] = x_left; + path_y[0] = y_left; + } + + ////////////////////////////////////////////// + // zone 2 + segments = abs(y_right - path_y[1]); + + // prevent overdraw + if (y_right >= path_raster[2]) segments = 0; + else path_raster[2] = y_right; + + // don't draw outside the window + if (path_raster[2] < path_top[2]) segments = 0; + + // proceed if visibility rules apply + if (segments > 0) + { + // use previous data + dx1 = (envelope1 * path_plane[1] / view_plane); + dx2 = (envelope2 * path_plane[1] / view_plane); + + // use temporary envelope pitch (this frame only) + dx3 = (envelope1 * plane / view_plane); + dx4 = (envelope2 * plane / view_plane); + + // project new shapes (left side) + x1_final = x_left + dx1; + x2_final = path_x[1] + dx3; + + // interpolate between projected points with shaping + left_inc = ((x2_final - x1_final) << 8) / segments; + + // project new shapes (right side) + x1_final = x_left + dx2; + x2_final = path_x[1] + dx4; + + // interpolate between projected points with shaping + right_inc = ((x2_final - x1_final) << 8) / segments; + + path_plane[1] = plane; + } + + // write out results + DSP4.out_count += (2 + 4 * segments); + DSP4_WRITE_WORD(index, segments); + index += 2; + + for (lcv = 1; lcv <= segments; lcv++) + { + int16 pos1, pos2; + + // pre-compute + pos1 = path_pos[2] + ((left_inc * lcv) >> 8) + dx1; + pos2 = path_pos[3] + ((right_inc * lcv) >> 8) + dx2; + + // clip offscreen data + if (pos1 < path_clipLeft[2]) pos1 = path_clipLeft[2]; + if (pos1 > path_clipRight[2]) pos1 = path_clipRight[2]; + if (pos2 < path_clipLeft[3]) pos2 = path_clipLeft[3]; + if (pos2 > path_clipRight[3]) pos2 = path_clipRight[3]; #if 0 - if(pos1==0x00ff) pos1=0; - if(pos2==0x00ff) pos2=0; - path_ptr[2] = -1; - //pos1 = -1; - pos2 = -1; + if (pos1 == 0x00ff) pos1 = 0; + if (pos2 == 0x00ff) pos2 = 0; + path_ptr[2] = -1; + //pos1 = -1; + pos2 = -1; #endif - // data - DSP4_WRITE_WORD(index,path_ptr[2]); index+=2; - DSP4.output[index++]=pos1&0xFF; - DSP4.output[index++]=pos2&0xFF; - - // post-update - path_ptr[2] -= 4; - path_ptr[3] -= 4; - } - lcv--; - - if(segments>0) - { - // project points w/out the envelopes - int16 inc = ((path_x[1]-x_right)<<8)/segments; - - // post-store - path_pos[2] += ((inc*lcv)>>8); - path_pos[3] += ((inc*lcv)>>8); - - path_x[1] = x_right; - path_y[1] = y_right; - } - } - } while(1); - - DSP4.waiting4command = TRUE; - DSP4.out_count = 2; - DSP4_WRITE_WORD(0,0); + // data + DSP4_WRITE_WORD(index, path_ptr[2]); + index += 2; + DSP4.output[index++] = pos1 & 0xFF; + DSP4.output[index++] = pos2 & 0xFF; + + // post-update + path_ptr[2] -= 4; + path_ptr[3] -= 4; + } + lcv--; + + if (segments > 0) + { + // project points w/out the envelopes + int16 inc = ((path_x[1] - x_right) << 8) / segments; + + // post-store + path_pos[2] += ((inc * lcv) >> 8); + path_pos[3] += ((inc * lcv) >> 8); + + path_x[1] = x_right; + path_y[1] = y_right; + } + } + } + while (1); + + DSP4.waiting4command = TRUE; + DSP4.out_count = 2; + DSP4_WRITE_WORD(0, 0); } #undef PRINT @@ -884,218 +912,234 @@ void DSP4_Op08() void DSP4_Op0D() { - uint16 command; - - DSP4.waiting4command = FALSE; - - // op flow control - switch(DSP4_Logic) { - case 1: goto resume1; break; - case 2: goto resume2; break; - } - - //////////////////////////////////////////////////// - // process initial inputs - - // sort inputs - // 0x00 = DSP4_READ_WORD(0x00); - project_focaly = DSP4_READ_WORD(0x02); - raster = DSP4_READ_WORD(0x04); - viewport_top = DSP4_READ_WORD(0x06); - project_y = DSP4_READ_WORD(0x08); - viewport_bottom = DSP4_READ_WORD(0x0a); - project_x1low = DSP4_READ_WORD(0x0c); - project_x1 = DSP4_READ_WORD(0x0e); - project_focalx = DSP4_READ_WORD(0x0e); - project_centerx = DSP4_READ_WORD(0x10); - project_ptr = DSP4_READ_WORD(0x12); - // 0xc0 = DSP4_READ_WORD(0x14); - project_pitchylow = DSP4_READ_WORD(0x16); - project_pitchy = DSP4_READ_WORD(0x18); - project_pitchxlow = DSP4_READ_WORD(0x1a); - project_pitchx = DSP4_READ_WORD(0x1c); - far_plane = DSP4_READ_WORD(0x1e); - // ? = DSP4_READ_WORD(0x20); - - // multi-op storage - multi_index1++; - multi_index1%=4; - - // remap 0D->09 window data ahead of time - // index starts at 1-3,0 - // - // Op0D: BL,TL,BR,TR - // Op09: TL,TR,BL,BR (1,2,3,0) - switch(multi_index1) - { - case 1: multi_index2=3; break; - case 2: multi_index2=1; break; - case 3: multi_index2=0; break; - case 0: multi_index2=2; break; - } - - // pre-compute - view_plane = PLANE_START; - - // figure out projection data - project_y -= viewport_bottom; - project_x = project_centerx + project_x1; - - // debug - block=0; - - //////////////////////////////////////////////////// - // command check - - do { - // scan next command - DSP4.in_count = 2; - - DSP4_WAIT(1) resume1: - - // inspect input - command = DSP4_READ_WORD(0); - - // terminate op - if(command == 0x8000) break; - - // already have 2 bytes in queue - DSP4.in_index = 2; - DSP4.in_count = 8; + uint16 command; + + DSP4.waiting4command = FALSE; + + // op flow control + switch (DSP4_Logic) + { + case 1: + goto resume1; + break; + case 2: + goto resume2; + break; + } + + //////////////////////////////////////////////////// + // process initial inputs + + // sort inputs + // 0x00 = DSP4_READ_WORD(0x00); + project_focaly = DSP4_READ_WORD(0x02); + raster = DSP4_READ_WORD(0x04); + viewport_top = DSP4_READ_WORD(0x06); + project_y = DSP4_READ_WORD(0x08); + viewport_bottom = DSP4_READ_WORD(0x0a); + project_x1low = DSP4_READ_WORD(0x0c); + project_x1 = DSP4_READ_WORD(0x0e); + project_focalx = DSP4_READ_WORD(0x0e); + project_centerx = DSP4_READ_WORD(0x10); + project_ptr = DSP4_READ_WORD(0x12); + // 0xc0 = DSP4_READ_WORD(0x14); + project_pitchylow = DSP4_READ_WORD(0x16); + project_pitchy = DSP4_READ_WORD(0x18); + project_pitchxlow = DSP4_READ_WORD(0x1a); + project_pitchx = DSP4_READ_WORD(0x1c); + far_plane = DSP4_READ_WORD(0x1e); + // ? = DSP4_READ_WORD(0x20); + + // multi-op storage + multi_index1++; + multi_index1 %= 4; + + // remap 0D->09 window data ahead of time + // index starts at 1-3,0 + // + // Op0D: BL,TL,BR,TR + // Op09: TL,TR,BL,BR (1,2,3,0) + switch (multi_index1) + { + case 1: + multi_index2 = 3; + break; + case 2: + multi_index2 = 1; + break; + case 3: + multi_index2 = 0; + break; + case 0: + multi_index2 = 2; + break; + } + + // pre-compute + view_plane = PLANE_START; + + // figure out projection data + project_y -= viewport_bottom; + project_x = project_centerx + project_x1; + + // debug + block = 0; + + //////////////////////////////////////////////////// + // command check + + do + { + // scan next command + DSP4.in_count = 2; + +DSP4_WAIT(1) resume1: + + // inspect input + command = DSP4_READ_WORD(0); + + // terminate op + if (command == 0x8000) break; + + // already have 2 bytes in queue + DSP4.in_index = 2; + DSP4.in_count = 8; DSP4_WAIT(2) - //////////////////////////////////////////////////// - // project section of the track + //////////////////////////////////////////////////// + // project section of the track - // inspect inputs + // inspect inputs int16 plane; - int16 index, lcv; + int16 index, lcv; int16 py_dy, px_dx; - int16 y_out, x_out; + int16 y_out, x_out; - resume2: +resume2: plane = DSP4_READ_WORD(0); - py_dy=0; - px_dx=0; - - - // ignore invalid data - if((uint16) plane == 0x8001) continue; - - // one-time init - if(far_plane) - { - // setup final data - // low16=plane - project_x1 = project_focalx; - project_y1 = project_focaly; - plane = far_plane; - far_plane = 0; - } - - // use proportional triangles to project new coords - project_x2 = project_focalx * plane / view_plane; - project_y2 = project_focaly * plane / view_plane; - - // quadratic regression (rough) - if(project_focaly>=-0x0f) - py_dy = (short) (project_focaly * project_focaly * -0.20533553 - - 1.08330005 * project_focaly - 69.61094639); - else - py_dy = (short) (project_focaly * project_focaly * -0.000657035759 - - 1.07629051 * project_focaly - 65.69315963); - - // approximate # of raster lines - segments = abs(project_y2-project_y1); - - // prevent overdraw - if(project_y2>=raster) segments=0; - else raster=project_y2; - - // don't draw outside the window - if(project_y20) - { - // interpolate between projected points - px_dx = ((project_x2-project_x1)<<8)/segments; - } - - // debug - ++block; + py_dy = 0; + px_dx = 0; + + + // ignore invalid data + if ((uint16) plane == 0x8001) continue; + + // one-time init + if (far_plane) + { + // setup final data + // low16=plane + project_x1 = project_focalx; + project_y1 = project_focaly; + plane = far_plane; + far_plane = 0; + } + + // use proportional triangles to project new coords + project_x2 = project_focalx * plane / view_plane; + project_y2 = project_focaly * plane / view_plane; + + // quadratic regression (rough) + if (project_focaly >= -0x0f) + py_dy = (short)(project_focaly * project_focaly * -0.20533553 + - 1.08330005 * project_focaly - 69.61094639); + else + py_dy = (short)(project_focaly * project_focaly * -0.000657035759 + - 1.07629051 * project_focaly - 65.69315963); + + // approximate # of raster lines + segments = abs(project_y2 - project_y1); + + // prevent overdraw + if (project_y2 >= raster) segments = 0; + else raster = project_y2; + + // don't draw outside the window + if (project_y2 < viewport_top) segments = 0; + + // project new positions + if (segments > 0) + { + // interpolate between projected points + px_dx = ((project_x2 - project_x1) << 8) / segments; + } + + // debug + ++block; #ifdef PRINT - printf("(line %d) Op0D check %02X, plane %04X\n",c,(uint16)segments,(uint16)(plane)); + printf("(line %d) Op0D check %02X, plane %04X\n", c, (uint16)segments, + (uint16)(plane)); #endif - // prepare output - DSP4.out_count=8+2+6*segments; + // prepare output + DSP4.out_count = 8 + 2 + 6 * segments; - DSP4_WRITE_WORD(0,project_focalx); - DSP4_WRITE_WORD(2,project_x2); - DSP4_WRITE_WORD(4,project_focaly); - DSP4_WRITE_WORD(6,project_y2); - DSP4_WRITE_WORD(8,segments); + DSP4_WRITE_WORD(0, project_focalx); + DSP4_WRITE_WORD(2, project_x2); + DSP4_WRITE_WORD(4, project_focaly); + DSP4_WRITE_WORD(6, project_y2); + DSP4_WRITE_WORD(8, segments); #if 0 - DSP4_WRITE_WORD(0,-1); - DSP4_WRITE_WORD(2,-1); - DSP4_WRITE_WORD(4,-1); - DSP4_WRITE_WORD(6,-1); - DSP4_WRITE_WORD(8,-1); + DSP4_WRITE_WORD(0, -1); + DSP4_WRITE_WORD(2, -1); + DSP4_WRITE_WORD(4, -1); + DSP4_WRITE_WORD(6, -1); + DSP4_WRITE_WORD(8, -1); #endif - index=10; + index = 10; - // iterate through each point - for( lcv=0; lcv>8); - x_out = project_x+((px_dx*lcv)>>8); + // iterate through each point + for (lcv = 0; lcv < segments; lcv++) + { + // step through the projected line + y_out = project_y + ((py_dy * lcv) >> 8); + x_out = project_x + ((px_dx * lcv) >> 8); #if 0 - project_ptr=-1; - //y_out=-1; - x_out=-1; + project_ptr = -1; + //y_out=-1; + x_out = -1; #endif - // data - DSP4_WRITE_WORD(index+0,project_ptr); - DSP4_WRITE_WORD(index+2,y_out); - DSP4_WRITE_WORD(index+4,x_out); - index += 6; - - // post-update - project_ptr -= 4; - } - - // post-update - project_y += ((py_dy*lcv)>>8); - project_x += ((px_dx*lcv)>>8); - - if(segments > 0) - { - project_x1 = project_x2; - project_y1 = project_y2; - - // multi-op storage - multi_farplane[multi_index2] = plane; - multi_raster[multi_index2] = project_y1; - } - - // update focal projection points - project_pitchy += (int8)DSP4.parameters[3]; - project_pitchx += (int8)DSP4.parameters[5]; - - project_focaly += project_pitchy; - project_focalx += project_pitchx; - } while(1); - - DSP4.waiting4command = TRUE; - DSP4.out_count = 0; + // data + DSP4_WRITE_WORD(index + 0, project_ptr); + DSP4_WRITE_WORD(index + 2, y_out); + DSP4_WRITE_WORD(index + 4, x_out); + index += 6; + + // post-update + project_ptr -= 4; + } + + // post-update + project_y += ((py_dy * lcv) >> 8); + project_x += ((px_dx * lcv) >> 8); + + if (segments > 0) + { + project_x1 = project_x2; + project_y1 = project_y2; + + // multi-op storage + multi_farplane[multi_index2] = plane; + multi_raster[multi_index2] = project_y1; + } + + // update focal projection points + project_pitchy += (int8)DSP4.parameters[3]; + project_pitchx += (int8)DSP4.parameters[5]; + + project_focaly += project_pitchy; + project_focalx += project_pitchx; + } + while (1); + + DSP4.waiting4command = TRUE; + DSP4.out_count = 0; } #undef PRINT @@ -1110,396 +1154,420 @@ void DSP4_Op0D() void DSP4_Op09() { - uint16 command; - - DSP4.waiting4command = FALSE; - - // op flow control - switch(DSP4_Logic) { - case 1: goto resume1; break; - case 2: goto resume2; break; - case 3: goto resume3; break; - case 4: goto resume4; break; - case 5: goto resume5; break; - case 6: goto resume6; break; - case 7: goto resume7; break; - } - - //////////////////////////////////////////////////// - // process initial inputs - - // debug - block=0; - - // grab screen information - view_plane = PLANE_START; - center_x = DSP4_READ_WORD(0x00); - center_y = DSP4_READ_WORD(0x02); - // 0x00 = DSP4_READ_WORD(0x04); - viewport_left = DSP4_READ_WORD(0x06); - viewport_right = DSP4_READ_WORD(0x08); - viewport_top = DSP4_READ_WORD(0x0a); - viewport_bottom = DSP4_READ_WORD(0x0c); + uint16 command; + + DSP4.waiting4command = FALSE; + + // op flow control + switch (DSP4_Logic) + { + case 1: + goto resume1; + break; + case 2: + goto resume2; + break; + case 3: + goto resume3; + break; + case 4: + goto resume4; + break; + case 5: + goto resume5; + break; + case 6: + goto resume6; + break; + case 7: + goto resume7; + break; + } + + //////////////////////////////////////////////////// + // process initial inputs + + // debug + block = 0; + + // grab screen information + view_plane = PLANE_START; + center_x = DSP4_READ_WORD(0x00); + center_y = DSP4_READ_WORD(0x02); + // 0x00 = DSP4_READ_WORD(0x04); + viewport_left = DSP4_READ_WORD(0x06); + viewport_right = DSP4_READ_WORD(0x08); + viewport_top = DSP4_READ_WORD(0x0a); + viewport_bottom = DSP4_READ_WORD(0x0c); #ifdef PRINT2 - printf("Window: (%04X,%04X) (%04X,%04X)\n", - viewport_left,viewport_right,viewport_top,viewport_bottom); + printf("Window: (%04X,%04X) (%04X,%04X)\n", + viewport_left, viewport_right, viewport_top, viewport_bottom); #endif - // expand viewport dimensions - viewport_left -= 8; + // expand viewport dimensions + viewport_left -= 8; - // cycle through viewport window data - multi_index1++; - multi_index1%=4; + // cycle through viewport window data + multi_index1++; + multi_index1 %= 4; #if 1 - // convert track line to the window region - project_y2 = center_y + multi_raster[multi_index1] * - (viewport_bottom-center_y)/(0x33-0); - if(op09_mode==0) project_y2 -= 2; + // convert track line to the window region + project_y2 = center_y + multi_raster[multi_index1] * + (viewport_bottom - center_y) / (0x33 - 0); + if (op09_mode == 0) project_y2 -= 2; #endif - goto no_sprite; + goto no_sprite; - do { - //////////////////////////////////////////////////// - // check for new sprites + do + { + //////////////////////////////////////////////////// + // check for new sprites - do { - uint16 second; + do + { + uint16 second; - DSP4.in_count = 4; - DSP4.in_index = 2; + DSP4.in_count = 4; + DSP4.in_index = 2; - DSP4_WAIT(1) resume1: +DSP4_WAIT(1) resume1: - // try to classify sprite - second = DSP4_READ_WORD(2); + // try to classify sprite + second = DSP4_READ_WORD(2); - // op termination - if(second == 0x8000) goto terminate; + // op termination + if (second == 0x8000) goto terminate; - second >>= 8; - sprite_type = 0; + second >>= 8; + sprite_type = 0; - // vehicle sprite - if(second == 0x90) - { - sprite_type = 1; - break; - } - // terrain sprite - else if(second != 0) - { - sprite_type = 2; - break; - } + // vehicle sprite + if (second == 0x90) + { + sprite_type = 1; + break; + } + // terrain sprite + else if (second != 0) + { + sprite_type = 2; + break; + } no_sprite: - // no sprite. try again + // no sprite. try again - DSP4.in_count = 2; + DSP4.in_count = 2; - DSP4_WAIT(2) resume2: - ; - } while (1); +DSP4_WAIT(2) resume2: + ; + } + while (1); - //////////////////////////////////////////////////// - // process projection information + //////////////////////////////////////////////////// + // process projection information sprite_found: - // vehicle sprite - if(sprite_type == 1) - { - int16 plane; - int16 car_left, car_right, car_left_a; - int16 focal_back, focal_front; + // vehicle sprite + if (sprite_type == 1) + { + int16 plane; + int16 car_left, car_right, car_left_a; + int16 focal_back, focal_front; uint8 distance, id; - // we already have 4 bytes we want - DSP4.in_count = 6+12; - DSP4.in_index = 4; - - DSP4_WAIT(3) resume3: - - // filter inputs - project_y1 = DSP4_READ_WORD(0x00); - // 0x9000 = DSP4_READ_WORD(0x02); - id = DSP4.parameters[0x04]; - distance = DSP4.parameters[0x05]; - focal_back = DSP4_READ_WORD(0x06); - focal_front = DSP4_READ_WORD(0x08); - car_left_a = DSP4_READ_WORD(0x0a); - car_left = DSP4_READ_WORD(0x0c); - plane = DSP4_READ_WORD(0x0e); - car_right = DSP4_READ_WORD(0x10); - - // calculate car's x-center - project_focalx = car_right-car_left; - - // determine how far into the screen to project - project_focaly = focal_back; - project_x = project_focalx * plane / view_plane; - segments = 0x33 - project_focaly * plane / view_plane; - far_plane = plane; - - // prepare memory - sprite_x = center_x+project_x; - sprite_y = viewport_bottom-segments; - far_plane = plane; - - // debug - ++block; + // we already have 4 bytes we want + DSP4.in_count = 6 + 12; + DSP4.in_index = 4; + +DSP4_WAIT(3) resume3: + + // filter inputs + project_y1 = DSP4_READ_WORD(0x00); + // 0x9000 = DSP4_READ_WORD(0x02); + id = DSP4.parameters[0x04]; + distance = DSP4.parameters[0x05]; + focal_back = DSP4_READ_WORD(0x06); + focal_front = DSP4_READ_WORD(0x08); + car_left_a = DSP4_READ_WORD(0x0a); + car_left = DSP4_READ_WORD(0x0c); + plane = DSP4_READ_WORD(0x0e); + car_right = DSP4_READ_WORD(0x10); + + // calculate car's x-center + project_focalx = car_right - car_left; + + // determine how far into the screen to project + project_focaly = focal_back; + project_x = project_focalx * plane / view_plane; + segments = 0x33 - project_focaly * plane / view_plane; + far_plane = plane; + + // prepare memory + sprite_x = center_x + project_x; + sprite_y = viewport_bottom - segments; + far_plane = plane; + + // debug + ++block; #ifdef PRINT - printf("(line %d) Op09 vehicle block %d, Loop %04X\n",c,block,(uint16)project_y1); - //printf("%04X %04X %04X %04X / ",focal_back,focal_front,car_left_a,car_left); - //printf("%02X %02X ", distance, id); + printf("(line %d) Op09 vehicle block %d, Loop %04X\n", c, block, + (uint16)project_y1); + //printf("%04X %04X %04X %04X / ",focal_back,focal_front,car_left_a,car_left); + //printf("%02X %02X ", distance, id); #endif - // make the car's x-center available - DSP4.out_count = 2; - DSP4_WRITE_WORD(0,project_focalx); + // make the car's x-center available + DSP4.out_count = 2; + DSP4_WRITE_WORD(0, project_focalx); #if 0 - DSP4_WRITE_WORD(0,-1); + DSP4_WRITE_WORD(0, -1); #endif - // grab a few remaining vehicle values - DSP4.in_count = 4; + // grab a few remaining vehicle values + DSP4.in_count = 4; DSP4_WAIT(4) - // store final values + // store final values int height; - resume4: +resume4: height = DSP4_READ_WORD(0); - sprite_offset = DSP4_READ_WORD(2); + sprite_offset = DSP4_READ_WORD(2); - // vertical lift factor - sprite_y += height; + // vertical lift factor + sprite_y += height; #ifdef PRINT_09 - printf("%04X\n",sprite_offset); + printf("%04X\n", sprite_offset); #endif - } - // terrain sprite - else if(sprite_type == 2) - { - int16 plane; - - // we already have 4 bytes we want - DSP4.in_count = 6+6+2; - DSP4.in_index = 4; - - DSP4_WAIT(5) resume5: - - // sort loop inputs - project_y1 = DSP4_READ_WORD(0x00); - plane = DSP4_READ_WORD(0x02); - project_centerx = DSP4_READ_WORD(0x04); - //project_y1 = DSP4_READ_WORD(0x06); - project_focalx = DSP4_READ_WORD(0x08); - project_focaly = DSP4_READ_WORD(0x0a); - sprite_offset = DSP4_READ_WORD(0x0c); - - // determine distances into virtual world - segments = 0x33 - project_y1; - project_x = project_focalx * plane / view_plane; - project_y = project_focaly * plane / view_plane; - - // prepare memory - sprite_x = center_x+project_x-project_centerx; - sprite_y = viewport_bottom-segments+project_y; - far_plane = plane; - - // debug - ++block; + } + // terrain sprite + else if (sprite_type == 2) + { + int16 plane; + + // we already have 4 bytes we want + DSP4.in_count = 6 + 6 + 2; + DSP4.in_index = 4; + +DSP4_WAIT(5) resume5: + + // sort loop inputs + project_y1 = DSP4_READ_WORD(0x00); + plane = DSP4_READ_WORD(0x02); + project_centerx = DSP4_READ_WORD(0x04); + //project_y1 = DSP4_READ_WORD(0x06); + project_focalx = DSP4_READ_WORD(0x08); + project_focaly = DSP4_READ_WORD(0x0a); + sprite_offset = DSP4_READ_WORD(0x0c); + + // determine distances into virtual world + segments = 0x33 - project_y1; + project_x = project_focalx * plane / view_plane; + project_y = project_focaly * plane / view_plane; + + // prepare memory + sprite_x = center_x + project_x - project_centerx; + sprite_y = viewport_bottom - segments + project_y; + far_plane = plane; + + // debug + ++block; #ifdef PRINT - printf("(line %d) Op09 terrain block %d, Loop %04X\n",c,block,(uint16)project_y1); + printf("(line %d) Op09 terrain block %d, Loop %04X\n", c, block, + (uint16)project_y1); #endif - } + } - // default sprite size: 16x16 - sprite_size = 1; + // default sprite size: 16x16 + sprite_size = 1; - //////////////////////////////////////////////////// - // convert tile data to OAM + //////////////////////////////////////////////////// + // convert tile data to OAM - do { - DSP4.in_count = 2; + do + { + DSP4.in_count = 2; - DSP4_WAIT(6) resume6: +DSP4_WAIT(6) resume6: - command = DSP4_READ_WORD(0); + command = DSP4_READ_WORD(0); - // opcode termination - if(command == 0x8000) goto terminate; + // opcode termination + if (command == 0x8000) goto terminate; - // toggle sprite size - if(command == 0x0000) - { - sprite_size = !sprite_size; + // toggle sprite size + if (command == 0x0000) + { + sprite_size = !sprite_size; #ifdef PRINT - printf("TOGGLE=%02X\n",(uint8)sprite_size); + printf("TOGGLE=%02X\n", (uint8)sprite_size); #endif - continue; - } + continue; + } - // new sprite information - command >>= 8; - if(command != 0x20 && command != 0x40 && - command != 0x60 && command != 0xa0 && - command != 0xc0 && command != 0xe0) - break; + // new sprite information + command >>= 8; + if (command != 0x20 && command != 0x40 && + command != 0x60 && command != 0xa0 && + command != 0xc0 && command != 0xe0) + break; - DSP4.in_count = 6; - DSP4.in_index = 2; + DSP4.in_count = 6; + DSP4.in_index = 2; DSP4_WAIT(7) - ///////////////////////////////////// - // process tile data + ///////////////////////////////////// + // process tile data - bool8 clip; - int16 sp_x, sp_y, sp_oam, sp_msb; - int16 sp_dx, sp_dy; + bool8 clip; + int16 sp_x, sp_y, sp_oam, sp_msb; + int16 sp_dx, sp_dy; - resume7: +resume7: - // sprite deltas - sp_dy = DSP4_READ_WORD(2); - sp_dx = DSP4_READ_WORD(4); + // sprite deltas + sp_dy = DSP4_READ_WORD(2); + sp_dx = DSP4_READ_WORD(4); - // update coordinates - sp_y = sprite_y + sp_dy; - sp_x = sprite_x + sp_dx; + // update coordinates + sp_y = sprite_y + sp_dy; + sp_x = sprite_x + sp_dx; - // reject points outside the clipping window - clip = FALSE; - if(sp_x < viewport_left || sp_x > viewport_right) clip=TRUE; - if(sp_y < viewport_top || sp_y > viewport_bottom) clip=TRUE; + // reject points outside the clipping window + clip = FALSE; + if (sp_x < viewport_left || sp_x > viewport_right) clip = TRUE; + if (sp_y < viewport_top || sp_y > viewport_bottom) clip = TRUE; - // track depth sorting - if(far_plane <= multi_farplane[multi_index1] && - sp_y >= project_y2) clip=TRUE; + // track depth sorting + if (far_plane <= multi_farplane[multi_index1] && + sp_y >= project_y2) clip = TRUE; #ifdef PRINT2 - printf("(line %d) %04X, %04X, %04X / %04X %04X\n",line, - (uint16)sp_x,(uint16)sp_y,(uint16)far_plane,(uint16)multi_farplane[multi_index1],(uint16)project_y2); + printf("(line %d) %04X, %04X, %04X / %04X %04X\n", line, + (uint16)sp_x, (uint16)sp_y, (uint16)far_plane, + (uint16)multi_farplane[multi_index1], (uint16)project_y2); #endif - // don't draw offscreen coordinates - DSP4.out_count = 0; - if(!clip) - { - int16 out_index = 0; - int16 offset = DSP4_READ_WORD(0); + // don't draw offscreen coordinates + DSP4.out_count = 0; + if (!clip) + { + int16 out_index = 0; + int16 offset = DSP4_READ_WORD(0); - // update sprite nametable/attribute information - sp_oam = sprite_offset + offset; - sp_msb = (sp_x<0 || sp_x>255); + // update sprite nametable/attribute information + sp_oam = sprite_offset + offset; + sp_msb = (sp_x < 0 || sp_x > 255); #ifdef PRINT - printf("(line %d) %04X, %04X, %04X, %04X, %04X\n",line, - (uint16)sp_oam,(uint16)sprite_offset,(uint16)offset, - (uint16)sp_x,(uint16)sp_y); + printf("(line %d) %04X, %04X, %04X, %04X, %04X\n", line, + (uint16)sp_oam, (uint16)sprite_offset, (uint16)offset, + (uint16)sp_x, (uint16)sp_y); #endif - // emit transparency information - if( - (sprite_offset&0x08) && - ((sprite_type==1 && sp_y>=0xcc) || - (sprite_type==2 && sp_y>=0xbb)) - ) - { - DSP4.out_count = 6; + // emit transparency information + if ( + (sprite_offset & 0x08) && + ((sprite_type == 1 && sp_y >= 0xcc) || + (sprite_type == 2 && sp_y >= 0xbb)) + ) + { + DSP4.out_count = 6; - // one block of OAM data - DSP4_WRITE_WORD(0,1); + // one block of OAM data + DSP4_WRITE_WORD(0, 1); - // OAM: x,y,tile,no attr - DSP4.output[2] = sp_x&0xFF; - DSP4.output[3] = (sp_y+6)&0xFF; - DSP4_WRITE_WORD(4,0xEE); + // OAM: x,y,tile,no attr + DSP4.output[2] = sp_x & 0xFF; + DSP4.output[3] = (sp_y + 6) & 0xFF; + DSP4_WRITE_WORD(4, 0xEE); - out_index = 6; + out_index = 6; - // OAM: size,msb data - DSP4_Op06(sprite_size,(char) sp_msb); - } + // OAM: size,msb data + DSP4_Op06(sprite_size, (char) sp_msb); + } - // normal data - DSP4.out_count += 8; + // normal data + DSP4.out_count += 8; - // one block of OAM data - DSP4_WRITE_WORD(out_index+0,1); + // one block of OAM data + DSP4_WRITE_WORD(out_index + 0, 1); - // OAM: x,y,tile,attr - DSP4.output[out_index+2] = sp_x&0xFF; - DSP4.output[out_index+3] = sp_y&0xFF; - DSP4_WRITE_WORD(out_index+4,sp_oam); + // OAM: x,y,tile,attr + DSP4.output[out_index + 2] = sp_x & 0xFF; + DSP4.output[out_index + 3] = sp_y & 0xFF; + DSP4_WRITE_WORD(out_index + 4, sp_oam); - // no following OAM data - DSP4_WRITE_WORD(out_index+6,0); + // no following OAM data + DSP4_WRITE_WORD(out_index + 6, 0); - // OAM: size,msb data - DSP4_Op06(sprite_size, (char) sp_msb); + // OAM: size,msb data + DSP4_Op06(sprite_size, (char) sp_msb); #if 0 - DSP4_WRITE_WORD(0,-1); - DSP4_WRITE_WORD(2,-1); - DSP4_WRITE_WORD(4,-1); - DSP4_WRITE_WORD(6,-1); - DSP4_WRITE_WORD(8,-1); - DSP4_WRITE_WORD(10,-1); - DSP4_WRITE_WORD(12,-1); + DSP4_WRITE_WORD(0, -1); + DSP4_WRITE_WORD(2, -1); + DSP4_WRITE_WORD(4, -1); + DSP4_WRITE_WORD(6, -1); + DSP4_WRITE_WORD(8, -1); + DSP4_WRITE_WORD(10, -1); + DSP4_WRITE_WORD(12, -1); #endif - } - - // no sprite information - if(DSP4.out_count == 0) - { - DSP4.out_count = 2; - DSP4_WRITE_WORD(0,0); - } - } while (1); - - ///////////////////////////////////// - // special cases: plane == 0x0000 - - // special vehicle case - if(command == 0x90) - { - sprite_type = 1; - - // shift bytes - DSP4.parameters[2] = DSP4.parameters[0]; - DSP4.parameters[3] = DSP4.parameters[1]; - DSP4.parameters[0] = 0; - DSP4.parameters[1] = 0; - - goto sprite_found; - } - // special terrain case - else if(command != 0x00 && command != 0xff) - { - sprite_type = 2; - - // shift bytes - DSP4.parameters[2] = DSP4.parameters[0]; - DSP4.parameters[3] = DSP4.parameters[1]; - DSP4.parameters[0] = 0; - DSP4.parameters[1] = 0; - - goto sprite_found; - } - } while (1); + } + + // no sprite information + if (DSP4.out_count == 0) + { + DSP4.out_count = 2; + DSP4_WRITE_WORD(0, 0); + } + } + while (1); + + ///////////////////////////////////// + // special cases: plane == 0x0000 + + // special vehicle case + if (command == 0x90) + { + sprite_type = 1; + + // shift bytes + DSP4.parameters[2] = DSP4.parameters[0]; + DSP4.parameters[3] = DSP4.parameters[1]; + DSP4.parameters[0] = 0; + DSP4.parameters[1] = 0; + + goto sprite_found; + } + // special terrain case + else if (command != 0x00 && command != 0xff) + { + sprite_type = 2; + + // shift bytes + DSP4.parameters[2] = DSP4.parameters[0]; + DSP4.parameters[3] = DSP4.parameters[1]; + DSP4.parameters[0] = 0; + DSP4.parameters[1] = 0; + + goto sprite_found; + } + } + while (1); terminate: - DSP4.waiting4command = TRUE; - DSP4.out_count=0; + DSP4.waiting4command = TRUE; + DSP4.out_count = 0; } #undef PRINT diff --git a/source/font.h b/source/font.h index 5720fbd..74538ca 100644 --- a/source/font.h +++ b/source/font.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,104 +43,105 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ -static const char *font[] = { -" . . . . .. . . ", -" .#. .#.#. . . ... .#. . . .##. .#. .#. . . . . ", -" .#. .#.#. .#.#. .###. .#..#. .#. .#. .#. .#. .#.#. .#. .#. ", -" .#. .#.#. .#####. .#.#. ..#. .#.#. .#. .#. .#. .#. ..#.. .... .#. ", -" .#. . . .#.#. .###. .#.. .#. . .#. .#. .###. .#####. .. .####. .. .#. ", -" . .#####. .#.#. .#..#. .#.#. .#. .#. .#. ..#.. .##. .... .##. .#. ", -" .#. .#.#. .###. . .#. .#.#. .#. .#. .#.#. .#. .#. .##. . ", -" . . . ... . . . . . . . . .#. .. ", -" . ", -" . . .. .... . .... .. .... .. .. . ", -" .#. .#. .##. .####. .#. .####. .##. .####. .##. .##. .. .. . . .#. ", -".#.#. .##. .#..#. ...#. .##. .#... .#.. ...#. .#..#. .#..#. .##. .##. .#. .... .#. .#.#. ", -".#.#. .#. . .#. .##. .#.#. .###. .###. .#. .##. .#..#. .##. .##. .#. .####. .#. ..#. ", -".#.#. .#. .#. ...#. .####. ...#. .#..#. .#. .#..#. .###. .. .. .#. .... .#. .#. ", -".#.#. .#. .#.. .#..#. ..#. .#..#. .#..#. .#. .#..#. ..#. .##. .##. .#. .####. .#. . ", -" .#. .###. .####. .##. .#. .##. .##. .#. .##. .##. .##. .#. .#. .... .#. .#. ", -" . ... .... .. . .. .. . .. .. .. .#. . . . ", -" . ", -" .. .. ... .. ... .... .... .. . . ... . . . . . . . . .. ", -" .##. .##. .###. .##. .###. .####. .####. .##. .#..#. .###. .#. .#..#. .#. .#. .#. .#. .#. .##. ", -".#..#. .#..#. .#..#. .#..#. .#..#. .#... .#... .#..#. .#..#. .#. .#. .#.#. .#. .##.##. .##..#. .#..#. ", -".#.##. .#..#. .###. .#. . .#..#. .###. .###. .#... .####. .#. .#. .##. .#. .#.#.#. .#.#.#. .#..#. ", -".#.##. .####. .#..#. .#. . .#..#. .#.. .#.. .#.##. .#..#. .#. . .#. .##. .#. .#...#. .#.#.#. .#..#. ", -".#... .#..#. .#..#. .#..#. .#..#. .#... .#. .#..#. .#..#. .#. .#..#. .#.#. .#... .#. .#. .#..##. .#..#. ", -" .##. .#..#. .###. .##. .###. .####. .#. .###. .#..#. .###. .##. .#..#. .####. .#. .#. .#. .#. .##. ", -" .. . . ... .. ... .... . ... . . ... .. . . .... . . . . .. ", -" ", -" ... .. ... .. ... . . . . . . . . . . .... ... ... . ", -".###. .##. .###. .##. .###. .#. .#. .#. .#. .#. .#. .#..#. .#.#. .####. .###. . .###. .#. ", -".#..#. .#..#. .#..#. .#..#. .#. .#. .#. .#. .#. .#...#. .#..#. .#.#. ...#. .#.. .#. ..#. .#.#. ", -".#..#. .#..#. .#..#. .#.. .#. .#. .#. .#. .#. .#.#.#. .##. .#.#. .#. .#. .#. .#. . . ", -".###. .#..#. .###. ..#. .#. .#. .#. .#. .#. .#.#.#. .#..#. .#. .#. .#. .#. .#. ", -".#.. .##.#. .#.#. .#..#. .#. .#...#. .#.#. .##.##. .#..#. .#. .#... .#.. .#. ..#. .... ", -".#. .##. .#..#. .##. .#. .###. .#. .#. .#. .#..#. .#. .####. .###. . .###. .####. ", -" . ..#. . . .. . ... . . . . . . .... ... ... .... ", -" . ", -" .. . . . . . . . .. ", -".##. .#. .#. .#. .#. .#. .#. .#. .##. ", -" .#. ... .#.. .. ..#. .. .#.#. ... .#.. .. . .#.. .#. .. .. ... .. ", -" .#. .###. .###. .##. .###. .##. .#.. .###. .###. .##. .#. .#.#. .#. .##.##. .###. .##. ", -" . .#..#. .#..#. .#.. .#..#. .#.##. .###. .#..#. .#..#. .#. .#. .##. .#. .#.#.#. .#..#. .#..#. ", -" .#.##. .#..#. .#.. .#..#. .##.. .#. .##. .#..#. .#. ..#. .#.#. .#. .#...#. .#..#. .#..#. ", -" .#.#. .###. .##. .###. .##. .#. .#... .#..#. .###. .#.#. .#..#. .###. .#. .#. .#..#. .##. ", -" . . ... .. ... .. . .###. . . ... .#. . . ... . . . . .. ", -" ... . ", -" . . . . . . ", -" .#. .#. .#. .#. .#.#. ", -" ... ... ... ... .#. . . . . . . . . . . .... .#. .#. .#. .#.#. ", -".###. .###. .###. .###. .###. .#..#. .#.#. .#...#. .#..#. .#..#. .####. .##. .#. .##. . . ", -".#..#. .#..#. .#..#. .##.. .#. .#..#. .#.#. .#.#.#. .##. .#..#. ..#. .#. .#. .#. ", -".#..#. .#..#. .#. . ..##. .#.. .#..#. .#.#. .#.#.#. .##. .#.#. .#.. .#. .#. .#. ", -".###. .###. .#. .###. .##. .###. .#. .#.#. .#..#. .#. .####. .#. .#. .#. ", -".#.. ..#. . ... .. ... . . . . . .#. .... . . . ", -" . . . ", +static const char* font[] = +{ + " . . . . .. . . ", + " .#. .#.#. . . ... .#. . . .##. .#. .#. . . . . ", + " .#. .#.#. .#.#. .###. .#..#. .#. .#. .#. .#. .#.#. .#. .#. ", + " .#. .#.#. .#####. .#.#. ..#. .#.#. .#. .#. .#. .#. ..#.. .... .#. ", + " .#. . . .#.#. .###. .#.. .#. . .#. .#. .###. .#####. .. .####. .. .#. ", + " . .#####. .#.#. .#..#. .#.#. .#. .#. .#. ..#.. .##. .... .##. .#. ", + " .#. .#.#. .###. . .#. .#.#. .#. .#. .#.#. .#. .#. .##. . ", + " . . . ... . . . . . . . . .#. .. ", + " . ", + " . . .. .... . .... .. .... .. .. . ", + " .#. .#. .##. .####. .#. .####. .##. .####. .##. .##. .. .. . . .#. ", + ".#.#. .##. .#..#. ...#. .##. .#... .#.. ...#. .#..#. .#..#. .##. .##. .#. .... .#. .#.#. ", + ".#.#. .#. . .#. .##. .#.#. .###. .###. .#. .##. .#..#. .##. .##. .#. .####. .#. ..#. ", + ".#.#. .#. .#. ...#. .####. ...#. .#..#. .#. .#..#. .###. .. .. .#. .... .#. .#. ", + ".#.#. .#. .#.. .#..#. ..#. .#..#. .#..#. .#. .#..#. ..#. .##. .##. .#. .####. .#. . ", + " .#. .###. .####. .##. .#. .##. .##. .#. .##. .##. .##. .#. .#. .... .#. .#. ", + " . ... .... .. . .. .. . .. .. .. .#. . . . ", + " . ", + " .. .. ... .. ... .... .... .. . . ... . . . . . . . . .. ", + " .##. .##. .###. .##. .###. .####. .####. .##. .#..#. .###. .#. .#..#. .#. .#. .#. .#. .#. .##. ", + ".#..#. .#..#. .#..#. .#..#. .#..#. .#... .#... .#..#. .#..#. .#. .#. .#.#. .#. .##.##. .##..#. .#..#. ", + ".#.##. .#..#. .###. .#. . .#..#. .###. .###. .#... .####. .#. .#. .##. .#. .#.#.#. .#.#.#. .#..#. ", + ".#.##. .####. .#..#. .#. . .#..#. .#.. .#.. .#.##. .#..#. .#. . .#. .##. .#. .#...#. .#.#.#. .#..#. ", + ".#... .#..#. .#..#. .#..#. .#..#. .#... .#. .#..#. .#..#. .#. .#..#. .#.#. .#... .#. .#. .#..##. .#..#. ", + " .##. .#..#. .###. .##. .###. .####. .#. .###. .#..#. .###. .##. .#..#. .####. .#. .#. .#. .#. .##. ", + " .. . . ... .. ... .... . ... . . ... .. . . .... . . . . .. ", + " ", + " ... .. ... .. ... . . . . . . . . . . .... ... ... . ", + ".###. .##. .###. .##. .###. .#. .#. .#. .#. .#. .#. .#..#. .#.#. .####. .###. . .###. .#. ", + ".#..#. .#..#. .#..#. .#..#. .#. .#. .#. .#. .#. .#...#. .#..#. .#.#. ...#. .#.. .#. ..#. .#.#. ", + ".#..#. .#..#. .#..#. .#.. .#. .#. .#. .#. .#. .#.#.#. .##. .#.#. .#. .#. .#. .#. . . ", + ".###. .#..#. .###. ..#. .#. .#. .#. .#. .#. .#.#.#. .#..#. .#. .#. .#. .#. .#. ", + ".#.. .##.#. .#.#. .#..#. .#. .#...#. .#.#. .##.##. .#..#. .#. .#... .#.. .#. ..#. .... ", + ".#. .##. .#..#. .##. .#. .###. .#. .#. .#. .#..#. .#. .####. .###. . .###. .####. ", + " . ..#. . . .. . ... . . . . . . .... ... ... .... ", + " . ", + " .. . . . . . . . .. ", + ".##. .#. .#. .#. .#. .#. .#. .#. .##. ", + " .#. ... .#.. .. ..#. .. .#.#. ... .#.. .. . .#.. .#. .. .. ... .. ", + " .#. .###. .###. .##. .###. .##. .#.. .###. .###. .##. .#. .#.#. .#. .##.##. .###. .##. ", + " . .#..#. .#..#. .#.. .#..#. .#.##. .###. .#..#. .#..#. .#. .#. .##. .#. .#.#.#. .#..#. .#..#. ", + " .#.##. .#..#. .#.. .#..#. .##.. .#. .##. .#..#. .#. ..#. .#.#. .#. .#...#. .#..#. .#..#. ", + " .#.#. .###. .##. .###. .##. .#. .#... .#..#. .###. .#.#. .#..#. .###. .#. .#. .#..#. .##. ", + " . . ... .. ... .. . .###. . . ... .#. . . ... . . . . .. ", + " ... . ", + " . . . . . . ", + " .#. .#. .#. .#. .#.#. ", + " ... ... ... ... .#. . . . . . . . . . . .... .#. .#. .#. .#.#. ", + ".###. .###. .###. .###. .###. .#..#. .#.#. .#...#. .#..#. .#..#. .####. .##. .#. .##. . . ", + ".#..#. .#..#. .#..#. .##.. .#. .#..#. .#.#. .#.#.#. .##. .#..#. ..#. .#. .#. .#. ", + ".#..#. .#..#. .#. . ..##. .#.. .#..#. .#.#. .#.#.#. .##. .#.#. .#.. .#. .#. .#. ", + ".###. .###. .#. .###. .##. .###. .#. .#.#. .#..#. .#. .####. .#. .#. .#. ", + ".#.. ..#. . ... .. ... . . . . . .#. .... . . . ", + " . . . ", }; static int font_width = 8; diff --git a/source/fxdbg.c b/source/fxdbg.c index 3479db1..75af980 100644 --- a/source/fxdbg.c +++ b/source/fxdbg.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -92,7 +92,7 @@ #include #include -extern const char *fx_apvMnemonicTable[]; +extern const char* fx_apvMnemonicTable[]; extern struct FxRegs_s GSU; @@ -118,292 +118,292 @@ extern struct FxRegs_s GSU; in this debug function. (See the diffrence of how the values vPipe1 and vPipe2 are read, compared to the values vByte1 and vByte2) - + */ -void FxPipeString(char * pvString) +void FxPipeString(char* pvString) { - char *p; - uint32 vOpcode = (GSU.vStatusReg & 0x300) | ((uint32)PIPE); - const char *m = fx_apvMnemonicTable[vOpcode]; - uint8 vPipe1,vPipe2,vByte1,vByte2; - uint8 vPipeBank = GSU.vPipeAdr >> 16; - - /* The next two bytes after the pipe's address */ - vPipe1 = GSU.apvRomBank[vPipeBank][USEX16(GSU.vPipeAdr+1)]; - vPipe2 = GSU.apvRomBank[vPipeBank][USEX16(GSU.vPipeAdr+2)]; - - /* The actual next two bytes to be read */ - vByte1 = PRGBANK(USEX16(R15)); - vByte2 = PRGBANK(USEX16(R15+1)); - - /* Print ROM address of the pipe */ - sprintf(pvString, "%02x:%04x %02x ", - USEX8(vPipeBank), USEX16(GSU.vPipeAdr), USEX8(PIPE)); - p = &pvString[strlen(pvString)]; - - /* Check if it's a branch instruction */ - if( PIPE >= 0x05 && PIPE <= 0x0f ) - { - sprintf(&pvString[11], "%02x ", USEX8(vPipe1)); + char* p; + uint32 vOpcode = (GSU.vStatusReg & 0x300) | ((uint32)PIPE); + const char* m = fx_apvMnemonicTable[vOpcode]; + uint8 vPipe1, vPipe2, vByte1, vByte2; + uint8 vPipeBank = GSU.vPipeAdr >> 16; + + /* The next two bytes after the pipe's address */ + vPipe1 = GSU.apvRomBank[vPipeBank][USEX16(GSU.vPipeAdr + 1)]; + vPipe2 = GSU.apvRomBank[vPipeBank][USEX16(GSU.vPipeAdr + 2)]; + + /* The actual next two bytes to be read */ + vByte1 = PRGBANK(USEX16(R15)); + vByte2 = PRGBANK(USEX16(R15 + 1)); + + /* Print ROM address of the pipe */ + sprintf(pvString, "%02x:%04x %02x ", + USEX8(vPipeBank), USEX16(GSU.vPipeAdr), USEX8(PIPE)); + p = &pvString[strlen(pvString)]; + + /* Check if it's a branch instruction */ + if (PIPE >= 0x05 && PIPE <= 0x0f) + { + sprintf(&pvString[11], "%02x ", USEX8(vPipe1)); #ifdef BRANCH_DELAY_RELATIVE - sprintf(p, m, USEX16(R15 + SEX8(vByte1) + 1 ) ); + sprintf(p, m, USEX16(R15 + SEX8(vByte1) + 1)); #else - sprintf(p, m, USEX16(R15 + SEX8(vByte1) - 1 ) ); + sprintf(p, m, USEX16(R15 + SEX8(vByte1) - 1)); #endif - } - /* Check for 'move' instruction */ - else if( PIPE >= 0x10 && PIPE <= 0x1f && TF(B) ) - sprintf(p, "move r%d,r%d", USEX8(PIPE & 0x0f), GSU.pvSreg - GSU.avReg); - /* Check for 'ibt', 'lms' or 'sms' */ - else if( PIPE >= 0xa0 && PIPE <= 0xaf ) - { - sprintf(&pvString[11], "%02x ", USEX8(vPipe1)); - if( (GSU.vStatusReg & 0x300) == 0x100 || (GSU.vStatusReg & 0x300) == 0x200 ) - sprintf(p, m, USEX16(vByte1) << 1 ); - else - sprintf(p, m, USEX16(vByte1) ); - } - /* Check for 'moves' */ - else if( PIPE >= 0xb0 && PIPE <= 0xbf && TF(B) ) - sprintf(p, "moves r%d,r%d", GSU.pvDreg - GSU.avReg, USEX8(PIPE & 0x0f) ); - /* Check for 'iwt', 'lm' or 'sm' */ - else if( PIPE >= 0xf0 ) - { - sprintf(&pvString[11], "%02x %02x ", USEX8(vPipe1), USEX8(vPipe2)); - sprintf(p, m, USEX8(vByte1) | (USEX16(vByte2)<<8) ); - } - /* Normal instruction */ - else - strcpy(p, m); + } + /* Check for 'move' instruction */ + else if (PIPE >= 0x10 && PIPE <= 0x1f && TF(B)) + sprintf(p, "move r%d,r%d", USEX8(PIPE & 0x0f), GSU.pvSreg - GSU.avReg); + /* Check for 'ibt', 'lms' or 'sms' */ + else if (PIPE >= 0xa0 && PIPE <= 0xaf) + { + sprintf(&pvString[11], "%02x ", USEX8(vPipe1)); + if ((GSU.vStatusReg & 0x300) == 0x100 || (GSU.vStatusReg & 0x300) == 0x200) + sprintf(p, m, USEX16(vByte1) << 1); + else + sprintf(p, m, USEX16(vByte1)); + } + /* Check for 'moves' */ + else if (PIPE >= 0xb0 && PIPE <= 0xbf && TF(B)) + sprintf(p, "moves r%d,r%d", GSU.pvDreg - GSU.avReg, USEX8(PIPE & 0x0f)); + /* Check for 'iwt', 'lm' or 'sm' */ + else if (PIPE >= 0xf0) + { + sprintf(&pvString[11], "%02x %02x ", USEX8(vPipe1), USEX8(vPipe2)); + sprintf(p, m, USEX8(vByte1) | (USEX16(vByte2) << 8)); + } + /* Normal instruction */ + else + strcpy(p, m); } -const char *fx_apvMnemonicTable[] = +const char* fx_apvMnemonicTable[] = { - /* - * ALT0 Table - */ - /* 00 - 0f */ - "stop", "nop", "cache", "lsr", "rol", "bra $%04x","blt $%04x","bge $%04x", - "bne $%04x","beq $%04x","bpl $%04x","bmi $%04x","bcc $%04x","bcs $%04x","bvc $%04x","bvs $%04x", - /* 10 - 1f */ - "to r0", "to r1", "to r2", "to r3", "to r4", "to r5", "to r6", "to r7", - "to r8", "to r9", "to r10", "to r11", "to r12", "to r13", "to r14", "to r15", - /* 20 - 2f */ - "with r0", "with r1", "with r2", "with r3", "with r4", "with r5", "with r6", "with r7", - "with r8", "with r9", "with r10", "with r11", "with r12", "with r13", "with r14", "with r15", - /* 30 - 3f */ - "stw (r0)","stw (r1)","stw (r2)", "stw (r3)", "stw (r4)", "stw (r5)", "stw (r6)", "stw (r7)", - "stw (r8)","stw (r9)","stw (r10)","stw (r11)","loop", "alt1", "alt2", "alt3", - /* 40 - 4f */ - "ldw (r0)","ldw (r1)","ldw (r2)", "ldw (r3)", "ldw (r4)", "ldw (r5)", "ldw (r6)", "ldw (r7)", - "ldw (r8)","ldw (r9)","ldw (r10)","ldw (r11)","plot", "swap", "color", "not", - /* 50 - 5f */ - "add r0", "add r1", "add r2", "add r3", "add r4", "add r5", "add r6", "add r7", - "add r8", "add r9", "add r10", "add r11", "add r12", "add r13", "add r14", "add r15", - /* 60 - 6f */ - "sub r0", "sub r1", "sub r2", "sub r3", "sub r4", "sub r5", "sub r6", "sub r7", - "sub r8", "sub r9", "sub r10", "sub r11", "sub r12", "sub r13", "sub r14", "sub r15", - /* 70 - 7f */ - "merge", "and r1", "and r2", "and r3", "and r4", "and r5", "and r6", "and r7", - "and r8", "and r9", "and r10", "and r11", "and r12", "and r13", "and r14", "and r15", - /* 80 - 8f */ - "mult r0", "mult r1", "mult r2", "mult r3", "mult r4", "mult r5", "mult r6", "mult r7", - "mult r8", "mult r9", "mult r10", "mult r11", "mult r12", "mult r13", "mult r14", "mult r15", - /* 90 - 9f */ - "sbk", "link #1", "link #2", "link #3", "link #4", "sex", "asr", "ror", - "jmp (r8)","jmp (r9)","jmp (r10)","jmp (r11)","jmp (r12)","jmp (r13)","lob", "fmult", - /* a0 - af */ - "ibt r0,#$%02x", "ibt r1,#$%02x", "ibt r2,#$%02x", "ibt r3,#$%02x", - "ibt r4,#$%02x", "ibt r5,#$%02x", "ibt r6,#$%02x", "ibt r7,#$%02x", - "ibt r8,#$%02x", "ibt r9,#$%02x", "ibt r10,#$%02x", "ibt r11,#$%02x", - "ibt r12,#$%02x", "ibt r13,#$%02x", "ibt r14,#$%02x", "ibt r15,#$%02x", - /* b0 - bf */ - "from r0", "from r1", "from r2", "from r3", "from r4", "from r5", "from r6", "from r7", - "from r8", "from r9", "from r10", "from r11", "from r12", "from r13", "from r14", "from r15", - /* c0 - cf */ - "hib", "or r1", "or r2", "or r3", "or r4", "or r5", "or r6", "or r7", - "or r8", "or r9", "or r10", "or r11", "or r12", "or r13", "or r14", "or r15", - /* d0 - df */ - "inc r0", "inc r1", "inc r2", "inc r3", "inc r4", "inc r5", "inc r6", "inc r7", - "inc r8", "inc r9", "inc r10", "inc r11", "inc r12", "inc r13", "inc r14", "getc", - /* e0 - ef */ - "dec r0", "dec r1", "dec r2", "dec r3", "dec r4", "dec r5", "dec r6", "dec r7", - "dec r8", "dec r9", "dec r10", "dec r11", "dec r12", "dec r13", "dec r14", "getb", - /* f0 - ff */ - "iwt r0,#$%04x", "iwt r1,#$%04x", "iwt r2,#$%04x", "iwt r3,#$%04x", - "iwt r4,#$%04x", "iwt r5,#$%04x", "iwt r6,#$%04x", "iwt r7,#$%04x", - "iwt r8,#$%04x", "iwt r9,#$%04x", "iwt r10,#$%04x", "iwt r11,#$%04x", - "iwt r12,#$%04x", "iwt r13,#$%04x", "iwt r14,#$%04x", "iwt r15,#$%04x", - - /* - * ALT1 Table - */ - - /* 00 - 0f */ - "stop", "nop", "cache", "lsr", "rol", "bra $%04x","blt $%04x","bge $%04x", - "bne $%04x","beq $%04x","bpl $%04x","bmi $%04x","bcc $%04x","bcs $%04x","bvc $%04x","bvs $%04x", - /* 10 - 1f */ - "to r0", "to r1", "to r2", "to r3", "to r4", "to r5", "to r6", "to r7", - "to r8", "to r9", "to r10", "to r11", "to r12", "to r13", "to r14", "to r15", - /* 20 - 2f */ - "with r0", "with r1", "with r2", "with r3", "with r4", "with r5", "with r6", "with r7", - "with r8", "with r9", "with r10", "with r11", "with r12", "with r13", "with r14", "with r15", - /* 30 - 3f */ - "stb (r0)","stb (r1)","stb (r2)", "stb (r3)", "stb (r4)", "stb (r5)", "stb (r6)", "stb (r7)", - "stb (r8)","stb (r9)","stb (r10)","stb (r11)","loop", "alt1", "alt2", "alt3", - /* 40 - 4f */ - "ldb (r0)","ldb (r1)","ldb (r2)", "ldb (r3)", "ldb (r4)", "ldb (r5)", "ldb (r6)", "ldb (r7)", - "ldb (r8)","ldb (r9)","ldb (r10)","ldb (r11)","rpix", "swap", "cmode", "not", - /* 50 - 5f */ - "adc r0", "adc r1", "adc r2", "adc r3", "adc r4", "adc r5", "adc r6", "adc r7", - "adc r8", "adc r9", "adc r10", "adc r11", "adc r12", "adc r13", "adc r14", "adc r15", - /* 60 - 6f */ - "sbc r0", "sbc r1", "sbc r2", "sbc r3", "sbc r4", "sbc r5", "sbc r6", "sbc r7", - "sbc r8", "sbc r9", "sbc r10", "sbc r11", "sbc r12", "sbc r13", "sbc r14", "sbc r15", - /* 70 - 7f */ - "merge", "bic r1", "bic r2", "bic r3", "bic r4", "bic r5", "bic r6", "bic r7", - "bic r8", "bic r9", "bic r10", "bic r11", "bic r12", "bic r13", "bic r14", "bic r15", - /* 80 - 8f */ - "umult r0","umult r1","umult r2", "umult r3", "umult r4", "umult r5", "umult r6", "umult r7", - "umult r8","umult r9","umult r10","umult r11","umult r12","umult r13","umult r14","umult r15", - /* 90 - 9f */ - "sbk", "link #1", "link #2", "link #3", "link #4", "sex", "div2", "ror", - "ljmp (r8)","ljmp (r9)","ljmp (r10)","ljmp (r11)", "ljmp (r12)", "ljmp (r13)", "lob", "lmult", - /* a0 - af */ - "lms r0,($%04x)", "lms r1,($%04x)", "lms r2,($%04x)", "lms r3,($%04x)", - "lms r4,($%04x)", "lms r5,($%04x)", "lms r6,($%04x)", "lms r7,($%04x)", - "lms r8,($%04x)", "lms r9,($%04x)", "lms r10,($%04x)", "lms r11,($%04x)", - "lms r12,($%04x)", "lms r13,($%04x)", "lms r14,($%04x)", "lms r15,($%04x)", - /* b0 - bf */ - "from r0", "from r1", "from r2", "from r3", "from r4", "from r5", "from r6", "from r7", - "from r8", "from r9", "from r10", "from r11", "from r12", "from r13", "from r14", "from r15", - /* c0 - cf */ - "hib", "xor r1", "xor r2", "xor r3", "xor r4", "xor r5", "xor r6", "xor r7", - "xor r8", "xor r9", "xor r10", "xor r11", "xor r12", "xor r13", "xor r14", "xor r15", - /* d0 - df */ - "inc r0", "inc r1", "inc r2", "inc r3", "inc r4", "inc r5", "inc r6", "inc r7", - "inc r8", "inc r9", "inc r10", "inc r11", "inc r12", "inc r13", "inc r14", "getc", - /* e0 - ef */ - "dec r0", "dec r1", "dec r2", "dec r3", "dec r4", "dec r5", "dec r6", "dec r7", - "dec r8", "dec r9", "dec r10", "dec r11", "dec r12", "dec r13", "dec r14", "getbh", - /* f0 - ff */ - "lm r0,($%04x)", "lm r1,($%04x)", "lm r2,($%04x)", "lm r3,($%04x)", - "lm r4,($%04x)", "lm r5,($%04x)", "lm r6,($%04x)", "lm r7,($%04x)", - "lm r8,($%04x)", "lm r9,($%04x)", "lm r10,($%04x)", "lm r11,($%04x)", - "lm r12,($%04x)", "lm r13,($%04x)", "lm r14,($%04x)", "lm r15,($%04x)", - - /* - * ALT2 Table - */ - - /* 00 - 0f */ - "stop", "nop", "cache", "lsr", "rol", "bra $%04x","blt $%04x","bge $%04x", - "bne $%04x","beq $%04x","bpl $%04x","bmi $%04x","bcc $%04x","bcs $%04x","bvc $%04x","bvs $%04x", - /* 10 - 1f */ - "to r0", "to r1", "to r2", "to r3", "to r4", "to r5", "to r6", "to r7", - "to r8", "to r9", "to r10", "to r11", "to r12", "to r13", "to r14", "to r15", - /* 20 - 2f */ - "with r0", "with r1", "with r2", "with r3", "with r4", "with r5", "with r6", "with r7", - "with r8", "with r9", "with r10", "with r11", "with r12", "with r13", "with r14", "with r15", - /* 30 - 3f */ - "stw (r0)","stw (r1)","stw (r2)", "stw (r3)", "stw (r4)", "stw (r5)", "stw (r6)", "stw (r7)", - "stw (r8)","stw (r9)","stw (r10)","stw (r11)","loop", "alt1", "alt2", "alt3", - /* 40 - 4f */ - "ldw (r0)","ldw (r1)","ldw (r2)", "ldw (r3)", "ldw (r4)", "ldw (r5)", "ldw (r6)", "ldw (r7)", - "ldw (r8)","ldw (r9)","ldw (r10)","ldw (r11)","plot", "swap", "color", "not", - /* 50 - 5f */ - "add #0", "add #1", "add #2", "add #3", "add #4", "add #5", "add #6", "add #7", - "add #8", "add #9", "add #10", "add #11", "add #12", "add #13", "add #14", "add #15", - /* 60 - 6f */ - "sub #0", "sub #1", "sub #2", "sub #3", "sub #4", "sub #5", "sub #6", "sub #7", - "sub #8", "sub #9", "sub #10", "sub #11", "sub #12", "sub #13", "sub #14", "sub #15", - /* 70 - 7f */ - "merge", "and #1", "and #2", "and #3", "and #4", "and #5", "and #6", "and #7", - "and #8", "and #9", "and #10", "and #11", "and #12", "and #13", "and #14", "and #15", - /* 80 - 8f */ - "mult #0", "mult #1", "mult #2", "mult #3", "mult #4", "mult #5", "mult #6", "mult #7", - "mult #8", "mult #9", "mult #10", "mult #11", "mult #12", "mult #13", "mult #14", "mult #15", - /* 90 - 9f */ - "sbk", "link #1", "link #2", "link #3", "link #4", "sex", "asr", "ror", - "jmp (r8)","jmp (r9)","jmp (r10)","jmp (r11)","jmp (r12)","jmp (r13)","lob", "fmult", - /* a0 - af */ - "sms ($%04x),r0", "sms ($%04x),r1", "sms ($%04x),r2", "sms ($%04x),r3", - "sms ($%04x),r4", "sms ($%04x),r5", "sms ($%04x),r6", "sms ($%04x),r7", - "sms ($%04x),r8", "sms ($%04x),r9", "sms ($%04x),r10", "sms ($%04x),r11", - "sms ($%04x),r12", "sms ($%04x),r13", "sms ($%04x),r14", "sms ($%04x),r15", - /* b0 - bf */ - "from r0", "from r1", "from r2", "from r3", "from r4", "from r5", "from r6", "from r7", - "from r8", "from r9", "from r10", "from r11", "from r12", "from r13", "from r14", "from r15", - /* c0 - cf */ - "hib", "or #1", "or #2", "or #3", "or #4", "or #5", "or #6", "or #7", - "or #8", "or #9", "or #10", "or #11", "or #12", "or #13", "or #14", "or #15", - /* d0 - df */ - "inc r0", "inc r1", "inc r2", "inc r3", "inc r4", "inc r5", "inc r6", "inc r7", - "inc r8", "inc r9", "inc r10", "inc r11", "inc r12", "inc r13", "inc r14", "ramb", - /* e0 - ef */ - "dec r0", "dec r1", "dec r2", "dec r3", "dec r4", "dec r5", "dec r6", "dec r7", - "dec r8", "dec r9", "dec r10", "dec r11", "dec r12", "dec r13", "dec r14", "getbl", - /* f0 - ff */ - "sm ($%04x),r0", "sm ($%04x),r1", "sm ($%04x),r2", "sm ($%04x),r3", - "sm ($%04x),r4", "sm ($%04x),r5", "sm ($%04x),r6", "sm ($%04x),r7", - "sm ($%04x),r8", "sm ($%04x),r9", "sm ($%04x),r10", "sm ($%04x),r11", - "sm ($%04x),r12", "sm ($%04x),r13", "sm ($%04x),r14", "sm ($%04x),r15", - - /* - * ALT3 Table - */ - - /* 00 - 0f */ - "stop", "nop", "cache", "lsr", "rol", "bra $%04x","blt $%04x","bge $%04x", - "bne $%04x","beq $%04x","bpl $%04x","bmi $%04x","bcc $%04x","bcs $%04x","bvc $%04x","bvs $%04x", - /* 10 - 1f */ - "to r0", "to r1", "to r2", "to r3", "to r4", "to r5", "to r6", "to r7", - "to r8", "to r9", "to r10", "to r11", "to r12", "to r13", "to r14", "to r15", - /* 20 - 2f */ - "with r0", "with r1", "with r2", "with r3", "with r4", "with r5", "with r6", "with r7", - "with r8", "with r9", "with r10", "with r11", "with r12", "with r13", "with r14", "with r15", - /* 30 - 3f */ - "stb (r0)","stb (r1)","stb (r2)", "stb (r3)", "stb (r4)", "stb (r5)", "stb (r6)", "stb (r7)", - "stb (r8)","stb (r9)","stb (r10)","stb (r11)","loop", "alt1", "alt2", "alt3", - /* 40 - 4f */ - "ldb (r0)","ldb (r1)","ldb (r2)", "ldb (r3)", "ldb (r4)", "ldb (r5)", "ldb (r6)", "ldb (r7)", - "ldb (r8)","ldb (r9)","ldb (r10)","ldb (r11)","rpix", "swap", "cmode", "not", - /* 50 - 5f */ - "adc #0", "adc #1", "adc #2", "adc #3", "adc #4", "adc #5", "adc #6", "adc #7", - "adc #8", "adc #9", "adc #10", "adc #11", "adc #12", "adc #13", "adc #14", "adc #15", - /* 60 - 6f */ - "cmp r0", "cmp r1", "cmp r2", "cmp r3", "cmp r4", "cmp r5", "cmp r6", "cmp r7", - "cmp r8", "cmp r9", "cmp r10", "cmp r11", "cmp r12", "cmp r13", "cmp r14", "cmp r15", - /* 70 - 7f */ - "merge", "bic #1", "bic #2", "bic #3", "bic #4", "bic #5", "bic #6", "bic #7", - "bic #8", "bic #9", "bic #10", "bic #11", "bic #12", "bic #13", "bic #14", "bic #15", - /* 80 - 8f */ - "umult #0","umult #1","umult #2", "umult #3", "umult #4", "umult #5", "umult #6", "umult #7", - "umult #8","umult #9","umult #10","umult #11","umult #12","umult #13","umult #14","umult #15", - /* 90 - 9f */ - "sbk", "link #1", "link #2", "link #3", "link #4", "sex", "div2", "ror", - "ljmp (r8)","ljmp (r9)","ljmp (r10)","ljmp (r11)", "ljmp (r12)", "ljmp (r13)", "lob", "lmult", - /* a0 - af */ - "lms r0,($%04x)", "lms r1,($%04x)", "lms r2,($%04x)", "lms r3,($%04x)", - "lms r4,($%04x)", "lms r5,($%04x)", "lms r6,($%04x)", "lms r7,($%04x)", - "lms r8,($%04x)", "lms r9,($%04x)", "lms r10,($%04x)", "lms r11,($%04x)", - "lms r12,($%04x)", "lms r13,($%04x)", "lms r14,($%04x)", "lms r15,($%04x)", - /* b0 - bf */ - "from r0", "from r1", "from r2", "from r3", "from r4", "from r5", "from r6", "from r7", - "from r8", "from r9", "from r10", "from r11", "from r12", "from r13", "from r14", "from r15", - /* c0 - cf */ - "hib", "xor #1", "xor #2", "xor #3", "xor #4", "xor #5", "xor #6", "xor #7", - "xor #8", "xor #9", "xor #10", "xor #11", "xor #12", "xor #13", "xor #14", "xor #15", - /* d0 - df */ - "inc r0", "inc r1", "inc r2", "inc r3", "inc r4", "inc r5", "inc r6", "inc r7", - "inc r8", "inc r9", "inc r10", "inc r11", "inc r12", "inc r13", "inc r14", "romb", - /* e0 - ef */ - "dec r0", "dec r1", "dec r2", "dec r3", "dec r4", "dec r5", "dec r6", "dec r7", - "dec r8", "dec r9", "dec r10", "dec r11", "dec r12", "dec r13", "dec r14", "getbs", - /* f0 - ff */ - "lm r0,($%04x)", "lm r1,($%04x)", "lm r2,($%04x)", "lm r3,($%04x)", - "lm r4,($%04x)", "lm r5,($%04x)", "lm r6,($%04x)", "lm r7,($%04x)", - "lm r8,($%04x)", "lm r9,($%04x)", "lm r10,($%04x)", "lm r11,($%04x)", - "lm r12,($%04x)", "lm r13,($%04x)", "lm r14,($%04x)", "lm r15,($%04x)", + /* + * ALT0 Table + */ + /* 00 - 0f */ + "stop", "nop", "cache", "lsr", "rol", "bra $%04x", "blt $%04x", "bge $%04x", + "bne $%04x", "beq $%04x", "bpl $%04x", "bmi $%04x", "bcc $%04x", "bcs $%04x", "bvc $%04x", "bvs $%04x", + /* 10 - 1f */ + "to r0", "to r1", "to r2", "to r3", "to r4", "to r5", "to r6", "to r7", + "to r8", "to r9", "to r10", "to r11", "to r12", "to r13", "to r14", "to r15", + /* 20 - 2f */ + "with r0", "with r1", "with r2", "with r3", "with r4", "with r5", "with r6", "with r7", + "with r8", "with r9", "with r10", "with r11", "with r12", "with r13", "with r14", "with r15", + /* 30 - 3f */ + "stw (r0)", "stw (r1)", "stw (r2)", "stw (r3)", "stw (r4)", "stw (r5)", "stw (r6)", "stw (r7)", + "stw (r8)", "stw (r9)", "stw (r10)", "stw (r11)", "loop", "alt1", "alt2", "alt3", + /* 40 - 4f */ + "ldw (r0)", "ldw (r1)", "ldw (r2)", "ldw (r3)", "ldw (r4)", "ldw (r5)", "ldw (r6)", "ldw (r7)", + "ldw (r8)", "ldw (r9)", "ldw (r10)", "ldw (r11)", "plot", "swap", "color", "not", + /* 50 - 5f */ + "add r0", "add r1", "add r2", "add r3", "add r4", "add r5", "add r6", "add r7", + "add r8", "add r9", "add r10", "add r11", "add r12", "add r13", "add r14", "add r15", + /* 60 - 6f */ + "sub r0", "sub r1", "sub r2", "sub r3", "sub r4", "sub r5", "sub r6", "sub r7", + "sub r8", "sub r9", "sub r10", "sub r11", "sub r12", "sub r13", "sub r14", "sub r15", + /* 70 - 7f */ + "merge", "and r1", "and r2", "and r3", "and r4", "and r5", "and r6", "and r7", + "and r8", "and r9", "and r10", "and r11", "and r12", "and r13", "and r14", "and r15", + /* 80 - 8f */ + "mult r0", "mult r1", "mult r2", "mult r3", "mult r4", "mult r5", "mult r6", "mult r7", + "mult r8", "mult r9", "mult r10", "mult r11", "mult r12", "mult r13", "mult r14", "mult r15", + /* 90 - 9f */ + "sbk", "link #1", "link #2", "link #3", "link #4", "sex", "asr", "ror", + "jmp (r8)", "jmp (r9)", "jmp (r10)", "jmp (r11)", "jmp (r12)", "jmp (r13)", "lob", "fmult", + /* a0 - af */ + "ibt r0,#$%02x", "ibt r1,#$%02x", "ibt r2,#$%02x", "ibt r3,#$%02x", + "ibt r4,#$%02x", "ibt r5,#$%02x", "ibt r6,#$%02x", "ibt r7,#$%02x", + "ibt r8,#$%02x", "ibt r9,#$%02x", "ibt r10,#$%02x", "ibt r11,#$%02x", + "ibt r12,#$%02x", "ibt r13,#$%02x", "ibt r14,#$%02x", "ibt r15,#$%02x", + /* b0 - bf */ + "from r0", "from r1", "from r2", "from r3", "from r4", "from r5", "from r6", "from r7", + "from r8", "from r9", "from r10", "from r11", "from r12", "from r13", "from r14", "from r15", + /* c0 - cf */ + "hib", "or r1", "or r2", "or r3", "or r4", "or r5", "or r6", "or r7", + "or r8", "or r9", "or r10", "or r11", "or r12", "or r13", "or r14", "or r15", + /* d0 - df */ + "inc r0", "inc r1", "inc r2", "inc r3", "inc r4", "inc r5", "inc r6", "inc r7", + "inc r8", "inc r9", "inc r10", "inc r11", "inc r12", "inc r13", "inc r14", "getc", + /* e0 - ef */ + "dec r0", "dec r1", "dec r2", "dec r3", "dec r4", "dec r5", "dec r6", "dec r7", + "dec r8", "dec r9", "dec r10", "dec r11", "dec r12", "dec r13", "dec r14", "getb", + /* f0 - ff */ + "iwt r0,#$%04x", "iwt r1,#$%04x", "iwt r2,#$%04x", "iwt r3,#$%04x", + "iwt r4,#$%04x", "iwt r5,#$%04x", "iwt r6,#$%04x", "iwt r7,#$%04x", + "iwt r8,#$%04x", "iwt r9,#$%04x", "iwt r10,#$%04x", "iwt r11,#$%04x", + "iwt r12,#$%04x", "iwt r13,#$%04x", "iwt r14,#$%04x", "iwt r15,#$%04x", + + /* + * ALT1 Table + */ + + /* 00 - 0f */ + "stop", "nop", "cache", "lsr", "rol", "bra $%04x", "blt $%04x", "bge $%04x", + "bne $%04x", "beq $%04x", "bpl $%04x", "bmi $%04x", "bcc $%04x", "bcs $%04x", "bvc $%04x", "bvs $%04x", + /* 10 - 1f */ + "to r0", "to r1", "to r2", "to r3", "to r4", "to r5", "to r6", "to r7", + "to r8", "to r9", "to r10", "to r11", "to r12", "to r13", "to r14", "to r15", + /* 20 - 2f */ + "with r0", "with r1", "with r2", "with r3", "with r4", "with r5", "with r6", "with r7", + "with r8", "with r9", "with r10", "with r11", "with r12", "with r13", "with r14", "with r15", + /* 30 - 3f */ + "stb (r0)", "stb (r1)", "stb (r2)", "stb (r3)", "stb (r4)", "stb (r5)", "stb (r6)", "stb (r7)", + "stb (r8)", "stb (r9)", "stb (r10)", "stb (r11)", "loop", "alt1", "alt2", "alt3", + /* 40 - 4f */ + "ldb (r0)", "ldb (r1)", "ldb (r2)", "ldb (r3)", "ldb (r4)", "ldb (r5)", "ldb (r6)", "ldb (r7)", + "ldb (r8)", "ldb (r9)", "ldb (r10)", "ldb (r11)", "rpix", "swap", "cmode", "not", + /* 50 - 5f */ + "adc r0", "adc r1", "adc r2", "adc r3", "adc r4", "adc r5", "adc r6", "adc r7", + "adc r8", "adc r9", "adc r10", "adc r11", "adc r12", "adc r13", "adc r14", "adc r15", + /* 60 - 6f */ + "sbc r0", "sbc r1", "sbc r2", "sbc r3", "sbc r4", "sbc r5", "sbc r6", "sbc r7", + "sbc r8", "sbc r9", "sbc r10", "sbc r11", "sbc r12", "sbc r13", "sbc r14", "sbc r15", + /* 70 - 7f */ + "merge", "bic r1", "bic r2", "bic r3", "bic r4", "bic r5", "bic r6", "bic r7", + "bic r8", "bic r9", "bic r10", "bic r11", "bic r12", "bic r13", "bic r14", "bic r15", + /* 80 - 8f */ + "umult r0", "umult r1", "umult r2", "umult r3", "umult r4", "umult r5", "umult r6", "umult r7", + "umult r8", "umult r9", "umult r10", "umult r11", "umult r12", "umult r13", "umult r14", "umult r15", + /* 90 - 9f */ + "sbk", "link #1", "link #2", "link #3", "link #4", "sex", "div2", "ror", + "ljmp (r8)", "ljmp (r9)", "ljmp (r10)", "ljmp (r11)", "ljmp (r12)", "ljmp (r13)", "lob", "lmult", + /* a0 - af */ + "lms r0,($%04x)", "lms r1,($%04x)", "lms r2,($%04x)", "lms r3,($%04x)", + "lms r4,($%04x)", "lms r5,($%04x)", "lms r6,($%04x)", "lms r7,($%04x)", + "lms r8,($%04x)", "lms r9,($%04x)", "lms r10,($%04x)", "lms r11,($%04x)", + "lms r12,($%04x)", "lms r13,($%04x)", "lms r14,($%04x)", "lms r15,($%04x)", + /* b0 - bf */ + "from r0", "from r1", "from r2", "from r3", "from r4", "from r5", "from r6", "from r7", + "from r8", "from r9", "from r10", "from r11", "from r12", "from r13", "from r14", "from r15", + /* c0 - cf */ + "hib", "xor r1", "xor r2", "xor r3", "xor r4", "xor r5", "xor r6", "xor r7", + "xor r8", "xor r9", "xor r10", "xor r11", "xor r12", "xor r13", "xor r14", "xor r15", + /* d0 - df */ + "inc r0", "inc r1", "inc r2", "inc r3", "inc r4", "inc r5", "inc r6", "inc r7", + "inc r8", "inc r9", "inc r10", "inc r11", "inc r12", "inc r13", "inc r14", "getc", + /* e0 - ef */ + "dec r0", "dec r1", "dec r2", "dec r3", "dec r4", "dec r5", "dec r6", "dec r7", + "dec r8", "dec r9", "dec r10", "dec r11", "dec r12", "dec r13", "dec r14", "getbh", + /* f0 - ff */ + "lm r0,($%04x)", "lm r1,($%04x)", "lm r2,($%04x)", "lm r3,($%04x)", + "lm r4,($%04x)", "lm r5,($%04x)", "lm r6,($%04x)", "lm r7,($%04x)", + "lm r8,($%04x)", "lm r9,($%04x)", "lm r10,($%04x)", "lm r11,($%04x)", + "lm r12,($%04x)", "lm r13,($%04x)", "lm r14,($%04x)", "lm r15,($%04x)", + + /* + * ALT2 Table + */ + + /* 00 - 0f */ + "stop", "nop", "cache", "lsr", "rol", "bra $%04x", "blt $%04x", "bge $%04x", + "bne $%04x", "beq $%04x", "bpl $%04x", "bmi $%04x", "bcc $%04x", "bcs $%04x", "bvc $%04x", "bvs $%04x", + /* 10 - 1f */ + "to r0", "to r1", "to r2", "to r3", "to r4", "to r5", "to r6", "to r7", + "to r8", "to r9", "to r10", "to r11", "to r12", "to r13", "to r14", "to r15", + /* 20 - 2f */ + "with r0", "with r1", "with r2", "with r3", "with r4", "with r5", "with r6", "with r7", + "with r8", "with r9", "with r10", "with r11", "with r12", "with r13", "with r14", "with r15", + /* 30 - 3f */ + "stw (r0)", "stw (r1)", "stw (r2)", "stw (r3)", "stw (r4)", "stw (r5)", "stw (r6)", "stw (r7)", + "stw (r8)", "stw (r9)", "stw (r10)", "stw (r11)", "loop", "alt1", "alt2", "alt3", + /* 40 - 4f */ + "ldw (r0)", "ldw (r1)", "ldw (r2)", "ldw (r3)", "ldw (r4)", "ldw (r5)", "ldw (r6)", "ldw (r7)", + "ldw (r8)", "ldw (r9)", "ldw (r10)", "ldw (r11)", "plot", "swap", "color", "not", + /* 50 - 5f */ + "add #0", "add #1", "add #2", "add #3", "add #4", "add #5", "add #6", "add #7", + "add #8", "add #9", "add #10", "add #11", "add #12", "add #13", "add #14", "add #15", + /* 60 - 6f */ + "sub #0", "sub #1", "sub #2", "sub #3", "sub #4", "sub #5", "sub #6", "sub #7", + "sub #8", "sub #9", "sub #10", "sub #11", "sub #12", "sub #13", "sub #14", "sub #15", + /* 70 - 7f */ + "merge", "and #1", "and #2", "and #3", "and #4", "and #5", "and #6", "and #7", + "and #8", "and #9", "and #10", "and #11", "and #12", "and #13", "and #14", "and #15", + /* 80 - 8f */ + "mult #0", "mult #1", "mult #2", "mult #3", "mult #4", "mult #5", "mult #6", "mult #7", + "mult #8", "mult #9", "mult #10", "mult #11", "mult #12", "mult #13", "mult #14", "mult #15", + /* 90 - 9f */ + "sbk", "link #1", "link #2", "link #3", "link #4", "sex", "asr", "ror", + "jmp (r8)", "jmp (r9)", "jmp (r10)", "jmp (r11)", "jmp (r12)", "jmp (r13)", "lob", "fmult", + /* a0 - af */ + "sms ($%04x),r0", "sms ($%04x),r1", "sms ($%04x),r2", "sms ($%04x),r3", + "sms ($%04x),r4", "sms ($%04x),r5", "sms ($%04x),r6", "sms ($%04x),r7", + "sms ($%04x),r8", "sms ($%04x),r9", "sms ($%04x),r10", "sms ($%04x),r11", + "sms ($%04x),r12", "sms ($%04x),r13", "sms ($%04x),r14", "sms ($%04x),r15", + /* b0 - bf */ + "from r0", "from r1", "from r2", "from r3", "from r4", "from r5", "from r6", "from r7", + "from r8", "from r9", "from r10", "from r11", "from r12", "from r13", "from r14", "from r15", + /* c0 - cf */ + "hib", "or #1", "or #2", "or #3", "or #4", "or #5", "or #6", "or #7", + "or #8", "or #9", "or #10", "or #11", "or #12", "or #13", "or #14", "or #15", + /* d0 - df */ + "inc r0", "inc r1", "inc r2", "inc r3", "inc r4", "inc r5", "inc r6", "inc r7", + "inc r8", "inc r9", "inc r10", "inc r11", "inc r12", "inc r13", "inc r14", "ramb", + /* e0 - ef */ + "dec r0", "dec r1", "dec r2", "dec r3", "dec r4", "dec r5", "dec r6", "dec r7", + "dec r8", "dec r9", "dec r10", "dec r11", "dec r12", "dec r13", "dec r14", "getbl", + /* f0 - ff */ + "sm ($%04x),r0", "sm ($%04x),r1", "sm ($%04x),r2", "sm ($%04x),r3", + "sm ($%04x),r4", "sm ($%04x),r5", "sm ($%04x),r6", "sm ($%04x),r7", + "sm ($%04x),r8", "sm ($%04x),r9", "sm ($%04x),r10", "sm ($%04x),r11", + "sm ($%04x),r12", "sm ($%04x),r13", "sm ($%04x),r14", "sm ($%04x),r15", + + /* + * ALT3 Table + */ + + /* 00 - 0f */ + "stop", "nop", "cache", "lsr", "rol", "bra $%04x", "blt $%04x", "bge $%04x", + "bne $%04x", "beq $%04x", "bpl $%04x", "bmi $%04x", "bcc $%04x", "bcs $%04x", "bvc $%04x", "bvs $%04x", + /* 10 - 1f */ + "to r0", "to r1", "to r2", "to r3", "to r4", "to r5", "to r6", "to r7", + "to r8", "to r9", "to r10", "to r11", "to r12", "to r13", "to r14", "to r15", + /* 20 - 2f */ + "with r0", "with r1", "with r2", "with r3", "with r4", "with r5", "with r6", "with r7", + "with r8", "with r9", "with r10", "with r11", "with r12", "with r13", "with r14", "with r15", + /* 30 - 3f */ + "stb (r0)", "stb (r1)", "stb (r2)", "stb (r3)", "stb (r4)", "stb (r5)", "stb (r6)", "stb (r7)", + "stb (r8)", "stb (r9)", "stb (r10)", "stb (r11)", "loop", "alt1", "alt2", "alt3", + /* 40 - 4f */ + "ldb (r0)", "ldb (r1)", "ldb (r2)", "ldb (r3)", "ldb (r4)", "ldb (r5)", "ldb (r6)", "ldb (r7)", + "ldb (r8)", "ldb (r9)", "ldb (r10)", "ldb (r11)", "rpix", "swap", "cmode", "not", + /* 50 - 5f */ + "adc #0", "adc #1", "adc #2", "adc #3", "adc #4", "adc #5", "adc #6", "adc #7", + "adc #8", "adc #9", "adc #10", "adc #11", "adc #12", "adc #13", "adc #14", "adc #15", + /* 60 - 6f */ + "cmp r0", "cmp r1", "cmp r2", "cmp r3", "cmp r4", "cmp r5", "cmp r6", "cmp r7", + "cmp r8", "cmp r9", "cmp r10", "cmp r11", "cmp r12", "cmp r13", "cmp r14", "cmp r15", + /* 70 - 7f */ + "merge", "bic #1", "bic #2", "bic #3", "bic #4", "bic #5", "bic #6", "bic #7", + "bic #8", "bic #9", "bic #10", "bic #11", "bic #12", "bic #13", "bic #14", "bic #15", + /* 80 - 8f */ + "umult #0", "umult #1", "umult #2", "umult #3", "umult #4", "umult #5", "umult #6", "umult #7", + "umult #8", "umult #9", "umult #10", "umult #11", "umult #12", "umult #13", "umult #14", "umult #15", + /* 90 - 9f */ + "sbk", "link #1", "link #2", "link #3", "link #4", "sex", "div2", "ror", + "ljmp (r8)", "ljmp (r9)", "ljmp (r10)", "ljmp (r11)", "ljmp (r12)", "ljmp (r13)", "lob", "lmult", + /* a0 - af */ + "lms r0,($%04x)", "lms r1,($%04x)", "lms r2,($%04x)", "lms r3,($%04x)", + "lms r4,($%04x)", "lms r5,($%04x)", "lms r6,($%04x)", "lms r7,($%04x)", + "lms r8,($%04x)", "lms r9,($%04x)", "lms r10,($%04x)", "lms r11,($%04x)", + "lms r12,($%04x)", "lms r13,($%04x)", "lms r14,($%04x)", "lms r15,($%04x)", + /* b0 - bf */ + "from r0", "from r1", "from r2", "from r3", "from r4", "from r5", "from r6", "from r7", + "from r8", "from r9", "from r10", "from r11", "from r12", "from r13", "from r14", "from r15", + /* c0 - cf */ + "hib", "xor #1", "xor #2", "xor #3", "xor #4", "xor #5", "xor #6", "xor #7", + "xor #8", "xor #9", "xor #10", "xor #11", "xor #12", "xor #13", "xor #14", "xor #15", + /* d0 - df */ + "inc r0", "inc r1", "inc r2", "inc r3", "inc r4", "inc r5", "inc r6", "inc r7", + "inc r8", "inc r9", "inc r10", "inc r11", "inc r12", "inc r13", "inc r14", "romb", + /* e0 - ef */ + "dec r0", "dec r1", "dec r2", "dec r3", "dec r4", "dec r5", "dec r6", "dec r7", + "dec r8", "dec r9", "dec r10", "dec r11", "dec r12", "dec r13", "dec r14", "getbs", + /* f0 - ff */ + "lm r0,($%04x)", "lm r1,($%04x)", "lm r2,($%04x)", "lm r3,($%04x)", + "lm r4,($%04x)", "lm r5,($%04x)", "lm r6,($%04x)", "lm r7,($%04x)", + "lm r8,($%04x)", "lm r9,($%04x)", "lm r10,($%04x)", "lm r11,($%04x)", + "lm r12,($%04x)", "lm r13,($%04x)", "lm r14,($%04x)", "lm r15,($%04x)", }; diff --git a/source/fxemu.c b/source/fxemu.c index 8dd7a15..b0ec6c7 100644 --- a/source/fxemu.c +++ b/source/fxemu.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -95,632 +95,636 @@ /* The FxChip Emulator's internal variables */ struct FxRegs_s GSU = FxRegs_s_null; -uint32 (**fx_ppfFunctionTable)(uint32) = 0; +uint32(**fx_ppfFunctionTable)(uint32) = 0; void (**fx_ppfPlotTable)() = 0; void (**fx_ppfOpcodeTable)() = 0; #if 0 void fx_setCache() { - uint32 c; - GSU.bCacheActive = TRUE; - GSU.pvRegisters[0x3e] &= 0xf0; - c = (uint32)GSU.pvRegisters[0x3e]; - c |= ((uint32)GSU.pvRegisters[0x3f])<<8; - if(c == GSU.vCacheBaseReg) - return; - GSU.vCacheBaseReg = c; - GSU.vCacheFlags = 0; - if(c < (0x10000-512)) - { - uint8 const* t = &ROM(c); - memcpy(GSU.pvCache,t,512); - } - else - { - uint8 const* t1; - uint8 const* t2; - uint32 i = 0x10000 - c; - t1 = &ROM(c); - t2 = &ROM(0); - memcpy(GSU.pvCache,t1,i); - memcpy(&GSU.pvCache[i],t2,512-i); - } + uint32 c; + GSU.bCacheActive = TRUE; + GSU.pvRegisters[0x3e] &= 0xf0; + c = (uint32)GSU.pvRegisters[0x3e]; + c |= ((uint32)GSU.pvRegisters[0x3f]) << 8; + if (c == GSU.vCacheBaseReg) + return; + GSU.vCacheBaseReg = c; + GSU.vCacheFlags = 0; + if (c < (0x10000 - 512)) + { + uint8 const* t = &ROM(c); + memcpy(GSU.pvCache, t, 512); + } + else + { + uint8 const* t1; + uint8 const* t2; + uint32 i = 0x10000 - c; + t1 = &ROM(c); + t2 = &ROM(0); + memcpy(GSU.pvCache, t1, i); + memcpy(&GSU.pvCache[i], t2, 512 - i); + } } #endif void FxCacheWriteAccess(uint16 vAddress) { #if 0 - if(!GSU.bCacheActive) - { - uint8 v = GSU.pvCache[GSU.pvCache[vAddress&0x1ff]; - fx_setCache(); - GSU.pvCache[GSU.pvCache[vAddress&0x1ff] = v; - } + if (!GSU.bCacheActive) + { + uint8 v = GSU.pvCache[GSU.pvCache[vAddress & 0x1ff]; + fx_setCache(); + GSU.pvCache[GSU.pvCache[vAddress & 0x1ff] = v; + } #endif - if((vAddress & 0x00f) == 0x00f) - GSU.vCacheFlags |= 1 << ((vAddress&0x1f0) >> 4); + if ((vAddress & 0x00f) == 0x00f) + GSU.vCacheFlags |= 1 << ((vAddress & 0x1f0) >> 4); } -void FxFlushCache() + void FxFlushCache() { - GSU.vCacheFlags = 0; - GSU.vCacheBaseReg = 0; - GSU.bCacheActive = FALSE; -// GSU.vPipe = 0x1; + GSU.vCacheFlags = 0; + GSU.vCacheBaseReg = 0; + GSU.bCacheActive = FALSE; + // GSU.vPipe = 0x1; } static void fx_backupCache() { #if 0 - uint32 i; - uint32 v = GSU.vCacheFlags; - uint32 c = USEX16(GSU.vCacheBaseReg); - if(v) - for(i=0; i<32; i++) - { - if(v&1) - { - if(c < (0x10000-16)) - { - uint8 * t = &GSU.pvPrgBank[c]; - memcpy(&GSU.avCacheBackup[i<<4],t,16); - memcpy(t,&GSU.pvCache[i<<4],16); - } - else - { - uint8 * t1; - uint8 * t2; - uint32 a = 0x10000 - c; - t1 = &GSU.pvPrgBank[c]; - t2 = &GSU.pvPrgBank[0]; - memcpy(&GSU.avCacheBackup[i<<4],t1,a); - memcpy(t1,&GSU.pvCache[i<<4],a); - memcpy(&GSU.avCacheBackup[(i<<4)+a],t2,16-a); - memcpy(t2,&GSU.pvCache[(i<<4)+a],16-a); - } - } - c = USEX16(c+16); - v >>= 1; - } + uint32 i; + uint32 v = GSU.vCacheFlags; + uint32 c = USEX16(GSU.vCacheBaseReg); + if (v) + for (i = 0; i < 32; i++) + { + if (v & 1) + { + if (c < (0x10000 - 16)) + { + uint8* t = &GSU.pvPrgBank[c]; + memcpy(&GSU.avCacheBackup[i << 4], t, 16); + memcpy(t, &GSU.pvCache[i << 4], 16); + } + else + { + uint8* t1; + uint8* t2; + uint32 a = 0x10000 - c; + t1 = &GSU.pvPrgBank[c]; + t2 = &GSU.pvPrgBank[0]; + memcpy(&GSU.avCacheBackup[i << 4], t1, a); + memcpy(t1, &GSU.pvCache[i << 4], a); + memcpy(&GSU.avCacheBackup[(i << 4) + a], t2, 16 - a); + memcpy(t2, &GSU.pvCache[(i << 4) + a], 16 - a); + } + } + c = USEX16(c + 16); + v >>= 1; + } #endif } static void fx_restoreCache() { #if 0 - uint32 i; - uint32 v = GSU.vCacheFlags; - uint32 c = USEX16(GSU.vCacheBaseReg); - if(v) - for(i=0; i<32; i++) - { - if(v&1) - { - if(c < (0x10000-16)) - { - uint8 * t = &GSU.pvPrgBank[c]; - memcpy(t,&GSU.avCacheBackup[i<<4],16); - memcpy(&GSU.pvCache[i<<4],t,16); - } - else - { - uint8 * t1; - uint8 * t2; - uint32 a = 0x10000 - c; - t1 = &GSU.pvPrgBank[c]; - t2 = &GSU.pvPrgBank[0]; - memcpy(t1,&GSU.avCacheBackup[i<<4],a); - memcpy(&GSU.pvCache[i<<4],t1,a); - memcpy(t2,&GSU.avCacheBackup[(i<<4)+a],16-a); - memcpy(&GSU.pvCache[(i<<4)+a],t2,16-a); - } - } - c = USEX16(c+16); - v >>= 1; - } + uint32 i; + uint32 v = GSU.vCacheFlags; + uint32 c = USEX16(GSU.vCacheBaseReg); + if (v) + for (i = 0; i < 32; i++) + { + if (v & 1) + { + if (c < (0x10000 - 16)) + { + uint8* t = &GSU.pvPrgBank[c]; + memcpy(t, &GSU.avCacheBackup[i << 4], 16); + memcpy(&GSU.pvCache[i << 4], t, 16); + } + else + { + uint8* t1; + uint8* t2; + uint32 a = 0x10000 - c; + t1 = &GSU.pvPrgBank[c]; + t2 = &GSU.pvPrgBank[0]; + memcpy(t1, &GSU.avCacheBackup[i << 4], a); + memcpy(&GSU.pvCache[i << 4], t1, a); + memcpy(t2, &GSU.avCacheBackup[(i << 4) + a], 16 - a); + memcpy(&GSU.pvCache[(i << 4) + a], t2, 16 - a); + } + } + c = USEX16(c + 16); + v >>= 1; + } #endif } void fx_flushCache() { - fx_restoreCache(); - GSU.vCacheFlags = 0; - GSU.bCacheActive = FALSE; + fx_restoreCache(); + GSU.vCacheFlags = 0; + GSU.bCacheActive = FALSE; } void fx_updateRamBank(uint8 Byte) { - // Update BankReg and Bank pointer - GSU.vRamBankReg = (uint32)Byte & (FX_RAM_BANKS-1); - GSU.pvRamBank = GSU.apvRamBank[Byte & 0x3]; + // Update BankReg and Bank pointer + GSU.vRamBankReg = (uint32)Byte & (FX_RAM_BANKS - 1); + GSU.pvRamBank = GSU.apvRamBank[Byte & 0x3]; } static void fx_readRegisterSpace() { - int i; - uint8 *p; - static uint32 avHeight[] = { 128, 160, 192, 256 }; - static uint32 avMult[] = { 16, 32, 32, 64 }; - - GSU.vErrorCode = 0; - - /* Update R0-R15 */ - p = GSU.pvRegisters; - for(i=0; i<16; i++) - { - GSU.avReg[i] = *p++; - GSU.avReg[i] += ((uint32)(*p++)) << 8; - } - - /* Update other registers */ - p = GSU.pvRegisters; - GSU.vStatusReg = (uint32)p[GSU_SFR]; - GSU.vStatusReg |= ((uint32)p[GSU_SFR+1]) << 8; - GSU.vPrgBankReg = (uint32)p[GSU_PBR]; - GSU.vRomBankReg = (uint32)p[GSU_ROMBR]; - GSU.vRamBankReg = ((uint32)p[GSU_RAMBR]) & (FX_RAM_BANKS-1); - GSU.vCacheBaseReg = (uint32)p[GSU_CBR]; - GSU.vCacheBaseReg |= ((uint32)p[GSU_CBR+1]) << 8; - - /* Update status register variables */ - GSU.vZero = !(GSU.vStatusReg & FLG_Z); - GSU.vSign = (GSU.vStatusReg & FLG_S) << 12; - GSU.vOverflow = (GSU.vStatusReg & FLG_OV) << 16; - GSU.vCarry = (GSU.vStatusReg & FLG_CY) >> 2; - - /* Set bank pointers */ - GSU.pvRamBank = GSU.apvRamBank[GSU.vRamBankReg & 0x3]; - GSU.pvRomBank = GSU.apvRomBank[GSU.vRomBankReg]; - GSU.pvPrgBank = GSU.apvRomBank[GSU.vPrgBankReg]; - - /* Set screen pointers */ - GSU.pvScreenBase = &GSU.pvRam[ USEX8(p[GSU_SCBR]) << 10 ]; - i = (int)(!!(p[GSU_SCMR] & 0x04)); - i |= ((int)(!!(p[GSU_SCMR] & 0x20))) << 1; - GSU.vScreenHeight = GSU.vScreenRealHeight = avHeight[i]; - GSU.vMode = p[GSU_SCMR] & 0x03; + int i; + uint8* p; + static uint32 avHeight[] = { 128, 160, 192, 256 }; + static uint32 avMult[] = { 16, 32, 32, 64 }; + + GSU.vErrorCode = 0; + + /* Update R0-R15 */ + p = GSU.pvRegisters; + for (i = 0; i < 16; i++) + { + GSU.avReg[i] = *p++; + GSU.avReg[i] += ((uint32)(*p++)) << 8; + } + + /* Update other registers */ + p = GSU.pvRegisters; + GSU.vStatusReg = (uint32)p[GSU_SFR]; + GSU.vStatusReg |= ((uint32)p[GSU_SFR + 1]) << 8; + GSU.vPrgBankReg = (uint32)p[GSU_PBR]; + GSU.vRomBankReg = (uint32)p[GSU_ROMBR]; + GSU.vRamBankReg = ((uint32)p[GSU_RAMBR]) & (FX_RAM_BANKS - 1); + GSU.vCacheBaseReg = (uint32)p[GSU_CBR]; + GSU.vCacheBaseReg |= ((uint32)p[GSU_CBR + 1]) << 8; + + /* Update status register variables */ + GSU.vZero = !(GSU.vStatusReg & FLG_Z); + GSU.vSign = (GSU.vStatusReg & FLG_S) << 12; + GSU.vOverflow = (GSU.vStatusReg & FLG_OV) << 16; + GSU.vCarry = (GSU.vStatusReg & FLG_CY) >> 2; + + /* Set bank pointers */ + GSU.pvRamBank = GSU.apvRamBank[GSU.vRamBankReg & 0x3]; + GSU.pvRomBank = GSU.apvRomBank[GSU.vRomBankReg]; + GSU.pvPrgBank = GSU.apvRomBank[GSU.vPrgBankReg]; + + /* Set screen pointers */ + GSU.pvScreenBase = &GSU.pvRam[ USEX8(p[GSU_SCBR]) << 10 ]; + i = (int)(!!(p[GSU_SCMR] & 0x04)); + i |= ((int)(!!(p[GSU_SCMR] & 0x20))) << 1; + GSU.vScreenHeight = GSU.vScreenRealHeight = avHeight[i]; + GSU.vMode = p[GSU_SCMR] & 0x03; #if 0 - if(GSU.vMode == 2) - error illegal color depth GSU.vMode; + if (GSU.vMode == 2) + error illegal color depth GSU.vMode; #endif - if(i == 3) - GSU.vScreenSize = (256/8) * (256/8) * 32; - else - GSU.vScreenSize = (GSU.vScreenHeight/8) * (256/8) * avMult[GSU.vMode]; - if (GSU.vPlotOptionReg & 0x10) - { - /* OBJ Mode (for drawing into sprites) */ - GSU.vScreenHeight = 256; - } + if (i == 3) + GSU.vScreenSize = (256 / 8) * (256 / 8) * 32; + else + GSU.vScreenSize = (GSU.vScreenHeight / 8) * (256 / 8) * avMult[GSU.vMode]; + if (GSU.vPlotOptionReg & 0x10) + { + /* OBJ Mode (for drawing into sprites) */ + GSU.vScreenHeight = 256; + } #if 0 - if(GSU.pvScreenBase + GSU.vScreenSize > GSU.pvRam + (GSU.nRamBanks * 65536)) - error illegal address for screen base register + if (GSU.pvScreenBase + GSU.vScreenSize > GSU.pvRam + (GSU.nRamBanks * 65536)) + error illegal address for screen base register #else - if(GSU.pvScreenBase + GSU.vScreenSize > GSU.pvRam + (GSU.nRamBanks * 65536)) - GSU.pvScreenBase = GSU.pvRam + (GSU.nRamBanks * 65536) - GSU.vScreenSize; + if (GSU.pvScreenBase + GSU.vScreenSize > GSU.pvRam + (GSU.nRamBanks * 65536)) + GSU.pvScreenBase = GSU.pvRam + (GSU.nRamBanks * 65536) - GSU.vScreenSize; #endif - GSU.pfPlot = fx_apfPlotTable[GSU.vMode]; - GSU.pfRpix = fx_apfPlotTable[GSU.vMode + 5]; + GSU.pfPlot = fx_apfPlotTable[GSU.vMode]; + GSU.pfRpix = fx_apfPlotTable[GSU.vMode + 5]; - fx_ppfOpcodeTable[0x04c] = GSU.pfPlot; - fx_ppfOpcodeTable[0x14c] = GSU.pfRpix; - fx_ppfOpcodeTable[0x24c] = GSU.pfPlot; - fx_ppfOpcodeTable[0x34c] = GSU.pfRpix; + fx_ppfOpcodeTable[0x04c] = GSU.pfPlot; + fx_ppfOpcodeTable[0x14c] = GSU.pfRpix; + fx_ppfOpcodeTable[0x24c] = GSU.pfPlot; + fx_ppfOpcodeTable[0x34c] = GSU.pfRpix; - fx_computeScreenPointers (); + fx_computeScreenPointers(); - fx_backupCache(); + fx_backupCache(); } void fx_dirtySCBR() { - GSU.vSCBRDirty = TRUE; + GSU.vSCBRDirty = TRUE; } -void fx_computeScreenPointers () +void fx_computeScreenPointers() { - if (GSU.vMode != GSU.vPrevMode || - GSU.vPrevScreenHeight != GSU.vScreenHeight || - GSU.vSCBRDirty) - { - int i; - - GSU.vSCBRDirty = FALSE; - - /* Make a list of pointers to the start of each screen column */ - switch (GSU.vScreenHeight) - { - case 128: - switch (GSU.vMode) - { - case 0: - for (i = 0; i < 32; i++) - { - GSU.apvScreen[i] = GSU.pvScreenBase + (i << 4); - GSU.x[i] = i << 8; - } - break; - case 1: - for (i = 0; i < 32; i++) - { - GSU.apvScreen[i] = GSU.pvScreenBase + (i << 5); - GSU.x[i] = i << 9; - } - break; - case 2: - case 3: - for (i = 0; i < 32; i++) - { - GSU.apvScreen[i] = GSU.pvScreenBase + (i << 6); - GSU.x[i] = i << 10; - } - break; - } - break; - case 160: - switch (GSU.vMode) - { - case 0: - for (i = 0; i < 32; i++) - { - GSU.apvScreen[i] = GSU.pvScreenBase + (i << 4); - GSU.x[i] = (i << 8) + (i << 6); - } - break; - case 1: - for (i = 0; i < 32; i++) - { - GSU.apvScreen[i] = GSU.pvScreenBase + (i << 5); - GSU.x[i] = (i << 9) + (i << 7); - } - break; - case 2: - case 3: - for (i = 0; i < 32; i++) - { - GSU.apvScreen[i] = GSU.pvScreenBase + (i << 6); - GSU.x[i] = (i << 10) + (i << 8); - } - break; - } - break; - case 192: - switch (GSU.vMode) - { - case 0: - for (i = 0; i < 32; i++) - { - GSU.apvScreen[i] = GSU.pvScreenBase + (i << 4); - GSU.x[i] = (i << 8) + (i << 7); - } - break; - case 1: - for (i = 0; i < 32; i++) - { - GSU.apvScreen[i] = GSU.pvScreenBase + (i << 5); - GSU.x[i] = (i << 9) + (i << 8); - } - break; - case 2: - case 3: - for (i = 0; i < 32; i++) - { - GSU.apvScreen[i] = GSU.pvScreenBase + (i << 6); - GSU.x[i] = (i << 10) + (i << 9); - } - break; - } - break; - case 256: - switch (GSU.vMode) - { - case 0: - for (i = 0; i < 32; i++) - { - GSU.apvScreen[i] = GSU.pvScreenBase + - ((i & 0x10) << 9) + ((i & 0xf) << 8); - GSU.x[i] = ((i & 0x10) << 8) + ((i & 0xf) << 4); - } - break; - case 1: - for (i = 0; i < 32; i++) - { - GSU.apvScreen[i] = GSU.pvScreenBase + - ((i & 0x10) << 10) + ((i & 0xf) << 9); - GSU.x[i] = ((i & 0x10) << 9) + ((i & 0xf) << 5); - } - break; - case 2: - case 3: - for (i = 0; i < 32; i++) - { - GSU.apvScreen[i] = GSU.pvScreenBase + - ((i & 0x10) << 11) + ((i & 0xf) << 10); - GSU.x[i] = ((i & 0x10) << 10) + ((i & 0xf) << 6); - } - break; - } - break; - } - GSU.vPrevMode = GSU.vMode; - GSU.vPrevScreenHeight = GSU.vScreenHeight; - } + if (GSU.vMode != GSU.vPrevMode || + GSU.vPrevScreenHeight != GSU.vScreenHeight || + GSU.vSCBRDirty) + { + int i; + + GSU.vSCBRDirty = FALSE; + + /* Make a list of pointers to the start of each screen column */ + switch (GSU.vScreenHeight) + { + case 128: + switch (GSU.vMode) + { + case 0: + for (i = 0; i < 32; i++) + { + GSU.apvScreen[i] = GSU.pvScreenBase + (i << 4); + GSU.x[i] = i << 8; + } + break; + case 1: + for (i = 0; i < 32; i++) + { + GSU.apvScreen[i] = GSU.pvScreenBase + (i << 5); + GSU.x[i] = i << 9; + } + break; + case 2: + case 3: + for (i = 0; i < 32; i++) + { + GSU.apvScreen[i] = GSU.pvScreenBase + (i << 6); + GSU.x[i] = i << 10; + } + break; + } + break; + case 160: + switch (GSU.vMode) + { + case 0: + for (i = 0; i < 32; i++) + { + GSU.apvScreen[i] = GSU.pvScreenBase + (i << 4); + GSU.x[i] = (i << 8) + (i << 6); + } + break; + case 1: + for (i = 0; i < 32; i++) + { + GSU.apvScreen[i] = GSU.pvScreenBase + (i << 5); + GSU.x[i] = (i << 9) + (i << 7); + } + break; + case 2: + case 3: + for (i = 0; i < 32; i++) + { + GSU.apvScreen[i] = GSU.pvScreenBase + (i << 6); + GSU.x[i] = (i << 10) + (i << 8); + } + break; + } + break; + case 192: + switch (GSU.vMode) + { + case 0: + for (i = 0; i < 32; i++) + { + GSU.apvScreen[i] = GSU.pvScreenBase + (i << 4); + GSU.x[i] = (i << 8) + (i << 7); + } + break; + case 1: + for (i = 0; i < 32; i++) + { + GSU.apvScreen[i] = GSU.pvScreenBase + (i << 5); + GSU.x[i] = (i << 9) + (i << 8); + } + break; + case 2: + case 3: + for (i = 0; i < 32; i++) + { + GSU.apvScreen[i] = GSU.pvScreenBase + (i << 6); + GSU.x[i] = (i << 10) + (i << 9); + } + break; + } + break; + case 256: + switch (GSU.vMode) + { + case 0: + for (i = 0; i < 32; i++) + { + GSU.apvScreen[i] = GSU.pvScreenBase + + ((i & 0x10) << 9) + ((i & 0xf) << 8); + GSU.x[i] = ((i & 0x10) << 8) + ((i & 0xf) << 4); + } + break; + case 1: + for (i = 0; i < 32; i++) + { + GSU.apvScreen[i] = GSU.pvScreenBase + + ((i & 0x10) << 10) + ((i & 0xf) << 9); + GSU.x[i] = ((i & 0x10) << 9) + ((i & 0xf) << 5); + } + break; + case 2: + case 3: + for (i = 0; i < 32; i++) + { + GSU.apvScreen[i] = GSU.pvScreenBase + + ((i & 0x10) << 11) + ((i & 0xf) << 10); + GSU.x[i] = ((i & 0x10) << 10) + ((i & 0xf) << 6); + } + break; + } + break; + } + GSU.vPrevMode = GSU.vMode; + GSU.vPrevScreenHeight = GSU.vScreenHeight; + } } static void fx_writeRegisterSpace() { - int i; - uint8 *p; - - p = GSU.pvRegisters; - for(i=0; i<16; i++) - { - *p++ = (uint8)GSU.avReg[i]; - *p++ = (uint8)(GSU.avReg[i] >> 8); - } - - /* Update status register */ - if( USEX16(GSU.vZero) == 0 ) SF(Z); - else CF(Z); - if( GSU.vSign & 0x8000 ) SF(S); - else CF(S); - if(GSU.vOverflow >= 0x8000 || GSU.vOverflow < -0x8000) SF(OV); - else CF(OV); - if(GSU.vCarry) SF(CY); - else CF(CY); - - p = GSU.pvRegisters; - p[GSU_SFR] = (uint8)GSU.vStatusReg; - p[GSU_SFR+1] = (uint8)(GSU.vStatusReg>>8); - p[GSU_PBR] = (uint8)GSU.vPrgBankReg; - p[GSU_ROMBR] = (uint8)GSU.vRomBankReg; - p[GSU_RAMBR] = (uint8)GSU.vRamBankReg; - p[GSU_CBR] = (uint8)GSU.vCacheBaseReg; - p[GSU_CBR+1] = (uint8)(GSU.vCacheBaseReg>>8); - - fx_restoreCache(); + int i; + uint8* p; + + p = GSU.pvRegisters; + for (i = 0; i < 16; i++) + { + *p++ = (uint8)GSU.avReg[i]; + *p++ = (uint8)(GSU.avReg[i] >> 8); + } + + /* Update status register */ + if (USEX16(GSU.vZero) == 0) SF(Z); + else CF(Z); + if (GSU.vSign & 0x8000) SF(S); + else CF(S); + if (GSU.vOverflow >= 0x8000 || GSU.vOverflow < -0x8000) SF(OV); + else CF(OV); + if (GSU.vCarry) SF(CY); + else CF(CY); + + p = GSU.pvRegisters; + p[GSU_SFR] = (uint8)GSU.vStatusReg; + p[GSU_SFR + 1] = (uint8)(GSU.vStatusReg >> 8); + p[GSU_PBR] = (uint8)GSU.vPrgBankReg; + p[GSU_ROMBR] = (uint8)GSU.vRomBankReg; + p[GSU_RAMBR] = (uint8)GSU.vRamBankReg; + p[GSU_CBR] = (uint8)GSU.vCacheBaseReg; + p[GSU_CBR + 1] = (uint8)(GSU.vCacheBaseReg >> 8); + + fx_restoreCache(); } /* Reset the FxChip */ -void FxReset(struct FxInit_s *psFxInfo) +void FxReset(struct FxInit_s* psFxInfo) { - int i; - static uint32 (**appfFunction[])(uint32) = { - &fx_apfFunctionTable[0], + int i; + static uint32(**appfFunction[])(uint32) = + { + &fx_apfFunctionTable[0], #if 0 - &fx_a_apfFunctionTable[0], - &fx_r_apfFunctionTable[0], - &fx_ar_apfFunctionTable[0], -#endif - }; - static void (**appfPlot[])() = { - &fx_apfPlotTable[0], + &fx_a_apfFunctionTable[0], + &fx_r_apfFunctionTable[0], + &fx_ar_apfFunctionTable[0], +#endif + }; + static void (**appfPlot[])() = + { + &fx_apfPlotTable[0], #if 0 - &fx_a_apfPlotTable[0], - &fx_r_apfPlotTable[0], - &fx_ar_apfPlotTable[0], -#endif - }; - static void (**appfOpcode[])() = { - &fx_apfOpcodeTable[0], -#if 0 - &fx_a_apfOpcodeTable[0], - &fx_r_apfOpcodeTable[0], - &fx_ar_apfOpcodeTable[0], -#endif - }; - - /* Get function pointers for the current emulation mode */ - fx_ppfFunctionTable = appfFunction[psFxInfo->vFlags & 0x3]; - fx_ppfPlotTable = appfPlot[psFxInfo->vFlags & 0x3]; - fx_ppfOpcodeTable = appfOpcode[psFxInfo->vFlags & 0x3]; - - /* Clear all internal variables */ - memset((uint8*)&GSU,0,sizeof(struct FxRegs_s)); - - /* Set default registers */ - GSU.pvSreg = GSU.pvDreg = &R0; - - /* Set RAM and ROM pointers */ - GSU.pvRegisters = psFxInfo->pvRegisters; - GSU.nRamBanks = psFxInfo->nRamBanks; - GSU.pvRam = psFxInfo->pvRam; - GSU.nRomBanks = psFxInfo->nRomBanks; - GSU.pvRom = psFxInfo->pvRom; - GSU.vPrevScreenHeight = ~0; - GSU.vPrevMode = ~0; - - /* The GSU can't access more than 2mb (16mbits) */ - if(GSU.nRomBanks > 0x20) - GSU.nRomBanks = 0x20; - - /* Clear FxChip register space */ - memset(GSU.pvRegisters,0,0x300); - - /* Set FxChip version Number */ - GSU.pvRegisters[0x3b] = 0; - - /* Make ROM bank table */ - for(i=0; i<256; i++) - { - uint32 b = i & 0x7f; - if (b >= 0x40) - { - if (GSU.nRomBanks > 1) - b %= GSU.nRomBanks; - else - b &= 1; - - GSU.apvRomBank[i] = &GSU.pvRom[ b << 16 ]; - } - else - { - b %= GSU.nRomBanks * 2; - GSU.apvRomBank[i] = &GSU.pvRom[ (b << 16) + 0x200000]; - } - } - - /* Make RAM bank table */ - for(i=0; i<4; i++) - { - GSU.apvRamBank[i] = &GSU.pvRam[(i % GSU.nRamBanks) << 16]; - GSU.apvRomBank[0x70 + i] = GSU.apvRamBank[i]; - } - - /* Start with a nop in the pipe */ - GSU.vPipe = 0x01; - - /* Set pointer to GSU cache */ - GSU.pvCache = &GSU.pvRegisters[0x100]; - - fx_readRegisterSpace(); + &fx_a_apfPlotTable[0], + &fx_r_apfPlotTable[0], + &fx_ar_apfPlotTable[0], +#endif + }; + static void (**appfOpcode[])() = + { + &fx_apfOpcodeTable[0], +#if 0 + &fx_a_apfOpcodeTable[0], + &fx_r_apfOpcodeTable[0], + &fx_ar_apfOpcodeTable[0], +#endif + }; + + /* Get function pointers for the current emulation mode */ + fx_ppfFunctionTable = appfFunction[psFxInfo->vFlags & 0x3]; + fx_ppfPlotTable = appfPlot[psFxInfo->vFlags & 0x3]; + fx_ppfOpcodeTable = appfOpcode[psFxInfo->vFlags & 0x3]; + + /* Clear all internal variables */ + memset((uint8*)&GSU, 0, sizeof(struct FxRegs_s)); + + /* Set default registers */ + GSU.pvSreg = GSU.pvDreg = &R0; + + /* Set RAM and ROM pointers */ + GSU.pvRegisters = psFxInfo->pvRegisters; + GSU.nRamBanks = psFxInfo->nRamBanks; + GSU.pvRam = psFxInfo->pvRam; + GSU.nRomBanks = psFxInfo->nRomBanks; + GSU.pvRom = psFxInfo->pvRom; + GSU.vPrevScreenHeight = ~0; + GSU.vPrevMode = ~0; + + /* The GSU can't access more than 2mb (16mbits) */ + if (GSU.nRomBanks > 0x20) + GSU.nRomBanks = 0x20; + + /* Clear FxChip register space */ + memset(GSU.pvRegisters, 0, 0x300); + + /* Set FxChip version Number */ + GSU.pvRegisters[0x3b] = 0; + + /* Make ROM bank table */ + for (i = 0; i < 256; i++) + { + uint32 b = i & 0x7f; + if (b >= 0x40) + { + if (GSU.nRomBanks > 1) + b %= GSU.nRomBanks; + else + b &= 1; + + GSU.apvRomBank[i] = &GSU.pvRom[ b << 16 ]; + } + else + { + b %= GSU.nRomBanks * 2; + GSU.apvRomBank[i] = &GSU.pvRom[(b << 16) + 0x200000]; + } + } + + /* Make RAM bank table */ + for (i = 0; i < 4; i++) + { + GSU.apvRamBank[i] = &GSU.pvRam[(i % GSU.nRamBanks) << 16]; + GSU.apvRomBank[0x70 + i] = GSU.apvRamBank[i]; + } + + /* Start with a nop in the pipe */ + GSU.vPipe = 0x01; + + /* Set pointer to GSU cache */ + GSU.pvCache = &GSU.pvRegisters[0x100]; + + fx_readRegisterSpace(); } static uint8 fx_checkStartAddress() { - /* Check if we start inside the cache */ - if(GSU.bCacheActive && R15 >= GSU.vCacheBaseReg && R15 < (GSU.vCacheBaseReg+512)) - return TRUE; - - /* Check if we're in an unused area */ - if(GSU.vPrgBankReg < 0x40 && R15 < 0x8000) - return FALSE; - if(GSU.vPrgBankReg >= 0x60 && GSU.vPrgBankReg <= 0x6f) - return FALSE; - if(GSU.vPrgBankReg >= 0x74) - return FALSE; - - /* Check if we're in RAM and the RAN flag is not set */ - if(GSU.vPrgBankReg >= 0x70 && GSU.vPrgBankReg <= 0x73 && !(SCMR&(1<<3)) ) - return FALSE; - - /* If not, we're in ROM, so check if the RON flag is set */ - if(!(SCMR&(1<<4))) - return FALSE; - - return TRUE; + /* Check if we start inside the cache */ + if (GSU.bCacheActive && R15 >= GSU.vCacheBaseReg + && R15 < (GSU.vCacheBaseReg + 512)) + return TRUE; + + /* Check if we're in an unused area */ + if (GSU.vPrgBankReg < 0x40 && R15 < 0x8000) + return FALSE; + if (GSU.vPrgBankReg >= 0x60 && GSU.vPrgBankReg <= 0x6f) + return FALSE; + if (GSU.vPrgBankReg >= 0x74) + return FALSE; + + /* Check if we're in RAM and the RAN flag is not set */ + if (GSU.vPrgBankReg >= 0x70 && GSU.vPrgBankReg <= 0x73 && !(SCMR & (1 << 3))) + return FALSE; + + /* If not, we're in ROM, so check if the RON flag is set */ + if (!(SCMR & (1 << 4))) + return FALSE; + + return TRUE; } /* Execute until the next stop instruction */ int FxEmulate(uint32 nInstructions) { - uint32 vCount; + uint32 vCount; - /* Read registers and initialize GSU session */ - fx_readRegisterSpace(); + /* Read registers and initialize GSU session */ + fx_readRegisterSpace(); - /* Check if the start address is valid */ - if(!fx_checkStartAddress()) - { - CF(G); - fx_writeRegisterSpace(); + /* Check if the start address is valid */ + if (!fx_checkStartAddress()) + { + CF(G); + fx_writeRegisterSpace(); #if 0 - GSU.vIllegalAddress = (GSU.vPrgBankReg << 24) | R15; - return FX_ERROR_ILLEGAL_ADDRESS; + GSU.vIllegalAddress = (GSU.vPrgBankReg << 24) | R15; + return FX_ERROR_ILLEGAL_ADDRESS; #else - return 0; + return 0; #endif - } + } - /* Execute GSU session */ - CF(IRQ); + /* Execute GSU session */ + CF(IRQ); - if(GSU.bBreakPoint) - vCount = fx_ppfFunctionTable[FX_FUNCTION_RUN_TO_BREAKPOINT](nInstructions); - else - vCount = fx_ppfFunctionTable[FX_FUNCTION_RUN](nInstructions); + if (GSU.bBreakPoint) + vCount = fx_ppfFunctionTable[FX_FUNCTION_RUN_TO_BREAKPOINT](nInstructions); + else + vCount = fx_ppfFunctionTable[FX_FUNCTION_RUN](nInstructions); - /* Store GSU registers */ - fx_writeRegisterSpace(); + /* Store GSU registers */ + fx_writeRegisterSpace(); - /* Check for error code */ - if(GSU.vErrorCode) - return GSU.vErrorCode; - else - return vCount; + /* Check for error code */ + if (GSU.vErrorCode) + return GSU.vErrorCode; + else + return vCount; } /* Breakpoints */ void FxBreakPointSet(uint32 vAddress) { - GSU.bBreakPoint = TRUE; - GSU.vBreakPoint = USEX16(vAddress); + GSU.bBreakPoint = TRUE; + GSU.vBreakPoint = USEX16(vAddress); } void FxBreakPointClear() { - GSU.bBreakPoint = FALSE; + GSU.bBreakPoint = FALSE; } /* Step by step execution */ int FxStepOver(uint32 nInstructions) { - uint32 vCount; - fx_readRegisterSpace(); + uint32 vCount; + fx_readRegisterSpace(); - /* Check if the start address is valid */ - if(!fx_checkStartAddress()) - { - CF(G); + /* Check if the start address is valid */ + if (!fx_checkStartAddress()) + { + CF(G); #if 0 - GSU.vIllegalAddress = (GSU.vPrgBankReg << 24) | R15; - return FX_ERROR_ILLEGAL_ADDRESS; + GSU.vIllegalAddress = (GSU.vPrgBankReg << 24) | R15; + return FX_ERROR_ILLEGAL_ADDRESS; #else - return 0; + return 0; #endif - } - - if( PIPE >= 0xf0 ) - GSU.vStepPoint = USEX16(R15+3); - else if( (PIPE >= 0x05 && PIPE <= 0x0f) || (PIPE >= 0xa0 && PIPE <= 0xaf) ) - GSU.vStepPoint = USEX16(R15+2); - else - GSU.vStepPoint = USEX16(R15+1); - vCount = fx_ppfFunctionTable[FX_FUNCTION_STEP_OVER](nInstructions); - fx_writeRegisterSpace(); - if(GSU.vErrorCode) - return GSU.vErrorCode; - else - return vCount; + } + + if (PIPE >= 0xf0) + GSU.vStepPoint = USEX16(R15 + 3); + else if ((PIPE >= 0x05 && PIPE <= 0x0f) || (PIPE >= 0xa0 && PIPE <= 0xaf)) + GSU.vStepPoint = USEX16(R15 + 2); + else + GSU.vStepPoint = USEX16(R15 + 1); + vCount = fx_ppfFunctionTable[FX_FUNCTION_STEP_OVER](nInstructions); + fx_writeRegisterSpace(); + if (GSU.vErrorCode) + return GSU.vErrorCode; + else + return vCount; } /* Errors */ int FxGetErrorCode() { - return GSU.vErrorCode; + return GSU.vErrorCode; } int FxGetIllegalAddress() { - return GSU.vIllegalAddress; + return GSU.vIllegalAddress; } /* Access to internal registers */ uint32 FxGetColorRegister() { - return GSU.vColorReg & 0xff; + return GSU.vColorReg & 0xff; } uint32 FxGetPlotOptionRegister() { - return GSU.vPlotOptionReg & 0x1f; + return GSU.vPlotOptionReg & 0x1f; } uint32 FxGetSourceRegisterIndex() { - return GSU.pvSreg - GSU.avReg; + return GSU.pvSreg - GSU.avReg; } uint32 FxGetDestinationRegisterIndex() { - return GSU.pvDreg - GSU.avReg; + return GSU.pvDreg - GSU.avReg; } uint8 FxPipe() { - return GSU.vPipe; + return GSU.vPipe; } diff --git a/source/fxemu.h b/source/fxemu.h index 270ea5c..f7943ab 100644 --- a/source/fxemu.h +++ b/source/fxemu.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -113,23 +113,24 @@ typedef int int32; /* The FxInfo_s structure, the link between the FxEmulator and the Snes Emulator */ struct FxInit_s { - uint32 vFlags; - uint8 * pvRegisters; /* 768 bytes located in the memory at address 0x3000 */ - uint32 nRamBanks; /* Number of 64kb-banks in GSU-RAM/BackupRAM (banks 0x70-0x73) */ - uint8 * pvRam; /* Pointer to GSU-RAM */ - uint32 nRomBanks; /* Number of 32kb-banks in Cart-ROM */ - uint8 * pvRom; /* Pointer to Cart-ROM */ + uint32 vFlags; + uint8* pvRegisters; /* 768 bytes located in the memory at address 0x3000 */ + uint32 nRamBanks; /* Number of 64kb-banks in GSU-RAM/BackupRAM (banks 0x70-0x73) */ + uint8* pvRam; /* Pointer to GSU-RAM */ + uint32 nRomBanks; /* Number of 32kb-banks in Cart-ROM */ + uint8* pvRom; /* Pointer to Cart-ROM */ }; /* Reset the FxChip */ -extern void FxReset(struct FxInit_s *psFxInfo); +extern void FxReset(struct FxInit_s* psFxInfo); /* Execute until the next stop instruction */ extern int FxEmulate(uint32 nInstructions); /* Write access to the cache */ extern void FxCacheWriteAccess(uint16 vAddress); -extern void FxFlushCache(); /* Callled when the G flag in SFR is set to zero */ +extern void +FxFlushCache(); /* Callled when the G flag in SFR is set to zero */ /* Breakpoint */ extern void FxBreakPointSet(uint32 vAddress); @@ -149,29 +150,29 @@ extern uint32 FxGetSourceRegisterIndex(); extern uint32 FxGetDestinationRegisterIndex(); /* Get string for opcode currently in the pipe */ -extern void FxPipeString(char * pvString); +extern void FxPipeString(char* pvString); /* Get the byte currently in the pipe */ extern uint8 FxPipe(); /* SCBR write seen. We need to update our cached screen pointers */ -extern void fx_dirtySCBR (void); +extern void fx_dirtySCBR(void); /* Update RamBankReg and RAM Bank pointer */ extern void fx_updateRamBank(uint8 Byte); /* Option flags */ -#define FX_FLAG_ADDRESS_CHECKING 0x01 -#define FX_FLAG_ROM_BUFFER 0x02 +#define FX_FLAG_ADDRESS_CHECKING 0x01 +#define FX_FLAG_ROM_BUFFER 0x02 /* Return codes from FxEmulate(), FxStepInto() or FxStepOver() */ -#define FX_BREAKPOINT -1 -#define FX_ERROR_ILLEGAL_ADDRESS -2 +#define FX_BREAKPOINT -1 +#define FX_ERROR_ILLEGAL_ADDRESS -2 /* Return the number of bytes in an opcode */ #define OPCODE_BYTES(op) ((((op)>=0x05&&(op)<=0xf)||((op)>=0xa0&&(op)<=0xaf))?2:(((op)>=0xf0)?3:1)) -extern void fx_computeScreenPointers (); +extern void fx_computeScreenPointers(); #endif diff --git a/source/fxinst.c b/source/fxinst.c index a5cdf01..9481284 100644 --- a/source/fxinst.c +++ b/source/fxinst.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -114,83 +114,95 @@ int gsu_bank [512] = {0}; /* 00 - stop - stop GSU execution (and maybe generate an IRQ) */ static void fx_stop() { - CF(G); - GSU.vCounter = 0; - GSU.vInstCount = GSU.vCounter; - - /* Check if we need to generate an IRQ */ - if(!(GSU.pvRegisters[GSU_CFGR] & 0x80)) - SF(IRQ); - - GSU.vPlotOptionReg = 0; - GSU.vPipe = 1; - CLRFLAGS; - R15++; + CF(G); + GSU.vCounter = 0; + GSU.vInstCount = GSU.vCounter; + + /* Check if we need to generate an IRQ */ + if (!(GSU.pvRegisters[GSU_CFGR] & 0x80)) + SF(IRQ); + + GSU.vPlotOptionReg = 0; + GSU.vPipe = 1; + CLRFLAGS; + R15++; } /* 01 - nop - no operation */ -static void fx_nop() { CLRFLAGS; R15++; } +static void fx_nop() +{ + CLRFLAGS; + R15++; +} extern void fx_flushCache(); /* 02 - cache - reintialize GSU cache */ static void fx_cache() { - uint32 c = R15 & 0xfff0; - if(GSU.vCacheBaseReg != c || !GSU.bCacheActive) - { - fx_flushCache(); - GSU.vCacheBaseReg = c; - GSU.bCacheActive = TRUE; + uint32 c = R15 & 0xfff0; + if (GSU.vCacheBaseReg != c || !GSU.bCacheActive) + { + fx_flushCache(); + GSU.vCacheBaseReg = c; + GSU.bCacheActive = TRUE; #if 0 - if(c < (0x10000-512)) - { - uint8 const* t = &ROM(c); - memcpy(GSU.pvCache,t,512); - } - else - { - uint8 const* t1; - uint8 const* t2; - uint32 i = 0x10000 - c; - t1 = &ROM(c); - t2 = &ROM(0); - memcpy(GSU.pvCache,t1,i); - memcpy(&GSU.pvCache[i],t2,512-i); - } -#endif - } - R15++; - CLRFLAGS; + if (c < (0x10000 - 512)) + { + uint8 const* t = &ROM(c); + memcpy(GSU.pvCache, t, 512); + } + else + { + uint8 const* t1; + uint8 const* t2; + uint32 i = 0x10000 - c; + t1 = &ROM(c); + t2 = &ROM(0); + memcpy(GSU.pvCache, t1, i); + memcpy(&GSU.pvCache[i], t2, 512 - i); + } +#endif + } + R15++; + CLRFLAGS; } /* 03 - lsr - logic shift right */ static void fx_lsr() { - uint32 v; - GSU.vCarry = SREG & 1; - v = USEX16(SREG) >> 1; - R15++; DREG = v; - GSU.vSign = v; - GSU.vZero = v; - TESTR14; - CLRFLAGS; + uint32 v; + GSU.vCarry = SREG & 1; + v = USEX16(SREG) >> 1; + R15++; + DREG = v; + GSU.vSign = v; + GSU.vZero = v; + TESTR14; + CLRFLAGS; } /* 04 - rol - rotate left */ static void fx_rol() { - uint32 v = USEX16((SREG << 1) + GSU.vCarry); - GSU.vCarry = (SREG >> 15) & 1; - R15++; DREG = v; - GSU.vSign = v; - GSU.vZero = v; - TESTR14; - CLRFLAGS; + uint32 v = USEX16((SREG << 1) + GSU.vCarry); + GSU.vCarry = (SREG >> 15) & 1; + R15++; + DREG = v; + GSU.vSign = v; + GSU.vZero = v; + TESTR14; + CLRFLAGS; } /* 05 - bra - branch always */ -static void fx_bra() { uint8 v = PIPE; R15++; FETCHPIPE; R15 += SEX8(v); } +static void fx_bra() +{ + uint8 v = PIPE; + R15++; + FETCHPIPE; + R15 += SEX8(v); +} /* Branch on condition */ #define BRA_COND(cond) uint8 v = PIPE; R15++; FETCHPIPE; if(cond) R15 += SEX8(v); else R15++; @@ -201,34 +213,64 @@ static void fx_bra() { uint8 v = PIPE; R15++; FETCHPIPE; R15 += SEX8(v); } #define TEST_CY (GSU.vCarry & 1) /* 06 - blt - branch on less than */ -static void fx_blt() { BRA_COND( (TEST_S!=0) != (TEST_OV!=0) ); } +static void fx_blt() +{ + BRA_COND((TEST_S != 0) != (TEST_OV != 0)); +} /* 07 - bge - branch on greater or equals */ -static void fx_bge() { BRA_COND( (TEST_S!=0) == (TEST_OV!=0)); } +static void fx_bge() +{ + BRA_COND((TEST_S != 0) == (TEST_OV != 0)); +} /* 08 - bne - branch on not equal */ -static void fx_bne() { BRA_COND( !TEST_Z ); } +static void fx_bne() +{ + BRA_COND(!TEST_Z); +} /* 09 - beq - branch on equal */ -static void fx_beq() { BRA_COND( TEST_Z ); } +static void fx_beq() +{ + BRA_COND(TEST_Z); +} /* 0a - bpl - branch on plus */ -static void fx_bpl() { BRA_COND( !TEST_S ); } +static void fx_bpl() +{ + BRA_COND(!TEST_S); +} /* 0b - bmi - branch on minus */ -static void fx_bmi() { BRA_COND( TEST_S ); } +static void fx_bmi() +{ + BRA_COND(TEST_S); +} /* 0c - bcc - branch on carry clear */ -static void fx_bcc() { BRA_COND( !TEST_CY ); } +static void fx_bcc() +{ + BRA_COND(!TEST_CY); +} /* 0d - bcs - branch on carry set */ -static void fx_bcs() { BRA_COND( TEST_CY ); } +static void fx_bcs() +{ + BRA_COND(TEST_CY); +} /* 0e - bvc - branch on overflow clear */ -static void fx_bvc() { BRA_COND( !TEST_OV ); } +static void fx_bvc() +{ + BRA_COND(!TEST_OV); +} /* 0f - bvs - branch on overflow set */ -static void fx_bvs() { BRA_COND( TEST_OV ); } +static void fx_bvs() +{ + BRA_COND(TEST_OV); +} /* 10-1f - to rn - set register n as destination register */ /* 10-1f(B) - move rn - move one register to another (if B flag is set) */ @@ -241,41 +283,137 @@ else { GSU.pvDreg = &GSU.avReg[reg]; } R15++; #define FX_TO_R15(reg) \ if(TF(B)) { GSU.avReg[(reg)] = SREG; CLRFLAGS; } \ else { GSU.pvDreg = &GSU.avReg[reg]; R15++; } -static void fx_to_r0() { FX_TO(0); } -static void fx_to_r1() { FX_TO(1); } -static void fx_to_r2() { FX_TO(2); } -static void fx_to_r3() { FX_TO(3); } -static void fx_to_r4() { FX_TO(4); } -static void fx_to_r5() { FX_TO(5); } -static void fx_to_r6() { FX_TO(6); } -static void fx_to_r7() { FX_TO(7); } -static void fx_to_r8() { FX_TO(8); } -static void fx_to_r9() { FX_TO(9); } -static void fx_to_r10() { FX_TO(10); } -static void fx_to_r11() { FX_TO(11); } -static void fx_to_r12() { FX_TO(12); } -static void fx_to_r13() { FX_TO(13); } -static void fx_to_r14() { FX_TO_R14(14); } -static void fx_to_r15() { FX_TO_R15(15); } +static void fx_to_r0() +{ + FX_TO(0); +} +static void fx_to_r1() +{ + FX_TO(1); +} +static void fx_to_r2() +{ + FX_TO(2); +} +static void fx_to_r3() +{ + FX_TO(3); +} +static void fx_to_r4() +{ + FX_TO(4); +} +static void fx_to_r5() +{ + FX_TO(5); +} +static void fx_to_r6() +{ + FX_TO(6); +} +static void fx_to_r7() +{ + FX_TO(7); +} +static void fx_to_r8() +{ + FX_TO(8); +} +static void fx_to_r9() +{ + FX_TO(9); +} +static void fx_to_r10() +{ + FX_TO(10); +} +static void fx_to_r11() +{ + FX_TO(11); +} +static void fx_to_r12() +{ + FX_TO(12); +} +static void fx_to_r13() +{ + FX_TO(13); +} +static void fx_to_r14() +{ + FX_TO_R14(14); +} +static void fx_to_r15() +{ + FX_TO_R15(15); +} /* 20-2f - to rn - set register n as source and destination register */ #define FX_WITH(reg) SF(B); GSU.pvSreg = GSU.pvDreg = &GSU.avReg[reg]; R15++; -static void fx_with_r0() { FX_WITH(0); } -static void fx_with_r1() { FX_WITH(1); } -static void fx_with_r2() { FX_WITH(2); } -static void fx_with_r3() { FX_WITH(3); } -static void fx_with_r4() { FX_WITH(4); } -static void fx_with_r5() { FX_WITH(5); } -static void fx_with_r6() { FX_WITH(6); } -static void fx_with_r7() { FX_WITH(7); } -static void fx_with_r8() { FX_WITH(8); } -static void fx_with_r9() { FX_WITH(9); } -static void fx_with_r10() { FX_WITH(10); } -static void fx_with_r11() { FX_WITH(11); } -static void fx_with_r12() { FX_WITH(12); } -static void fx_with_r13() { FX_WITH(13); } -static void fx_with_r14() { FX_WITH(14); } -static void fx_with_r15() { FX_WITH(15); } +static void fx_with_r0() +{ + FX_WITH(0); +} +static void fx_with_r1() +{ + FX_WITH(1); +} +static void fx_with_r2() +{ + FX_WITH(2); +} +static void fx_with_r3() +{ + FX_WITH(3); +} +static void fx_with_r4() +{ + FX_WITH(4); +} +static void fx_with_r5() +{ + FX_WITH(5); +} +static void fx_with_r6() +{ + FX_WITH(6); +} +static void fx_with_r7() +{ + FX_WITH(7); +} +static void fx_with_r8() +{ + FX_WITH(8); +} +static void fx_with_r9() +{ + FX_WITH(9); +} +static void fx_with_r10() +{ + FX_WITH(10); +} +static void fx_with_r11() +{ + FX_WITH(11); +} +static void fx_with_r12() +{ + FX_WITH(12); +} +static void fx_with_r13() +{ + FX_WITH(13); +} +static void fx_with_r14() +{ + FX_WITH(14); +} +static void fx_with_r15() +{ + FX_WITH(15); +} /* 30-3b - stw (rn) - store word */ #define FX_STW(reg) \ @@ -283,58 +421,146 @@ GSU.vLastRamAdr = GSU.avReg[reg]; \ RAM(GSU.avReg[reg]) = (uint8)SREG; \ RAM(GSU.avReg[reg]^1) = (uint8)(SREG>>8); \ CLRFLAGS; R15++ -static void fx_stw_r0() { FX_STW(0); } -static void fx_stw_r1() { FX_STW(1); } -static void fx_stw_r2() { FX_STW(2); } -static void fx_stw_r3() { FX_STW(3); } -static void fx_stw_r4() { FX_STW(4); } -static void fx_stw_r5() { FX_STW(5); } -static void fx_stw_r6() { FX_STW(6); } -static void fx_stw_r7() { FX_STW(7); } -static void fx_stw_r8() { FX_STW(8); } -static void fx_stw_r9() { FX_STW(9); } -static void fx_stw_r10() { FX_STW(10); } -static void fx_stw_r11() { FX_STW(11); } +static void fx_stw_r0() +{ + FX_STW(0); +} +static void fx_stw_r1() +{ + FX_STW(1); +} +static void fx_stw_r2() +{ + FX_STW(2); +} +static void fx_stw_r3() +{ + FX_STW(3); +} +static void fx_stw_r4() +{ + FX_STW(4); +} +static void fx_stw_r5() +{ + FX_STW(5); +} +static void fx_stw_r6() +{ + FX_STW(6); +} +static void fx_stw_r7() +{ + FX_STW(7); +} +static void fx_stw_r8() +{ + FX_STW(8); +} +static void fx_stw_r9() +{ + FX_STW(9); +} +static void fx_stw_r10() +{ + FX_STW(10); +} +static void fx_stw_r11() +{ + FX_STW(11); +} /* 30-3b(ALT1) - stb (rn) - store byte */ #define FX_STB(reg) \ GSU.vLastRamAdr = GSU.avReg[reg]; \ RAM(GSU.avReg[reg]) = (uint8)SREG; \ CLRFLAGS; R15++ -static void fx_stb_r0() { FX_STB(0); } -static void fx_stb_r1() { FX_STB(1); } -static void fx_stb_r2() { FX_STB(2); } -static void fx_stb_r3() { FX_STB(3); } -static void fx_stb_r4() { FX_STB(4); } -static void fx_stb_r5() { FX_STB(5); } -static void fx_stb_r6() { FX_STB(6); } -static void fx_stb_r7() { FX_STB(7); } -static void fx_stb_r8() { FX_STB(8); } -static void fx_stb_r9() { FX_STB(9); } -static void fx_stb_r10() { FX_STB(10); } -static void fx_stb_r11() { FX_STB(11); } +static void fx_stb_r0() +{ + FX_STB(0); +} +static void fx_stb_r1() +{ + FX_STB(1); +} +static void fx_stb_r2() +{ + FX_STB(2); +} +static void fx_stb_r3() +{ + FX_STB(3); +} +static void fx_stb_r4() +{ + FX_STB(4); +} +static void fx_stb_r5() +{ + FX_STB(5); +} +static void fx_stb_r6() +{ + FX_STB(6); +} +static void fx_stb_r7() +{ + FX_STB(7); +} +static void fx_stb_r8() +{ + FX_STB(8); +} +static void fx_stb_r9() +{ + FX_STB(9); +} +static void fx_stb_r10() +{ + FX_STB(10); +} +static void fx_stb_r11() +{ + FX_STB(11); +} /* 3c - loop - decrement loop counter, and branch on not zero */ static void fx_loop() { - GSU.vSign = GSU.vZero = --R12; - if( (uint16) R12 != 0 ) - R15 = R13; - else - R15++; + GSU.vSign = GSU.vZero = --R12; + if ((uint16) R12 != 0) + R15 = R13; + else + R15++; - CLRFLAGS; + CLRFLAGS; } /* 3d - alt1 - set alt1 mode */ -static void fx_alt1() { SF(ALT1); CF(B); R15++; } +static void fx_alt1() +{ + SF(ALT1); + CF(B); + R15++; +} /* 3e - alt2 - set alt2 mode */ -static void fx_alt2() { SF(ALT2); CF(B); R15++; } +static void fx_alt2() +{ + SF(ALT2); + CF(B); + R15++; +} /* 3f - alt3 - set alt3 mode */ -static void fx_alt3() { SF(ALT1); SF(ALT2); CF(B); R15++; } - +static void fx_alt3() +{ + SF(ALT1); + SF(ALT2); + CF(B); + R15++; +} + /* 40-4b - ldw (rn) - load word from RAM */ #define FX_LDW(reg) uint32 v; \ GSU.vLastRamAdr = GSU.avReg[reg]; \ @@ -343,18 +569,54 @@ v |= ((uint32)RAM(GSU.avReg[reg]^1))<<8; \ R15++; DREG = v; \ TESTR14; \ CLRFLAGS -static void fx_ldw_r0() { FX_LDW(0); } -static void fx_ldw_r1() { FX_LDW(1); } -static void fx_ldw_r2() { FX_LDW(2); } -static void fx_ldw_r3() { FX_LDW(3); } -static void fx_ldw_r4() { FX_LDW(4); } -static void fx_ldw_r5() { FX_LDW(5); } -static void fx_ldw_r6() { FX_LDW(6); } -static void fx_ldw_r7() { FX_LDW(7); } -static void fx_ldw_r8() { FX_LDW(8); } -static void fx_ldw_r9() { FX_LDW(9); } -static void fx_ldw_r10() { FX_LDW(10); } -static void fx_ldw_r11() { FX_LDW(11); } +static void fx_ldw_r0() +{ + FX_LDW(0); +} +static void fx_ldw_r1() +{ + FX_LDW(1); +} +static void fx_ldw_r2() +{ + FX_LDW(2); +} +static void fx_ldw_r3() +{ + FX_LDW(3); +} +static void fx_ldw_r4() +{ + FX_LDW(4); +} +static void fx_ldw_r5() +{ + FX_LDW(5); +} +static void fx_ldw_r6() +{ + FX_LDW(6); +} +static void fx_ldw_r7() +{ + FX_LDW(7); +} +static void fx_ldw_r8() +{ + FX_LDW(8); +} +static void fx_ldw_r9() +{ + FX_LDW(9); +} +static void fx_ldw_r10() +{ + FX_LDW(10); +} +static void fx_ldw_r11() +{ + FX_LDW(11); +} /* 40-4b(ALT1) - ldb (rn) - load byte */ #define FX_LDB(reg) uint32 v; \ @@ -363,276 +625,313 @@ v = (uint32)RAM(GSU.avReg[reg]); \ R15++; DREG = v; \ TESTR14; \ CLRFLAGS -static void fx_ldb_r0() { FX_LDB(0); } -static void fx_ldb_r1() { FX_LDB(1); } -static void fx_ldb_r2() { FX_LDB(2); } -static void fx_ldb_r3() { FX_LDB(3); } -static void fx_ldb_r4() { FX_LDB(4); } -static void fx_ldb_r5() { FX_LDB(5); } -static void fx_ldb_r6() { FX_LDB(6); } -static void fx_ldb_r7() { FX_LDB(7); } -static void fx_ldb_r8() { FX_LDB(8); } -static void fx_ldb_r9() { FX_LDB(9); } -static void fx_ldb_r10() { FX_LDB(10); } -static void fx_ldb_r11() { FX_LDB(11); } +static void fx_ldb_r0() +{ + FX_LDB(0); +} +static void fx_ldb_r1() +{ + FX_LDB(1); +} +static void fx_ldb_r2() +{ + FX_LDB(2); +} +static void fx_ldb_r3() +{ + FX_LDB(3); +} +static void fx_ldb_r4() +{ + FX_LDB(4); +} +static void fx_ldb_r5() +{ + FX_LDB(5); +} +static void fx_ldb_r6() +{ + FX_LDB(6); +} +static void fx_ldb_r7() +{ + FX_LDB(7); +} +static void fx_ldb_r8() +{ + FX_LDB(8); +} +static void fx_ldb_r9() +{ + FX_LDB(9); +} +static void fx_ldb_r10() +{ + FX_LDB(10); +} +static void fx_ldb_r11() +{ + FX_LDB(11); +} /* 4c - plot - plot pixel with R1,R2 as x,y and the color register as the color */ static void fx_plot_2bit() { - uint32 x = USEX8(R1); - uint32 y = USEX8(R2); - uint8 *a; - uint8 v,c; + uint32 x = USEX8(R1); + uint32 y = USEX8(R2); + uint8* a; + uint8 v, c; - R15++; - CLRFLAGS; - R1++; + R15++; + CLRFLAGS; + R1++; #ifdef CHECK_LIMITS - if(y >= GSU.vScreenHeight) return; + if (y >= GSU.vScreenHeight) return; #endif - if(GSU.vPlotOptionReg & 0x02) - c = (x^y)&1 ? (uint8)(GSU.vColorReg>>4) : (uint8)GSU.vColorReg; - else - c = (uint8)GSU.vColorReg; - - if( !(GSU.vPlotOptionReg & 0x01) && !(c & 0xf)) return; - a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1); - v = 128 >> (x&7); - - if(c & 0x01) a[0] |= v; - else a[0] &= ~v; - if(c & 0x02) a[1] |= v; - else a[1] &= ~v; + if (GSU.vPlotOptionReg & 0x02) + c = (x ^ y) & 1 ? (uint8)(GSU.vColorReg >> 4) : (uint8)GSU.vColorReg; + else + c = (uint8)GSU.vColorReg; + + if (!(GSU.vPlotOptionReg & 0x01) && !(c & 0xf)) return; + a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1); + v = 128 >> (x & 7); + + if (c & 0x01) a[0] |= v; + else a[0] &= ~v; + if (c & 0x02) a[1] |= v; + else a[1] &= ~v; } /* 2c(ALT1) - rpix - read color of the pixel with R1,R2 as x,y */ static void fx_rpix_2bit() { - uint32 x = USEX8(R1); - uint32 y = USEX8(R2); - uint8 *a; - uint8 v; + uint32 x = USEX8(R1); + uint32 y = USEX8(R2); + uint8* a; + uint8 v; - R15++; - CLRFLAGS; + R15++; + CLRFLAGS; #ifdef CHECK_LIMITS - if(y >= GSU.vScreenHeight) return; + if (y >= GSU.vScreenHeight) return; #endif - a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1); - v = 128 >> (x&7); + a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1); + v = 128 >> (x & 7); - DREG = 0; - DREG |= ((uint32)((a[0] & v) != 0)) << 0; - DREG |= ((uint32)((a[1] & v) != 0)) << 1; - TESTR14; + DREG = 0; + DREG |= ((uint32)((a[0] & v) != 0)) << 0; + DREG |= ((uint32)((a[1] & v) != 0)) << 1; + TESTR14; } /* 4c - plot - plot pixel with R1,R2 as x,y and the color register as the color */ static void fx_plot_4bit() { - uint32 x = USEX8(R1); - uint32 y = USEX8(R2); - uint8 *a; - uint8 v,c; + uint32 x = USEX8(R1); + uint32 y = USEX8(R2); + uint8* a; + uint8 v, c; + + R15++; + CLRFLAGS; + R1++; - R15++; - CLRFLAGS; - R1++; - #ifdef CHECK_LIMITS - if(y >= GSU.vScreenHeight) return; + if (y >= GSU.vScreenHeight) return; #endif - if(GSU.vPlotOptionReg & 0x02) - c = (x^y)&1 ? (uint8)(GSU.vColorReg>>4) : (uint8)GSU.vColorReg; - else - c = (uint8)GSU.vColorReg; - - if( !(GSU.vPlotOptionReg & 0x01) && !(c & 0xf)) return; - - a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1); - v = 128 >> (x&7); - - if(c & 0x01) a[0x00] |= v; - else a[0x00] &= ~v; - if(c & 0x02) a[0x01] |= v; - else a[0x01] &= ~v; - if(c & 0x04) a[0x10] |= v; - else a[0x10] &= ~v; - if(c & 0x08) a[0x11] |= v; - else a[0x11] &= ~v; + if (GSU.vPlotOptionReg & 0x02) + c = (x ^ y) & 1 ? (uint8)(GSU.vColorReg >> 4) : (uint8)GSU.vColorReg; + else + c = (uint8)GSU.vColorReg; + + if (!(GSU.vPlotOptionReg & 0x01) && !(c & 0xf)) return; + + a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1); + v = 128 >> (x & 7); + + if (c & 0x01) a[0x00] |= v; + else a[0x00] &= ~v; + if (c & 0x02) a[0x01] |= v; + else a[0x01] &= ~v; + if (c & 0x04) a[0x10] |= v; + else a[0x10] &= ~v; + if (c & 0x08) a[0x11] |= v; + else a[0x11] &= ~v; } /* 4c(ALT1) - rpix - read color of the pixel with R1,R2 as x,y */ static void fx_rpix_4bit() { - uint32 x = USEX8(R1); - uint32 y = USEX8(R2); - uint8 *a; - uint8 v; + uint32 x = USEX8(R1); + uint32 y = USEX8(R2); + uint8* a; + uint8 v; - R15++; - CLRFLAGS; + R15++; + CLRFLAGS; #ifdef CHECK_LIMITS - if(y >= GSU.vScreenHeight) return; + if (y >= GSU.vScreenHeight) return; #endif - a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1); - v = 128 >> (x&7); + a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1); + v = 128 >> (x & 7); - DREG = 0; - DREG |= ((uint32)((a[0x00] & v) != 0)) << 0; - DREG |= ((uint32)((a[0x01] & v) != 0)) << 1; - DREG |= ((uint32)((a[0x10] & v) != 0)) << 2; - DREG |= ((uint32)((a[0x11] & v) != 0)) << 3; - TESTR14; + DREG = 0; + DREG |= ((uint32)((a[0x00] & v) != 0)) << 0; + DREG |= ((uint32)((a[0x01] & v) != 0)) << 1; + DREG |= ((uint32)((a[0x10] & v) != 0)) << 2; + DREG |= ((uint32)((a[0x11] & v) != 0)) << 3; + TESTR14; } /* 8c - plot - plot pixel with R1,R2 as x,y and the color register as the color */ static void fx_plot_8bit() { - uint32 x = USEX8(R1); - uint32 y = USEX8(R2); - uint8 *a; - uint8 v,c; + uint32 x = USEX8(R1); + uint32 y = USEX8(R2); + uint8* a; + uint8 v, c; + + R15++; + CLRFLAGS; + R1++; - R15++; - CLRFLAGS; - R1++; - #ifdef CHECK_LIMITS - if(y >= GSU.vScreenHeight) return; + if (y >= GSU.vScreenHeight) return; #endif - c = (uint8)GSU.vColorReg; - if( !(GSU.vPlotOptionReg & 0x10) ) - { - if( !(GSU.vPlotOptionReg & 0x01) && !(c&0xf)) return; - } - else - if( !(GSU.vPlotOptionReg & 0x01) && !c) return; - - a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1); - v = 128 >> (x&7); - - if(c & 0x01) a[0x00] |= v; - else a[0x00] &= ~v; - if(c & 0x02) a[0x01] |= v; - else a[0x01] &= ~v; - if(c & 0x04) a[0x10] |= v; - else a[0x10] &= ~v; - if(c & 0x08) a[0x11] |= v; - else a[0x11] &= ~v; - if(c & 0x10) a[0x20] |= v; - else a[0x20] &= ~v; - if(c & 0x20) a[0x21] |= v; - else a[0x21] &= ~v; - if(c & 0x40) a[0x30] |= v; - else a[0x30] &= ~v; - if(c & 0x80) a[0x31] |= v; - else a[0x31] &= ~v; + c = (uint8)GSU.vColorReg; + if (!(GSU.vPlotOptionReg & 0x10)) + { + if (!(GSU.vPlotOptionReg & 0x01) && !(c & 0xf)) return; + } + else if (!(GSU.vPlotOptionReg & 0x01) && !c) return; + + a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1); + v = 128 >> (x & 7); + + if (c & 0x01) a[0x00] |= v; + else a[0x00] &= ~v; + if (c & 0x02) a[0x01] |= v; + else a[0x01] &= ~v; + if (c & 0x04) a[0x10] |= v; + else a[0x10] &= ~v; + if (c & 0x08) a[0x11] |= v; + else a[0x11] &= ~v; + if (c & 0x10) a[0x20] |= v; + else a[0x20] &= ~v; + if (c & 0x20) a[0x21] |= v; + else a[0x21] &= ~v; + if (c & 0x40) a[0x30] |= v; + else a[0x30] &= ~v; + if (c & 0x80) a[0x31] |= v; + else a[0x31] &= ~v; } /* 4c(ALT1) - rpix - read color of the pixel with R1,R2 as x,y */ static void fx_rpix_8bit() { - uint32 x = USEX8(R1); - uint32 y = USEX8(R2); - uint8 *a; - uint8 v; + uint32 x = USEX8(R1); + uint32 y = USEX8(R2); + uint8* a; + uint8 v; - R15++; - CLRFLAGS; + R15++; + CLRFLAGS; #ifdef CHECK_LIMITS - if(y >= GSU.vScreenHeight) return; + if (y >= GSU.vScreenHeight) return; #endif - a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1); - v = 128 >> (x&7); - - DREG = 0; - DREG |= ((uint32)((a[0x00] & v) != 0)) << 0; - DREG |= ((uint32)((a[0x01] & v) != 0)) << 1; - DREG |= ((uint32)((a[0x10] & v) != 0)) << 2; - DREG |= ((uint32)((a[0x11] & v) != 0)) << 3; - DREG |= ((uint32)((a[0x20] & v) != 0)) << 4; - DREG |= ((uint32)((a[0x21] & v) != 0)) << 5; - DREG |= ((uint32)((a[0x30] & v) != 0)) << 6; - DREG |= ((uint32)((a[0x31] & v) != 0)) << 7; - GSU.vZero = DREG; - TESTR14; + a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1); + v = 128 >> (x & 7); + + DREG = 0; + DREG |= ((uint32)((a[0x00] & v) != 0)) << 0; + DREG |= ((uint32)((a[0x01] & v) != 0)) << 1; + DREG |= ((uint32)((a[0x10] & v) != 0)) << 2; + DREG |= ((uint32)((a[0x11] & v) != 0)) << 3; + DREG |= ((uint32)((a[0x20] & v) != 0)) << 4; + DREG |= ((uint32)((a[0x21] & v) != 0)) << 5; + DREG |= ((uint32)((a[0x30] & v) != 0)) << 6; + DREG |= ((uint32)((a[0x31] & v) != 0)) << 7; + GSU.vZero = DREG; + TESTR14; } /* 4o - plot - plot pixel with R1,R2 as x,y and the color register as the color */ static void fx_plot_obj() { - printf ("ERROR fx_plot_obj called\n"); + printf("ERROR fx_plot_obj called\n"); } /* 4c(ALT1) - rpix - read color of the pixel with R1,R2 as x,y */ static void fx_rpix_obj() { - printf ("ERROR fx_rpix_obj called\n"); + printf("ERROR fx_rpix_obj called\n"); } /* 4d - swap - swap upper and lower byte of a register */ static void fx_swap() { - uint8 c = (uint8)SREG; - uint8 d = (uint8)(SREG>>8); - uint32 v = (((uint32)c)<<8)|((uint32)d); - R15++; DREG = v; - GSU.vSign = v; - GSU.vZero = v; - TESTR14; - CLRFLAGS; + uint8 c = (uint8)SREG; + uint8 d = (uint8)(SREG >> 8); + uint32 v = (((uint32)c) << 8) | ((uint32)d); + R15++; + DREG = v; + GSU.vSign = v; + GSU.vZero = v; + TESTR14; + CLRFLAGS; } /* 4e - color - copy source register to color register */ static void fx_color() { - uint8 c = (uint8)SREG; - if(GSU.vPlotOptionReg & 0x04) - c = (c&0xf0) | (c>>4); - if(GSU.vPlotOptionReg & 0x08) - { - GSU.vColorReg &= 0xf0; - GSU.vColorReg |= c & 0x0f; - } - else - GSU.vColorReg = USEX8(c); - CLRFLAGS; - R15++; + uint8 c = (uint8)SREG; + if (GSU.vPlotOptionReg & 0x04) + c = (c & 0xf0) | (c >> 4); + if (GSU.vPlotOptionReg & 0x08) + { + GSU.vColorReg &= 0xf0; + GSU.vColorReg |= c & 0x0f; + } + else + GSU.vColorReg = USEX8(c); + CLRFLAGS; + R15++; } /* 4e(ALT1) - cmode - set plot option register */ static void fx_cmode() { - GSU.vPlotOptionReg = SREG; - - if(GSU.vPlotOptionReg & 0x10) - { - /* OBJ Mode (for drawing into sprites) */ - GSU.vScreenHeight = 256; - } - else - GSU.vScreenHeight = GSU.vScreenRealHeight; - - fx_computeScreenPointers (); - CLRFLAGS; - R15++; + GSU.vPlotOptionReg = SREG; + + if (GSU.vPlotOptionReg & 0x10) + { + /* OBJ Mode (for drawing into sprites) */ + GSU.vScreenHeight = 256; + } + else + GSU.vScreenHeight = GSU.vScreenRealHeight; + + fx_computeScreenPointers(); + CLRFLAGS; + R15++; } /* 4f - not - perform exclusive exor with 1 on all bits */ static void fx_not() { - uint32 v = ~SREG; - R15++; DREG = v; - GSU.vSign = v; - GSU.vZero = v; - TESTR14; - CLRFLAGS; + uint32 v = ~SREG; + R15++; + DREG = v; + GSU.vSign = v; + GSU.vZero = v; + TESTR14; + CLRFLAGS; } /* 50-5f - add rn - add, register + register */ @@ -645,22 +944,70 @@ GSU.vZero = s; \ R15++; DREG = s; \ TESTR14; \ CLRFLAGS -static void fx_add_r0() { FX_ADD(0); } -static void fx_add_r1() { FX_ADD(1); } -static void fx_add_r2() { FX_ADD(2); } -static void fx_add_r3() { FX_ADD(3); } -static void fx_add_r4() { FX_ADD(4); } -static void fx_add_r5() { FX_ADD(5); } -static void fx_add_r6() { FX_ADD(6); } -static void fx_add_r7() { FX_ADD(7); } -static void fx_add_r8() { FX_ADD(8); } -static void fx_add_r9() { FX_ADD(9); } -static void fx_add_r10() { FX_ADD(10); } -static void fx_add_r11() { FX_ADD(11); } -static void fx_add_r12() { FX_ADD(12); } -static void fx_add_r13() { FX_ADD(13); } -static void fx_add_r14() { FX_ADD(14); } -static void fx_add_r15() { FX_ADD(15); } +static void fx_add_r0() +{ + FX_ADD(0); +} +static void fx_add_r1() +{ + FX_ADD(1); +} +static void fx_add_r2() +{ + FX_ADD(2); +} +static void fx_add_r3() +{ + FX_ADD(3); +} +static void fx_add_r4() +{ + FX_ADD(4); +} +static void fx_add_r5() +{ + FX_ADD(5); +} +static void fx_add_r6() +{ + FX_ADD(6); +} +static void fx_add_r7() +{ + FX_ADD(7); +} +static void fx_add_r8() +{ + FX_ADD(8); +} +static void fx_add_r9() +{ + FX_ADD(9); +} +static void fx_add_r10() +{ + FX_ADD(10); +} +static void fx_add_r11() +{ + FX_ADD(11); +} +static void fx_add_r12() +{ + FX_ADD(12); +} +static void fx_add_r13() +{ + FX_ADD(13); +} +static void fx_add_r14() +{ + FX_ADD(14); +} +static void fx_add_r15() +{ + FX_ADD(15); +} /* 50-5f(ALT1) - adc rn - add with carry, register + register */ #define FX_ADC(reg) \ @@ -672,50 +1019,146 @@ GSU.vZero = s; \ R15++; DREG = s; \ TESTR14; \ CLRFLAGS -static void fx_adc_r0() { FX_ADC(0); } -static void fx_adc_r1() { FX_ADC(1); } -static void fx_adc_r2() { FX_ADC(2); } -static void fx_adc_r3() { FX_ADC(3); } -static void fx_adc_r4() { FX_ADC(4); } -static void fx_adc_r5() { FX_ADC(5); } -static void fx_adc_r6() { FX_ADC(6); } -static void fx_adc_r7() { FX_ADC(7); } -static void fx_adc_r8() { FX_ADC(8); } -static void fx_adc_r9() { FX_ADC(9); } -static void fx_adc_r10() { FX_ADC(10); } -static void fx_adc_r11() { FX_ADC(11); } -static void fx_adc_r12() { FX_ADC(12); } -static void fx_adc_r13() { FX_ADC(13); } -static void fx_adc_r14() { FX_ADC(14); } -static void fx_adc_r15() { FX_ADC(15); } - -/* 50-5f(ALT2) - add #n - add, register + immediate */ -#define FX_ADD_I(imm) \ -int32 s = SUSEX16(SREG) + imm; \ -GSU.vCarry = s >= 0x10000; \ -GSU.vOverflow = ~(SREG ^ imm) & (imm ^ s) & 0x8000; \ -GSU.vSign = s; \ -GSU.vZero = s; \ -R15++; DREG = s; \ -TESTR14; \ -CLRFLAGS -static void fx_add_i0() { FX_ADD_I(0); } -static void fx_add_i1() { FX_ADD_I(1); } -static void fx_add_i2() { FX_ADD_I(2); } -static void fx_add_i3() { FX_ADD_I(3); } -static void fx_add_i4() { FX_ADD_I(4); } -static void fx_add_i5() { FX_ADD_I(5); } -static void fx_add_i6() { FX_ADD_I(6); } -static void fx_add_i7() { FX_ADD_I(7); } -static void fx_add_i8() { FX_ADD_I(8); } -static void fx_add_i9() { FX_ADD_I(9); } -static void fx_add_i10() { FX_ADD_I(10); } -static void fx_add_i11() { FX_ADD_I(11); } -static void fx_add_i12() { FX_ADD_I(12); } -static void fx_add_i13() { FX_ADD_I(13); } -static void fx_add_i14() { FX_ADD_I(14); } -static void fx_add_i15() { FX_ADD_I(15); } - +static void fx_adc_r0() +{ + FX_ADC(0); +} +static void fx_adc_r1() +{ + FX_ADC(1); +} +static void fx_adc_r2() +{ + FX_ADC(2); +} +static void fx_adc_r3() +{ + FX_ADC(3); +} +static void fx_adc_r4() +{ + FX_ADC(4); +} +static void fx_adc_r5() +{ + FX_ADC(5); +} +static void fx_adc_r6() +{ + FX_ADC(6); +} +static void fx_adc_r7() +{ + FX_ADC(7); +} +static void fx_adc_r8() +{ + FX_ADC(8); +} +static void fx_adc_r9() +{ + FX_ADC(9); +} +static void fx_adc_r10() +{ + FX_ADC(10); +} +static void fx_adc_r11() +{ + FX_ADC(11); +} +static void fx_adc_r12() +{ + FX_ADC(12); +} +static void fx_adc_r13() +{ + FX_ADC(13); +} +static void fx_adc_r14() +{ + FX_ADC(14); +} +static void fx_adc_r15() +{ + FX_ADC(15); +} + +/* 50-5f(ALT2) - add #n - add, register + immediate */ +#define FX_ADD_I(imm) \ +int32 s = SUSEX16(SREG) + imm; \ +GSU.vCarry = s >= 0x10000; \ +GSU.vOverflow = ~(SREG ^ imm) & (imm ^ s) & 0x8000; \ +GSU.vSign = s; \ +GSU.vZero = s; \ +R15++; DREG = s; \ +TESTR14; \ +CLRFLAGS +static void fx_add_i0() +{ + FX_ADD_I(0); +} +static void fx_add_i1() +{ + FX_ADD_I(1); +} +static void fx_add_i2() +{ + FX_ADD_I(2); +} +static void fx_add_i3() +{ + FX_ADD_I(3); +} +static void fx_add_i4() +{ + FX_ADD_I(4); +} +static void fx_add_i5() +{ + FX_ADD_I(5); +} +static void fx_add_i6() +{ + FX_ADD_I(6); +} +static void fx_add_i7() +{ + FX_ADD_I(7); +} +static void fx_add_i8() +{ + FX_ADD_I(8); +} +static void fx_add_i9() +{ + FX_ADD_I(9); +} +static void fx_add_i10() +{ + FX_ADD_I(10); +} +static void fx_add_i11() +{ + FX_ADD_I(11); +} +static void fx_add_i12() +{ + FX_ADD_I(12); +} +static void fx_add_i13() +{ + FX_ADD_I(13); +} +static void fx_add_i14() +{ + FX_ADD_I(14); +} +static void fx_add_i15() +{ + FX_ADD_I(15); +} + /* 50-5f(ALT3) - adc #n - add with carry, register + immediate */ #define FX_ADC_I(imm) \ int32 s = SUSEX16(SREG) + imm + SUSEX16(GSU.vCarry); \ @@ -726,22 +1169,70 @@ GSU.vZero = s; \ R15++; DREG = s; \ TESTR14; \ CLRFLAGS -static void fx_adc_i0() { FX_ADC_I(0); } -static void fx_adc_i1() { FX_ADC_I(1); } -static void fx_adc_i2() { FX_ADC_I(2); } -static void fx_adc_i3() { FX_ADC_I(3); } -static void fx_adc_i4() { FX_ADC_I(4); } -static void fx_adc_i5() { FX_ADC_I(5); } -static void fx_adc_i6() { FX_ADC_I(6); } -static void fx_adc_i7() { FX_ADC_I(7); } -static void fx_adc_i8() { FX_ADC_I(8); } -static void fx_adc_i9() { FX_ADC_I(9); } -static void fx_adc_i10() { FX_ADC_I(10); } -static void fx_adc_i11() { FX_ADC_I(11); } -static void fx_adc_i12() { FX_ADC_I(12); } -static void fx_adc_i13() { FX_ADC_I(13); } -static void fx_adc_i14() { FX_ADC_I(14); } -static void fx_adc_i15() { FX_ADC_I(15); } +static void fx_adc_i0() +{ + FX_ADC_I(0); +} +static void fx_adc_i1() +{ + FX_ADC_I(1); +} +static void fx_adc_i2() +{ + FX_ADC_I(2); +} +static void fx_adc_i3() +{ + FX_ADC_I(3); +} +static void fx_adc_i4() +{ + FX_ADC_I(4); +} +static void fx_adc_i5() +{ + FX_ADC_I(5); +} +static void fx_adc_i6() +{ + FX_ADC_I(6); +} +static void fx_adc_i7() +{ + FX_ADC_I(7); +} +static void fx_adc_i8() +{ + FX_ADC_I(8); +} +static void fx_adc_i9() +{ + FX_ADC_I(9); +} +static void fx_adc_i10() +{ + FX_ADC_I(10); +} +static void fx_adc_i11() +{ + FX_ADC_I(11); +} +static void fx_adc_i12() +{ + FX_ADC_I(12); +} +static void fx_adc_i13() +{ + FX_ADC_I(13); +} +static void fx_adc_i14() +{ + FX_ADC_I(14); +} +static void fx_adc_i15() +{ + FX_ADC_I(15); +} /* 60-6f - sub rn - subtract, register - register */ #define FX_SUB(reg) \ @@ -753,22 +1244,70 @@ GSU.vZero = s; \ R15++; DREG = s; \ TESTR14; \ CLRFLAGS -static void fx_sub_r0() { FX_SUB(0); } -static void fx_sub_r1() { FX_SUB(1); } -static void fx_sub_r2() { FX_SUB(2); } -static void fx_sub_r3() { FX_SUB(3); } -static void fx_sub_r4() { FX_SUB(4); } -static void fx_sub_r5() { FX_SUB(5); } -static void fx_sub_r6() { FX_SUB(6); } -static void fx_sub_r7() { FX_SUB(7); } -static void fx_sub_r8() { FX_SUB(8); } -static void fx_sub_r9() { FX_SUB(9); } -static void fx_sub_r10() { FX_SUB(10); } -static void fx_sub_r11() { FX_SUB(11); } -static void fx_sub_r12() { FX_SUB(12); } -static void fx_sub_r13() { FX_SUB(13); } -static void fx_sub_r14() { FX_SUB(14); } -static void fx_sub_r15() { FX_SUB(15); } +static void fx_sub_r0() +{ + FX_SUB(0); +} +static void fx_sub_r1() +{ + FX_SUB(1); +} +static void fx_sub_r2() +{ + FX_SUB(2); +} +static void fx_sub_r3() +{ + FX_SUB(3); +} +static void fx_sub_r4() +{ + FX_SUB(4); +} +static void fx_sub_r5() +{ + FX_SUB(5); +} +static void fx_sub_r6() +{ + FX_SUB(6); +} +static void fx_sub_r7() +{ + FX_SUB(7); +} +static void fx_sub_r8() +{ + FX_SUB(8); +} +static void fx_sub_r9() +{ + FX_SUB(9); +} +static void fx_sub_r10() +{ + FX_SUB(10); +} +static void fx_sub_r11() +{ + FX_SUB(11); +} +static void fx_sub_r12() +{ + FX_SUB(12); +} +static void fx_sub_r13() +{ + FX_SUB(13); +} +static void fx_sub_r14() +{ + FX_SUB(14); +} +static void fx_sub_r15() +{ + FX_SUB(15); +} /* 60-6f(ALT1) - sbc rn - subtract with carry, register - register */ #define FX_SBC(reg) \ @@ -780,22 +1319,70 @@ GSU.vZero = s; \ R15++; DREG = s; \ TESTR14; \ CLRFLAGS -static void fx_sbc_r0() { FX_SBC(0); } -static void fx_sbc_r1() { FX_SBC(1); } -static void fx_sbc_r2() { FX_SBC(2); } -static void fx_sbc_r3() { FX_SBC(3); } -static void fx_sbc_r4() { FX_SBC(4); } -static void fx_sbc_r5() { FX_SBC(5); } -static void fx_sbc_r6() { FX_SBC(6); } -static void fx_sbc_r7() { FX_SBC(7); } -static void fx_sbc_r8() { FX_SBC(8); } -static void fx_sbc_r9() { FX_SBC(9); } -static void fx_sbc_r10() { FX_SBC(10); } -static void fx_sbc_r11() { FX_SBC(11); } -static void fx_sbc_r12() { FX_SBC(12); } -static void fx_sbc_r13() { FX_SBC(13); } -static void fx_sbc_r14() { FX_SBC(14); } -static void fx_sbc_r15() { FX_SBC(15); } +static void fx_sbc_r0() +{ + FX_SBC(0); +} +static void fx_sbc_r1() +{ + FX_SBC(1); +} +static void fx_sbc_r2() +{ + FX_SBC(2); +} +static void fx_sbc_r3() +{ + FX_SBC(3); +} +static void fx_sbc_r4() +{ + FX_SBC(4); +} +static void fx_sbc_r5() +{ + FX_SBC(5); +} +static void fx_sbc_r6() +{ + FX_SBC(6); +} +static void fx_sbc_r7() +{ + FX_SBC(7); +} +static void fx_sbc_r8() +{ + FX_SBC(8); +} +static void fx_sbc_r9() +{ + FX_SBC(9); +} +static void fx_sbc_r10() +{ + FX_SBC(10); +} +static void fx_sbc_r11() +{ + FX_SBC(11); +} +static void fx_sbc_r12() +{ + FX_SBC(12); +} +static void fx_sbc_r13() +{ + FX_SBC(13); +} +static void fx_sbc_r14() +{ + FX_SBC(14); +} +static void fx_sbc_r15() +{ + FX_SBC(15); +} /* 60-6f(ALT2) - sub #n - subtract, register - immediate */ #define FX_SUB_I(imm) \ @@ -807,22 +1394,70 @@ GSU.vZero = s; \ R15++; DREG = s; \ TESTR14; \ CLRFLAGS -static void fx_sub_i0() { FX_SUB_I(0); } -static void fx_sub_i1() { FX_SUB_I(1); } -static void fx_sub_i2() { FX_SUB_I(2); } -static void fx_sub_i3() { FX_SUB_I(3); } -static void fx_sub_i4() { FX_SUB_I(4); } -static void fx_sub_i5() { FX_SUB_I(5); } -static void fx_sub_i6() { FX_SUB_I(6); } -static void fx_sub_i7() { FX_SUB_I(7); } -static void fx_sub_i8() { FX_SUB_I(8); } -static void fx_sub_i9() { FX_SUB_I(9); } -static void fx_sub_i10() { FX_SUB_I(10); } -static void fx_sub_i11() { FX_SUB_I(11); } -static void fx_sub_i12() { FX_SUB_I(12); } -static void fx_sub_i13() { FX_SUB_I(13); } -static void fx_sub_i14() { FX_SUB_I(14); } -static void fx_sub_i15() { FX_SUB_I(15); } +static void fx_sub_i0() +{ + FX_SUB_I(0); +} +static void fx_sub_i1() +{ + FX_SUB_I(1); +} +static void fx_sub_i2() +{ + FX_SUB_I(2); +} +static void fx_sub_i3() +{ + FX_SUB_I(3); +} +static void fx_sub_i4() +{ + FX_SUB_I(4); +} +static void fx_sub_i5() +{ + FX_SUB_I(5); +} +static void fx_sub_i6() +{ + FX_SUB_I(6); +} +static void fx_sub_i7() +{ + FX_SUB_I(7); +} +static void fx_sub_i8() +{ + FX_SUB_I(8); +} +static void fx_sub_i9() +{ + FX_SUB_I(9); +} +static void fx_sub_i10() +{ + FX_SUB_I(10); +} +static void fx_sub_i11() +{ + FX_SUB_I(11); +} +static void fx_sub_i12() +{ + FX_SUB_I(12); +} +static void fx_sub_i13() +{ + FX_SUB_I(13); +} +static void fx_sub_i14() +{ + FX_SUB_I(14); +} +static void fx_sub_i15() +{ + FX_SUB_I(15); +} /* 60-6f(ALT3) - cmp rn - compare, register, register */ #define FX_CMP(reg) \ @@ -833,34 +1468,83 @@ GSU.vSign = s; \ GSU.vZero = s; \ R15++; \ CLRFLAGS; -static void fx_cmp_r0() { FX_CMP(0); } -static void fx_cmp_r1() { FX_CMP(1); } -static void fx_cmp_r2() { FX_CMP(2); } -static void fx_cmp_r3() { FX_CMP(3); } -static void fx_cmp_r4() { FX_CMP(4); } -static void fx_cmp_r5() { FX_CMP(5); } -static void fx_cmp_r6() { FX_CMP(6); } -static void fx_cmp_r7() { FX_CMP(7); } -static void fx_cmp_r8() { FX_CMP(8); } -static void fx_cmp_r9() { FX_CMP(9); } -static void fx_cmp_r10() { FX_CMP(10); } -static void fx_cmp_r11() { FX_CMP(11); } -static void fx_cmp_r12() { FX_CMP(12); } -static void fx_cmp_r13() { FX_CMP(13); } -static void fx_cmp_r14() { FX_CMP(14); } -static void fx_cmp_r15() { FX_CMP(15); } +static void fx_cmp_r0() +{ + FX_CMP(0); +} +static void fx_cmp_r1() +{ + FX_CMP(1); +} +static void fx_cmp_r2() +{ + FX_CMP(2); +} +static void fx_cmp_r3() +{ + FX_CMP(3); +} +static void fx_cmp_r4() +{ + FX_CMP(4); +} +static void fx_cmp_r5() +{ + FX_CMP(5); +} +static void fx_cmp_r6() +{ + FX_CMP(6); +} +static void fx_cmp_r7() +{ + FX_CMP(7); +} +static void fx_cmp_r8() +{ + FX_CMP(8); +} +static void fx_cmp_r9() +{ + FX_CMP(9); +} +static void fx_cmp_r10() +{ + FX_CMP(10); +} +static void fx_cmp_r11() +{ + FX_CMP(11); +} +static void fx_cmp_r12() +{ + FX_CMP(12); +} +static void fx_cmp_r13() +{ + FX_CMP(13); +} +static void fx_cmp_r14() +{ + FX_CMP(14); +} +static void fx_cmp_r15() +{ + FX_CMP(15); +} /* 70 - merge - R7 as upper byte, R8 as lower byte (used for texture-mapping) */ static void fx_merge() { - uint32 v = (R7&0xff00) | ((R8&0xff00)>>8); - R15++; DREG = v; - GSU.vOverflow = (v & 0xc0c0) << 16; - GSU.vZero = !(v & 0xf0f0); - GSU.vSign = ((v | (v<<8)) & 0x8000); - GSU.vCarry = (v & 0xe0e0) != 0; - TESTR14; - CLRFLAGS; + uint32 v = (R7 & 0xff00) | ((R8 & 0xff00) >> 8); + R15++; + DREG = v; + GSU.vOverflow = (v & 0xc0c0) << 16; + GSU.vZero = !(v & 0xf0f0); + GSU.vSign = ((v | (v << 8)) & 0x8000); + GSU.vCarry = (v & 0xe0e0) != 0; + TESTR14; + CLRFLAGS; } /* 71-7f - and rn - reister & register */ @@ -871,45 +1555,135 @@ GSU.vSign = v; \ GSU.vZero = v; \ TESTR14; \ CLRFLAGS; -static void fx_and_r1() { FX_AND(1); } -static void fx_and_r2() { FX_AND(2); } -static void fx_and_r3() { FX_AND(3); } -static void fx_and_r4() { FX_AND(4); } -static void fx_and_r5() { FX_AND(5); } -static void fx_and_r6() { FX_AND(6); } -static void fx_and_r7() { FX_AND(7); } -static void fx_and_r8() { FX_AND(8); } -static void fx_and_r9() { FX_AND(9); } -static void fx_and_r10() { FX_AND(10); } -static void fx_and_r11() { FX_AND(11); } -static void fx_and_r12() { FX_AND(12); } -static void fx_and_r13() { FX_AND(13); } -static void fx_and_r14() { FX_AND(14); } -static void fx_and_r15() { FX_AND(15); } +static void fx_and_r1() +{ + FX_AND(1); +} +static void fx_and_r2() +{ + FX_AND(2); +} +static void fx_and_r3() +{ + FX_AND(3); +} +static void fx_and_r4() +{ + FX_AND(4); +} +static void fx_and_r5() +{ + FX_AND(5); +} +static void fx_and_r6() +{ + FX_AND(6); +} +static void fx_and_r7() +{ + FX_AND(7); +} +static void fx_and_r8() +{ + FX_AND(8); +} +static void fx_and_r9() +{ + FX_AND(9); +} +static void fx_and_r10() +{ + FX_AND(10); +} +static void fx_and_r11() +{ + FX_AND(11); +} +static void fx_and_r12() +{ + FX_AND(12); +} +static void fx_and_r13() +{ + FX_AND(13); +} +static void fx_and_r14() +{ + FX_AND(14); +} +static void fx_and_r15() +{ + FX_AND(15); +} /* 71-7f(ALT1) - bic rn - reister & ~register */ #define FX_BIC(reg) \ -uint32 v = SREG & ~GSU.avReg[reg]; \ +uint32 v = SREG & ~GSU.avReg[reg]; \ R15++; DREG = v; \ GSU.vSign = v; \ GSU.vZero = v; \ TESTR14; \ CLRFLAGS; -static void fx_bic_r1() { FX_BIC(1); } -static void fx_bic_r2() { FX_BIC(2); } -static void fx_bic_r3() { FX_BIC(3); } -static void fx_bic_r4() { FX_BIC(4); } -static void fx_bic_r5() { FX_BIC(5); } -static void fx_bic_r6() { FX_BIC(6); } -static void fx_bic_r7() { FX_BIC(7); } -static void fx_bic_r8() { FX_BIC(8); } -static void fx_bic_r9() { FX_BIC(9); } -static void fx_bic_r10() { FX_BIC(10); } -static void fx_bic_r11() { FX_BIC(11); } -static void fx_bic_r12() { FX_BIC(12); } -static void fx_bic_r13() { FX_BIC(13); } -static void fx_bic_r14() { FX_BIC(14); } -static void fx_bic_r15() { FX_BIC(15); } +static void fx_bic_r1() +{ + FX_BIC(1); +} +static void fx_bic_r2() +{ + FX_BIC(2); +} +static void fx_bic_r3() +{ + FX_BIC(3); +} +static void fx_bic_r4() +{ + FX_BIC(4); +} +static void fx_bic_r5() +{ + FX_BIC(5); +} +static void fx_bic_r6() +{ + FX_BIC(6); +} +static void fx_bic_r7() +{ + FX_BIC(7); +} +static void fx_bic_r8() +{ + FX_BIC(8); +} +static void fx_bic_r9() +{ + FX_BIC(9); +} +static void fx_bic_r10() +{ + FX_BIC(10); +} +static void fx_bic_r11() +{ + FX_BIC(11); +} +static void fx_bic_r12() +{ + FX_BIC(12); +} +static void fx_bic_r13() +{ + FX_BIC(13); +} +static void fx_bic_r14() +{ + FX_BIC(14); +} +static void fx_bic_r15() +{ + FX_BIC(15); +} /* 71-7f(ALT2) - and #n - reister & immediate */ #define FX_AND_I(imm) \ @@ -919,21 +1693,66 @@ GSU.vSign = v; \ GSU.vZero = v; \ TESTR14; \ CLRFLAGS; -static void fx_and_i1() { FX_AND_I(1); } -static void fx_and_i2() { FX_AND_I(2); } -static void fx_and_i3() { FX_AND_I(3); } -static void fx_and_i4() { FX_AND_I(4); } -static void fx_and_i5() { FX_AND_I(5); } -static void fx_and_i6() { FX_AND_I(6); } -static void fx_and_i7() { FX_AND_I(7); } -static void fx_and_i8() { FX_AND_I(8); } -static void fx_and_i9() { FX_AND_I(9); } -static void fx_and_i10() { FX_AND_I(10); } -static void fx_and_i11() { FX_AND_I(11); } -static void fx_and_i12() { FX_AND_I(12); } -static void fx_and_i13() { FX_AND_I(13); } -static void fx_and_i14() { FX_AND_I(14); } -static void fx_and_i15() { FX_AND_I(15); } +static void fx_and_i1() +{ + FX_AND_I(1); +} +static void fx_and_i2() +{ + FX_AND_I(2); +} +static void fx_and_i3() +{ + FX_AND_I(3); +} +static void fx_and_i4() +{ + FX_AND_I(4); +} +static void fx_and_i5() +{ + FX_AND_I(5); +} +static void fx_and_i6() +{ + FX_AND_I(6); +} +static void fx_and_i7() +{ + FX_AND_I(7); +} +static void fx_and_i8() +{ + FX_AND_I(8); +} +static void fx_and_i9() +{ + FX_AND_I(9); +} +static void fx_and_i10() +{ + FX_AND_I(10); +} +static void fx_and_i11() +{ + FX_AND_I(11); +} +static void fx_and_i12() +{ + FX_AND_I(12); +} +static void fx_and_i13() +{ + FX_AND_I(13); +} +static void fx_and_i14() +{ + FX_AND_I(14); +} +static void fx_and_i15() +{ + FX_AND_I(15); +} /* 71-7f(ALT3) - bic #n - reister & ~immediate */ #define FX_BIC_I(imm) \ @@ -943,21 +1762,66 @@ GSU.vSign = v; \ GSU.vZero = v; \ TESTR14; \ CLRFLAGS; -static void fx_bic_i1() { FX_BIC_I(1); } -static void fx_bic_i2() { FX_BIC_I(2); } -static void fx_bic_i3() { FX_BIC_I(3); } -static void fx_bic_i4() { FX_BIC_I(4); } -static void fx_bic_i5() { FX_BIC_I(5); } -static void fx_bic_i6() { FX_BIC_I(6); } -static void fx_bic_i7() { FX_BIC_I(7); } -static void fx_bic_i8() { FX_BIC_I(8); } -static void fx_bic_i9() { FX_BIC_I(9); } -static void fx_bic_i10() { FX_BIC_I(10); } -static void fx_bic_i11() { FX_BIC_I(11); } -static void fx_bic_i12() { FX_BIC_I(12); } -static void fx_bic_i13() { FX_BIC_I(13); } -static void fx_bic_i14() { FX_BIC_I(14); } -static void fx_bic_i15() { FX_BIC_I(15); } +static void fx_bic_i1() +{ + FX_BIC_I(1); +} +static void fx_bic_i2() +{ + FX_BIC_I(2); +} +static void fx_bic_i3() +{ + FX_BIC_I(3); +} +static void fx_bic_i4() +{ + FX_BIC_I(4); +} +static void fx_bic_i5() +{ + FX_BIC_I(5); +} +static void fx_bic_i6() +{ + FX_BIC_I(6); +} +static void fx_bic_i7() +{ + FX_BIC_I(7); +} +static void fx_bic_i8() +{ + FX_BIC_I(8); +} +static void fx_bic_i9() +{ + FX_BIC_I(9); +} +static void fx_bic_i10() +{ + FX_BIC_I(10); +} +static void fx_bic_i11() +{ + FX_BIC_I(11); +} +static void fx_bic_i12() +{ + FX_BIC_I(12); +} +static void fx_bic_i13() +{ + FX_BIC_I(13); +} +static void fx_bic_i14() +{ + FX_BIC_I(14); +} +static void fx_bic_i15() +{ + FX_BIC_I(15); +} /* 80-8f - mult rn - 8 bit to 16 bit signed multiply, register * register */ #define FX_MULT(reg) \ @@ -967,22 +1831,70 @@ GSU.vSign = v; \ GSU.vZero = v; \ TESTR14; \ CLRFLAGS; -static void fx_mult_r0() { FX_MULT(0); } -static void fx_mult_r1() { FX_MULT(1); } -static void fx_mult_r2() { FX_MULT(2); } -static void fx_mult_r3() { FX_MULT(3); } -static void fx_mult_r4() { FX_MULT(4); } -static void fx_mult_r5() { FX_MULT(5); } -static void fx_mult_r6() { FX_MULT(6); } -static void fx_mult_r7() { FX_MULT(7); } -static void fx_mult_r8() { FX_MULT(8); } -static void fx_mult_r9() { FX_MULT(9); } -static void fx_mult_r10() { FX_MULT(10); } -static void fx_mult_r11() { FX_MULT(11); } -static void fx_mult_r12() { FX_MULT(12); } -static void fx_mult_r13() { FX_MULT(13); } -static void fx_mult_r14() { FX_MULT(14); } -static void fx_mult_r15() { FX_MULT(15); } +static void fx_mult_r0() +{ + FX_MULT(0); +} +static void fx_mult_r1() +{ + FX_MULT(1); +} +static void fx_mult_r2() +{ + FX_MULT(2); +} +static void fx_mult_r3() +{ + FX_MULT(3); +} +static void fx_mult_r4() +{ + FX_MULT(4); +} +static void fx_mult_r5() +{ + FX_MULT(5); +} +static void fx_mult_r6() +{ + FX_MULT(6); +} +static void fx_mult_r7() +{ + FX_MULT(7); +} +static void fx_mult_r8() +{ + FX_MULT(8); +} +static void fx_mult_r9() +{ + FX_MULT(9); +} +static void fx_mult_r10() +{ + FX_MULT(10); +} +static void fx_mult_r11() +{ + FX_MULT(11); +} +static void fx_mult_r12() +{ + FX_MULT(12); +} +static void fx_mult_r13() +{ + FX_MULT(13); +} +static void fx_mult_r14() +{ + FX_MULT(14); +} +static void fx_mult_r15() +{ + FX_MULT(15); +} /* 80-8f(ALT1) - umult rn - 8 bit to 16 bit unsigned multiply, register * register */ #define FX_UMULT(reg) \ @@ -992,23 +1904,71 @@ GSU.vSign = v; \ GSU.vZero = v; \ TESTR14; \ CLRFLAGS; -static void fx_umult_r0() { FX_UMULT(0); } -static void fx_umult_r1() { FX_UMULT(1); } -static void fx_umult_r2() { FX_UMULT(2); } -static void fx_umult_r3() { FX_UMULT(3); } -static void fx_umult_r4() { FX_UMULT(4); } -static void fx_umult_r5() { FX_UMULT(5); } -static void fx_umult_r6() { FX_UMULT(6); } -static void fx_umult_r7() { FX_UMULT(7); } -static void fx_umult_r8() { FX_UMULT(8); } -static void fx_umult_r9() { FX_UMULT(9); } -static void fx_umult_r10() { FX_UMULT(10); } -static void fx_umult_r11() { FX_UMULT(11); } -static void fx_umult_r12() { FX_UMULT(12); } -static void fx_umult_r13() { FX_UMULT(13); } -static void fx_umult_r14() { FX_UMULT(14); } -static void fx_umult_r15() { FX_UMULT(15); } - +static void fx_umult_r0() +{ + FX_UMULT(0); +} +static void fx_umult_r1() +{ + FX_UMULT(1); +} +static void fx_umult_r2() +{ + FX_UMULT(2); +} +static void fx_umult_r3() +{ + FX_UMULT(3); +} +static void fx_umult_r4() +{ + FX_UMULT(4); +} +static void fx_umult_r5() +{ + FX_UMULT(5); +} +static void fx_umult_r6() +{ + FX_UMULT(6); +} +static void fx_umult_r7() +{ + FX_UMULT(7); +} +static void fx_umult_r8() +{ + FX_UMULT(8); +} +static void fx_umult_r9() +{ + FX_UMULT(9); +} +static void fx_umult_r10() +{ + FX_UMULT(10); +} +static void fx_umult_r11() +{ + FX_UMULT(11); +} +static void fx_umult_r12() +{ + FX_UMULT(12); +} +static void fx_umult_r13() +{ + FX_UMULT(13); +} +static void fx_umult_r14() +{ + FX_UMULT(14); +} +static void fx_umult_r15() +{ + FX_UMULT(15); +} + /* 80-8f(ALT2) - mult #n - 8 bit to 16 bit signed multiply, register * immediate */ #define FX_MULT_I(imm) \ uint32 v = (uint32) (SEX8(SREG) * ((int32)imm)); \ @@ -1017,23 +1977,71 @@ GSU.vSign = v; \ GSU.vZero = v; \ TESTR14; \ CLRFLAGS; -static void fx_mult_i0() { FX_MULT_I(0); } -static void fx_mult_i1() { FX_MULT_I(1); } -static void fx_mult_i2() { FX_MULT_I(2); } -static void fx_mult_i3() { FX_MULT_I(3); } -static void fx_mult_i4() { FX_MULT_I(4); } -static void fx_mult_i5() { FX_MULT_I(5); } -static void fx_mult_i6() { FX_MULT_I(6); } -static void fx_mult_i7() { FX_MULT_I(7); } -static void fx_mult_i8() { FX_MULT_I(8); } -static void fx_mult_i9() { FX_MULT_I(9); } -static void fx_mult_i10() { FX_MULT_I(10); } -static void fx_mult_i11() { FX_MULT_I(11); } -static void fx_mult_i12() { FX_MULT_I(12); } -static void fx_mult_i13() { FX_MULT_I(13); } -static void fx_mult_i14() { FX_MULT_I(14); } -static void fx_mult_i15() { FX_MULT_I(15); } - +static void fx_mult_i0() +{ + FX_MULT_I(0); +} +static void fx_mult_i1() +{ + FX_MULT_I(1); +} +static void fx_mult_i2() +{ + FX_MULT_I(2); +} +static void fx_mult_i3() +{ + FX_MULT_I(3); +} +static void fx_mult_i4() +{ + FX_MULT_I(4); +} +static void fx_mult_i5() +{ + FX_MULT_I(5); +} +static void fx_mult_i6() +{ + FX_MULT_I(6); +} +static void fx_mult_i7() +{ + FX_MULT_I(7); +} +static void fx_mult_i8() +{ + FX_MULT_I(8); +} +static void fx_mult_i9() +{ + FX_MULT_I(9); +} +static void fx_mult_i10() +{ + FX_MULT_I(10); +} +static void fx_mult_i11() +{ + FX_MULT_I(11); +} +static void fx_mult_i12() +{ + FX_MULT_I(12); +} +static void fx_mult_i13() +{ + FX_MULT_I(13); +} +static void fx_mult_i14() +{ + FX_MULT_I(14); +} +static void fx_mult_i15() +{ + FX_MULT_I(15); +} + /* 80-8f(ALT3) - umult #n - 8 bit to 16 bit unsigned multiply, register * immediate */ #define FX_UMULT_I(imm) \ uint32 v = USEX8(SREG) * ((uint32)imm); \ @@ -1042,102 +2050,184 @@ GSU.vSign = v; \ GSU.vZero = v; \ TESTR14; \ CLRFLAGS; -static void fx_umult_i0() { FX_UMULT_I(0); } -static void fx_umult_i1() { FX_UMULT_I(1); } -static void fx_umult_i2() { FX_UMULT_I(2); } -static void fx_umult_i3() { FX_UMULT_I(3); } -static void fx_umult_i4() { FX_UMULT_I(4); } -static void fx_umult_i5() { FX_UMULT_I(5); } -static void fx_umult_i6() { FX_UMULT_I(6); } -static void fx_umult_i7() { FX_UMULT_I(7); } -static void fx_umult_i8() { FX_UMULT_I(8); } -static void fx_umult_i9() { FX_UMULT_I(9); } -static void fx_umult_i10() { FX_UMULT_I(10); } -static void fx_umult_i11() { FX_UMULT_I(11); } -static void fx_umult_i12() { FX_UMULT_I(12); } -static void fx_umult_i13() { FX_UMULT_I(13); } -static void fx_umult_i14() { FX_UMULT_I(14); } -static void fx_umult_i15() { FX_UMULT_I(15); } - +static void fx_umult_i0() +{ + FX_UMULT_I(0); +} +static void fx_umult_i1() +{ + FX_UMULT_I(1); +} +static void fx_umult_i2() +{ + FX_UMULT_I(2); +} +static void fx_umult_i3() +{ + FX_UMULT_I(3); +} +static void fx_umult_i4() +{ + FX_UMULT_I(4); +} +static void fx_umult_i5() +{ + FX_UMULT_I(5); +} +static void fx_umult_i6() +{ + FX_UMULT_I(6); +} +static void fx_umult_i7() +{ + FX_UMULT_I(7); +} +static void fx_umult_i8() +{ + FX_UMULT_I(8); +} +static void fx_umult_i9() +{ + FX_UMULT_I(9); +} +static void fx_umult_i10() +{ + FX_UMULT_I(10); +} +static void fx_umult_i11() +{ + FX_UMULT_I(11); +} +static void fx_umult_i12() +{ + FX_UMULT_I(12); +} +static void fx_umult_i13() +{ + FX_UMULT_I(13); +} +static void fx_umult_i14() +{ + FX_UMULT_I(14); +} +static void fx_umult_i15() +{ + FX_UMULT_I(15); +} + /* 90 - sbk - store word to last accessed RAM address */ static void fx_sbk() { - RAM(GSU.vLastRamAdr) = (uint8)SREG; - RAM(GSU.vLastRamAdr^1) = (uint8)(SREG>>8); - CLRFLAGS; - R15++; + RAM(GSU.vLastRamAdr) = (uint8)SREG; + RAM(GSU.vLastRamAdr ^ 1) = (uint8)(SREG >> 8); + CLRFLAGS; + R15++; } /* 91-94 - link #n - R11 = R15 + immediate */ #define FX_LINK_I(lkn) R11 = R15 + lkn; CLRFLAGS; R15++ -static void fx_link_i1() { FX_LINK_I(1); } -static void fx_link_i2() { FX_LINK_I(2); } -static void fx_link_i3() { FX_LINK_I(3); } -static void fx_link_i4() { FX_LINK_I(4); } +static void fx_link_i1() +{ + FX_LINK_I(1); +} +static void fx_link_i2() +{ + FX_LINK_I(2); +} +static void fx_link_i3() +{ + FX_LINK_I(3); +} +static void fx_link_i4() +{ + FX_LINK_I(4); +} /* 95 - sex - sign extend 8 bit to 16 bit */ static void fx_sex() { - uint32 v = (uint32)SEX8(SREG); - R15++; DREG = v; - GSU.vSign = v; - GSU.vZero = v; - TESTR14; - CLRFLAGS; + uint32 v = (uint32)SEX8(SREG); + R15++; + DREG = v; + GSU.vSign = v; + GSU.vZero = v; + TESTR14; + CLRFLAGS; } /* 96 - asr - aritmetric shift right by one */ static void fx_asr() { - uint32 v; - GSU.vCarry = SREG & 1; - v = (uint32)(SEX16(SREG)>>1); - R15++; DREG = v; - GSU.vSign = v; - GSU.vZero = v; - TESTR14; - CLRFLAGS; + uint32 v; + GSU.vCarry = SREG & 1; + v = (uint32)(SEX16(SREG) >> 1); + R15++; + DREG = v; + GSU.vSign = v; + GSU.vZero = v; + TESTR14; + CLRFLAGS; } /* 96(ALT1) - div2 - aritmetric shift right by one */ static void fx_div2() { - uint32 v; - int32 s = SEX16(SREG); - GSU.vCarry = s & 1; - if(s == -1) - v = 0; - else - v = (uint32)(s>>1); - R15++; DREG = v; - GSU.vSign = v; - GSU.vZero = v; - TESTR14; - CLRFLAGS; + uint32 v; + int32 s = SEX16(SREG); + GSU.vCarry = s & 1; + if (s == -1) + v = 0; + else + v = (uint32)(s >> 1); + R15++; + DREG = v; + GSU.vSign = v; + GSU.vZero = v; + TESTR14; + CLRFLAGS; } /* 97 - ror - rotate right by one */ static void fx_ror() { - uint32 v = (USEX16(SREG)>>1) | (GSU.vCarry<<15); - GSU.vCarry = SREG & 1; - R15++; DREG = v; - GSU.vSign = v; - GSU.vZero = v; - TESTR14; - CLRFLAGS; + uint32 v = (USEX16(SREG) >> 1) | (GSU.vCarry << 15); + GSU.vCarry = SREG & 1; + R15++; + DREG = v; + GSU.vSign = v; + GSU.vZero = v; + TESTR14; + CLRFLAGS; } /* 98-9d - jmp rn - jump to address of register */ #define FX_JMP(reg) \ R15 = GSU.avReg[reg]; \ CLRFLAGS; -static void fx_jmp_r8() { FX_JMP(8); } -static void fx_jmp_r9() { FX_JMP(9); } -static void fx_jmp_r10() { FX_JMP(10); } -static void fx_jmp_r11() { FX_JMP(11); } -static void fx_jmp_r12() { FX_JMP(12); } -static void fx_jmp_r13() { FX_JMP(13); } +static void fx_jmp_r8() +{ + FX_JMP(8); +} +static void fx_jmp_r9() +{ + FX_JMP(9); +} +static void fx_jmp_r10() +{ + FX_JMP(10); +} +static void fx_jmp_r11() +{ + FX_JMP(11); +} +static void fx_jmp_r12() +{ + FX_JMP(12); +} +static void fx_jmp_r13() +{ + FX_JMP(13); +} /* 98-9d(ALT1) - ljmp rn - set program bank to source register and jump to address of register */ #define FX_LJMP(reg) \ @@ -1145,52 +2235,73 @@ GSU.vPrgBankReg = GSU.avReg[reg] & 0x7f; \ GSU.pvPrgBank = GSU.apvRomBank[GSU.vPrgBankReg]; \ R15 = SREG; \ GSU.bCacheActive = FALSE; fx_cache(); R15--; -static void fx_ljmp_r8() { FX_LJMP(8); } -static void fx_ljmp_r9() { FX_LJMP(9); } -static void fx_ljmp_r10() { FX_LJMP(10); } -static void fx_ljmp_r11() { FX_LJMP(11); } -static void fx_ljmp_r12() { FX_LJMP(12); } -static void fx_ljmp_r13() { FX_LJMP(13); } +static void fx_ljmp_r8() +{ + FX_LJMP(8); +} +static void fx_ljmp_r9() +{ + FX_LJMP(9); +} +static void fx_ljmp_r10() +{ + FX_LJMP(10); +} +static void fx_ljmp_r11() +{ + FX_LJMP(11); +} +static void fx_ljmp_r12() +{ + FX_LJMP(12); +} +static void fx_ljmp_r13() +{ + FX_LJMP(13); +} /* 9e - lob - set upper byte to zero (keep low byte) */ static void fx_lob() { - uint32 v = USEX8(SREG); - R15++; DREG = v; - GSU.vSign = v<<8; - GSU.vZero = v<<8; - TESTR14; - CLRFLAGS; + uint32 v = USEX8(SREG); + R15++; + DREG = v; + GSU.vSign = v << 8; + GSU.vZero = v << 8; + TESTR14; + CLRFLAGS; } /* 9f - fmult - 16 bit to 32 bit signed multiplication, upper 16 bits only */ static void fx_fmult() { - uint32 v; - uint32 c = (uint32) (SEX16(SREG) * SEX16(R6)); - v = c >> 16; - R15++; DREG = v; - GSU.vSign = v; - GSU.vZero = v; - GSU.vCarry = (c >> 15) & 1; - TESTR14; - CLRFLAGS; + uint32 v; + uint32 c = (uint32)(SEX16(SREG) * SEX16(R6)); + v = c >> 16; + R15++; + DREG = v; + GSU.vSign = v; + GSU.vZero = v; + GSU.vCarry = (c >> 15) & 1; + TESTR14; + CLRFLAGS; } /* 9f(ALT1) - lmult - 16 bit to 32 bit signed multiplication */ static void fx_lmult() { - uint32 v; - uint32 c = (uint32) (SEX16(SREG) * SEX16(R6)); - R4 = c; - v = c >> 16; - R15++; DREG = v; - GSU.vSign = v; - GSU.vZero = v; - /* XXX R6 or R4? */ - GSU.vCarry = (R4 >> 15) & 1; /* should it be bit 15 of R4 instead? */ - TESTR14; - CLRFLAGS; + uint32 v; + uint32 c = (uint32)(SEX16(SREG) * SEX16(R6)); + R4 = c; + v = c >> 16; + R15++; + DREG = v; + GSU.vSign = v; + GSU.vZero = v; + /* XXX R6 or R4? */ + GSU.vCarry = (R4 >> 15) & 1; /* should it be bit 15 of R4 instead? */ + TESTR14; + CLRFLAGS; } /* a0-af - ibt rn,#pp - immediate byte transfer */ @@ -1199,22 +2310,71 @@ uint8 v = PIPE; R15++; \ FETCHPIPE; R15++; \ GSU.avReg[reg] = SEX8(v); \ CLRFLAGS; -static void fx_ibt_r0() { FX_IBT(0); } -static void fx_ibt_r1() { FX_IBT(1); } -static void fx_ibt_r2() { FX_IBT(2); } -static void fx_ibt_r3() { FX_IBT(3); } -static void fx_ibt_r4() { FX_IBT(4); } -static void fx_ibt_r5() { FX_IBT(5); } -static void fx_ibt_r6() { FX_IBT(6); } -static void fx_ibt_r7() { FX_IBT(7); } -static void fx_ibt_r8() { FX_IBT(8); } -static void fx_ibt_r9() { FX_IBT(9); } -static void fx_ibt_r10() { FX_IBT(10); } -static void fx_ibt_r11() { FX_IBT(11); } -static void fx_ibt_r12() { FX_IBT(12); } -static void fx_ibt_r13() { FX_IBT(13); } -static void fx_ibt_r14() { FX_IBT(14); READR14; } -static void fx_ibt_r15() { FX_IBT(15); } +static void fx_ibt_r0() +{ + FX_IBT(0); +} +static void fx_ibt_r1() +{ + FX_IBT(1); +} +static void fx_ibt_r2() +{ + FX_IBT(2); +} +static void fx_ibt_r3() +{ + FX_IBT(3); +} +static void fx_ibt_r4() +{ + FX_IBT(4); +} +static void fx_ibt_r5() +{ + FX_IBT(5); +} +static void fx_ibt_r6() +{ + FX_IBT(6); +} +static void fx_ibt_r7() +{ + FX_IBT(7); +} +static void fx_ibt_r8() +{ + FX_IBT(8); +} +static void fx_ibt_r9() +{ + FX_IBT(9); +} +static void fx_ibt_r10() +{ + FX_IBT(10); +} +static void fx_ibt_r11() +{ + FX_IBT(11); +} +static void fx_ibt_r12() +{ + FX_IBT(12); +} +static void fx_ibt_r13() +{ + FX_IBT(13); +} +static void fx_ibt_r14() +{ + FX_IBT(14); + READR14; +} +static void fx_ibt_r15() +{ + FX_IBT(15); +} /* a0-af(ALT1) - lms rn,(yy) - load word from RAM (short address) */ #define FX_LMS(reg) \ @@ -1223,22 +2383,71 @@ R15++; FETCHPIPE; R15++; \ GSU.avReg[reg] = (uint32)RAM(GSU.vLastRamAdr); \ GSU.avReg[reg] |= ((uint32)RAM(GSU.vLastRamAdr+1))<<8; \ CLRFLAGS; -static void fx_lms_r0() { FX_LMS(0); } -static void fx_lms_r1() { FX_LMS(1); } -static void fx_lms_r2() { FX_LMS(2); } -static void fx_lms_r3() { FX_LMS(3); } -static void fx_lms_r4() { FX_LMS(4); } -static void fx_lms_r5() { FX_LMS(5); } -static void fx_lms_r6() { FX_LMS(6); } -static void fx_lms_r7() { FX_LMS(7); } -static void fx_lms_r8() { FX_LMS(8); } -static void fx_lms_r9() { FX_LMS(9); } -static void fx_lms_r10() { FX_LMS(10); } -static void fx_lms_r11() { FX_LMS(11); } -static void fx_lms_r12() { FX_LMS(12); } -static void fx_lms_r13() { FX_LMS(13); } -static void fx_lms_r14() { FX_LMS(14); READR14; } -static void fx_lms_r15() { FX_LMS(15); } +static void fx_lms_r0() +{ + FX_LMS(0); +} +static void fx_lms_r1() +{ + FX_LMS(1); +} +static void fx_lms_r2() +{ + FX_LMS(2); +} +static void fx_lms_r3() +{ + FX_LMS(3); +} +static void fx_lms_r4() +{ + FX_LMS(4); +} +static void fx_lms_r5() +{ + FX_LMS(5); +} +static void fx_lms_r6() +{ + FX_LMS(6); +} +static void fx_lms_r7() +{ + FX_LMS(7); +} +static void fx_lms_r8() +{ + FX_LMS(8); +} +static void fx_lms_r9() +{ + FX_LMS(9); +} +static void fx_lms_r10() +{ + FX_LMS(10); +} +static void fx_lms_r11() +{ + FX_LMS(11); +} +static void fx_lms_r12() +{ + FX_LMS(12); +} +static void fx_lms_r13() +{ + FX_LMS(13); +} +static void fx_lms_r14() +{ + FX_LMS(14); + READR14; +} +static void fx_lms_r15() +{ + FX_LMS(15); +} /* a0-af(ALT2) - sms (yy),rn - store word in RAM (short address) */ /* If rn == r15, is the value of r15 before or after the extra byte is read? */ @@ -1249,22 +2458,70 @@ R15++; FETCHPIPE; \ RAM(GSU.vLastRamAdr) = (uint8)v; \ RAM(GSU.vLastRamAdr+1) = (uint8)(v>>8); \ CLRFLAGS; R15++; -static void fx_sms_r0() { FX_SMS(0); } -static void fx_sms_r1() { FX_SMS(1); } -static void fx_sms_r2() { FX_SMS(2); } -static void fx_sms_r3() { FX_SMS(3); } -static void fx_sms_r4() { FX_SMS(4); } -static void fx_sms_r5() { FX_SMS(5); } -static void fx_sms_r6() { FX_SMS(6); } -static void fx_sms_r7() { FX_SMS(7); } -static void fx_sms_r8() { FX_SMS(8); } -static void fx_sms_r9() { FX_SMS(9); } -static void fx_sms_r10() { FX_SMS(10); } -static void fx_sms_r11() { FX_SMS(11); } -static void fx_sms_r12() { FX_SMS(12); } -static void fx_sms_r13() { FX_SMS(13); } -static void fx_sms_r14() { FX_SMS(14); } -static void fx_sms_r15() { FX_SMS(15); } +static void fx_sms_r0() +{ + FX_SMS(0); +} +static void fx_sms_r1() +{ + FX_SMS(1); +} +static void fx_sms_r2() +{ + FX_SMS(2); +} +static void fx_sms_r3() +{ + FX_SMS(3); +} +static void fx_sms_r4() +{ + FX_SMS(4); +} +static void fx_sms_r5() +{ + FX_SMS(5); +} +static void fx_sms_r6() +{ + FX_SMS(6); +} +static void fx_sms_r7() +{ + FX_SMS(7); +} +static void fx_sms_r8() +{ + FX_SMS(8); +} +static void fx_sms_r9() +{ + FX_SMS(9); +} +static void fx_sms_r10() +{ + FX_SMS(10); +} +static void fx_sms_r11() +{ + FX_SMS(11); +} +static void fx_sms_r12() +{ + FX_SMS(12); +} +static void fx_sms_r13() +{ + FX_SMS(13); +} +static void fx_sms_r14() +{ + FX_SMS(14); +} +static void fx_sms_r15() +{ + FX_SMS(15); +} /* b0-bf - from rn - set source register */ /* b0-bf(B) - moves rn - move register to register, and set flags, (if B flag is set) */ @@ -1272,32 +2529,81 @@ static void fx_sms_r15() { FX_SMS(15); } if(TF(B)) { uint32 v = GSU.avReg[reg]; R15++; DREG = v; \ GSU.vOverflow = (v&0x80) << 16; GSU.vSign = v; GSU.vZero = v; TESTR14; CLRFLAGS; } \ else { GSU.pvSreg = &GSU.avReg[reg]; R15++; } -static void fx_from_r0() { FX_FROM(0); } -static void fx_from_r1() { FX_FROM(1); } -static void fx_from_r2() { FX_FROM(2); } -static void fx_from_r3() { FX_FROM(3); } -static void fx_from_r4() { FX_FROM(4); } -static void fx_from_r5() { FX_FROM(5); } -static void fx_from_r6() { FX_FROM(6); } -static void fx_from_r7() { FX_FROM(7); } -static void fx_from_r8() { FX_FROM(8); } -static void fx_from_r9() { FX_FROM(9); } -static void fx_from_r10() { FX_FROM(10); } -static void fx_from_r11() { FX_FROM(11); } -static void fx_from_r12() { FX_FROM(12); } -static void fx_from_r13() { FX_FROM(13); } -static void fx_from_r14() { FX_FROM(14); } -static void fx_from_r15() { FX_FROM(15); } +static void fx_from_r0() +{ + FX_FROM(0); +} +static void fx_from_r1() +{ + FX_FROM(1); +} +static void fx_from_r2() +{ + FX_FROM(2); +} +static void fx_from_r3() +{ + FX_FROM(3); +} +static void fx_from_r4() +{ + FX_FROM(4); +} +static void fx_from_r5() +{ + FX_FROM(5); +} +static void fx_from_r6() +{ + FX_FROM(6); +} +static void fx_from_r7() +{ + FX_FROM(7); +} +static void fx_from_r8() +{ + FX_FROM(8); +} +static void fx_from_r9() +{ + FX_FROM(9); +} +static void fx_from_r10() +{ + FX_FROM(10); +} +static void fx_from_r11() +{ + FX_FROM(11); +} +static void fx_from_r12() +{ + FX_FROM(12); +} +static void fx_from_r13() +{ + FX_FROM(13); +} +static void fx_from_r14() +{ + FX_FROM(14); +} +static void fx_from_r15() +{ + FX_FROM(15); +} /* c0 - hib - move high-byte to low-byte */ static void fx_hib() { - uint32 v = USEX8(SREG>>8); - R15++; DREG = v; - GSU.vSign = v<<8; - GSU.vZero = v<<8; - TESTR14; - CLRFLAGS; + uint32 v = USEX8(SREG >> 8); + R15++; + DREG = v; + GSU.vSign = v << 8; + GSU.vZero = v << 8; + TESTR14; + CLRFLAGS; } /* c1-cf - or rn */ @@ -1307,21 +2613,66 @@ GSU.vSign = v; \ GSU.vZero = v; \ TESTR14; \ CLRFLAGS; -static void fx_or_r1() { FX_OR(1); } -static void fx_or_r2() { FX_OR(2); } -static void fx_or_r3() { FX_OR(3); } -static void fx_or_r4() { FX_OR(4); } -static void fx_or_r5() { FX_OR(5); } -static void fx_or_r6() { FX_OR(6); } -static void fx_or_r7() { FX_OR(7); } -static void fx_or_r8() { FX_OR(8); } -static void fx_or_r9() { FX_OR(9); } -static void fx_or_r10() { FX_OR(10); } -static void fx_or_r11() { FX_OR(11); } -static void fx_or_r12() { FX_OR(12); } -static void fx_or_r13() { FX_OR(13); } -static void fx_or_r14() { FX_OR(14); } -static void fx_or_r15() { FX_OR(15); } +static void fx_or_r1() +{ + FX_OR(1); +} +static void fx_or_r2() +{ + FX_OR(2); +} +static void fx_or_r3() +{ + FX_OR(3); +} +static void fx_or_r4() +{ + FX_OR(4); +} +static void fx_or_r5() +{ + FX_OR(5); +} +static void fx_or_r6() +{ + FX_OR(6); +} +static void fx_or_r7() +{ + FX_OR(7); +} +static void fx_or_r8() +{ + FX_OR(8); +} +static void fx_or_r9() +{ + FX_OR(9); +} +static void fx_or_r10() +{ + FX_OR(10); +} +static void fx_or_r11() +{ + FX_OR(11); +} +static void fx_or_r12() +{ + FX_OR(12); +} +static void fx_or_r13() +{ + FX_OR(13); +} +static void fx_or_r14() +{ + FX_OR(14); +} +static void fx_or_r15() +{ + FX_OR(15); +} /* c1-cf(ALT1) - xor rn */ #define FX_XOR(reg) \ @@ -1330,21 +2681,66 @@ GSU.vSign = v; \ GSU.vZero = v; \ TESTR14; \ CLRFLAGS; -static void fx_xor_r1() { FX_XOR(1); } -static void fx_xor_r2() { FX_XOR(2); } -static void fx_xor_r3() { FX_XOR(3); } -static void fx_xor_r4() { FX_XOR(4); } -static void fx_xor_r5() { FX_XOR(5); } -static void fx_xor_r6() { FX_XOR(6); } -static void fx_xor_r7() { FX_XOR(7); } -static void fx_xor_r8() { FX_XOR(8); } -static void fx_xor_r9() { FX_XOR(9); } -static void fx_xor_r10() { FX_XOR(10); } -static void fx_xor_r11() { FX_XOR(11); } -static void fx_xor_r12() { FX_XOR(12); } -static void fx_xor_r13() { FX_XOR(13); } -static void fx_xor_r14() { FX_XOR(14); } -static void fx_xor_r15() { FX_XOR(15); } +static void fx_xor_r1() +{ + FX_XOR(1); +} +static void fx_xor_r2() +{ + FX_XOR(2); +} +static void fx_xor_r3() +{ + FX_XOR(3); +} +static void fx_xor_r4() +{ + FX_XOR(4); +} +static void fx_xor_r5() +{ + FX_XOR(5); +} +static void fx_xor_r6() +{ + FX_XOR(6); +} +static void fx_xor_r7() +{ + FX_XOR(7); +} +static void fx_xor_r8() +{ + FX_XOR(8); +} +static void fx_xor_r9() +{ + FX_XOR(9); +} +static void fx_xor_r10() +{ + FX_XOR(10); +} +static void fx_xor_r11() +{ + FX_XOR(11); +} +static void fx_xor_r12() +{ + FX_XOR(12); +} +static void fx_xor_r13() +{ + FX_XOR(13); +} +static void fx_xor_r14() +{ + FX_XOR(14); +} +static void fx_xor_r15() +{ + FX_XOR(15); +} /* c1-cf(ALT2) - or #n */ #define FX_OR_I(imm) \ @@ -1353,21 +2749,66 @@ GSU.vSign = v; \ GSU.vZero = v; \ TESTR14; \ CLRFLAGS; -static void fx_or_i1() { FX_OR_I(1); } -static void fx_or_i2() { FX_OR_I(2); } -static void fx_or_i3() { FX_OR_I(3); } -static void fx_or_i4() { FX_OR_I(4); } -static void fx_or_i5() { FX_OR_I(5); } -static void fx_or_i6() { FX_OR_I(6); } -static void fx_or_i7() { FX_OR_I(7); } -static void fx_or_i8() { FX_OR_I(8); } -static void fx_or_i9() { FX_OR_I(9); } -static void fx_or_i10() { FX_OR_I(10); } -static void fx_or_i11() { FX_OR_I(11); } -static void fx_or_i12() { FX_OR_I(12); } -static void fx_or_i13() { FX_OR_I(13); } -static void fx_or_i14() { FX_OR_I(14); } -static void fx_or_i15() { FX_OR_I(15); } +static void fx_or_i1() +{ + FX_OR_I(1); +} +static void fx_or_i2() +{ + FX_OR_I(2); +} +static void fx_or_i3() +{ + FX_OR_I(3); +} +static void fx_or_i4() +{ + FX_OR_I(4); +} +static void fx_or_i5() +{ + FX_OR_I(5); +} +static void fx_or_i6() +{ + FX_OR_I(6); +} +static void fx_or_i7() +{ + FX_OR_I(7); +} +static void fx_or_i8() +{ + FX_OR_I(8); +} +static void fx_or_i9() +{ + FX_OR_I(9); +} +static void fx_or_i10() +{ + FX_OR_I(10); +} +static void fx_or_i11() +{ + FX_OR_I(11); +} +static void fx_or_i12() +{ + FX_OR_I(12); +} +static void fx_or_i13() +{ + FX_OR_I(13); +} +static void fx_or_i14() +{ + FX_OR_I(14); +} +static void fx_or_i15() +{ + FX_OR_I(15); +} /* c1-cf(ALT3) - xor #n */ #define FX_XOR_I(imm) \ @@ -1376,21 +2817,66 @@ GSU.vSign = v; \ GSU.vZero = v; \ TESTR14; \ CLRFLAGS; -static void fx_xor_i1() { FX_XOR_I(1); } -static void fx_xor_i2() { FX_XOR_I(2); } -static void fx_xor_i3() { FX_XOR_I(3); } -static void fx_xor_i4() { FX_XOR_I(4); } -static void fx_xor_i5() { FX_XOR_I(5); } -static void fx_xor_i6() { FX_XOR_I(6); } -static void fx_xor_i7() { FX_XOR_I(7); } -static void fx_xor_i8() { FX_XOR_I(8); } -static void fx_xor_i9() { FX_XOR_I(9); } -static void fx_xor_i10() { FX_XOR_I(10); } -static void fx_xor_i11() { FX_XOR_I(11); } -static void fx_xor_i12() { FX_XOR_I(12); } -static void fx_xor_i13() { FX_XOR_I(13); } -static void fx_xor_i14() { FX_XOR_I(14); } -static void fx_xor_i15() { FX_XOR_I(15); } +static void fx_xor_i1() +{ + FX_XOR_I(1); +} +static void fx_xor_i2() +{ + FX_XOR_I(2); +} +static void fx_xor_i3() +{ + FX_XOR_I(3); +} +static void fx_xor_i4() +{ + FX_XOR_I(4); +} +static void fx_xor_i5() +{ + FX_XOR_I(5); +} +static void fx_xor_i6() +{ + FX_XOR_I(6); +} +static void fx_xor_i7() +{ + FX_XOR_I(7); +} +static void fx_xor_i8() +{ + FX_XOR_I(8); +} +static void fx_xor_i9() +{ + FX_XOR_I(9); +} +static void fx_xor_i10() +{ + FX_XOR_I(10); +} +static void fx_xor_i11() +{ + FX_XOR_I(11); +} +static void fx_xor_i12() +{ + FX_XOR_I(12); +} +static void fx_xor_i13() +{ + FX_XOR_I(13); +} +static void fx_xor_i14() +{ + FX_XOR_I(14); +} +static void fx_xor_i15() +{ + FX_XOR_I(15); +} /* d0-de - inc rn - increase by one */ #define FX_INC(reg) \ @@ -1398,60 +2884,106 @@ GSU.avReg[reg] += 1; \ GSU.vSign = GSU.avReg[reg]; \ GSU.vZero = GSU.avReg[reg]; \ CLRFLAGS; R15++; -static void fx_inc_r0() { FX_INC(0); } -static void fx_inc_r1() { FX_INC(1); } -static void fx_inc_r2() { FX_INC(2); } -static void fx_inc_r3() { FX_INC(3); } -static void fx_inc_r4() { FX_INC(4); } -static void fx_inc_r5() { FX_INC(5); } -static void fx_inc_r6() { FX_INC(6); } -static void fx_inc_r7() { FX_INC(7); } -static void fx_inc_r8() { FX_INC(8); } -static void fx_inc_r9() { FX_INC(9); } -static void fx_inc_r10() { FX_INC(10); } -static void fx_inc_r11() { FX_INC(11); } -static void fx_inc_r12() { FX_INC(12); } -static void fx_inc_r13() { FX_INC(13); } -static void fx_inc_r14() { FX_INC(14); READR14; } +static void fx_inc_r0() +{ + FX_INC(0); +} +static void fx_inc_r1() +{ + FX_INC(1); +} +static void fx_inc_r2() +{ + FX_INC(2); +} +static void fx_inc_r3() +{ + FX_INC(3); +} +static void fx_inc_r4() +{ + FX_INC(4); +} +static void fx_inc_r5() +{ + FX_INC(5); +} +static void fx_inc_r6() +{ + FX_INC(6); +} +static void fx_inc_r7() +{ + FX_INC(7); +} +static void fx_inc_r8() +{ + FX_INC(8); +} +static void fx_inc_r9() +{ + FX_INC(9); +} +static void fx_inc_r10() +{ + FX_INC(10); +} +static void fx_inc_r11() +{ + FX_INC(11); +} +static void fx_inc_r12() +{ + FX_INC(12); +} +static void fx_inc_r13() +{ + FX_INC(13); +} +static void fx_inc_r14() +{ + FX_INC(14); + READR14; +} /* df - getc - transfer ROM buffer to color register */ static void fx_getc() { #ifndef FX_DO_ROMBUFFER - uint8 c; - c = ROM(R14); + uint8 c; + c = ROM(R14); #else - uint8 c = GSU.vRomBuffer; + uint8 c = GSU.vRomBuffer; #endif - if(GSU.vPlotOptionReg & 0x04) - c = (c&0xf0) | (c>>4); - if(GSU.vPlotOptionReg & 0x08) - { - GSU.vColorReg &= 0xf0; - GSU.vColorReg |= c & 0x0f; - } - else - GSU.vColorReg = USEX8(c); - CLRFLAGS; - R15++; + if (GSU.vPlotOptionReg & 0x04) + c = (c & 0xf0) | (c >> 4); + if (GSU.vPlotOptionReg & 0x08) + { + GSU.vColorReg &= 0xf0; + GSU.vColorReg |= c & 0x0f; + } + else + GSU.vColorReg = USEX8(c); + CLRFLAGS; + R15++; } /* df(ALT2) - ramb - set current RAM bank */ static void fx_ramb() { - GSU.vRamBankReg = SREG & (FX_RAM_BANKS-1); - GSU.pvRamBank = GSU.apvRamBank[GSU.vRamBankReg & 0x3]; - CLRFLAGS; - R15++; + GSU.vRamBankReg = SREG & (FX_RAM_BANKS - 1); + GSU.pvRamBank = GSU.apvRamBank[GSU.vRamBankReg & 0x3]; + CLRFLAGS; + R15++; } /* df(ALT3) - romb - set current ROM bank */ static void fx_romb() { - GSU.vRomBankReg = USEX8(SREG) & 0x7f; - GSU.pvRomBank = GSU.apvRomBank[GSU.vRomBankReg]; - CLRFLAGS; - R15++; + GSU.vRomBankReg = USEX8(SREG) & 0x7f; + GSU.pvRomBank = GSU.apvRomBank[GSU.vRomBankReg]; + CLRFLAGS; + R15++; } /* e0-ee - dec rn - decrement by one */ @@ -1460,82 +2992,132 @@ GSU.avReg[reg] -= 1; \ GSU.vSign = GSU.avReg[reg]; \ GSU.vZero = GSU.avReg[reg]; \ CLRFLAGS; R15++; -static void fx_dec_r0() { FX_DEC(0); } -static void fx_dec_r1() { FX_DEC(1); } -static void fx_dec_r2() { FX_DEC(2); } -static void fx_dec_r3() { FX_DEC(3); } -static void fx_dec_r4() { FX_DEC(4); } -static void fx_dec_r5() { FX_DEC(5); } -static void fx_dec_r6() { FX_DEC(6); } -static void fx_dec_r7() { FX_DEC(7); } -static void fx_dec_r8() { FX_DEC(8); } -static void fx_dec_r9() { FX_DEC(9); } -static void fx_dec_r10() { FX_DEC(10); } -static void fx_dec_r11() { FX_DEC(11); } -static void fx_dec_r12() { FX_DEC(12); } -static void fx_dec_r13() { FX_DEC(13); } -static void fx_dec_r14() { FX_DEC(14); READR14; } +static void fx_dec_r0() +{ + FX_DEC(0); +} +static void fx_dec_r1() +{ + FX_DEC(1); +} +static void fx_dec_r2() +{ + FX_DEC(2); +} +static void fx_dec_r3() +{ + FX_DEC(3); +} +static void fx_dec_r4() +{ + FX_DEC(4); +} +static void fx_dec_r5() +{ + FX_DEC(5); +} +static void fx_dec_r6() +{ + FX_DEC(6); +} +static void fx_dec_r7() +{ + FX_DEC(7); +} +static void fx_dec_r8() +{ + FX_DEC(8); +} +static void fx_dec_r9() +{ + FX_DEC(9); +} +static void fx_dec_r10() +{ + FX_DEC(10); +} +static void fx_dec_r11() +{ + FX_DEC(11); +} +static void fx_dec_r12() +{ + FX_DEC(12); +} +static void fx_dec_r13() +{ + FX_DEC(13); +} +static void fx_dec_r14() +{ + FX_DEC(14); + READR14; +} /* ef - getb - get byte from ROM at address R14 */ static void fx_getb() { - uint32 v; + uint32 v; #ifndef FX_DO_ROMBUFFER - v = (uint32)ROM(R14); + v = (uint32)ROM(R14); #else - v = (uint32)GSU.vRomBuffer; + v = (uint32)GSU.vRomBuffer; #endif - R15++; DREG = v; - TESTR14; - CLRFLAGS; + R15++; + DREG = v; + TESTR14; + CLRFLAGS; } /* ef(ALT1) - getbh - get high-byte from ROM at address R14 */ static void fx_getbh() { - uint32 v; + uint32 v; #ifndef FX_DO_ROMBUFFER - uint32 c; - c = (uint32)ROM(R14); + uint32 c; + c = (uint32)ROM(R14); #else - uint32 c = USEX8(GSU.vRomBuffer); + uint32 c = USEX8(GSU.vRomBuffer); #endif - v = USEX8(SREG) | (c<<8); - R15++; DREG = v; - TESTR14; - CLRFLAGS; + v = USEX8(SREG) | (c << 8); + R15++; + DREG = v; + TESTR14; + CLRFLAGS; } /* ef(ALT2) - getbl - get low-byte from ROM at address R14 */ static void fx_getbl() { - uint32 v; + uint32 v; #ifndef FX_DO_ROMBUFFER - uint32 c; - c = (uint32)ROM(R14); + uint32 c; + c = (uint32)ROM(R14); #else - uint32 c = USEX8(GSU.vRomBuffer); + uint32 c = USEX8(GSU.vRomBuffer); #endif - v = (SREG & 0xff00) | c; - R15++; DREG = v; - TESTR14; - CLRFLAGS; + v = (SREG & 0xff00) | c; + R15++; + DREG = v; + TESTR14; + CLRFLAGS; } /* ef(ALT3) - getbs - get sign extended byte from ROM at address R14 */ static void fx_getbs() { - uint32 v; + uint32 v; #ifndef FX_DO_ROMBUFFER - int8 c; - c = ROM(R14); - v = SEX8(c); + int8 c; + c = ROM(R14); + v = SEX8(c); #else - v = SEX8(GSU.vRomBuffer); + v = SEX8(GSU.vRomBuffer); #endif - R15++; DREG = v; - TESTR14; - CLRFLAGS; + R15++; + DREG = v; + TESTR14; + CLRFLAGS; } /* f0-ff - iwt rn,#xx - immediate word transfer to register */ @@ -1544,22 +3126,71 @@ uint32 v = PIPE; R15++; FETCHPIPE; R15++; \ v |= USEX8(PIPE) << 8; FETCHPIPE; R15++; \ GSU.avReg[reg] = v; \ CLRFLAGS; -static void fx_iwt_r0() { FX_IWT(0); } -static void fx_iwt_r1() { FX_IWT(1); } -static void fx_iwt_r2() { FX_IWT(2); } -static void fx_iwt_r3() { FX_IWT(3); } -static void fx_iwt_r4() { FX_IWT(4); } -static void fx_iwt_r5() { FX_IWT(5); } -static void fx_iwt_r6() { FX_IWT(6); } -static void fx_iwt_r7() { FX_IWT(7); } -static void fx_iwt_r8() { FX_IWT(8); } -static void fx_iwt_r9() { FX_IWT(9); } -static void fx_iwt_r10() { FX_IWT(10); } -static void fx_iwt_r11() { FX_IWT(11); } -static void fx_iwt_r12() { FX_IWT(12); } -static void fx_iwt_r13() { FX_IWT(13); } -static void fx_iwt_r14() { FX_IWT(14); READR14; } -static void fx_iwt_r15() { FX_IWT(15); } +static void fx_iwt_r0() +{ + FX_IWT(0); +} +static void fx_iwt_r1() +{ + FX_IWT(1); +} +static void fx_iwt_r2() +{ + FX_IWT(2); +} +static void fx_iwt_r3() +{ + FX_IWT(3); +} +static void fx_iwt_r4() +{ + FX_IWT(4); +} +static void fx_iwt_r5() +{ + FX_IWT(5); +} +static void fx_iwt_r6() +{ + FX_IWT(6); +} +static void fx_iwt_r7() +{ + FX_IWT(7); +} +static void fx_iwt_r8() +{ + FX_IWT(8); +} +static void fx_iwt_r9() +{ + FX_IWT(9); +} +static void fx_iwt_r10() +{ + FX_IWT(10); +} +static void fx_iwt_r11() +{ + FX_IWT(11); +} +static void fx_iwt_r12() +{ + FX_IWT(12); +} +static void fx_iwt_r13() +{ + FX_IWT(13); +} +static void fx_iwt_r14() +{ + FX_IWT(14); + READR14; +} +static void fx_iwt_r15() +{ + FX_IWT(15); +} /* f0-ff(ALT1) - lm rn,(xx) - load word from RAM */ #define FX_LM(reg) \ @@ -1568,22 +3199,71 @@ GSU.vLastRamAdr |= USEX8(PIPE) << 8; FETCHPIPE; R15++; \ GSU.avReg[reg] = RAM(GSU.vLastRamAdr); \ GSU.avReg[reg] |= USEX8(RAM(GSU.vLastRamAdr^1)) << 8; \ CLRFLAGS; -static void fx_lm_r0() { FX_LM(0); } -static void fx_lm_r1() { FX_LM(1); } -static void fx_lm_r2() { FX_LM(2); } -static void fx_lm_r3() { FX_LM(3); } -static void fx_lm_r4() { FX_LM(4); } -static void fx_lm_r5() { FX_LM(5); } -static void fx_lm_r6() { FX_LM(6); } -static void fx_lm_r7() { FX_LM(7); } -static void fx_lm_r8() { FX_LM(8); } -static void fx_lm_r9() { FX_LM(9); } -static void fx_lm_r10() { FX_LM(10); } -static void fx_lm_r11() { FX_LM(11); } -static void fx_lm_r12() { FX_LM(12); } -static void fx_lm_r13() { FX_LM(13); } -static void fx_lm_r14() { FX_LM(14); READR14; } -static void fx_lm_r15() { FX_LM(15); } +static void fx_lm_r0() +{ + FX_LM(0); +} +static void fx_lm_r1() +{ + FX_LM(1); +} +static void fx_lm_r2() +{ + FX_LM(2); +} +static void fx_lm_r3() +{ + FX_LM(3); +} +static void fx_lm_r4() +{ + FX_LM(4); +} +static void fx_lm_r5() +{ + FX_LM(5); +} +static void fx_lm_r6() +{ + FX_LM(6); +} +static void fx_lm_r7() +{ + FX_LM(7); +} +static void fx_lm_r8() +{ + FX_LM(8); +} +static void fx_lm_r9() +{ + FX_LM(9); +} +static void fx_lm_r10() +{ + FX_LM(10); +} +static void fx_lm_r11() +{ + FX_LM(11); +} +static void fx_lm_r12() +{ + FX_LM(12); +} +static void fx_lm_r13() +{ + FX_LM(13); +} +static void fx_lm_r14() +{ + FX_LM(14); + READR14; +} +static void fx_lm_r15() +{ + FX_LM(15); +} /* f0-ff(ALT2) - sm (xx),rn - store word in RAM */ /* If rn == r15, is the value of r15 before or after the extra bytes are read? */ @@ -1594,92 +3274,140 @@ GSU.vLastRamAdr |= USEX8(PIPE) << 8; FETCHPIPE; \ RAM(GSU.vLastRamAdr) = (uint8)v; \ RAM(GSU.vLastRamAdr^1) = (uint8)(v>>8); \ CLRFLAGS; R15++; -static void fx_sm_r0() { FX_SM(0); } -static void fx_sm_r1() { FX_SM(1); } -static void fx_sm_r2() { FX_SM(2); } -static void fx_sm_r3() { FX_SM(3); } -static void fx_sm_r4() { FX_SM(4); } -static void fx_sm_r5() { FX_SM(5); } -static void fx_sm_r6() { FX_SM(6); } -static void fx_sm_r7() { FX_SM(7); } -static void fx_sm_r8() { FX_SM(8); } -static void fx_sm_r9() { FX_SM(9); } -static void fx_sm_r10() { FX_SM(10); } -static void fx_sm_r11() { FX_SM(11); } -static void fx_sm_r12() { FX_SM(12); } -static void fx_sm_r13() { FX_SM(13); } -static void fx_sm_r14() { FX_SM(14); } -static void fx_sm_r15() { FX_SM(15); } +static void fx_sm_r0() +{ + FX_SM(0); +} +static void fx_sm_r1() +{ + FX_SM(1); +} +static void fx_sm_r2() +{ + FX_SM(2); +} +static void fx_sm_r3() +{ + FX_SM(3); +} +static void fx_sm_r4() +{ + FX_SM(4); +} +static void fx_sm_r5() +{ + FX_SM(5); +} +static void fx_sm_r6() +{ + FX_SM(6); +} +static void fx_sm_r7() +{ + FX_SM(7); +} +static void fx_sm_r8() +{ + FX_SM(8); +} +static void fx_sm_r9() +{ + FX_SM(9); +} +static void fx_sm_r10() +{ + FX_SM(10); +} +static void fx_sm_r11() +{ + FX_SM(11); +} +static void fx_sm_r12() +{ + FX_SM(12); +} +static void fx_sm_r13() +{ + FX_SM(13); +} +static void fx_sm_r14() +{ + FX_SM(14); +} +static void fx_sm_r15() +{ + FX_SM(15); +} /*** GSU executions functions ***/ static uint32 fx_run(uint32 nInstructions) { - GSU.vCounter = nInstructions; - READR14; - while( TF(G) && (GSU.vCounter-- > 0) ) - FX_STEP; - /* -#ifndef FX_ADDRESS_CHECK - GSU.vPipeAdr = USEX16(R15-1) | (USEX8(GSU.vPrgBankReg)<<16); -#endif -*/ - return (nInstructions - GSU.vInstCount); + GSU.vCounter = nInstructions; + READR14; + while (TF(G) && (GSU.vCounter-- > 0)) + FX_STEP; + /* + #ifndef FX_ADDRESS_CHECK + GSU.vPipeAdr = USEX16(R15-1) | (USEX8(GSU.vPrgBankReg)<<16); + #endif + */ + return (nInstructions - GSU.vInstCount); } static uint32 fx_run_to_breakpoint(uint32 nInstructions) { - uint32 vCounter = 0; - while(TF(G) && vCounter < nInstructions) - { - vCounter++; - FX_STEP; - if(USEX16(R15) == GSU.vBreakPoint) - { - GSU.vErrorCode = FX_BREAKPOINT; - break; - } - } - /* -#ifndef FX_ADDRESS_CHECK - GSU.vPipeAdr = USEX16(R15-1) | (USEX8(GSU.vPrgBankReg)<<16); -#endif -*/ - return vCounter; + uint32 vCounter = 0; + while (TF(G) && vCounter < nInstructions) + { + vCounter++; + FX_STEP; + if (USEX16(R15) == GSU.vBreakPoint) + { + GSU.vErrorCode = FX_BREAKPOINT; + break; + } + } + /* + #ifndef FX_ADDRESS_CHECK + GSU.vPipeAdr = USEX16(R15-1) | (USEX8(GSU.vPrgBankReg)<<16); + #endif + */ + return vCounter; } static uint32 fx_step_over(uint32 nInstructions) { - uint32 vCounter = 0; - while(TF(G) && vCounter < nInstructions) - { - vCounter++; - FX_STEP; - if(USEX16(R15) == GSU.vBreakPoint) - { - GSU.vErrorCode = FX_BREAKPOINT; - break; - } - if(USEX16(R15) == GSU.vStepPoint) - break; - } - /* -#ifndef FX_ADDRESS_CHECK - GSU.vPipeAdr = USEX16(R15-1) | (USEX8(GSU.vPrgBankReg)<<16); -#endif -*/ - return vCounter; + uint32 vCounter = 0; + while (TF(G) && vCounter < nInstructions) + { + vCounter++; + FX_STEP; + if (USEX16(R15) == GSU.vBreakPoint) + { + GSU.vErrorCode = FX_BREAKPOINT; + break; + } + if (USEX16(R15) == GSU.vStepPoint) + break; + } + /* + #ifndef FX_ADDRESS_CHECK + GSU.vPipeAdr = USEX16(R15-1) | (USEX8(GSU.vPrgBankReg)<<16); + #endif + */ + return vCounter; } #ifdef FX_FUNCTION_TABLE -uint32 (*FX_FUNCTION_TABLE[])(uint32) = +uint32(*FX_FUNCTION_TABLE[])(uint32) = #else -uint32 (*fx_apfFunctionTable[])(uint32) = +uint32(*fx_apfFunctionTable[])(uint32) = #endif { - &fx_run, - &fx_run_to_breakpoint, - &fx_step_over, + &fx_run, + &fx_run_to_breakpoint, + &fx_step_over, }; /*** Special table for the different plot configurations ***/ @@ -1690,8 +3418,8 @@ void (*FX_PLOT_TABLE[])() = void (*fx_apfPlotTable[])() = #endif { - &fx_plot_2bit, &fx_plot_4bit, &fx_plot_4bit, &fx_plot_8bit, &fx_plot_obj, - &fx_rpix_2bit, &fx_rpix_4bit, &fx_rpix_4bit, &fx_rpix_8bit, &fx_rpix_obj, + &fx_plot_2bit, &fx_plot_4bit, &fx_plot_4bit, &fx_plot_8bit, &fx_plot_obj, + &fx_rpix_2bit, &fx_rpix_4bit, &fx_rpix_4bit, &fx_rpix_8bit, &fx_rpix_obj, }; /*** Opcode table ***/ @@ -1702,215 +3430,215 @@ void (*FX_OPCODE_TABLE[])() = void (*fx_apfOpcodeTable[])() = #endif { - /* - * ALT0 Table - */ - /* 00 - 0f */ - &fx_stop, &fx_nop, &fx_cache, &fx_lsr, &fx_rol, &fx_bra, &fx_bge, &fx_blt, - &fx_bne, &fx_beq, &fx_bpl, &fx_bmi, &fx_bcc, &fx_bcs, &fx_bvc, &fx_bvs, - /* 10 - 1f */ - &fx_to_r0, &fx_to_r1, &fx_to_r2, &fx_to_r3, &fx_to_r4, &fx_to_r5, &fx_to_r6, &fx_to_r7, - &fx_to_r8, &fx_to_r9, &fx_to_r10, &fx_to_r11, &fx_to_r12, &fx_to_r13, &fx_to_r14, &fx_to_r15, - /* 20 - 2f */ - &fx_with_r0, &fx_with_r1, &fx_with_r2, &fx_with_r3, &fx_with_r4, &fx_with_r5, &fx_with_r6, &fx_with_r7, - &fx_with_r8, &fx_with_r9, &fx_with_r10, &fx_with_r11, &fx_with_r12, &fx_with_r13, &fx_with_r14, &fx_with_r15, - /* 30 - 3f */ - &fx_stw_r0, &fx_stw_r1, &fx_stw_r2, &fx_stw_r3, &fx_stw_r4, &fx_stw_r5, &fx_stw_r6, &fx_stw_r7, - &fx_stw_r8, &fx_stw_r9, &fx_stw_r10, &fx_stw_r11, &fx_loop, &fx_alt1, &fx_alt2, &fx_alt3, - /* 40 - 4f */ - &fx_ldw_r0, &fx_ldw_r1, &fx_ldw_r2, &fx_ldw_r3, &fx_ldw_r4, &fx_ldw_r5, &fx_ldw_r6, &fx_ldw_r7, - &fx_ldw_r8, &fx_ldw_r9, &fx_ldw_r10, &fx_ldw_r11, &fx_plot_2bit,&fx_swap, &fx_color, &fx_not, - /* 50 - 5f */ - &fx_add_r0, &fx_add_r1, &fx_add_r2, &fx_add_r3, &fx_add_r4, &fx_add_r5, &fx_add_r6, &fx_add_r7, - &fx_add_r8, &fx_add_r9, &fx_add_r10, &fx_add_r11, &fx_add_r12, &fx_add_r13, &fx_add_r14, &fx_add_r15, - /* 60 - 6f */ - &fx_sub_r0, &fx_sub_r1, &fx_sub_r2, &fx_sub_r3, &fx_sub_r4, &fx_sub_r5, &fx_sub_r6, &fx_sub_r7, - &fx_sub_r8, &fx_sub_r9, &fx_sub_r10, &fx_sub_r11, &fx_sub_r12, &fx_sub_r13, &fx_sub_r14, &fx_sub_r15, - /* 70 - 7f */ - &fx_merge, &fx_and_r1, &fx_and_r2, &fx_and_r3, &fx_and_r4, &fx_and_r5, &fx_and_r6, &fx_and_r7, - &fx_and_r8, &fx_and_r9, &fx_and_r10, &fx_and_r11, &fx_and_r12, &fx_and_r13, &fx_and_r14, &fx_and_r15, - /* 80 - 8f */ - &fx_mult_r0, &fx_mult_r1, &fx_mult_r2, &fx_mult_r3, &fx_mult_r4, &fx_mult_r5, &fx_mult_r6, &fx_mult_r7, - &fx_mult_r8, &fx_mult_r9, &fx_mult_r10, &fx_mult_r11, &fx_mult_r12, &fx_mult_r13, &fx_mult_r14, &fx_mult_r15, - /* 90 - 9f */ - &fx_sbk, &fx_link_i1, &fx_link_i2, &fx_link_i3, &fx_link_i4, &fx_sex, &fx_asr, &fx_ror, - &fx_jmp_r8, &fx_jmp_r9, &fx_jmp_r10, &fx_jmp_r11, &fx_jmp_r12, &fx_jmp_r13, &fx_lob, &fx_fmult, - /* a0 - af */ - &fx_ibt_r0, &fx_ibt_r1, &fx_ibt_r2, &fx_ibt_r3, &fx_ibt_r4, &fx_ibt_r5, &fx_ibt_r6, &fx_ibt_r7, - &fx_ibt_r8, &fx_ibt_r9, &fx_ibt_r10, &fx_ibt_r11, &fx_ibt_r12, &fx_ibt_r13, &fx_ibt_r14, &fx_ibt_r15, - /* b0 - bf */ - &fx_from_r0, &fx_from_r1, &fx_from_r2, &fx_from_r3, &fx_from_r4, &fx_from_r5, &fx_from_r6, &fx_from_r7, - &fx_from_r8, &fx_from_r9, &fx_from_r10, &fx_from_r11, &fx_from_r12, &fx_from_r13, &fx_from_r14, &fx_from_r15, - /* c0 - cf */ - &fx_hib, &fx_or_r1, &fx_or_r2, &fx_or_r3, &fx_or_r4, &fx_or_r5, &fx_or_r6, &fx_or_r7, - &fx_or_r8, &fx_or_r9, &fx_or_r10, &fx_or_r11, &fx_or_r12, &fx_or_r13, &fx_or_r14, &fx_or_r15, - /* d0 - df */ - &fx_inc_r0, &fx_inc_r1, &fx_inc_r2, &fx_inc_r3, &fx_inc_r4, &fx_inc_r5, &fx_inc_r6, &fx_inc_r7, - &fx_inc_r8, &fx_inc_r9, &fx_inc_r10, &fx_inc_r11, &fx_inc_r12, &fx_inc_r13, &fx_inc_r14, &fx_getc, - /* e0 - ef */ - &fx_dec_r0, &fx_dec_r1, &fx_dec_r2, &fx_dec_r3, &fx_dec_r4, &fx_dec_r5, &fx_dec_r6, &fx_dec_r7, - &fx_dec_r8, &fx_dec_r9, &fx_dec_r10, &fx_dec_r11, &fx_dec_r12, &fx_dec_r13, &fx_dec_r14, &fx_getb, - /* f0 - ff */ - &fx_iwt_r0, &fx_iwt_r1, &fx_iwt_r2, &fx_iwt_r3, &fx_iwt_r4, &fx_iwt_r5, &fx_iwt_r6, &fx_iwt_r7, - &fx_iwt_r8, &fx_iwt_r9, &fx_iwt_r10, &fx_iwt_r11, &fx_iwt_r12, &fx_iwt_r13, &fx_iwt_r14, &fx_iwt_r15, - - /* - * ALT1 Table - */ - - /* 00 - 0f */ - &fx_stop, &fx_nop, &fx_cache, &fx_lsr, &fx_rol, &fx_bra, &fx_bge, &fx_blt, - &fx_bne, &fx_beq, &fx_bpl, &fx_bmi, &fx_bcc, &fx_bcs, &fx_bvc, &fx_bvs, - /* 10 - 1f */ - &fx_to_r0, &fx_to_r1, &fx_to_r2, &fx_to_r3, &fx_to_r4, &fx_to_r5, &fx_to_r6, &fx_to_r7, - &fx_to_r8, &fx_to_r9, &fx_to_r10, &fx_to_r11, &fx_to_r12, &fx_to_r13, &fx_to_r14, &fx_to_r15, - /* 20 - 2f */ - &fx_with_r0, &fx_with_r1, &fx_with_r2, &fx_with_r3, &fx_with_r4, &fx_with_r5, &fx_with_r6, &fx_with_r7, - &fx_with_r8, &fx_with_r9, &fx_with_r10, &fx_with_r11, &fx_with_r12, &fx_with_r13, &fx_with_r14, &fx_with_r15, - /* 30 - 3f */ - &fx_stb_r0, &fx_stb_r1, &fx_stb_r2, &fx_stb_r3, &fx_stb_r4, &fx_stb_r5, &fx_stb_r6, &fx_stb_r7, - &fx_stb_r8, &fx_stb_r9, &fx_stb_r10, &fx_stb_r11, &fx_loop, &fx_alt1, &fx_alt2, &fx_alt3, - /* 40 - 4f */ - &fx_ldb_r0, &fx_ldb_r1, &fx_ldb_r2, &fx_ldb_r3, &fx_ldb_r4, &fx_ldb_r5, &fx_ldb_r6, &fx_ldb_r7, - &fx_ldb_r8, &fx_ldb_r9, &fx_ldb_r10, &fx_ldb_r11, &fx_rpix_2bit,&fx_swap, &fx_cmode, &fx_not, - /* 50 - 5f */ - &fx_adc_r0, &fx_adc_r1, &fx_adc_r2, &fx_adc_r3, &fx_adc_r4, &fx_adc_r5, &fx_adc_r6, &fx_adc_r7, - &fx_adc_r8, &fx_adc_r9, &fx_adc_r10, &fx_adc_r11, &fx_adc_r12, &fx_adc_r13, &fx_adc_r14, &fx_adc_r15, - /* 60 - 6f */ - &fx_sbc_r0, &fx_sbc_r1, &fx_sbc_r2, &fx_sbc_r3, &fx_sbc_r4, &fx_sbc_r5, &fx_sbc_r6, &fx_sbc_r7, - &fx_sbc_r8, &fx_sbc_r9, &fx_sbc_r10, &fx_sbc_r11, &fx_sbc_r12, &fx_sbc_r13, &fx_sbc_r14, &fx_sbc_r15, - /* 70 - 7f */ - &fx_merge, &fx_bic_r1, &fx_bic_r2, &fx_bic_r3, &fx_bic_r4, &fx_bic_r5, &fx_bic_r6, &fx_bic_r7, - &fx_bic_r8, &fx_bic_r9, &fx_bic_r10, &fx_bic_r11, &fx_bic_r12, &fx_bic_r13, &fx_bic_r14, &fx_bic_r15, - /* 80 - 8f */ - &fx_umult_r0,&fx_umult_r1,&fx_umult_r2, &fx_umult_r3, &fx_umult_r4, &fx_umult_r5, &fx_umult_r6, &fx_umult_r7, - &fx_umult_r8,&fx_umult_r9,&fx_umult_r10,&fx_umult_r11,&fx_umult_r12,&fx_umult_r13,&fx_umult_r14,&fx_umult_r15, - /* 90 - 9f */ - &fx_sbk, &fx_link_i1, &fx_link_i2, &fx_link_i3, &fx_link_i4, &fx_sex, &fx_div2, &fx_ror, - &fx_ljmp_r8, &fx_ljmp_r9, &fx_ljmp_r10, &fx_ljmp_r11, &fx_ljmp_r12, &fx_ljmp_r13, &fx_lob, &fx_lmult, - /* a0 - af */ - &fx_lms_r0, &fx_lms_r1, &fx_lms_r2, &fx_lms_r3, &fx_lms_r4, &fx_lms_r5, &fx_lms_r6, &fx_lms_r7, - &fx_lms_r8, &fx_lms_r9, &fx_lms_r10, &fx_lms_r11, &fx_lms_r12, &fx_lms_r13, &fx_lms_r14, &fx_lms_r15, - /* b0 - bf */ - &fx_from_r0, &fx_from_r1, &fx_from_r2, &fx_from_r3, &fx_from_r4, &fx_from_r5, &fx_from_r6, &fx_from_r7, - &fx_from_r8, &fx_from_r9, &fx_from_r10, &fx_from_r11, &fx_from_r12, &fx_from_r13, &fx_from_r14, &fx_from_r15, - /* c0 - cf */ - &fx_hib, &fx_xor_r1, &fx_xor_r2, &fx_xor_r3, &fx_xor_r4, &fx_xor_r5, &fx_xor_r6, &fx_xor_r7, - &fx_xor_r8, &fx_xor_r9, &fx_xor_r10, &fx_xor_r11, &fx_xor_r12, &fx_xor_r13, &fx_xor_r14, &fx_xor_r15, - /* d0 - df */ - &fx_inc_r0, &fx_inc_r1, &fx_inc_r2, &fx_inc_r3, &fx_inc_r4, &fx_inc_r5, &fx_inc_r6, &fx_inc_r7, - &fx_inc_r8, &fx_inc_r9, &fx_inc_r10, &fx_inc_r11, &fx_inc_r12, &fx_inc_r13, &fx_inc_r14, &fx_getc, - /* e0 - ef */ - &fx_dec_r0, &fx_dec_r1, &fx_dec_r2, &fx_dec_r3, &fx_dec_r4, &fx_dec_r5, &fx_dec_r6, &fx_dec_r7, - &fx_dec_r8, &fx_dec_r9, &fx_dec_r10, &fx_dec_r11, &fx_dec_r12, &fx_dec_r13, &fx_dec_r14, &fx_getbh, - /* f0 - ff */ - &fx_lm_r0, &fx_lm_r1, &fx_lm_r2, &fx_lm_r3, &fx_lm_r4, &fx_lm_r5, &fx_lm_r6, &fx_lm_r7, - &fx_lm_r8, &fx_lm_r9, &fx_lm_r10, &fx_lm_r11, &fx_lm_r12, &fx_lm_r13, &fx_lm_r14, &fx_lm_r15, - - /* - * ALT2 Table - */ - - /* 00 - 0f */ - &fx_stop, &fx_nop, &fx_cache, &fx_lsr, &fx_rol, &fx_bra, &fx_bge, &fx_blt, - &fx_bne, &fx_beq, &fx_bpl, &fx_bmi, &fx_bcc, &fx_bcs, &fx_bvc, &fx_bvs, - /* 10 - 1f */ - &fx_to_r0, &fx_to_r1, &fx_to_r2, &fx_to_r3, &fx_to_r4, &fx_to_r5, &fx_to_r6, &fx_to_r7, - &fx_to_r8, &fx_to_r9, &fx_to_r10, &fx_to_r11, &fx_to_r12, &fx_to_r13, &fx_to_r14, &fx_to_r15, - /* 20 - 2f */ - &fx_with_r0, &fx_with_r1, &fx_with_r2, &fx_with_r3, &fx_with_r4, &fx_with_r5, &fx_with_r6, &fx_with_r7, - &fx_with_r8, &fx_with_r9, &fx_with_r10, &fx_with_r11, &fx_with_r12, &fx_with_r13, &fx_with_r14, &fx_with_r15, - /* 30 - 3f */ - &fx_stw_r0, &fx_stw_r1, &fx_stw_r2, &fx_stw_r3, &fx_stw_r4, &fx_stw_r5, &fx_stw_r6, &fx_stw_r7, - &fx_stw_r8, &fx_stw_r9, &fx_stw_r10, &fx_stw_r11, &fx_loop, &fx_alt1, &fx_alt2, &fx_alt3, - /* 40 - 4f */ - &fx_ldw_r0, &fx_ldw_r1, &fx_ldw_r2, &fx_ldw_r3, &fx_ldw_r4, &fx_ldw_r5, &fx_ldw_r6, &fx_ldw_r7, - &fx_ldw_r8, &fx_ldw_r9, &fx_ldw_r10, &fx_ldw_r11, &fx_plot_2bit,&fx_swap, &fx_color, &fx_not, - /* 50 - 5f */ - &fx_add_i0, &fx_add_i1, &fx_add_i2, &fx_add_i3, &fx_add_i4, &fx_add_i5, &fx_add_i6, &fx_add_i7, - &fx_add_i8, &fx_add_i9, &fx_add_i10, &fx_add_i11, &fx_add_i12, &fx_add_i13, &fx_add_i14, &fx_add_i15, - /* 60 - 6f */ - &fx_sub_i0, &fx_sub_i1, &fx_sub_i2, &fx_sub_i3, &fx_sub_i4, &fx_sub_i5, &fx_sub_i6, &fx_sub_i7, - &fx_sub_i8, &fx_sub_i9, &fx_sub_i10, &fx_sub_i11, &fx_sub_i12, &fx_sub_i13, &fx_sub_i14, &fx_sub_i15, - /* 70 - 7f */ - &fx_merge, &fx_and_i1, &fx_and_i2, &fx_and_i3, &fx_and_i4, &fx_and_i5, &fx_and_i6, &fx_and_i7, - &fx_and_i8, &fx_and_i9, &fx_and_i10, &fx_and_i11, &fx_and_i12, &fx_and_i13, &fx_and_i14, &fx_and_i15, - /* 80 - 8f */ - &fx_mult_i0, &fx_mult_i1, &fx_mult_i2, &fx_mult_i3, &fx_mult_i4, &fx_mult_i5, &fx_mult_i6, &fx_mult_i7, - &fx_mult_i8, &fx_mult_i9, &fx_mult_i10, &fx_mult_i11, &fx_mult_i12, &fx_mult_i13, &fx_mult_i14, &fx_mult_i15, - /* 90 - 9f */ - &fx_sbk, &fx_link_i1, &fx_link_i2, &fx_link_i3, &fx_link_i4, &fx_sex, &fx_asr, &fx_ror, - &fx_jmp_r8, &fx_jmp_r9, &fx_jmp_r10, &fx_jmp_r11, &fx_jmp_r12, &fx_jmp_r13, &fx_lob, &fx_fmult, - /* a0 - af */ - &fx_sms_r0, &fx_sms_r1, &fx_sms_r2, &fx_sms_r3, &fx_sms_r4, &fx_sms_r5, &fx_sms_r6, &fx_sms_r7, - &fx_sms_r8, &fx_sms_r9, &fx_sms_r10, &fx_sms_r11, &fx_sms_r12, &fx_sms_r13, &fx_sms_r14, &fx_sms_r15, - /* b0 - bf */ - &fx_from_r0, &fx_from_r1, &fx_from_r2, &fx_from_r3, &fx_from_r4, &fx_from_r5, &fx_from_r6, &fx_from_r7, - &fx_from_r8, &fx_from_r9, &fx_from_r10, &fx_from_r11, &fx_from_r12, &fx_from_r13, &fx_from_r14, &fx_from_r15, - /* c0 - cf */ - &fx_hib, &fx_or_i1, &fx_or_i2, &fx_or_i3, &fx_or_i4, &fx_or_i5, &fx_or_i6, &fx_or_i7, - &fx_or_i8, &fx_or_i9, &fx_or_i10, &fx_or_i11, &fx_or_i12, &fx_or_i13, &fx_or_i14, &fx_or_i15, - /* d0 - df */ - &fx_inc_r0, &fx_inc_r1, &fx_inc_r2, &fx_inc_r3, &fx_inc_r4, &fx_inc_r5, &fx_inc_r6, &fx_inc_r7, - &fx_inc_r8, &fx_inc_r9, &fx_inc_r10, &fx_inc_r11, &fx_inc_r12, &fx_inc_r13, &fx_inc_r14, &fx_ramb, - /* e0 - ef */ - &fx_dec_r0, &fx_dec_r1, &fx_dec_r2, &fx_dec_r3, &fx_dec_r4, &fx_dec_r5, &fx_dec_r6, &fx_dec_r7, - &fx_dec_r8, &fx_dec_r9, &fx_dec_r10, &fx_dec_r11, &fx_dec_r12, &fx_dec_r13, &fx_dec_r14, &fx_getbl, - /* f0 - ff */ - &fx_sm_r0, &fx_sm_r1, &fx_sm_r2, &fx_sm_r3, &fx_sm_r4, &fx_sm_r5, &fx_sm_r6, &fx_sm_r7, - &fx_sm_r8, &fx_sm_r9, &fx_sm_r10, &fx_sm_r11, &fx_sm_r12, &fx_sm_r13, &fx_sm_r14, &fx_sm_r15, - - /* - * ALT3 Table - */ - - /* 00 - 0f */ - &fx_stop, &fx_nop, &fx_cache, &fx_lsr, &fx_rol, &fx_bra, &fx_bge, &fx_blt, - &fx_bne, &fx_beq, &fx_bpl, &fx_bmi, &fx_bcc, &fx_bcs, &fx_bvc, &fx_bvs, - /* 10 - 1f */ - &fx_to_r0, &fx_to_r1, &fx_to_r2, &fx_to_r3, &fx_to_r4, &fx_to_r5, &fx_to_r6, &fx_to_r7, - &fx_to_r8, &fx_to_r9, &fx_to_r10, &fx_to_r11, &fx_to_r12, &fx_to_r13, &fx_to_r14, &fx_to_r15, - /* 20 - 2f */ - &fx_with_r0, &fx_with_r1, &fx_with_r2, &fx_with_r3, &fx_with_r4, &fx_with_r5, &fx_with_r6, &fx_with_r7, - &fx_with_r8, &fx_with_r9, &fx_with_r10, &fx_with_r11, &fx_with_r12, &fx_with_r13, &fx_with_r14, &fx_with_r15, - /* 30 - 3f */ - &fx_stb_r0, &fx_stb_r1, &fx_stb_r2, &fx_stb_r3, &fx_stb_r4, &fx_stb_r5, &fx_stb_r6, &fx_stb_r7, - &fx_stb_r8, &fx_stb_r9, &fx_stb_r10, &fx_stb_r11, &fx_loop, &fx_alt1, &fx_alt2, &fx_alt3, - /* 40 - 4f */ - &fx_ldb_r0, &fx_ldb_r1, &fx_ldb_r2, &fx_ldb_r3, &fx_ldb_r4, &fx_ldb_r5, &fx_ldb_r6, &fx_ldb_r7, - &fx_ldb_r8, &fx_ldb_r9, &fx_ldb_r10, &fx_ldb_r11, &fx_rpix_2bit,&fx_swap, &fx_cmode, &fx_not, - /* 50 - 5f */ - &fx_adc_i0, &fx_adc_i1, &fx_adc_i2, &fx_adc_i3, &fx_adc_i4, &fx_adc_i5, &fx_adc_i6, &fx_adc_i7, - &fx_adc_i8, &fx_adc_i9, &fx_adc_i10, &fx_adc_i11, &fx_adc_i12, &fx_adc_i13, &fx_adc_i14, &fx_adc_i15, - /* 60 - 6f */ - &fx_cmp_r0, &fx_cmp_r1, &fx_cmp_r2, &fx_cmp_r3, &fx_cmp_r4, &fx_cmp_r5, &fx_cmp_r6, &fx_cmp_r7, - &fx_cmp_r8, &fx_cmp_r9, &fx_cmp_r10, &fx_cmp_r11, &fx_cmp_r12, &fx_cmp_r13, &fx_cmp_r14, &fx_cmp_r15, - /* 70 - 7f */ - &fx_merge, &fx_bic_i1, &fx_bic_i2, &fx_bic_i3, &fx_bic_i4, &fx_bic_i5, &fx_bic_i6, &fx_bic_i7, - &fx_bic_i8, &fx_bic_i9, &fx_bic_i10, &fx_bic_i11, &fx_bic_i12, &fx_bic_i13, &fx_bic_i14, &fx_bic_i15, - /* 80 - 8f */ - &fx_umult_i0,&fx_umult_i1,&fx_umult_i2, &fx_umult_i3, &fx_umult_i4, &fx_umult_i5, &fx_umult_i6, &fx_umult_i7, - &fx_umult_i8,&fx_umult_i9,&fx_umult_i10,&fx_umult_i11,&fx_umult_i12,&fx_umult_i13,&fx_umult_i14,&fx_umult_i15, - /* 90 - 9f */ - &fx_sbk, &fx_link_i1, &fx_link_i2, &fx_link_i3, &fx_link_i4, &fx_sex, &fx_div2, &fx_ror, - &fx_ljmp_r8, &fx_ljmp_r9, &fx_ljmp_r10, &fx_ljmp_r11, &fx_ljmp_r12, &fx_ljmp_r13, &fx_lob, &fx_lmult, - /* a0 - af */ - &fx_lms_r0, &fx_lms_r1, &fx_lms_r2, &fx_lms_r3, &fx_lms_r4, &fx_lms_r5, &fx_lms_r6, &fx_lms_r7, - &fx_lms_r8, &fx_lms_r9, &fx_lms_r10, &fx_lms_r11, &fx_lms_r12, &fx_lms_r13, &fx_lms_r14, &fx_lms_r15, - /* b0 - bf */ - &fx_from_r0, &fx_from_r1, &fx_from_r2, &fx_from_r3, &fx_from_r4, &fx_from_r5, &fx_from_r6, &fx_from_r7, - &fx_from_r8, &fx_from_r9, &fx_from_r10, &fx_from_r11, &fx_from_r12, &fx_from_r13, &fx_from_r14, &fx_from_r15, - /* c0 - cf */ - &fx_hib, &fx_xor_i1, &fx_xor_i2, &fx_xor_i3, &fx_xor_i4, &fx_xor_i5, &fx_xor_i6, &fx_xor_i7, - &fx_xor_i8, &fx_xor_i9, &fx_xor_i10, &fx_xor_i11, &fx_xor_i12, &fx_xor_i13, &fx_xor_i14, &fx_xor_i15, - /* d0 - df */ - &fx_inc_r0, &fx_inc_r1, &fx_inc_r2, &fx_inc_r3, &fx_inc_r4, &fx_inc_r5, &fx_inc_r6, &fx_inc_r7, - &fx_inc_r8, &fx_inc_r9, &fx_inc_r10, &fx_inc_r11, &fx_inc_r12, &fx_inc_r13, &fx_inc_r14, &fx_romb, - /* e0 - ef */ - &fx_dec_r0, &fx_dec_r1, &fx_dec_r2, &fx_dec_r3, &fx_dec_r4, &fx_dec_r5, &fx_dec_r6, &fx_dec_r7, - &fx_dec_r8, &fx_dec_r9, &fx_dec_r10, &fx_dec_r11, &fx_dec_r12, &fx_dec_r13, &fx_dec_r14, &fx_getbs, - /* f0 - ff */ - &fx_lm_r0, &fx_lm_r1, &fx_lm_r2, &fx_lm_r3, &fx_lm_r4, &fx_lm_r5, &fx_lm_r6, &fx_lm_r7, - &fx_lm_r8, &fx_lm_r9, &fx_lm_r10, &fx_lm_r11, &fx_lm_r12, &fx_lm_r13, &fx_lm_r14, &fx_lm_r15, + /* + * ALT0 Table + */ + /* 00 - 0f */ + &fx_stop, &fx_nop, &fx_cache, &fx_lsr, &fx_rol, &fx_bra, &fx_bge, &fx_blt, + &fx_bne, &fx_beq, &fx_bpl, &fx_bmi, &fx_bcc, &fx_bcs, &fx_bvc, &fx_bvs, + /* 10 - 1f */ + &fx_to_r0, &fx_to_r1, &fx_to_r2, &fx_to_r3, &fx_to_r4, &fx_to_r5, &fx_to_r6, &fx_to_r7, + &fx_to_r8, &fx_to_r9, &fx_to_r10, &fx_to_r11, &fx_to_r12, &fx_to_r13, &fx_to_r14, &fx_to_r15, + /* 20 - 2f */ + &fx_with_r0, &fx_with_r1, &fx_with_r2, &fx_with_r3, &fx_with_r4, &fx_with_r5, &fx_with_r6, &fx_with_r7, + &fx_with_r8, &fx_with_r9, &fx_with_r10, &fx_with_r11, &fx_with_r12, &fx_with_r13, &fx_with_r14, &fx_with_r15, + /* 30 - 3f */ + &fx_stw_r0, &fx_stw_r1, &fx_stw_r2, &fx_stw_r3, &fx_stw_r4, &fx_stw_r5, &fx_stw_r6, &fx_stw_r7, + &fx_stw_r8, &fx_stw_r9, &fx_stw_r10, &fx_stw_r11, &fx_loop, &fx_alt1, &fx_alt2, &fx_alt3, + /* 40 - 4f */ + &fx_ldw_r0, &fx_ldw_r1, &fx_ldw_r2, &fx_ldw_r3, &fx_ldw_r4, &fx_ldw_r5, &fx_ldw_r6, &fx_ldw_r7, + &fx_ldw_r8, &fx_ldw_r9, &fx_ldw_r10, &fx_ldw_r11, &fx_plot_2bit, &fx_swap, &fx_color, &fx_not, + /* 50 - 5f */ + &fx_add_r0, &fx_add_r1, &fx_add_r2, &fx_add_r3, &fx_add_r4, &fx_add_r5, &fx_add_r6, &fx_add_r7, + &fx_add_r8, &fx_add_r9, &fx_add_r10, &fx_add_r11, &fx_add_r12, &fx_add_r13, &fx_add_r14, &fx_add_r15, + /* 60 - 6f */ + &fx_sub_r0, &fx_sub_r1, &fx_sub_r2, &fx_sub_r3, &fx_sub_r4, &fx_sub_r5, &fx_sub_r6, &fx_sub_r7, + &fx_sub_r8, &fx_sub_r9, &fx_sub_r10, &fx_sub_r11, &fx_sub_r12, &fx_sub_r13, &fx_sub_r14, &fx_sub_r15, + /* 70 - 7f */ + &fx_merge, &fx_and_r1, &fx_and_r2, &fx_and_r3, &fx_and_r4, &fx_and_r5, &fx_and_r6, &fx_and_r7, + &fx_and_r8, &fx_and_r9, &fx_and_r10, &fx_and_r11, &fx_and_r12, &fx_and_r13, &fx_and_r14, &fx_and_r15, + /* 80 - 8f */ + &fx_mult_r0, &fx_mult_r1, &fx_mult_r2, &fx_mult_r3, &fx_mult_r4, &fx_mult_r5, &fx_mult_r6, &fx_mult_r7, + &fx_mult_r8, &fx_mult_r9, &fx_mult_r10, &fx_mult_r11, &fx_mult_r12, &fx_mult_r13, &fx_mult_r14, &fx_mult_r15, + /* 90 - 9f */ + &fx_sbk, &fx_link_i1, &fx_link_i2, &fx_link_i3, &fx_link_i4, &fx_sex, &fx_asr, &fx_ror, + &fx_jmp_r8, &fx_jmp_r9, &fx_jmp_r10, &fx_jmp_r11, &fx_jmp_r12, &fx_jmp_r13, &fx_lob, &fx_fmult, + /* a0 - af */ + &fx_ibt_r0, &fx_ibt_r1, &fx_ibt_r2, &fx_ibt_r3, &fx_ibt_r4, &fx_ibt_r5, &fx_ibt_r6, &fx_ibt_r7, + &fx_ibt_r8, &fx_ibt_r9, &fx_ibt_r10, &fx_ibt_r11, &fx_ibt_r12, &fx_ibt_r13, &fx_ibt_r14, &fx_ibt_r15, + /* b0 - bf */ + &fx_from_r0, &fx_from_r1, &fx_from_r2, &fx_from_r3, &fx_from_r4, &fx_from_r5, &fx_from_r6, &fx_from_r7, + &fx_from_r8, &fx_from_r9, &fx_from_r10, &fx_from_r11, &fx_from_r12, &fx_from_r13, &fx_from_r14, &fx_from_r15, + /* c0 - cf */ + &fx_hib, &fx_or_r1, &fx_or_r2, &fx_or_r3, &fx_or_r4, &fx_or_r5, &fx_or_r6, &fx_or_r7, + &fx_or_r8, &fx_or_r9, &fx_or_r10, &fx_or_r11, &fx_or_r12, &fx_or_r13, &fx_or_r14, &fx_or_r15, + /* d0 - df */ + &fx_inc_r0, &fx_inc_r1, &fx_inc_r2, &fx_inc_r3, &fx_inc_r4, &fx_inc_r5, &fx_inc_r6, &fx_inc_r7, + &fx_inc_r8, &fx_inc_r9, &fx_inc_r10, &fx_inc_r11, &fx_inc_r12, &fx_inc_r13, &fx_inc_r14, &fx_getc, + /* e0 - ef */ + &fx_dec_r0, &fx_dec_r1, &fx_dec_r2, &fx_dec_r3, &fx_dec_r4, &fx_dec_r5, &fx_dec_r6, &fx_dec_r7, + &fx_dec_r8, &fx_dec_r9, &fx_dec_r10, &fx_dec_r11, &fx_dec_r12, &fx_dec_r13, &fx_dec_r14, &fx_getb, + /* f0 - ff */ + &fx_iwt_r0, &fx_iwt_r1, &fx_iwt_r2, &fx_iwt_r3, &fx_iwt_r4, &fx_iwt_r5, &fx_iwt_r6, &fx_iwt_r7, + &fx_iwt_r8, &fx_iwt_r9, &fx_iwt_r10, &fx_iwt_r11, &fx_iwt_r12, &fx_iwt_r13, &fx_iwt_r14, &fx_iwt_r15, + + /* + * ALT1 Table + */ + + /* 00 - 0f */ + &fx_stop, &fx_nop, &fx_cache, &fx_lsr, &fx_rol, &fx_bra, &fx_bge, &fx_blt, + &fx_bne, &fx_beq, &fx_bpl, &fx_bmi, &fx_bcc, &fx_bcs, &fx_bvc, &fx_bvs, + /* 10 - 1f */ + &fx_to_r0, &fx_to_r1, &fx_to_r2, &fx_to_r3, &fx_to_r4, &fx_to_r5, &fx_to_r6, &fx_to_r7, + &fx_to_r8, &fx_to_r9, &fx_to_r10, &fx_to_r11, &fx_to_r12, &fx_to_r13, &fx_to_r14, &fx_to_r15, + /* 20 - 2f */ + &fx_with_r0, &fx_with_r1, &fx_with_r2, &fx_with_r3, &fx_with_r4, &fx_with_r5, &fx_with_r6, &fx_with_r7, + &fx_with_r8, &fx_with_r9, &fx_with_r10, &fx_with_r11, &fx_with_r12, &fx_with_r13, &fx_with_r14, &fx_with_r15, + /* 30 - 3f */ + &fx_stb_r0, &fx_stb_r1, &fx_stb_r2, &fx_stb_r3, &fx_stb_r4, &fx_stb_r5, &fx_stb_r6, &fx_stb_r7, + &fx_stb_r8, &fx_stb_r9, &fx_stb_r10, &fx_stb_r11, &fx_loop, &fx_alt1, &fx_alt2, &fx_alt3, + /* 40 - 4f */ + &fx_ldb_r0, &fx_ldb_r1, &fx_ldb_r2, &fx_ldb_r3, &fx_ldb_r4, &fx_ldb_r5, &fx_ldb_r6, &fx_ldb_r7, + &fx_ldb_r8, &fx_ldb_r9, &fx_ldb_r10, &fx_ldb_r11, &fx_rpix_2bit, &fx_swap, &fx_cmode, &fx_not, + /* 50 - 5f */ + &fx_adc_r0, &fx_adc_r1, &fx_adc_r2, &fx_adc_r3, &fx_adc_r4, &fx_adc_r5, &fx_adc_r6, &fx_adc_r7, + &fx_adc_r8, &fx_adc_r9, &fx_adc_r10, &fx_adc_r11, &fx_adc_r12, &fx_adc_r13, &fx_adc_r14, &fx_adc_r15, + /* 60 - 6f */ + &fx_sbc_r0, &fx_sbc_r1, &fx_sbc_r2, &fx_sbc_r3, &fx_sbc_r4, &fx_sbc_r5, &fx_sbc_r6, &fx_sbc_r7, + &fx_sbc_r8, &fx_sbc_r9, &fx_sbc_r10, &fx_sbc_r11, &fx_sbc_r12, &fx_sbc_r13, &fx_sbc_r14, &fx_sbc_r15, + /* 70 - 7f */ + &fx_merge, &fx_bic_r1, &fx_bic_r2, &fx_bic_r3, &fx_bic_r4, &fx_bic_r5, &fx_bic_r6, &fx_bic_r7, + &fx_bic_r8, &fx_bic_r9, &fx_bic_r10, &fx_bic_r11, &fx_bic_r12, &fx_bic_r13, &fx_bic_r14, &fx_bic_r15, + /* 80 - 8f */ + &fx_umult_r0, &fx_umult_r1, &fx_umult_r2, &fx_umult_r3, &fx_umult_r4, &fx_umult_r5, &fx_umult_r6, &fx_umult_r7, + &fx_umult_r8, &fx_umult_r9, &fx_umult_r10, &fx_umult_r11, &fx_umult_r12, &fx_umult_r13, &fx_umult_r14, &fx_umult_r15, + /* 90 - 9f */ + &fx_sbk, &fx_link_i1, &fx_link_i2, &fx_link_i3, &fx_link_i4, &fx_sex, &fx_div2, &fx_ror, + &fx_ljmp_r8, &fx_ljmp_r9, &fx_ljmp_r10, &fx_ljmp_r11, &fx_ljmp_r12, &fx_ljmp_r13, &fx_lob, &fx_lmult, + /* a0 - af */ + &fx_lms_r0, &fx_lms_r1, &fx_lms_r2, &fx_lms_r3, &fx_lms_r4, &fx_lms_r5, &fx_lms_r6, &fx_lms_r7, + &fx_lms_r8, &fx_lms_r9, &fx_lms_r10, &fx_lms_r11, &fx_lms_r12, &fx_lms_r13, &fx_lms_r14, &fx_lms_r15, + /* b0 - bf */ + &fx_from_r0, &fx_from_r1, &fx_from_r2, &fx_from_r3, &fx_from_r4, &fx_from_r5, &fx_from_r6, &fx_from_r7, + &fx_from_r8, &fx_from_r9, &fx_from_r10, &fx_from_r11, &fx_from_r12, &fx_from_r13, &fx_from_r14, &fx_from_r15, + /* c0 - cf */ + &fx_hib, &fx_xor_r1, &fx_xor_r2, &fx_xor_r3, &fx_xor_r4, &fx_xor_r5, &fx_xor_r6, &fx_xor_r7, + &fx_xor_r8, &fx_xor_r9, &fx_xor_r10, &fx_xor_r11, &fx_xor_r12, &fx_xor_r13, &fx_xor_r14, &fx_xor_r15, + /* d0 - df */ + &fx_inc_r0, &fx_inc_r1, &fx_inc_r2, &fx_inc_r3, &fx_inc_r4, &fx_inc_r5, &fx_inc_r6, &fx_inc_r7, + &fx_inc_r8, &fx_inc_r9, &fx_inc_r10, &fx_inc_r11, &fx_inc_r12, &fx_inc_r13, &fx_inc_r14, &fx_getc, + /* e0 - ef */ + &fx_dec_r0, &fx_dec_r1, &fx_dec_r2, &fx_dec_r3, &fx_dec_r4, &fx_dec_r5, &fx_dec_r6, &fx_dec_r7, + &fx_dec_r8, &fx_dec_r9, &fx_dec_r10, &fx_dec_r11, &fx_dec_r12, &fx_dec_r13, &fx_dec_r14, &fx_getbh, + /* f0 - ff */ + &fx_lm_r0, &fx_lm_r1, &fx_lm_r2, &fx_lm_r3, &fx_lm_r4, &fx_lm_r5, &fx_lm_r6, &fx_lm_r7, + &fx_lm_r8, &fx_lm_r9, &fx_lm_r10, &fx_lm_r11, &fx_lm_r12, &fx_lm_r13, &fx_lm_r14, &fx_lm_r15, + + /* + * ALT2 Table + */ + + /* 00 - 0f */ + &fx_stop, &fx_nop, &fx_cache, &fx_lsr, &fx_rol, &fx_bra, &fx_bge, &fx_blt, + &fx_bne, &fx_beq, &fx_bpl, &fx_bmi, &fx_bcc, &fx_bcs, &fx_bvc, &fx_bvs, + /* 10 - 1f */ + &fx_to_r0, &fx_to_r1, &fx_to_r2, &fx_to_r3, &fx_to_r4, &fx_to_r5, &fx_to_r6, &fx_to_r7, + &fx_to_r8, &fx_to_r9, &fx_to_r10, &fx_to_r11, &fx_to_r12, &fx_to_r13, &fx_to_r14, &fx_to_r15, + /* 20 - 2f */ + &fx_with_r0, &fx_with_r1, &fx_with_r2, &fx_with_r3, &fx_with_r4, &fx_with_r5, &fx_with_r6, &fx_with_r7, + &fx_with_r8, &fx_with_r9, &fx_with_r10, &fx_with_r11, &fx_with_r12, &fx_with_r13, &fx_with_r14, &fx_with_r15, + /* 30 - 3f */ + &fx_stw_r0, &fx_stw_r1, &fx_stw_r2, &fx_stw_r3, &fx_stw_r4, &fx_stw_r5, &fx_stw_r6, &fx_stw_r7, + &fx_stw_r8, &fx_stw_r9, &fx_stw_r10, &fx_stw_r11, &fx_loop, &fx_alt1, &fx_alt2, &fx_alt3, + /* 40 - 4f */ + &fx_ldw_r0, &fx_ldw_r1, &fx_ldw_r2, &fx_ldw_r3, &fx_ldw_r4, &fx_ldw_r5, &fx_ldw_r6, &fx_ldw_r7, + &fx_ldw_r8, &fx_ldw_r9, &fx_ldw_r10, &fx_ldw_r11, &fx_plot_2bit, &fx_swap, &fx_color, &fx_not, + /* 50 - 5f */ + &fx_add_i0, &fx_add_i1, &fx_add_i2, &fx_add_i3, &fx_add_i4, &fx_add_i5, &fx_add_i6, &fx_add_i7, + &fx_add_i8, &fx_add_i9, &fx_add_i10, &fx_add_i11, &fx_add_i12, &fx_add_i13, &fx_add_i14, &fx_add_i15, + /* 60 - 6f */ + &fx_sub_i0, &fx_sub_i1, &fx_sub_i2, &fx_sub_i3, &fx_sub_i4, &fx_sub_i5, &fx_sub_i6, &fx_sub_i7, + &fx_sub_i8, &fx_sub_i9, &fx_sub_i10, &fx_sub_i11, &fx_sub_i12, &fx_sub_i13, &fx_sub_i14, &fx_sub_i15, + /* 70 - 7f */ + &fx_merge, &fx_and_i1, &fx_and_i2, &fx_and_i3, &fx_and_i4, &fx_and_i5, &fx_and_i6, &fx_and_i7, + &fx_and_i8, &fx_and_i9, &fx_and_i10, &fx_and_i11, &fx_and_i12, &fx_and_i13, &fx_and_i14, &fx_and_i15, + /* 80 - 8f */ + &fx_mult_i0, &fx_mult_i1, &fx_mult_i2, &fx_mult_i3, &fx_mult_i4, &fx_mult_i5, &fx_mult_i6, &fx_mult_i7, + &fx_mult_i8, &fx_mult_i9, &fx_mult_i10, &fx_mult_i11, &fx_mult_i12, &fx_mult_i13, &fx_mult_i14, &fx_mult_i15, + /* 90 - 9f */ + &fx_sbk, &fx_link_i1, &fx_link_i2, &fx_link_i3, &fx_link_i4, &fx_sex, &fx_asr, &fx_ror, + &fx_jmp_r8, &fx_jmp_r9, &fx_jmp_r10, &fx_jmp_r11, &fx_jmp_r12, &fx_jmp_r13, &fx_lob, &fx_fmult, + /* a0 - af */ + &fx_sms_r0, &fx_sms_r1, &fx_sms_r2, &fx_sms_r3, &fx_sms_r4, &fx_sms_r5, &fx_sms_r6, &fx_sms_r7, + &fx_sms_r8, &fx_sms_r9, &fx_sms_r10, &fx_sms_r11, &fx_sms_r12, &fx_sms_r13, &fx_sms_r14, &fx_sms_r15, + /* b0 - bf */ + &fx_from_r0, &fx_from_r1, &fx_from_r2, &fx_from_r3, &fx_from_r4, &fx_from_r5, &fx_from_r6, &fx_from_r7, + &fx_from_r8, &fx_from_r9, &fx_from_r10, &fx_from_r11, &fx_from_r12, &fx_from_r13, &fx_from_r14, &fx_from_r15, + /* c0 - cf */ + &fx_hib, &fx_or_i1, &fx_or_i2, &fx_or_i3, &fx_or_i4, &fx_or_i5, &fx_or_i6, &fx_or_i7, + &fx_or_i8, &fx_or_i9, &fx_or_i10, &fx_or_i11, &fx_or_i12, &fx_or_i13, &fx_or_i14, &fx_or_i15, + /* d0 - df */ + &fx_inc_r0, &fx_inc_r1, &fx_inc_r2, &fx_inc_r3, &fx_inc_r4, &fx_inc_r5, &fx_inc_r6, &fx_inc_r7, + &fx_inc_r8, &fx_inc_r9, &fx_inc_r10, &fx_inc_r11, &fx_inc_r12, &fx_inc_r13, &fx_inc_r14, &fx_ramb, + /* e0 - ef */ + &fx_dec_r0, &fx_dec_r1, &fx_dec_r2, &fx_dec_r3, &fx_dec_r4, &fx_dec_r5, &fx_dec_r6, &fx_dec_r7, + &fx_dec_r8, &fx_dec_r9, &fx_dec_r10, &fx_dec_r11, &fx_dec_r12, &fx_dec_r13, &fx_dec_r14, &fx_getbl, + /* f0 - ff */ + &fx_sm_r0, &fx_sm_r1, &fx_sm_r2, &fx_sm_r3, &fx_sm_r4, &fx_sm_r5, &fx_sm_r6, &fx_sm_r7, + &fx_sm_r8, &fx_sm_r9, &fx_sm_r10, &fx_sm_r11, &fx_sm_r12, &fx_sm_r13, &fx_sm_r14, &fx_sm_r15, + + /* + * ALT3 Table + */ + + /* 00 - 0f */ + &fx_stop, &fx_nop, &fx_cache, &fx_lsr, &fx_rol, &fx_bra, &fx_bge, &fx_blt, + &fx_bne, &fx_beq, &fx_bpl, &fx_bmi, &fx_bcc, &fx_bcs, &fx_bvc, &fx_bvs, + /* 10 - 1f */ + &fx_to_r0, &fx_to_r1, &fx_to_r2, &fx_to_r3, &fx_to_r4, &fx_to_r5, &fx_to_r6, &fx_to_r7, + &fx_to_r8, &fx_to_r9, &fx_to_r10, &fx_to_r11, &fx_to_r12, &fx_to_r13, &fx_to_r14, &fx_to_r15, + /* 20 - 2f */ + &fx_with_r0, &fx_with_r1, &fx_with_r2, &fx_with_r3, &fx_with_r4, &fx_with_r5, &fx_with_r6, &fx_with_r7, + &fx_with_r8, &fx_with_r9, &fx_with_r10, &fx_with_r11, &fx_with_r12, &fx_with_r13, &fx_with_r14, &fx_with_r15, + /* 30 - 3f */ + &fx_stb_r0, &fx_stb_r1, &fx_stb_r2, &fx_stb_r3, &fx_stb_r4, &fx_stb_r5, &fx_stb_r6, &fx_stb_r7, + &fx_stb_r8, &fx_stb_r9, &fx_stb_r10, &fx_stb_r11, &fx_loop, &fx_alt1, &fx_alt2, &fx_alt3, + /* 40 - 4f */ + &fx_ldb_r0, &fx_ldb_r1, &fx_ldb_r2, &fx_ldb_r3, &fx_ldb_r4, &fx_ldb_r5, &fx_ldb_r6, &fx_ldb_r7, + &fx_ldb_r8, &fx_ldb_r9, &fx_ldb_r10, &fx_ldb_r11, &fx_rpix_2bit, &fx_swap, &fx_cmode, &fx_not, + /* 50 - 5f */ + &fx_adc_i0, &fx_adc_i1, &fx_adc_i2, &fx_adc_i3, &fx_adc_i4, &fx_adc_i5, &fx_adc_i6, &fx_adc_i7, + &fx_adc_i8, &fx_adc_i9, &fx_adc_i10, &fx_adc_i11, &fx_adc_i12, &fx_adc_i13, &fx_adc_i14, &fx_adc_i15, + /* 60 - 6f */ + &fx_cmp_r0, &fx_cmp_r1, &fx_cmp_r2, &fx_cmp_r3, &fx_cmp_r4, &fx_cmp_r5, &fx_cmp_r6, &fx_cmp_r7, + &fx_cmp_r8, &fx_cmp_r9, &fx_cmp_r10, &fx_cmp_r11, &fx_cmp_r12, &fx_cmp_r13, &fx_cmp_r14, &fx_cmp_r15, + /* 70 - 7f */ + &fx_merge, &fx_bic_i1, &fx_bic_i2, &fx_bic_i3, &fx_bic_i4, &fx_bic_i5, &fx_bic_i6, &fx_bic_i7, + &fx_bic_i8, &fx_bic_i9, &fx_bic_i10, &fx_bic_i11, &fx_bic_i12, &fx_bic_i13, &fx_bic_i14, &fx_bic_i15, + /* 80 - 8f */ + &fx_umult_i0, &fx_umult_i1, &fx_umult_i2, &fx_umult_i3, &fx_umult_i4, &fx_umult_i5, &fx_umult_i6, &fx_umult_i7, + &fx_umult_i8, &fx_umult_i9, &fx_umult_i10, &fx_umult_i11, &fx_umult_i12, &fx_umult_i13, &fx_umult_i14, &fx_umult_i15, + /* 90 - 9f */ + &fx_sbk, &fx_link_i1, &fx_link_i2, &fx_link_i3, &fx_link_i4, &fx_sex, &fx_div2, &fx_ror, + &fx_ljmp_r8, &fx_ljmp_r9, &fx_ljmp_r10, &fx_ljmp_r11, &fx_ljmp_r12, &fx_ljmp_r13, &fx_lob, &fx_lmult, + /* a0 - af */ + &fx_lms_r0, &fx_lms_r1, &fx_lms_r2, &fx_lms_r3, &fx_lms_r4, &fx_lms_r5, &fx_lms_r6, &fx_lms_r7, + &fx_lms_r8, &fx_lms_r9, &fx_lms_r10, &fx_lms_r11, &fx_lms_r12, &fx_lms_r13, &fx_lms_r14, &fx_lms_r15, + /* b0 - bf */ + &fx_from_r0, &fx_from_r1, &fx_from_r2, &fx_from_r3, &fx_from_r4, &fx_from_r5, &fx_from_r6, &fx_from_r7, + &fx_from_r8, &fx_from_r9, &fx_from_r10, &fx_from_r11, &fx_from_r12, &fx_from_r13, &fx_from_r14, &fx_from_r15, + /* c0 - cf */ + &fx_hib, &fx_xor_i1, &fx_xor_i2, &fx_xor_i3, &fx_xor_i4, &fx_xor_i5, &fx_xor_i6, &fx_xor_i7, + &fx_xor_i8, &fx_xor_i9, &fx_xor_i10, &fx_xor_i11, &fx_xor_i12, &fx_xor_i13, &fx_xor_i14, &fx_xor_i15, + /* d0 - df */ + &fx_inc_r0, &fx_inc_r1, &fx_inc_r2, &fx_inc_r3, &fx_inc_r4, &fx_inc_r5, &fx_inc_r6, &fx_inc_r7, + &fx_inc_r8, &fx_inc_r9, &fx_inc_r10, &fx_inc_r11, &fx_inc_r12, &fx_inc_r13, &fx_inc_r14, &fx_romb, + /* e0 - ef */ + &fx_dec_r0, &fx_dec_r1, &fx_dec_r2, &fx_dec_r3, &fx_dec_r4, &fx_dec_r5, &fx_dec_r6, &fx_dec_r7, + &fx_dec_r8, &fx_dec_r9, &fx_dec_r10, &fx_dec_r11, &fx_dec_r12, &fx_dec_r13, &fx_dec_r14, &fx_getbs, + /* f0 - ff */ + &fx_lm_r0, &fx_lm_r1, &fx_lm_r2, &fx_lm_r3, &fx_lm_r4, &fx_lm_r5, &fx_lm_r6, &fx_lm_r7, + &fx_lm_r8, &fx_lm_r9, &fx_lm_r10, &fx_lm_r11, &fx_lm_r12, &fx_lm_r13, &fx_lm_r14, &fx_lm_r15, }; diff --git a/source/fxinst.h b/source/fxinst.h index 43b6a28..ff9a044 100644 --- a/source/fxinst.h +++ b/source/fxinst.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -95,95 +95,95 @@ * * The 16 generic 16 bit registers: * (Some have a special function in special circumstances) - * 3000 - R0 default source/destination register - * 3002 - R1 pixel plot X position register - * 3004 - R2 pixel plot Y position register + * 3000 - R0 default source/destination register + * 3002 - R1 pixel plot X position register + * 3004 - R2 pixel plot Y position register * 3006 - R3 - * 3008 - R4 lower 16 bit result of lmult - * 300a - R5 - * 300c - R6 multiplier for fmult and lmult - * 300e - R7 fixed point texel X position for merge - * 3010 - R8 fixed point texel Y position for merge - * 3012 - R9 - * 3014 - R10 - * 3016 - R11 return address set by link - * 3018 - R12 loop counter - * 301a - R13 loop point address - * 301c - R14 rom address for getb, getbh, getbl, getbs - * 301e - R15 program counter + * 3008 - R4 lower 16 bit result of lmult + * 300a - R5 + * 300c - R6 multiplier for fmult and lmult + * 300e - R7 fixed point texel X position for merge + * 3010 - R8 fixed point texel Y position for merge + * 3012 - R9 + * 3014 - R10 + * 3016 - R11 return address set by link + * 3018 - R12 loop counter + * 301a - R13 loop point address + * 301c - R14 rom address for getb, getbh, getbl, getbs + * 301e - R15 program counter + * + * 3020-302f - unused * - * 3020-302f - unused - * * Other internal registers - * 3030 - SFR status flag register (16bit) - * 3032 - unused + * 3030 - SFR status flag register (16bit) + * 3032 - unused * 3033 - BRAMR Backup RAM register (8bit) - * 3034 - PBR program bank register (8bit) - * 3035 - unused - * 3036 - ROMBR rom bank register (8bit) - * 3037 - CFGR control flags register (8bit) - * 3038 - SCBR screen base register (8bit) - * 3039 - CLSR clock speed register (8bit) - * 303a - SCMR screen mode register (8bit) - * 303b - VCR version code register (8bit) (read only) - * 303c - RAMBR ram bank register (8bit) - * 303d - unused - * 303e - CBR cache base register (16bit) + * 3034 - PBR program bank register (8bit) + * 3035 - unused + * 3036 - ROMBR rom bank register (8bit) + * 3037 - CFGR control flags register (8bit) + * 3038 - SCBR screen base register (8bit) + * 3039 - CLSR clock speed register (8bit) + * 303a - SCMR screen mode register (8bit) + * 303b - VCR version code register (8bit) (read only) + * 303c - RAMBR ram bank register (8bit) + * 303d - unused + * 303e - CBR cache base register (16bit) * - * 3040-30ff - unused + * 3040-30ff - unused * - * 3100-32ff - CACHERAM 512 bytes of GSU cache memory + * 3100-32ff - CACHERAM 512 bytes of GSU cache memory * * SFR status flag register bits: - * 0 - - * 1 Z Zero flag - * 2 CY Carry flag - * 3 S Sign flag - * 4 OV Overflow flag - * 5 G Go flag (set to 1 when the GSU is running) - * 6 R Set to 1 when reading ROM using R14 address - * 7 - - * 8 ALT1 Mode set-up flag for the next instruction - * 9 ALT2 Mode set-up flag for the next instruction - * 10 IL Immediate lower 8-bit flag - * 11 IH Immediate higher 8-bit flag - * 12 B Set to 1 when the WITH instruction is executed - * 13 - - * 14 - - * 15 IRQ Set to 1 when GSU caused an interrupt + * 0 - + * 1 Z Zero flag + * 2 CY Carry flag + * 3 S Sign flag + * 4 OV Overflow flag + * 5 G Go flag (set to 1 when the GSU is running) + * 6 R Set to 1 when reading ROM using R14 address + * 7 - + * 8 ALT1 Mode set-up flag for the next instruction + * 9 ALT2 Mode set-up flag for the next instruction + * 10 IL Immediate lower 8-bit flag + * 11 IH Immediate higher 8-bit flag + * 12 B Set to 1 when the WITH instruction is executed + * 13 - + * 14 - + * 15 IRQ Set to 1 when GSU caused an interrupt * Set to 0 when read by 658c16 * * BRAMR = 0, BackupRAM is disabled * BRAMR = 1, BackupRAM is enabled * * CFGR control flags register bits: - * 0 - - * 1 - - * 2 - - * 3 - - * 4 - - * 5 MS0 Multiplier speed, 0=standard, 1=high speed - * 6 - - * 7 IRQ Set to 1 when GSU interrupt request is masked + * 0 - + * 1 - + * 2 - + * 3 - + * 4 - + * 5 MS0 Multiplier speed, 0=standard, 1=high speed + * 6 - + * 7 IRQ Set to 1 when GSU interrupt request is masked * * CLSR clock speed register bits: - * 0 CLSR clock speed, 0 = 10.7Mhz, 1 = 21.4Mhz + * 0 CLSR clock speed, 0 = 10.7Mhz, 1 = 21.4Mhz * * SCMR screen mode register bits: - * 0 MD0 color depth mode bit 0 - * 1 MD1 color depth mode bit 1 - * 2 HT0 screen height bit 1 - * 3 RAN RAM access control - * 4 RON ROM access control - * 5 HT1 screen height bit 2 - * 6 - - * 7 - + * 0 MD0 color depth mode bit 0 + * 1 MD1 color depth mode bit 1 + * 2 HT0 screen height bit 1 + * 3 RAN RAM access control + * 4 RON ROM access control + * 5 HT1 screen height bit 2 + * 6 - + * 7 - * - * RON = 0 SNES CPU has ROM access - * RON = 1 GSU has ROM access + * RON = 0 SNES CPU has ROM access + * RON = 1 GSU has ROM access * - * RAN = 0 SNES has game pak RAM access - * RAN = 1 GSU has game pak RAM access + * RAN = 0 SNES has game pak RAM access + * RAN = 1 GSU has game pak RAM access * * HT1 HT0 Screen height mode * 0 0 128 pixels high @@ -198,8 +198,8 @@ * 1 1 256 color mode * * CBR cache base register bits: - * 15-4 Specify base address for data to cache from ROM or RAM - * 3-0 Are 0 when address is read + * 15-4 Specify base address for data to cache from ROM or RAM + * 3-0 Are 0 when address is read * * Write access to the program counter (301e) from * the SNES-CPU will start the GSU, and it will not @@ -218,69 +218,69 @@ struct FxRegs_s { - /* FxChip registers */ - uint32 avReg[16]; /* 16 Generic registers */ - uint32 vColorReg; /* Internal color register */ - uint32 vPlotOptionReg; /* Plot option register */ - uint32 vStatusReg; /* Status register */ - uint32 vPrgBankReg; /* Program bank index register */ - uint32 vRomBankReg; /* Rom bank index register */ - uint32 vRamBankReg; /* Ram bank index register */ - uint32 vCacheBaseReg; /* Cache base address register */ - uint32 vCacheFlags; /* Saying what parts of the cache was written to */ - uint32 vLastRamAdr; /* Last RAM address accessed */ - uint32 * pvDreg; /* Pointer to current destination register */ - uint32 * pvSreg; /* Pointer to current source register */ - uint8 vRomBuffer; /* Current byte read by R14 */ - uint8 vPipe; /* Instructionset pipe */ - uint32 vPipeAdr; /* The address of where the pipe was read from */ - - /* status register optimization stuff */ - uint32 vSign; /* v & 0x8000 */ - uint32 vZero; /* v == 0 */ - uint32 vCarry; /* a value of 1 or 0 */ - int32 vOverflow; /* (v >= 0x8000 || v < -0x8000) */ - - /* Other emulator variables */ - - int32 vErrorCode; - uint32 vIllegalAddress; - - uint8 bBreakPoint; - uint32 vBreakPoint; - uint32 vStepPoint; - - uint8 * pvRegisters; /* 768 bytes located in the memory at address 0x3000 */ - uint32 nRamBanks; /* Number of 64kb-banks in FxRam (Don't confuse it with SNES-Ram!!!) */ - uint8 * pvRam; /* Pointer to FxRam */ - uint32 nRomBanks; /* Number of 32kb-banks in Cart-ROM */ - uint8 * pvRom; /* Pointer to Cart-ROM */ - - uint32 vMode; /* Color depth/mode */ - uint32 vPrevMode; /* Previous depth */ - uint8 * pvScreenBase; - uint8 * apvScreen[32]; /* Pointer to each of the 32 screen colums */ - int x[32]; - uint32 vScreenHeight; /* 128, 160, 192 or 256 (could be overriden by cmode) */ - uint32 vScreenRealHeight; /* 128, 160, 192 or 256 */ - uint32 vPrevScreenHeight; - uint32 vScreenSize; - void (*pfPlot)(); - void (*pfRpix)(); - - uint8 * pvRamBank; /* Pointer to current RAM-bank */ - uint8 * pvRomBank; /* Pointer to current ROM-bank */ - uint8 * pvPrgBank; /* Pointer to current program ROM-bank */ - - uint8 * apvRamBank[FX_RAM_BANKS];/* Ram bank table (max 256kb) */ - uint8 * apvRomBank[256]; /* Rom bank table */ - - uint8 bCacheActive; - uint8 * pvCache; /* Pointer to the GSU cache */ - uint8 avCacheBackup[512]; /* Backup of ROM when the cache has replaced it */ - uint32 vCounter; - uint32 vInstCount; - uint32 vSCBRDirty; /* if SCBR is written, our cached screen pointers need updating */ + /* FxChip registers */ + uint32 avReg[16]; /* 16 Generic registers */ + uint32 vColorReg; /* Internal color register */ + uint32 vPlotOptionReg; /* Plot option register */ + uint32 vStatusReg; /* Status register */ + uint32 vPrgBankReg; /* Program bank index register */ + uint32 vRomBankReg; /* Rom bank index register */ + uint32 vRamBankReg; /* Ram bank index register */ + uint32 vCacheBaseReg; /* Cache base address register */ + uint32 vCacheFlags; /* Saying what parts of the cache was written to */ + uint32 vLastRamAdr; /* Last RAM address accessed */ + uint32* pvDreg; /* Pointer to current destination register */ + uint32* pvSreg; /* Pointer to current source register */ + uint8 vRomBuffer; /* Current byte read by R14 */ + uint8 vPipe; /* Instructionset pipe */ + uint32 vPipeAdr; /* The address of where the pipe was read from */ + + /* status register optimization stuff */ + uint32 vSign; /* v & 0x8000 */ + uint32 vZero; /* v == 0 */ + uint32 vCarry; /* a value of 1 or 0 */ + int32 vOverflow; /* (v >= 0x8000 || v < -0x8000) */ + + /* Other emulator variables */ + + int32 vErrorCode; + uint32 vIllegalAddress; + + uint8 bBreakPoint; + uint32 vBreakPoint; + uint32 vStepPoint; + + uint8* pvRegisters; /* 768 bytes located in the memory at address 0x3000 */ + uint32 nRamBanks; /* Number of 64kb-banks in FxRam (Don't confuse it with SNES-Ram!!!) */ + uint8* pvRam; /* Pointer to FxRam */ + uint32 nRomBanks; /* Number of 32kb-banks in Cart-ROM */ + uint8* pvRom; /* Pointer to Cart-ROM */ + + uint32 vMode; /* Color depth/mode */ + uint32 vPrevMode; /* Previous depth */ + uint8* pvScreenBase; + uint8* apvScreen[32]; /* Pointer to each of the 32 screen colums */ + int x[32]; + uint32 vScreenHeight; /* 128, 160, 192 or 256 (could be overriden by cmode) */ + uint32 vScreenRealHeight; /* 128, 160, 192 or 256 */ + uint32 vPrevScreenHeight; + uint32 vScreenSize; + void (*pfPlot)(); + void (*pfRpix)(); + + uint8* pvRamBank; /* Pointer to current RAM-bank */ + uint8* pvRomBank; /* Pointer to current ROM-bank */ + uint8* pvPrgBank; /* Pointer to current program ROM-bank */ + + uint8* apvRamBank[FX_RAM_BANKS];/* Ram bank table (max 256kb) */ + uint8* apvRomBank[256]; /* Rom bank table */ + + uint8 bCacheActive; + uint8* pvCache; /* Pointer to the GSU cache */ + uint8 avCacheBackup[512]; /* Backup of ROM when the cache has replaced it */ + uint32 vCounter; + uint32 vInstCount; + uint32 vSCBRDirty; /* if SCBR is written, our cached screen pointers need updating */ }; #define FxRegs_s_null { \ @@ -446,24 +446,24 @@ struct FxRegs_s #define FX_STEP { uint32 vOpcode = (uint32)PIPE; FETCHPIPE; \ (*fx_ppfOpcodeTable[ (GSU.vStatusReg & 0x300) | vOpcode ])(); } \ -#define FX_FUNCTION_RUN 0 -#define FX_FUNCTION_RUN_TO_BREAKPOINT 1 -#define FX_FUNCTION_STEP_OVER 2 +#define FX_FUNCTION_RUN 0 +#define FX_FUNCTION_RUN_TO_BREAKPOINT 1 +#define FX_FUNCTION_STEP_OVER 2 -extern uint32 (**fx_ppfFunctionTable)(uint32); +extern uint32(**fx_ppfFunctionTable)(uint32); extern void (**fx_ppfPlotTable)(); extern void (**fx_ppfOpcodeTable)(); -extern uint32 (*fx_apfFunctionTable[])(uint32); +extern uint32(*fx_apfFunctionTable[])(uint32); extern void (*fx_apfOpcodeTable[])(); extern void (*fx_apfPlotTable[])(); -extern uint32 (*fx_a_apfFunctionTable[])(uint32); +extern uint32(*fx_a_apfFunctionTable[])(uint32); extern void (*fx_a_apfOpcodeTable[])(); extern void (*fx_a_apfPlotTable[])(); -extern uint32 (*fx_r_apfFunctionTable[])(uint32); +extern uint32(*fx_r_apfFunctionTable[])(uint32); extern void (*fx_r_apfOpcodeTable[])(); extern void (*fx_r_apfPlotTable[])(); -extern uint32 (*fx_ar_apfFunctionTable[])(uint32); +extern uint32(*fx_ar_apfFunctionTable[])(uint32); extern void (*fx_ar_apfOpcodeTable[])(); extern void (*fx_ar_apfPlotTable[])(); diff --git a/source/getset.h b/source/getset.h index 511634d..558ed98 100644 --- a/source/getset.h +++ b/source/getset.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -100,612 +100,621 @@ extern uint8 OpenBus; -uint8 S9xGetByte (uint32 Address) +uint8 S9xGetByte(uint32 Address) { - int block; - uint8 *GetAddress = Memory.Map [block = (Address >> MEMMAP_SHIFT) & MEMMAP_MASK]; + int block; + uint8* GetAddress = Memory.Map [block = (Address >> MEMMAP_SHIFT) & + MEMMAP_MASK]; - if(!CPU.InDMA) - CPU.Cycles += Memory.MemorySpeed [block]; + if (!CPU.InDMA) + CPU.Cycles += Memory.MemorySpeed [block]; - if (GetAddress >= (uint8 *) MAP_LAST) - { + if (GetAddress >= (uint8*) MAP_LAST) + { #ifdef CPU_SHUTDOWN - if (Memory.BlockIsRAM [block]) - CPU.WaitAddress = CPU.PCAtOpcodeStart; + if (Memory.BlockIsRAM [block]) + CPU.WaitAddress = CPU.PCAtOpcodeStart; #endif - return (*(GetAddress + (Address & 0xffff))); - } - - switch ((intptr_t) GetAddress) - { - case MAP_PPU: - return (S9xGetPPU (Address & 0xffff)); - case MAP_CPU: - return (S9xGetCPU (Address & 0xffff)); - case MAP_DSP: + return (*(GetAddress + (Address & 0xffff))); + } + + switch ((intptr_t) GetAddress) + { + case MAP_PPU: + return (S9xGetPPU(Address & 0xffff)); + case MAP_CPU: + return (S9xGetCPU(Address & 0xffff)); + case MAP_DSP: #ifdef DSP_DUMMY_LOOPS - printf("Get DSP Byte @ %06X\n", Address); + printf("Get DSP Byte @ %06X\n", Address); #endif - return (S9xGetDSP (Address & 0xffff)); - case MAP_SA1RAM: - case MAP_LOROM_SRAM: - //Address &0x7FFF -offset into bank - //Address&0xFF0000 -bank - //bank>>1 | offset = s-ram address, unbound - //unbound & SRAMMask = Sram offset - return (*(Memory.SRAM + ((((Address&0xFF0000)>>1) |(Address&0x7FFF)) &Memory.SRAMMask))); -// return (*(Memory.SRAM + ((Address & Memory.SRAMMask)))); - - case MAP_RONLY_SRAM: - case MAP_HIROM_SRAM: - return (*(Memory.SRAM + (((Address & 0x7fff) - 0x6000 + - ((Address & 0xf0000) >> 3)) & Memory.SRAMMask))); - - case MAP_BWRAM: - return (*(Memory.BWRAM + ((Address & 0x7fff) - 0x6000))); - - case MAP_C4: - return (S9xGetC4 (Address & 0xffff)); - - case MAP_SPC7110_ROM: - return S9xGetSPC7110Byte(Address); - - case MAP_SPC7110_DRAM: - return S9xGetSPC7110(0x4800); - - case MAP_OBC_RAM: - return GetOBC1(Address & 0xffff); - - case MAP_SETA_DSP: - return S9xGetSetaDSP(Address); - - case MAP_SETA_RISC: - return S9xGetST018(Address); - - - + return (S9xGetDSP(Address & 0xffff)); + case MAP_SA1RAM: + case MAP_LOROM_SRAM: + //Address &0x7FFF -offset into bank + //Address&0xFF0000 -bank + //bank>>1 | offset = s-ram address, unbound + //unbound & SRAMMask = Sram offset + return (*(Memory.SRAM + ((((Address & 0xFF0000) >> 1) | + (Address & 0x7FFF)) &Memory.SRAMMask))); + // return (*(Memory.SRAM + ((Address & Memory.SRAMMask)))); + + case MAP_RONLY_SRAM: + case MAP_HIROM_SRAM: + return (*(Memory.SRAM + (((Address & 0x7fff) - 0x6000 + + ((Address & 0xf0000) >> 3)) & Memory.SRAMMask))); + + case MAP_BWRAM: + return (*(Memory.BWRAM + ((Address & 0x7fff) - 0x6000))); + + case MAP_C4: + return (S9xGetC4(Address & 0xffff)); + + case MAP_SPC7110_ROM: + return S9xGetSPC7110Byte(Address); + + case MAP_SPC7110_DRAM: + return S9xGetSPC7110(0x4800); + + case MAP_OBC_RAM: + return GetOBC1(Address & 0xffff); + + case MAP_SETA_DSP: + return S9xGetSetaDSP(Address); + + case MAP_SETA_RISC: + return S9xGetST018(Address); + + + case MAP_DEBUG: - return OpenBus; + return OpenBus; - default: - case MAP_NONE: + default: + case MAP_NONE: #ifdef MK_TRACE_BAD_READS - char address[20]; - sprintf(address, TEXT("%06X"),Address); - MessageBox(GUI.hWnd, address, TEXT("GetByte"), MB_OK); + char address[20]; + sprintf(address, TEXT("%06X"), Address); + MessageBox(GUI.hWnd, address, TEXT("GetByte"), MB_OK); #endif - return OpenBus; - } + return OpenBus; + } } -uint16 S9xGetWord (uint32 Address) +uint16 S9xGetWord(uint32 Address) { - if ((Address & 0x0fff) == 0x0fff) - { - OpenBus = S9xGetByte (Address); - return (OpenBus | (S9xGetByte (Address + 1) << 8)); - } - int block; - uint8 *GetAddress = Memory.Map [block = (Address >> MEMMAP_SHIFT) & MEMMAP_MASK]; - - if(!CPU.InDMA) - CPU.Cycles += (Memory.MemorySpeed [block]<<1); - - - if (GetAddress >= (uint8 *) MAP_LAST) - { + if ((Address & 0x0fff) == 0x0fff) + { + OpenBus = S9xGetByte(Address); + return (OpenBus | (S9xGetByte(Address + 1) << 8)); + } + int block; + uint8* GetAddress = Memory.Map [block = (Address >> MEMMAP_SHIFT) & + MEMMAP_MASK]; + + if (!CPU.InDMA) + CPU.Cycles += (Memory.MemorySpeed [block] << 1); + + + if (GetAddress >= (uint8*) MAP_LAST) + { #ifdef CPU_SHUTDOWN - if (Memory.BlockIsRAM [block]) - CPU.WaitAddress = CPU.PCAtOpcodeStart; + if (Memory.BlockIsRAM [block]) + CPU.WaitAddress = CPU.PCAtOpcodeStart; #endif #ifdef FAST_LSB_WORD_ACCESS - return (*(uint16 *) (GetAddress + (Address & 0xffff))); + return (*(uint16*)(GetAddress + (Address & 0xffff))); #else - return (*(GetAddress + (Address & 0xffff)) | - (*(GetAddress + (Address & 0xffff) + 1) << 8)); -#endif - } - - switch ((intptr_t) GetAddress) - { - case MAP_PPU: - return (S9xGetPPU (Address & 0xffff) | - (S9xGetPPU ((Address + 1) & 0xffff) << 8)); - case MAP_CPU: - return (S9xGetCPU (Address & 0xffff) | - (S9xGetCPU ((Address + 1) & 0xffff) << 8)); - case MAP_DSP: + return (*(GetAddress + (Address & 0xffff)) | + (*(GetAddress + (Address & 0xffff) + 1) << 8)); +#endif + } + + switch ((intptr_t) GetAddress) + { + case MAP_PPU: + return (S9xGetPPU(Address & 0xffff) | + (S9xGetPPU((Address + 1) & 0xffff) << 8)); + case MAP_CPU: + return (S9xGetCPU(Address & 0xffff) | + (S9xGetCPU((Address + 1) & 0xffff) << 8)); + case MAP_DSP: #ifdef DSP_DUMMY_LOOPS - printf("Get DSP Word @ %06X\n", Address); + printf("Get DSP Word @ %06X\n", Address); #endif - return (S9xGetDSP (Address & 0xffff) | - (S9xGetDSP ((Address + 1) & 0xffff) << 8)); - case MAP_SA1RAM: - case MAP_LOROM_SRAM: - //Address &0x7FFF -offset into bank - //Address&0xFF0000 -bank - //bank>>1 | offset = s-ram address, unbound - //unbound & SRAMMask = Sram offset - /* BJ: no FAST_LSB_WORD_ACCESS here, since if Memory.SRAMMask=0x7ff - * then the high byte doesn't follow the low byte. */ - return - (*(Memory.SRAM + ((((Address&0xFF0000)>>1) |(Address&0x7FFF)) &Memory.SRAMMask)))| - ((*(Memory.SRAM + (((((Address+1)&0xFF0000)>>1) |((Address+1)&0x7FFF)) &Memory.SRAMMask)))<<8); - - //return (*(uint16*)(Memory.SRAM + ((((Address&0xFF0000)>>1)|(Address&0x7FFF)) & Memory.SRAMMask));// | - // (*(Memory.SRAM + ((Address + 1) & Memory.SRAMMask)) << 8)); - - case MAP_RONLY_SRAM: - case MAP_HIROM_SRAM: - /* BJ: no FAST_LSB_WORD_ACCESS here, since if Memory.SRAMMask=0x7ff - * then the high byte doesn't follow the low byte. */ - return (*(Memory.SRAM + - (((Address & 0x7fff) - 0x6000 + - ((Address & 0xf0000) >> 3)) & Memory.SRAMMask)) | - (*(Memory.SRAM + - ((((Address + 1) & 0x7fff) - 0x6000 + - (((Address + 1) & 0xf0000) >> 3)) & Memory.SRAMMask)) << 8)); - - case MAP_BWRAM: + return (S9xGetDSP(Address & 0xffff) | + (S9xGetDSP((Address + 1) & 0xffff) << 8)); + case MAP_SA1RAM: + case MAP_LOROM_SRAM: + //Address &0x7FFF -offset into bank + //Address&0xFF0000 -bank + //bank>>1 | offset = s-ram address, unbound + //unbound & SRAMMask = Sram offset + /* BJ: no FAST_LSB_WORD_ACCESS here, since if Memory.SRAMMask=0x7ff + * then the high byte doesn't follow the low byte. */ + return + (*(Memory.SRAM + ((((Address & 0xFF0000) >> 1) | (Address & 0x7FFF)) + &Memory.SRAMMask))) | + ((*(Memory.SRAM + (((((Address + 1) & 0xFF0000) >> 1) | (( + Address + 1) & 0x7FFF)) &Memory.SRAMMask))) << 8); + + //return (*(uint16*)(Memory.SRAM + ((((Address&0xFF0000)>>1)|(Address&0x7FFF)) & Memory.SRAMMask));// | + // (*(Memory.SRAM + ((Address + 1) & Memory.SRAMMask)) << 8)); + + case MAP_RONLY_SRAM: + case MAP_HIROM_SRAM: + /* BJ: no FAST_LSB_WORD_ACCESS here, since if Memory.SRAMMask=0x7ff + * then the high byte doesn't follow the low byte. */ + return (*(Memory.SRAM + + (((Address & 0x7fff) - 0x6000 + + ((Address & 0xf0000) >> 3)) & Memory.SRAMMask)) | + (*(Memory.SRAM + + ((((Address + 1) & 0x7fff) - 0x6000 + + (((Address + 1) & 0xf0000) >> 3)) & Memory.SRAMMask)) << 8)); + + case MAP_BWRAM: #ifdef FAST_LSB_WORD_ACCESS - return (*(uint16 *) (Memory.BWRAM + ((Address & 0x7fff) - 0x6000))); + return (*(uint16*)(Memory.BWRAM + ((Address & 0x7fff) - 0x6000))); #else - return (*(Memory.BWRAM + ((Address & 0x7fff) - 0x6000)) | - (*(Memory.BWRAM + (((Address + 1) & 0x7fff) - 0x6000)) << 8)); + return (*(Memory.BWRAM + ((Address & 0x7fff) - 0x6000)) | + (*(Memory.BWRAM + (((Address + 1) & 0x7fff) - 0x6000)) << 8)); #endif - - case MAP_C4: - return (S9xGetC4 (Address & 0xffff) | - (S9xGetC4 ((Address + 1) & 0xffff) << 8)); - - case MAP_SPC7110_ROM: - return (S9xGetSPC7110Byte(Address)| - (S9xGetSPC7110Byte (Address+1))<<8); - case MAP_SPC7110_DRAM: - return (S9xGetSPC7110(0x4800)| - (S9xGetSPC7110 (0x4800) << 8)); - case MAP_OBC_RAM: - return GetOBC1(Address&0xFFFF)| (GetOBC1((Address+1)&0xFFFF)<<8); - - case MAP_SETA_DSP: - return S9xGetSetaDSP(Address)| (S9xGetSetaDSP((Address+1))<<8); - - case MAP_SETA_RISC: - return S9xGetST018(Address)| (S9xGetST018((Address+1))<<8); - - case MAP_DEBUG: - return (OpenBus | (OpenBus<<8)); - - default: - case MAP_NONE: + + case MAP_C4: + return (S9xGetC4(Address & 0xffff) | + (S9xGetC4((Address + 1) & 0xffff) << 8)); + + case MAP_SPC7110_ROM: + return (S9xGetSPC7110Byte(Address) | + (S9xGetSPC7110Byte(Address + 1)) << 8); + case MAP_SPC7110_DRAM: + return (S9xGetSPC7110(0x4800) | + (S9xGetSPC7110(0x4800) << 8)); + case MAP_OBC_RAM: + return GetOBC1(Address & 0xFFFF) | (GetOBC1((Address + 1) & 0xFFFF) << 8); + + case MAP_SETA_DSP: + return S9xGetSetaDSP(Address) | (S9xGetSetaDSP((Address + 1)) << 8); + + case MAP_SETA_RISC: + return S9xGetST018(Address) | (S9xGetST018((Address + 1)) << 8); + + case MAP_DEBUG: + return (OpenBus | (OpenBus << 8)); + + default: + case MAP_NONE: #ifdef MK_TRACE_BAD_READS - char address[20]; - sprintf(address, TEXT("%06X"),Address); - MessageBox(GUI.hWnd, address, TEXT("GetWord"), MB_OK); + char address[20]; + sprintf(address, TEXT("%06X"), Address); + MessageBox(GUI.hWnd, address, TEXT("GetWord"), MB_OK); #endif - return (OpenBus | (OpenBus<<8)); - } + return (OpenBus | (OpenBus << 8)); + } } -void S9xSetByte (uint8 Byte, uint32 Address) +void S9xSetByte(uint8 Byte, uint32 Address) { #if defined(CPU_SHUTDOWN) - CPU.WaitAddress = NULL; + CPU.WaitAddress = NULL; #endif - int block; - uint8 *SetAddress = Memory.WriteMap [block = ((Address >> MEMMAP_SHIFT) & MEMMAP_MASK)]; + int block; + uint8* SetAddress = Memory.WriteMap [block = ((Address >> MEMMAP_SHIFT) & + MEMMAP_MASK)]; + + if (!CPU.InDMA) + CPU.Cycles += Memory.MemorySpeed [block]; - if (!CPU.InDMA) - CPU.Cycles += Memory.MemorySpeed [block]; - - if (SetAddress >= (uint8 *) MAP_LAST) - { + if (SetAddress >= (uint8*) MAP_LAST) + { #ifdef CPU_SHUTDOWN - SetAddress += Address & 0xffff; - if (SetAddress == SA1.WaitByteAddress1 || - SetAddress == SA1.WaitByteAddress2) - { - SA1.Executing = SA1.S9xOpcodes != NULL; - SA1.WaitCounter = 0; - } - *SetAddress = Byte; + SetAddress += Address & 0xffff; + if (SetAddress == SA1.WaitByteAddress1 || + SetAddress == SA1.WaitByteAddress2) + { + SA1.Executing = SA1.S9xOpcodes != NULL; + SA1.WaitCounter = 0; + } + *SetAddress = Byte; #else - *(SetAddress + (Address & 0xffff)) = Byte; + *(SetAddress + (Address & 0xffff)) = Byte; #endif - return; - } - - switch ((intptr_t) SetAddress) - { - case MAP_PPU: - S9xSetPPU (Byte, Address & 0xffff); - return; - - case MAP_CPU: - S9xSetCPU (Byte, Address & 0xffff); - return; - - case MAP_DSP: + return; + } + + switch ((intptr_t) SetAddress) + { + case MAP_PPU: + S9xSetPPU(Byte, Address & 0xffff); + return; + + case MAP_CPU: + S9xSetCPU(Byte, Address & 0xffff); + return; + + case MAP_DSP: #ifdef DSP_DUMMY_LOOPS - printf("DSP Byte: %02X to %06X\n", Byte, Address); + printf("DSP Byte: %02X to %06X\n", Byte, Address); #endif - S9xSetDSP (Byte, Address & 0xffff); - return; - - case MAP_LOROM_SRAM: - if (Memory.SRAMMask) - { - *(Memory.SRAM + ((((Address&0xFF0000)>>1)|(Address&0x7FFF))& Memory.SRAMMask))=Byte; -// *(Memory.SRAM + (Address & Memory.SRAMMask)) = Byte; - CPU.SRAMModified = TRUE; - } - return; - - case MAP_HIROM_SRAM: - if (Memory.SRAMMask) - { - *(Memory.SRAM + (((Address & 0x7fff) - 0x6000 + - ((Address & 0xf0000) >> 3)) & Memory.SRAMMask)) = Byte; - CPU.SRAMModified = TRUE; - } - return; - - case MAP_BWRAM: - *(Memory.BWRAM + ((Address & 0x7fff) - 0x6000)) = Byte; - CPU.SRAMModified = TRUE; - return; - - case MAP_DEBUG: - - case MAP_SA1RAM: - *(Memory.SRAM + (Address & 0xffff)) = Byte; - SA1.Executing = !SA1.Waiting; - break; - - case MAP_C4: - S9xSetC4 (Byte, Address & 0xffff); - return; - - case MAP_SPC7110_DRAM: - s7r.bank50[(Address & 0xffff)]= (uint8) Byte; - break; - - case MAP_OBC_RAM: - SetOBC1(Byte, Address &0xFFFF); - return; - - case MAP_SETA_DSP: - S9xSetSetaDSP(Byte,Address); - return; - - case MAP_SETA_RISC: - S9xSetST018(Byte,Address); - return; - default: - case MAP_NONE: + S9xSetDSP(Byte, Address & 0xffff); + return; + + case MAP_LOROM_SRAM: + if (Memory.SRAMMask) + { + *(Memory.SRAM + ((((Address & 0xFF0000) >> 1) | (Address & 0x7FFF))& + Memory.SRAMMask)) = Byte; + // *(Memory.SRAM + (Address & Memory.SRAMMask)) = Byte; + CPU.SRAMModified = TRUE; + } + return; + + case MAP_HIROM_SRAM: + if (Memory.SRAMMask) + { + *(Memory.SRAM + (((Address & 0x7fff) - 0x6000 + + ((Address & 0xf0000) >> 3)) & Memory.SRAMMask)) = Byte; + CPU.SRAMModified = TRUE; + } + return; + + case MAP_BWRAM: + *(Memory.BWRAM + ((Address & 0x7fff) - 0x6000)) = Byte; + CPU.SRAMModified = TRUE; + return; + + case MAP_DEBUG: + + case MAP_SA1RAM: + *(Memory.SRAM + (Address & 0xffff)) = Byte; + SA1.Executing = !SA1.Waiting; + break; + + case MAP_C4: + S9xSetC4(Byte, Address & 0xffff); + return; + + case MAP_SPC7110_DRAM: + s7r.bank50[(Address & 0xffff)] = (uint8) Byte; + break; + + case MAP_OBC_RAM: + SetOBC1(Byte, Address & 0xFFFF); + return; + + case MAP_SETA_DSP: + S9xSetSetaDSP(Byte, Address); + return; + + case MAP_SETA_RISC: + S9xSetST018(Byte, Address); + return; + default: + case MAP_NONE: #ifdef MK_TRACE_BAD_WRITES - char address[20]; - sprintf(address, TEXT("%06X"),Address); - MessageBox(GUI.hWnd, address, TEXT("SetByte"), MB_OK); + char address[20]; + sprintf(address, TEXT("%06X"), Address); + MessageBox(GUI.hWnd, address, TEXT("SetByte"), MB_OK); #endif - return; - } + return; + } } -void S9xSetWord (uint16 Word, uint32 Address) +void S9xSetWord(uint16 Word, uint32 Address) { - if((Address & 0x0FFF)==0x0FFF) - { - S9xSetByte(Word&0x00FF, Address); - S9xSetByte(Word>>8, Address+1); - return; - } + if ((Address & 0x0FFF) == 0x0FFF) + { + S9xSetByte(Word & 0x00FF, Address); + S9xSetByte(Word >> 8, Address + 1); + return; + } #if defined(CPU_SHUTDOWN) - CPU.WaitAddress = NULL; + CPU.WaitAddress = NULL; #endif - int block; - uint8 *SetAddress = Memory.WriteMap [block = ((Address >> MEMMAP_SHIFT) & MEMMAP_MASK)]; + int block; + uint8* SetAddress = Memory.WriteMap [block = ((Address >> MEMMAP_SHIFT) & + MEMMAP_MASK)]; - if (!CPU.InDMA) - CPU.Cycles += Memory.MemorySpeed [block] << 1; + if (!CPU.InDMA) + CPU.Cycles += Memory.MemorySpeed [block] << 1; - if (SetAddress >= (uint8 *) MAP_LAST) - { + if (SetAddress >= (uint8*) MAP_LAST) + { #ifdef CPU_SHUTDOWN - SetAddress += Address & 0xffff; - if (SetAddress == SA1.WaitByteAddress1 || - SetAddress == SA1.WaitByteAddress2) - { - SA1.Executing = SA1.S9xOpcodes != NULL; - SA1.WaitCounter = 0; - } + SetAddress += Address & 0xffff; + if (SetAddress == SA1.WaitByteAddress1 || + SetAddress == SA1.WaitByteAddress2) + { + SA1.Executing = SA1.S9xOpcodes != NULL; + SA1.WaitCounter = 0; + } #ifdef FAST_LSB_WORD_ACCESS - *(uint16 *) SetAddress = Word; + *(uint16*) SetAddress = Word; #else - *SetAddress = (uint8) Word; - *(SetAddress + 1) = Word >> 8; + *SetAddress = (uint8) Word; + *(SetAddress + 1) = Word >> 8; #endif #else #ifdef FAST_LSB_WORD_ACCESS - *(uint16 *) (SetAddress + (Address & 0xffff)) = Word; + *(uint16*)(SetAddress + (Address & 0xffff)) = Word; #else - *(SetAddress + (Address & 0xffff)) = (uint8) Word; - *(SetAddress + ((Address + 1) & 0xffff)) = Word >> 8; + *(SetAddress + (Address & 0xffff)) = (uint8) Word; + *(SetAddress + ((Address + 1) & 0xffff)) = Word >> 8; #endif #endif - return; - } - - switch ((intptr_t) SetAddress) - { - case MAP_PPU: - S9xSetPPU ((uint8) Word, Address & 0xffff); - S9xSetPPU (Word >> 8, (Address & 0xffff) + 1); - return; - - case MAP_CPU: - S9xSetCPU ((uint8) Word, (Address & 0xffff)); - S9xSetCPU (Word >> 8, (Address & 0xffff) + 1); - return; - - case MAP_DSP: + return; + } + + switch ((intptr_t) SetAddress) + { + case MAP_PPU: + S9xSetPPU((uint8) Word, Address & 0xffff); + S9xSetPPU(Word >> 8, (Address & 0xffff) + 1); + return; + + case MAP_CPU: + S9xSetCPU((uint8) Word, (Address & 0xffff)); + S9xSetCPU(Word >> 8, (Address & 0xffff) + 1); + return; + + case MAP_DSP: #ifdef DSP_DUMMY_LOOPS - printf("DSP Word: %04X to %06X\n", Word, Address); + printf("DSP Word: %04X to %06X\n", Word, Address); #endif - S9xSetDSP ((uint8) Word, (Address & 0xffff)); - S9xSetDSP (Word >> 8, (Address & 0xffff) + 1); - return; - - case MAP_LOROM_SRAM: - if (Memory.SRAMMask) - { - /* BJ: no FAST_LSB_WORD_ACCESS here, since if Memory.SRAMMask=0x7ff - * then the high byte doesn't follow the low byte. */ - *(Memory.SRAM + ((((Address&0xFF0000)>>1)|(Address&0x7FFF))& Memory.SRAMMask)) = (uint8) Word; - *(Memory.SRAM + (((((Address+1)&0xFF0000)>>1)|((Address+1)&0x7FFF))& Memory.SRAMMask)) = Word >> 8; - -// *(Memory.SRAM + (Address & Memory.SRAMMask)) = (uint8) Word; -// *(Memory.SRAM + ((Address + 1) & Memory.SRAMMask)) = Word >> 8; - CPU.SRAMModified = TRUE; - } - return; - - case MAP_HIROM_SRAM: - if (Memory.SRAMMask) - { - /* BJ: no FAST_LSB_WORD_ACCESS here, since if Memory.SRAMMask=0x7ff - * then the high byte doesn't follow the low byte. */ - *(Memory.SRAM + - (((Address & 0x7fff) - 0x6000 + - ((Address & 0xf0000) >> 3) & Memory.SRAMMask))) = (uint8) Word; - *(Memory.SRAM + - ((((Address + 1) & 0x7fff) - 0x6000 + - (((Address + 1) & 0xf0000) >> 3) & Memory.SRAMMask))) = (uint8) (Word >> 8); - CPU.SRAMModified = TRUE; - } - return; - - case MAP_BWRAM: + S9xSetDSP((uint8) Word, (Address & 0xffff)); + S9xSetDSP(Word >> 8, (Address & 0xffff) + 1); + return; + + case MAP_LOROM_SRAM: + if (Memory.SRAMMask) + { + /* BJ: no FAST_LSB_WORD_ACCESS here, since if Memory.SRAMMask=0x7ff + * then the high byte doesn't follow the low byte. */ + *(Memory.SRAM + ((((Address & 0xFF0000) >> 1) | (Address & 0x7FFF))& + Memory.SRAMMask)) = (uint8) Word; + *(Memory.SRAM + (((((Address + 1) & 0xFF0000) >> 1) | (( + Address + 1) & 0x7FFF))& Memory.SRAMMask)) = Word >> 8; + + // *(Memory.SRAM + (Address & Memory.SRAMMask)) = (uint8) Word; + // *(Memory.SRAM + ((Address + 1) & Memory.SRAMMask)) = Word >> 8; + CPU.SRAMModified = TRUE; + } + return; + + case MAP_HIROM_SRAM: + if (Memory.SRAMMask) + { + /* BJ: no FAST_LSB_WORD_ACCESS here, since if Memory.SRAMMask=0x7ff + * then the high byte doesn't follow the low byte. */ + *(Memory.SRAM + + (((Address & 0x7fff) - 0x6000 + + ((Address & 0xf0000) >> 3) & Memory.SRAMMask))) = (uint8) Word; + *(Memory.SRAM + + ((((Address + 1) & 0x7fff) - 0x6000 + + (((Address + 1) & 0xf0000) >> 3) & Memory.SRAMMask))) = (uint8)(Word >> 8); + CPU.SRAMModified = TRUE; + } + return; + + case MAP_BWRAM: #ifdef FAST_LSB_WORD_ACCESS - *(uint16 *) (Memory.BWRAM + ((Address & 0x7fff) - 0x6000)) = Word; + *(uint16*)(Memory.BWRAM + ((Address & 0x7fff) - 0x6000)) = Word; #else - *(Memory.BWRAM + ((Address & 0x7fff) - 0x6000)) = (uint8) Word; - *(Memory.BWRAM + (((Address + 1) & 0x7fff) - 0x6000)) = (uint8) (Word >> 8); + *(Memory.BWRAM + ((Address & 0x7fff) - 0x6000)) = (uint8) Word; + *(Memory.BWRAM + (((Address + 1) & 0x7fff) - 0x6000)) = (uint8)(Word >> 8); #endif - CPU.SRAMModified = TRUE; - return; - - case MAP_DEBUG: - - case MAP_SPC7110_DRAM: - s7r.bank50[(Address & 0xffff)]= (uint8) Word; - s7r.bank50[((Address + 1) & 0xffff)]= (uint8) Word; - break; - case MAP_SA1RAM: - *(Memory.SRAM + (Address & 0xffff)) = (uint8) Word; - *(Memory.SRAM + ((Address + 1) & 0xffff)) = (uint8) (Word >> 8); - SA1.Executing = !SA1.Waiting; - break; - - case MAP_C4: - S9xSetC4 (Word & 0xff, Address & 0xffff); - S9xSetC4 ((uint8) (Word >> 8), (Address + 1) & 0xffff); - return; - - case MAP_OBC_RAM: - SetOBC1(Word & 0xff, Address &0xFFFF); - SetOBC1 ((uint8) (Word >> 8), (Address + 1) & 0xffff); - return; - - case MAP_SETA_DSP: - S9xSetSetaDSP (Word & 0xff, Address); - S9xSetSetaDSP ((uint8) (Word >> 8),(Address + 1)); - return; - - case MAP_SETA_RISC: - S9xSetST018 (Word & 0xff, Address); - S9xSetST018 ((uint8) (Word >> 8),(Address + 1)); - return; - - default: - case MAP_NONE: + CPU.SRAMModified = TRUE; + return; + + case MAP_DEBUG: + + case MAP_SPC7110_DRAM: + s7r.bank50[(Address & 0xffff)] = (uint8) Word; + s7r.bank50[((Address + 1) & 0xffff)] = (uint8) Word; + break; + case MAP_SA1RAM: + *(Memory.SRAM + (Address & 0xffff)) = (uint8) Word; + *(Memory.SRAM + ((Address + 1) & 0xffff)) = (uint8)(Word >> 8); + SA1.Executing = !SA1.Waiting; + break; + + case MAP_C4: + S9xSetC4(Word & 0xff, Address & 0xffff); + S9xSetC4((uint8)(Word >> 8), (Address + 1) & 0xffff); + return; + + case MAP_OBC_RAM: + SetOBC1(Word & 0xff, Address & 0xFFFF); + SetOBC1((uint8)(Word >> 8), (Address + 1) & 0xffff); + return; + + case MAP_SETA_DSP: + S9xSetSetaDSP(Word & 0xff, Address); + S9xSetSetaDSP((uint8)(Word >> 8), (Address + 1)); + return; + + case MAP_SETA_RISC: + S9xSetST018(Word & 0xff, Address); + S9xSetST018((uint8)(Word >> 8), (Address + 1)); + return; + + default: + case MAP_NONE: #ifdef MK_TRACE_BAD_WRITES - char address[20]; - sprintf(address, TEXT("%06X"),Address); - MessageBox(GUI.hWnd, address, TEXT("SetWord"), MB_OK); + char address[20]; + sprintf(address, TEXT("%06X"), Address); + MessageBox(GUI.hWnd, address, TEXT("SetWord"), MB_OK); #endif - return; - } + return; + } } -uint8 *GetBasePointer (uint32 Address) +uint8* GetBasePointer(uint32 Address) { - uint8 *GetAddress = Memory.Map [(Address >> MEMMAP_SHIFT) & MEMMAP_MASK]; - if (GetAddress >= (uint8 *) MAP_LAST) - return (GetAddress); - if(Settings.SPC7110&&((Address&0x7FFFFF)==0x4800)) - { - return s7r.bank50; - } - switch ((intptr_t) GetAddress) - { - case MAP_SPC7110_DRAM: - { - return s7r.bank50; - } - case MAP_SPC7110_ROM: - return Get7110BasePtr(Address); - case MAP_PPU: -//just a guess, but it looks like this should match the CPU as a source. - return (Memory.FillRAM); -// return (Memory.FillRAM - 0x2000); - case MAP_CPU: -//fixes Ogre Battle's green lines - return (Memory.FillRAM); -// return (Memory.FillRAM - 0x4000); - case MAP_DSP: - return (Memory.FillRAM - 0x6000); - case MAP_SA1RAM: - case MAP_LOROM_SRAM: - return (Memory.SRAM); - case MAP_BWRAM: - return (Memory.BWRAM - 0x6000); - case MAP_HIROM_SRAM: - return (Memory.SRAM - 0x6000); - case MAP_C4: - return (Memory.C4RAM - 0x6000); - case MAP_OBC_RAM: - return GetBasePointerOBC1(Address); - case MAP_SETA_DSP: - return Memory.SRAM; - case MAP_DEBUG: - - default: - case MAP_NONE: + uint8* GetAddress = Memory.Map [(Address >> MEMMAP_SHIFT) & MEMMAP_MASK]; + if (GetAddress >= (uint8*) MAP_LAST) + return (GetAddress); + if (Settings.SPC7110 && ((Address & 0x7FFFFF) == 0x4800)) + return s7r.bank50; + switch ((intptr_t) GetAddress) + { + case MAP_SPC7110_DRAM: + { + return s7r.bank50; + } + case MAP_SPC7110_ROM: + return Get7110BasePtr(Address); + case MAP_PPU: + //just a guess, but it looks like this should match the CPU as a source. + return (Memory.FillRAM); + // return (Memory.FillRAM - 0x2000); + case MAP_CPU: + //fixes Ogre Battle's green lines + return (Memory.FillRAM); + // return (Memory.FillRAM - 0x4000); + case MAP_DSP: + return (Memory.FillRAM - 0x6000); + case MAP_SA1RAM: + case MAP_LOROM_SRAM: + return (Memory.SRAM); + case MAP_BWRAM: + return (Memory.BWRAM - 0x6000); + case MAP_HIROM_SRAM: + return (Memory.SRAM - 0x6000); + case MAP_C4: + return (Memory.C4RAM - 0x6000); + case MAP_OBC_RAM: + return GetBasePointerOBC1(Address); + case MAP_SETA_DSP: + return Memory.SRAM; + case MAP_DEBUG: + + default: + case MAP_NONE: #if defined(MK_TRACE_BAD_READS) || defined(MK_TRACE_BAD_WRITES) - char fsd[12]; - sprintf(fsd, TEXT("%06X"), Address); - MessageBox(GUI.hWnd, fsd, TEXT("Rogue DMA"), MB_OK); + char fsd[12]; + sprintf(fsd, TEXT("%06X"), Address); + MessageBox(GUI.hWnd, fsd, TEXT("Rogue DMA"), MB_OK); #endif - return (0); - } + return (0); + } } -uint8 *S9xGetMemPointer (uint32 Address) +uint8* S9xGetMemPointer(uint32 Address) { - uint8 *GetAddress = Memory.Map [(Address >> MEMMAP_SHIFT) & MEMMAP_MASK]; - if (GetAddress >= (uint8 *) MAP_LAST) - return (GetAddress + (Address & 0xffff)); - - if(Settings.SPC7110&&((Address&0x7FFFFF)==0x4800)) - return s7r.bank50; - - switch ((intptr_t) GetAddress) - { - case MAP_SPC7110_DRAM: - return &s7r.bank50[Address&0x0000FFFF]; - case MAP_PPU: - return (Memory.FillRAM + (Address & 0xffff)); - case MAP_CPU: - return (Memory.FillRAM + (Address & 0xffff)); - case MAP_DSP: - return (Memory.FillRAM - 0x6000 + (Address & 0xffff)); - case MAP_SA1RAM: - case MAP_LOROM_SRAM: - return (Memory.SRAM + (Address & 0xffff)); - case MAP_BWRAM: - return (Memory.BWRAM - 0x6000 + (Address & 0xffff)); - case MAP_HIROM_SRAM: - return (Memory.SRAM - 0x6000 + (Address & 0xffff)); - case MAP_C4: - return (Memory.C4RAM - 0x6000 + (Address & 0xffff)); - case MAP_OBC_RAM: - return GetMemPointerOBC1(Address); - case MAP_SETA_DSP: - return Memory.SRAM+ ((Address & 0xffff) & Memory.SRAMMask); - case MAP_DEBUG: - default: - case MAP_NONE: + uint8* GetAddress = Memory.Map [(Address >> MEMMAP_SHIFT) & MEMMAP_MASK]; + if (GetAddress >= (uint8*) MAP_LAST) + return (GetAddress + (Address & 0xffff)); + + if (Settings.SPC7110 && ((Address & 0x7FFFFF) == 0x4800)) + return s7r.bank50; + + switch ((intptr_t) GetAddress) + { + case MAP_SPC7110_DRAM: + return &s7r.bank50[Address & 0x0000FFFF]; + case MAP_PPU: + return (Memory.FillRAM + (Address & 0xffff)); + case MAP_CPU: + return (Memory.FillRAM + (Address & 0xffff)); + case MAP_DSP: + return (Memory.FillRAM - 0x6000 + (Address & 0xffff)); + case MAP_SA1RAM: + case MAP_LOROM_SRAM: + return (Memory.SRAM + (Address & 0xffff)); + case MAP_BWRAM: + return (Memory.BWRAM - 0x6000 + (Address & 0xffff)); + case MAP_HIROM_SRAM: + return (Memory.SRAM - 0x6000 + (Address & 0xffff)); + case MAP_C4: + return (Memory.C4RAM - 0x6000 + (Address & 0xffff)); + case MAP_OBC_RAM: + return GetMemPointerOBC1(Address); + case MAP_SETA_DSP: + return Memory.SRAM + ((Address & 0xffff) & Memory.SRAMMask); + case MAP_DEBUG: + default: + case MAP_NONE: #if defined(MK_TRACE_BAD_READS) || defined(MK_TRACE_BAD_WRITES) - char fsd[12]; - sprintf(fsd, TEXT("%06X"), Address); - MessageBox(GUI.hWnd, fsd, TEXT("Rogue DMA"), MB_OK); + char fsd[12]; + sprintf(fsd, TEXT("%06X"), Address); + MessageBox(GUI.hWnd, fsd, TEXT("Rogue DMA"), MB_OK); #endif - return (0); - } + return (0); + } } -void S9xSetPCBase (uint32 Address) +void S9xSetPCBase(uint32 Address) { - int block; - uint8 *GetAddress = Memory.Map [block = (Address >> MEMMAP_SHIFT) & MEMMAP_MASK]; - - CPU.MemSpeed = Memory.MemorySpeed [block]; - CPU.MemSpeedx2 = CPU.MemSpeed << 1; - - if (GetAddress >= (uint8 *) MAP_LAST) - { - CPU.PCBase = GetAddress; - CPU.PC = GetAddress + (Address & 0xffff); - return; - } - - switch ((intptr_t) GetAddress) - { - case MAP_PPU: - CPU.PCBase = Memory.FillRAM; - CPU.PC = CPU.PCBase + (Address & 0xffff); - return; - - case MAP_CPU: - CPU.PCBase = Memory.FillRAM; - CPU.PC = CPU.PCBase + (Address & 0xffff); - return; - - case MAP_DSP: - CPU.PCBase = Memory.FillRAM - 0x6000; - CPU.PC = CPU.PCBase + (Address & 0xffff); - return; - - case MAP_SA1RAM: - case MAP_LOROM_SRAM: - CPU.PCBase = Memory.SRAM; - CPU.PC = CPU.PCBase + (Address & 0xffff); - return; - - case MAP_BWRAM: - CPU.PCBase = Memory.BWRAM - 0x6000; - CPU.PC = CPU.PCBase + (Address & 0xffff); - return; - case MAP_HIROM_SRAM: - CPU.PCBase = Memory.SRAM - 0x6000; - CPU.PC = CPU.PCBase + (Address & 0xffff); - return; - - case MAP_C4: - CPU.PCBase = Memory.C4RAM - 0x6000; - CPU.PC = CPU.PCBase + (Address & 0xffff); - return; - - case MAP_DEBUG: - - default: - case MAP_NONE: - CPU.PCBase = Memory.SRAM; - CPU.PC = Memory.SRAM + (Address & 0xffff); - return; - } + int block; + uint8* GetAddress = Memory.Map [block = (Address >> MEMMAP_SHIFT) & + MEMMAP_MASK]; + + CPU.MemSpeed = Memory.MemorySpeed [block]; + CPU.MemSpeedx2 = CPU.MemSpeed << 1; + + if (GetAddress >= (uint8*) MAP_LAST) + { + CPU.PCBase = GetAddress; + CPU.PC = GetAddress + (Address & 0xffff); + return; + } + + switch ((intptr_t) GetAddress) + { + case MAP_PPU: + CPU.PCBase = Memory.FillRAM; + CPU.PC = CPU.PCBase + (Address & 0xffff); + return; + + case MAP_CPU: + CPU.PCBase = Memory.FillRAM; + CPU.PC = CPU.PCBase + (Address & 0xffff); + return; + + case MAP_DSP: + CPU.PCBase = Memory.FillRAM - 0x6000; + CPU.PC = CPU.PCBase + (Address & 0xffff); + return; + + case MAP_SA1RAM: + case MAP_LOROM_SRAM: + CPU.PCBase = Memory.SRAM; + CPU.PC = CPU.PCBase + (Address & 0xffff); + return; + + case MAP_BWRAM: + CPU.PCBase = Memory.BWRAM - 0x6000; + CPU.PC = CPU.PCBase + (Address & 0xffff); + return; + case MAP_HIROM_SRAM: + CPU.PCBase = Memory.SRAM - 0x6000; + CPU.PC = CPU.PCBase + (Address & 0xffff); + return; + + case MAP_C4: + CPU.PCBase = Memory.C4RAM - 0x6000; + CPU.PC = CPU.PCBase + (Address & 0xffff); + return; + + case MAP_DEBUG: + + default: + case MAP_NONE: + CPU.PCBase = Memory.SRAM; + CPU.PC = Memory.SRAM + (Address & 0xffff); + return; + } } #endif diff --git a/source/gfx.c b/source/gfx.c index 73c53ea..c2cca59 100644 --- a/source/gfx.c +++ b/source/gfx.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -102,9 +102,9 @@ #define M8 19 void output_png(); -void ComputeClipWindows (); -static void S9xDisplayFrameRate (); -static void S9xDisplayString (const char *string); +void ComputeClipWindows(); +static void S9xDisplayFrameRate(); +static void S9xDisplayString(const char* string); extern uint8 BitShifts[8][4]; extern uint8 TileShifts[8][4]; @@ -127,7 +127,7 @@ extern struct SLineMatrixData LineMatrixData [240]; extern uint8 Mode7Depths [2]; #define CLIP_10_BIT_SIGNED(a) \ - ((a) & ((1 << 10) - 1)) + (((((a) & (1 << 13)) ^ (1 << 13)) - (1 << 13)) >> 3) + ((a) & ((1 << 10) - 1)) + (((((a) & (1 << 13)) ^ (1 << 13)) - (1 << 13)) >> 3) #define ON_MAIN(N) \ (GFX.r212c & (1 << (N)) && \ @@ -170,2341 +170,2413 @@ extern uint8 Mode7Depths [2]; #define BLACK BUILD_PIXEL(0,0,0) -void DrawTile16 (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount); -void DrawClippedTile16 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount); -void DrawTile16HalfWidth (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount); -void DrawClippedTile16HalfWidth (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount); -void DrawTile16x2 (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount); -void DrawClippedTile16x2 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount); -void DrawTile16x2x2 (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount); -void DrawClippedTile16x2x2 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount); -void DrawLargePixel16 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Pixels, - uint32 StartLine, uint32 LineCount); -void DrawLargePixel16HalfWidth (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Pixels, - uint32 StartLine, uint32 LineCount); - -void DrawTile16Add (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount); - -void DrawClippedTile16Add (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount); - -void DrawTile16Add1_2 (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount); - -void DrawClippedTile16Add1_2 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount); - -void DrawTile16FixedAdd1_2 (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount); - -void DrawClippedTile16FixedAdd1_2 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount); - -void DrawTile16Sub (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount); - -void DrawClippedTile16Sub (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount); - -void DrawTile16Sub1_2 (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount); - -void DrawClippedTile16Sub1_2 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount); - -void DrawTile16FixedSub1_2 (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount); - -void DrawClippedTile16FixedSub1_2 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount); - -void DrawLargePixel16Add (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Pixels, - uint32 StartLine, uint32 LineCount); - -void DrawLargePixel16Add1_2 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Pixels, - uint32 StartLine, uint32 LineCount); - -void DrawLargePixel16Sub (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Pixels, - uint32 StartLine, uint32 LineCount); - -void DrawLargePixel16Sub1_2 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Pixels, - uint32 StartLine, uint32 LineCount); - -bool8 S9xGraphicsInit () +void DrawTile16(uint32 Tile, int32 Offset, uint32 StartLine, + uint32 LineCount); +void DrawClippedTile16(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount); +void DrawTile16HalfWidth(uint32 Tile, int32 Offset, uint32 StartLine, + uint32 LineCount); +void DrawClippedTile16HalfWidth(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount); +void DrawTile16x2(uint32 Tile, int32 Offset, uint32 StartLine, + uint32 LineCount); +void DrawClippedTile16x2(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount); +void DrawTile16x2x2(uint32 Tile, int32 Offset, uint32 StartLine, + uint32 LineCount); +void DrawClippedTile16x2x2(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount); +void DrawLargePixel16(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount); +void DrawLargePixel16HalfWidth(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount); + +void DrawTile16Add(uint32 Tile, int32 Offset, uint32 StartLine, + uint32 LineCount); + +void DrawClippedTile16Add(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount); + +void DrawTile16Add1_2(uint32 Tile, int32 Offset, uint32 StartLine, + uint32 LineCount); + +void DrawClippedTile16Add1_2(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount); + +void DrawTile16FixedAdd1_2(uint32 Tile, int32 Offset, uint32 StartLine, + uint32 LineCount); + +void DrawClippedTile16FixedAdd1_2(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount); + +void DrawTile16Sub(uint32 Tile, int32 Offset, uint32 StartLine, + uint32 LineCount); + +void DrawClippedTile16Sub(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount); + +void DrawTile16Sub1_2(uint32 Tile, int32 Offset, uint32 StartLine, + uint32 LineCount); + +void DrawClippedTile16Sub1_2(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount); + +void DrawTile16FixedSub1_2(uint32 Tile, int32 Offset, uint32 StartLine, + uint32 LineCount); + +void DrawClippedTile16FixedSub1_2(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount); + +void DrawLargePixel16Add(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount); + +void DrawLargePixel16Add1_2(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount); + +void DrawLargePixel16Sub(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount); + +void DrawLargePixel16Sub1_2(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount); + +bool8 S9xGraphicsInit() { - register uint32 PixelOdd = 1; - register uint32 PixelEven = 2; - - uint8 bitshift; - for (bitshift = 0; bitshift < 4; bitshift++) - { - register int i; - for (i = 0; i < 16; i++) - { - register uint32 h = 0; - register uint32 l = 0; + register uint32 PixelOdd = 1; + register uint32 PixelEven = 2; + + uint8 bitshift; + for (bitshift = 0; bitshift < 4; bitshift++) + { + register int i; + for (i = 0; i < 16; i++) + { + register uint32 h = 0; + register uint32 l = 0; #if defined(LSB_FIRST) - if (i & 8) - h |= PixelOdd; - if (i & 4) - h |= PixelOdd << 8; - if (i & 2) - h |= PixelOdd << 16; - if (i & 1) - h |= PixelOdd << 24; - if (i & 8) - l |= PixelOdd; - if (i & 4) - l |= PixelOdd << 8; - if (i & 2) - l |= PixelOdd << 16; - if (i & 1) - l |= PixelOdd << 24; + if (i & 8) + h |= PixelOdd; + if (i & 4) + h |= PixelOdd << 8; + if (i & 2) + h |= PixelOdd << 16; + if (i & 1) + h |= PixelOdd << 24; + if (i & 8) + l |= PixelOdd; + if (i & 4) + l |= PixelOdd << 8; + if (i & 2) + l |= PixelOdd << 16; + if (i & 1) + l |= PixelOdd << 24; #else - if (i & 8) - h |= (PixelOdd << 24); - if (i & 4) - h |= (PixelOdd << 16); - if (i & 2) - h |= (PixelOdd << 8); - if (i & 1) - h |= PixelOdd; - if (i & 8) - l |= (PixelOdd << 24); - if (i & 4) - l |= (PixelOdd << 16); - if (i & 2) - l |= (PixelOdd << 8); - if (i & 1) - l |= PixelOdd; + if (i & 8) + h |= (PixelOdd << 24); + if (i & 4) + h |= (PixelOdd << 16); + if (i & 2) + h |= (PixelOdd << 8); + if (i & 1) + h |= PixelOdd; + if (i & 8) + l |= (PixelOdd << 24); + if (i & 4) + l |= (PixelOdd << 16); + if (i & 2) + l |= (PixelOdd << 8); + if (i & 1) + l |= PixelOdd; #endif - odd_high[bitshift][i] = h; - odd_low[bitshift][i] = l; - h = l = 0; + odd_high[bitshift][i] = h; + odd_low[bitshift][i] = l; + h = l = 0; #if defined(LSB_FIRST) - if (i & 8) - h |= PixelEven; - if (i & 4) - h |= PixelEven << 8; - if (i & 2) - h |= PixelEven << 16; - if (i & 1) - h |= PixelEven << 24; - if (i & 8) - l |= PixelEven; - if (i & 4) - l |= PixelEven << 8; - if (i & 2) - l |= PixelEven << 16; - if (i & 1) - l |= PixelEven << 24; + if (i & 8) + h |= PixelEven; + if (i & 4) + h |= PixelEven << 8; + if (i & 2) + h |= PixelEven << 16; + if (i & 1) + h |= PixelEven << 24; + if (i & 8) + l |= PixelEven; + if (i & 4) + l |= PixelEven << 8; + if (i & 2) + l |= PixelEven << 16; + if (i & 1) + l |= PixelEven << 24; #else - if (i & 8) - h |= (PixelEven << 24); - if (i & 4) - h |= (PixelEven << 16); - if (i & 2) - h |= (PixelEven << 8); - if (i & 1) - h |= PixelEven; - if (i & 8) - l |= (PixelEven << 24); - if (i & 4) - l |= (PixelEven << 16); - if (i & 2) - l |= (PixelEven << 8); - if (i & 1) - l |= PixelEven; + if (i & 8) + h |= (PixelEven << 24); + if (i & 4) + h |= (PixelEven << 16); + if (i & 2) + h |= (PixelEven << 8); + if (i & 1) + h |= PixelEven; + if (i & 8) + l |= (PixelEven << 24); + if (i & 4) + l |= (PixelEven << 16); + if (i & 2) + l |= (PixelEven << 8); + if (i & 1) + l |= PixelEven; #endif - even_high[bitshift][i] = h; - even_low[bitshift][i] = l; - } - PixelEven <<= 2; - PixelOdd <<= 2; - } + even_high[bitshift][i] = h; + even_low[bitshift][i] = l; + } + PixelEven <<= 2; + PixelOdd <<= 2; + } - GFX.RealPitch = GFX.Pitch2 = GFX.Pitch; - GFX.ZPitch = GFX.Pitch; - GFX.ZPitch >>= 1; - GFX.Delta = (GFX.SubScreen - GFX.Screen) >> 1; - GFX.DepthDelta = GFX.SubZBuffer - GFX.ZBuffer; - //GFX.InfoStringTimeout = 0; - //GFX.InfoString = NULL; - - PPU.BG_Forced = 0; - IPPU.OBJChanged = TRUE; - - IPPU.DirectColourMapsNeedRebuild = TRUE; - GFX.PixSize = 1; - DrawTilePtr = DrawTile16; - DrawClippedTilePtr = DrawClippedTile16; - DrawLargePixelPtr = DrawLargePixel16; - if (Settings.SupportHiRes) - { - DrawHiResTilePtr= DrawTile16; - DrawHiResClippedTilePtr = DrawClippedTile16; - } - else - { - DrawHiResTilePtr= DrawTile16HalfWidth; - DrawHiResClippedTilePtr = DrawClippedTile16HalfWidth; - } - GFX.PPL = GFX.Pitch >> 1; - GFX.PPLx2 = GFX.Pitch; - S9xFixColourBrightness (); - - if (!(GFX.X2 = (uint16 *) malloc (sizeof (uint16) * 0x10000))) - return (FALSE); - - if (!(GFX.ZERO_OR_X2 = (uint16 *) malloc (sizeof (uint16) * 0x10000)) || - !(GFX.ZERO = (uint16 *) malloc (sizeof (uint16) * 0x10000))) - { - if (GFX.ZERO_OR_X2) - { - free ((char *) GFX.ZERO_OR_X2); - GFX.ZERO_OR_X2 = NULL; - } - if (GFX.X2) - { - free ((char *) GFX.X2); - GFX.X2 = NULL; - } - return (FALSE); - } - uint32 r, g, b; - - // Build a lookup table that multiplies a packed RGB value by 2 with - // saturation. - for (r = 0; r <= MAX_RED; r++) - { - uint32 r2 = r << 1; - if (r2 > MAX_RED) - r2 = MAX_RED; - for (g = 0; g <= MAX_GREEN; g++) - { - uint32 g2 = g << 1; - if (g2 > MAX_GREEN) - g2 = MAX_GREEN; - for (b = 0; b <= MAX_BLUE; b++) - { - uint32 b2 = b << 1; - if (b2 > MAX_BLUE) - b2 = MAX_BLUE; - GFX.X2 [BUILD_PIXEL2 (r, g, b)] = BUILD_PIXEL2 (r2, g2, b2); - GFX.X2 [BUILD_PIXEL2 (r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2 (r2, g2, b2); - } - } - } - ZeroMemory (GFX.ZERO, 0x10000 * sizeof (uint16)); - ZeroMemory (GFX.ZERO_OR_X2, 0x10000 * sizeof (uint16)); - // Build a lookup table that if the top bit of the color value is zero - // then the value is zero, otherwise multiply the value by 2. Used by - // the color subtraction code. + GFX.RealPitch = GFX.Pitch2 = GFX.Pitch; + GFX.ZPitch = GFX.Pitch; + GFX.ZPitch >>= 1; + GFX.Delta = (GFX.SubScreen - GFX.Screen) >> 1; + GFX.DepthDelta = GFX.SubZBuffer - GFX.ZBuffer; + //GFX.InfoStringTimeout = 0; + //GFX.InfoString = NULL; + + PPU.BG_Forced = 0; + IPPU.OBJChanged = TRUE; + + IPPU.DirectColourMapsNeedRebuild = TRUE; + GFX.PixSize = 1; + DrawTilePtr = DrawTile16; + DrawClippedTilePtr = DrawClippedTile16; + DrawLargePixelPtr = DrawLargePixel16; + if (Settings.SupportHiRes) + { + DrawHiResTilePtr = DrawTile16; + DrawHiResClippedTilePtr = DrawClippedTile16; + } + else + { + DrawHiResTilePtr = DrawTile16HalfWidth; + DrawHiResClippedTilePtr = DrawClippedTile16HalfWidth; + } + GFX.PPL = GFX.Pitch >> 1; + GFX.PPLx2 = GFX.Pitch; + S9xFixColourBrightness(); + + if (!(GFX.X2 = (uint16*) malloc(sizeof(uint16) * 0x10000))) + return (FALSE); + + if (!(GFX.ZERO_OR_X2 = (uint16*) malloc(sizeof(uint16) * 0x10000)) || + !(GFX.ZERO = (uint16*) malloc(sizeof(uint16) * 0x10000))) + { + if (GFX.ZERO_OR_X2) + { + free((char*) GFX.ZERO_OR_X2); + GFX.ZERO_OR_X2 = NULL; + } + if (GFX.X2) + { + free((char*) GFX.X2); + GFX.X2 = NULL; + } + return (FALSE); + } + uint32 r, g, b; + + // Build a lookup table that multiplies a packed RGB value by 2 with + // saturation. + for (r = 0; r <= MAX_RED; r++) + { + uint32 r2 = r << 1; + if (r2 > MAX_RED) + r2 = MAX_RED; + for (g = 0; g <= MAX_GREEN; g++) + { + uint32 g2 = g << 1; + if (g2 > MAX_GREEN) + g2 = MAX_GREEN; + for (b = 0; b <= MAX_BLUE; b++) + { + uint32 b2 = b << 1; + if (b2 > MAX_BLUE) + b2 = MAX_BLUE; + GFX.X2 [BUILD_PIXEL2(r, g, b)] = BUILD_PIXEL2(r2, g2, b2); + GFX.X2 [BUILD_PIXEL2(r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2(r2, g2, b2); + } + } + } + ZeroMemory(GFX.ZERO, 0x10000 * sizeof(uint16)); + ZeroMemory(GFX.ZERO_OR_X2, 0x10000 * sizeof(uint16)); + // Build a lookup table that if the top bit of the color value is zero + // then the value is zero, otherwise multiply the value by 2. Used by + // the color subtraction code. #if defined(OLD_COLOUR_BLENDING) - for (r = 0; r <= MAX_RED; r++) - { - uint32 r2 = r; - if ((r2 & 0x10) == 0) - r2 = 0; - else - r2 = (r2 << 1) & MAX_RED; - - for (g = 0; g <= MAX_GREEN; g++) - { - uint32 g2 = g; - if ((g2 & GREEN_HI_BIT) == 0) - g2 = 0; - else - g2 = (g2 << 1) & MAX_GREEN; - - for (b = 0; b <= MAX_BLUE; b++) - { - uint32 b2 = b; - if ((b2 & 0x10) == 0) - b2 = 0; - else - b2 = (b2 << 1) & MAX_BLUE; - - GFX.ZERO_OR_X2 [BUILD_PIXEL2 (r, g, b)] = BUILD_PIXEL2 (r2, g2, b2); - GFX.ZERO_OR_X2 [BUILD_PIXEL2 (r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2 (r2, g2, b2); - } - } - } + for (r = 0; r <= MAX_RED; r++) + { + uint32 r2 = r; + if ((r2 & 0x10) == 0) + r2 = 0; + else + r2 = (r2 << 1) & MAX_RED; + + for (g = 0; g <= MAX_GREEN; g++) + { + uint32 g2 = g; + if ((g2 & GREEN_HI_BIT) == 0) + g2 = 0; + else + g2 = (g2 << 1) & MAX_GREEN; + + for (b = 0; b <= MAX_BLUE; b++) + { + uint32 b2 = b; + if ((b2 & 0x10) == 0) + b2 = 0; + else + b2 = (b2 << 1) & MAX_BLUE; + + GFX.ZERO_OR_X2 [BUILD_PIXEL2(r, g, b)] = BUILD_PIXEL2(r2, g2, b2); + GFX.ZERO_OR_X2 [BUILD_PIXEL2(r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2(r2, g2, + b2); + } + } + } #else - for (r = 0; r <= MAX_RED; r++) - { - uint32 r2 = r; - if ((r2 & 0x10) == 0) - r2 = 0; + for (r = 0; r <= MAX_RED; r++) + { + uint32 r2 = r; + if ((r2 & 0x10) == 0) + r2 = 0; + else + r2 = (r2 << 1) & MAX_RED; + + if (r2 == 0) + r2 = 1; + for (g = 0; g <= MAX_GREEN; g++) + { + uint32 g2 = g; + if ((g2 & GREEN_HI_BIT) == 0) + g2 = 0; + else + g2 = (g2 << 1) & MAX_GREEN; + + if (g2 == 0) + g2 = 1; + for (b = 0; b <= MAX_BLUE; b++) + { + uint32 b2 = b; + if ((b2 & 0x10) == 0) + b2 = 0; else - r2 = (r2 << 1) & MAX_RED; + b2 = (b2 << 1) & MAX_BLUE; - if (r2 == 0) - r2 = 1; - for (g = 0; g <= MAX_GREEN; g++) - { - uint32 g2 = g; - if ((g2 & GREEN_HI_BIT) == 0) - g2 = 0; - else - g2 = (g2 << 1) & MAX_GREEN; - - if (g2 == 0) - g2 = 1; - for (b = 0; b <= MAX_BLUE; b++) - { - uint32 b2 = b; - if ((b2 & 0x10) == 0) - b2 = 0; - else - b2 = (b2 << 1) & MAX_BLUE; - - if (b2 == 0) - b2 = 1; - GFX.ZERO_OR_X2 [BUILD_PIXEL2 (r, g, b)] = BUILD_PIXEL2 (r2, g2, b2); - GFX.ZERO_OR_X2 [BUILD_PIXEL2 (r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2 (r2, g2, b2); - } - } - } + if (b2 == 0) + b2 = 1; + GFX.ZERO_OR_X2 [BUILD_PIXEL2(r, g, b)] = BUILD_PIXEL2(r2, g2, b2); + GFX.ZERO_OR_X2 [BUILD_PIXEL2(r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2(r2, g2, + b2); + } + } + } #endif - // Build a lookup table that if the top bit of the color value is zero - // then the value is zero, otherwise its just the value. - for (r = 0; r <= MAX_RED; r++) - { - uint32 r2 = r; - if ((r2 & 0x10) == 0) - r2 = 0; - else - r2 &= ~0x10; - - for (g = 0; g <= MAX_GREEN; g++) - { - uint32 g2 = g; - if ((g2 & GREEN_HI_BIT) == 0) - g2 = 0; - else - g2 &= ~GREEN_HI_BIT; - for (b = 0; b <= MAX_BLUE; b++) - { - uint32 b2 = b; - if ((b2 & 0x10) == 0) - b2 = 0; - else - b2 &= ~0x10; - - GFX.ZERO [BUILD_PIXEL2 (r, g, b)] = BUILD_PIXEL2 (r2, g2, b2); - GFX.ZERO [BUILD_PIXEL2 (r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2 (r2, g2, b2); - } - } - } - return (TRUE); + // Build a lookup table that if the top bit of the color value is zero + // then the value is zero, otherwise its just the value. + for (r = 0; r <= MAX_RED; r++) + { + uint32 r2 = r; + if ((r2 & 0x10) == 0) + r2 = 0; + else + r2 &= ~0x10; + + for (g = 0; g <= MAX_GREEN; g++) + { + uint32 g2 = g; + if ((g2 & GREEN_HI_BIT) == 0) + g2 = 0; + else + g2 &= ~GREEN_HI_BIT; + for (b = 0; b <= MAX_BLUE; b++) + { + uint32 b2 = b; + if ((b2 & 0x10) == 0) + b2 = 0; + else + b2 &= ~0x10; + + GFX.ZERO [BUILD_PIXEL2(r, g, b)] = BUILD_PIXEL2(r2, g2, b2); + GFX.ZERO [BUILD_PIXEL2(r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2(r2, g2, b2); + } + } + } + return (TRUE); } -void S9xGraphicsDeinit (void) +void S9xGraphicsDeinit(void) { - // Free any memory allocated in S9xGraphicsInit - if (GFX.X2) - { - free ((char *) GFX.X2); - GFX.X2 = NULL; - } - if (GFX.ZERO_OR_X2) - { - free ((char *) GFX.ZERO_OR_X2); - GFX.ZERO_OR_X2 = NULL; - } - if (GFX.ZERO) - { - free ((char *) GFX.ZERO); - GFX.ZERO = NULL; - } + // Free any memory allocated in S9xGraphicsInit + if (GFX.X2) + { + free((char*) GFX.X2); + GFX.X2 = NULL; + } + if (GFX.ZERO_OR_X2) + { + free((char*) GFX.ZERO_OR_X2); + GFX.ZERO_OR_X2 = NULL; + } + if (GFX.ZERO) + { + free((char*) GFX.ZERO); + GFX.ZERO = NULL; + } } -void S9xBuildDirectColourMaps () +void S9xBuildDirectColourMaps() { - uint32 p,c; - for (p = 0; p < 8; p++) - { - for (c = 0; c < 256; c++) - { -// XXX: Brightness - DirectColourMaps [p][c] = BUILD_PIXEL (((c & 7) << 2) | ((p & 1) << 1), - ((c & 0x38) >> 1) | (p & 2), - ((c & 0xc0) >> 3) | (p & 4)); - } - } - IPPU.DirectColourMapsNeedRebuild = FALSE; + uint32 p, c; + for (p = 0; p < 8; p++) + { + for (c = 0; c < 256; c++) + { + // XXX: Brightness + DirectColourMaps [p][c] = BUILD_PIXEL(((c & 7) << 2) | ((p & 1) << 1), + ((c & 0x38) >> 1) | (p & 2), + ((c & 0xc0) >> 3) | (p & 4)); + } + } + IPPU.DirectColourMapsNeedRebuild = FALSE; } -void S9xStartScreenRefresh () +void S9xStartScreenRefresh() { - if (GFX.InfoStringTimeout > 0 && --GFX.InfoStringTimeout == 0) - GFX.InfoString = NULL; - - if (IPPU.RenderThisFrame) - { - if (!S9xInitUpdate ()) - { - IPPU.RenderThisFrame = FALSE; - return; - } - - IPPU.RenderedFramesCount++; - IPPU.PreviousLine = IPPU.CurrentLine = 0; - IPPU.MaxBrightness = PPU.Brightness; - IPPU.LatchedBlanking = PPU.ForcedBlanking; - - if(PPU.BGMode == 5 || PPU.BGMode == 6) - IPPU.Interlace = (Memory.FillRAM[0x2133] & 1); - if (Settings.SupportHiRes && (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.Interlace)) - { - IPPU.RenderedScreenWidth = 512; - IPPU.DoubleWidthPixels = TRUE; - IPPU.HalfWidthPixels = FALSE; - - if (IPPU.Interlace) - { - IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1; - IPPU.DoubleHeightPixels = TRUE; - GFX.Pitch2 = GFX.RealPitch; - GFX.Pitch = GFX.RealPitch * 2; + if (GFX.InfoStringTimeout > 0 && --GFX.InfoStringTimeout == 0) + GFX.InfoString = NULL; + + if (IPPU.RenderThisFrame) + { + if (!S9xInitUpdate()) + { + IPPU.RenderThisFrame = FALSE; + return; + } + + IPPU.RenderedFramesCount++; + IPPU.PreviousLine = IPPU.CurrentLine = 0; + IPPU.MaxBrightness = PPU.Brightness; + IPPU.LatchedBlanking = PPU.ForcedBlanking; + + if (PPU.BGMode == 5 || PPU.BGMode == 6) + IPPU.Interlace = (Memory.FillRAM[0x2133] & 1); + if (Settings.SupportHiRes && (PPU.BGMode == 5 || PPU.BGMode == 6 + || IPPU.Interlace)) + { + IPPU.RenderedScreenWidth = 512; + IPPU.DoubleWidthPixels = TRUE; + IPPU.HalfWidthPixels = FALSE; + + if (IPPU.Interlace) + { + IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1; + IPPU.DoubleHeightPixels = TRUE; + GFX.Pitch2 = GFX.RealPitch; + GFX.Pitch = GFX.RealPitch * 2; GFX.PPL = GFX.PPLx2 = GFX.RealPitch; - } - else - { - IPPU.RenderedScreenHeight = PPU.ScreenHeight; - GFX.Pitch2 = GFX.Pitch = GFX.RealPitch; + } + else + { + IPPU.RenderedScreenHeight = PPU.ScreenHeight; + GFX.Pitch2 = GFX.Pitch = GFX.RealPitch; IPPU.DoubleHeightPixels = FALSE; GFX.PPL = GFX.Pitch >> 1; - GFX.PPLx2 = GFX.PPL << 1; - } - } - else if (!Settings.SupportHiRes && (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.Interlace)) - { - IPPU.RenderedScreenWidth = 256; - IPPU.DoubleWidthPixels = FALSE; - // Secret of Mana displays menus with mode 5. - // Make them readable. - IPPU.HalfWidthPixels = TRUE; - } - else - { - IPPU.RenderedScreenWidth = 256; - IPPU.RenderedScreenHeight = PPU.ScreenHeight; - IPPU.DoubleWidthPixels = FALSE; - IPPU.HalfWidthPixels = FALSE; - IPPU.DoubleHeightPixels = FALSE; - { - GFX.Pitch2 = GFX.Pitch = GFX.RealPitch; - GFX.PPL = GFX.PPLx2 >> 1; - GFX.ZPitch = GFX.RealPitch; + GFX.PPLx2 = GFX.PPL << 1; + } + } + else if (!Settings.SupportHiRes && (PPU.BGMode == 5 || PPU.BGMode == 6 + || IPPU.Interlace)) + { + IPPU.RenderedScreenWidth = 256; + IPPU.DoubleWidthPixels = FALSE; + // Secret of Mana displays menus with mode 5. + // Make them readable. + IPPU.HalfWidthPixels = TRUE; + } + else + { + IPPU.RenderedScreenWidth = 256; + IPPU.RenderedScreenHeight = PPU.ScreenHeight; + IPPU.DoubleWidthPixels = FALSE; + IPPU.HalfWidthPixels = FALSE; + IPPU.DoubleHeightPixels = FALSE; + { + GFX.Pitch2 = GFX.Pitch = GFX.RealPitch; + GFX.PPL = GFX.PPLx2 >> 1; + GFX.ZPitch = GFX.RealPitch; GFX.ZPitch >>= 1; - } - } + } + } - PPU.RecomputeClipWindows = TRUE; - GFX.DepthDelta = GFX.SubZBuffer - GFX.ZBuffer; - GFX.Delta = (GFX.SubScreen - GFX.Screen) >> 1; - } + PPU.RecomputeClipWindows = TRUE; + GFX.DepthDelta = GFX.SubZBuffer - GFX.ZBuffer; + GFX.Delta = (GFX.SubScreen - GFX.Screen) >> 1; + } - if (++IPPU.FrameCount % Memory.ROMFramesPerSecond == 0) - { - IPPU.DisplayedRenderedFrameCount = IPPU.RenderedFramesCount; - IPPU.RenderedFramesCount = 0; - IPPU.FrameCount = 0; - } + if (++IPPU.FrameCount % Memory.ROMFramesPerSecond == 0) + { + IPPU.DisplayedRenderedFrameCount = IPPU.RenderedFramesCount; + IPPU.RenderedFramesCount = 0; + IPPU.FrameCount = 0; + } } -void RenderLine (uint8 C) +void RenderLine(uint8 C) { - if (IPPU.RenderThisFrame) - { - LineData[C].BG[0].VOffset = PPU.BG[0].VOffset + 1; - LineData[C].BG[0].HOffset = PPU.BG[0].HOffset; - LineData[C].BG[1].VOffset = PPU.BG[1].VOffset + 1; - LineData[C].BG[1].HOffset = PPU.BG[1].HOffset; - - if (PPU.BGMode == 7) - { - struct SLineMatrixData *p = &LineMatrixData [C]; - p->MatrixA = PPU.MatrixA; - p->MatrixB = PPU.MatrixB; - p->MatrixC = PPU.MatrixC; - p->MatrixD = PPU.MatrixD; - p->CentreX = PPU.CentreX; - p->CentreY = PPU.CentreY; - } - else - { - if (Settings.StarfoxHack && PPU.BG[2].VOffset == 0 && - PPU.BG[2].HOffset == 0xe000) - { - LineData[C].BG[2].VOffset = 0xe1; - LineData[C].BG[2].HOffset = 0; - } - else - { - LineData[C].BG[2].VOffset = PPU.BG[2].VOffset + 1; - LineData[C].BG[2].HOffset = PPU.BG[2].HOffset; - LineData[C].BG[3].VOffset = PPU.BG[3].VOffset + 1; - LineData[C].BG[3].HOffset = PPU.BG[3].HOffset; - } - } - IPPU.CurrentLine = C + 1; - } else { - /* if we're not rendering this frame, we still need to update this */ - // XXX: Check ForceBlank? Or anything else? - if(IPPU.OBJChanged) S9xSetupOBJ(); - PPU.RangeTimeOver |= GFX.OBJLines[C].RTOFlags; - } + if (IPPU.RenderThisFrame) + { + LineData[C].BG[0].VOffset = PPU.BG[0].VOffset + 1; + LineData[C].BG[0].HOffset = PPU.BG[0].HOffset; + LineData[C].BG[1].VOffset = PPU.BG[1].VOffset + 1; + LineData[C].BG[1].HOffset = PPU.BG[1].HOffset; + + if (PPU.BGMode == 7) + { + struct SLineMatrixData* p = &LineMatrixData [C]; + p->MatrixA = PPU.MatrixA; + p->MatrixB = PPU.MatrixB; + p->MatrixC = PPU.MatrixC; + p->MatrixD = PPU.MatrixD; + p->CentreX = PPU.CentreX; + p->CentreY = PPU.CentreY; + } + else + { + if (Settings.StarfoxHack && PPU.BG[2].VOffset == 0 && + PPU.BG[2].HOffset == 0xe000) + { + LineData[C].BG[2].VOffset = 0xe1; + LineData[C].BG[2].HOffset = 0; + } + else + { + LineData[C].BG[2].VOffset = PPU.BG[2].VOffset + 1; + LineData[C].BG[2].HOffset = PPU.BG[2].HOffset; + LineData[C].BG[3].VOffset = PPU.BG[3].VOffset + 1; + LineData[C].BG[3].HOffset = PPU.BG[3].HOffset; + } + } + IPPU.CurrentLine = C + 1; + } + else + { + /* if we're not rendering this frame, we still need to update this */ + // XXX: Check ForceBlank? Or anything else? + if (IPPU.OBJChanged) S9xSetupOBJ(); + PPU.RangeTimeOver |= GFX.OBJLines[C].RTOFlags; + } } -void S9xEndScreenRefresh () +void S9xEndScreenRefresh() { - IPPU.HDMAStarted = FALSE; - if (IPPU.RenderThisFrame) - { - FLUSH_REDRAW (); - if (IPPU.ColorsChanged) - { + IPPU.HDMAStarted = FALSE; + if (IPPU.RenderThisFrame) + { + FLUSH_REDRAW(); + if (IPPU.ColorsChanged) + { uint32 saved = PPU.CGDATA[0]; - IPPU.ColorsChanged = FALSE; - PPU.CGDATA[0] = saved; - } + IPPU.ColorsChanged = FALSE; + PPU.CGDATA[0] = saved; + } - GFX.Pitch = GFX.Pitch2 = GFX.RealPitch; - GFX.PPL = GFX.PPLx2 >> 1; - S9xDeinitUpdate (IPPU.RenderedScreenWidth, IPPU.RenderedScreenHeight); - } + GFX.Pitch = GFX.Pitch2 = GFX.RealPitch; + GFX.PPL = GFX.PPLx2 >> 1; + S9xDeinitUpdate(IPPU.RenderedScreenWidth, IPPU.RenderedScreenHeight); + } - S9xApplyCheats (); + S9xApplyCheats(); - if (CPU.SRAMModified) - { - S9xAutoSaveSRAM (); - CPU.SRAMModified = FALSE; - } + if (CPU.SRAMModified) + { + S9xAutoSaveSRAM(); + CPU.SRAMModified = FALSE; + } } -void S9xSetInfoString (const char *string) +void S9xSetInfoString(const char* string) { - GFX.InfoString = string; - GFX.InfoStringTimeout = 120; + GFX.InfoString = string; + GFX.InfoStringTimeout = 120; } -inline void SelectTileRenderer (bool8 normal) +inline void SelectTileRenderer(bool8 normal) { - if (normal) - { - if (IPPU.HalfWidthPixels) - { - DrawTilePtr = DrawTile16HalfWidth; - DrawClippedTilePtr = DrawClippedTile16HalfWidth; - DrawLargePixelPtr = DrawLargePixel16HalfWidth; - } - else - { - DrawTilePtr = DrawTile16; - DrawClippedTilePtr = DrawClippedTile16; - DrawLargePixelPtr = DrawLargePixel16; - } - } - else - { - switch (GFX.r2131 & 0xC0) - { - case 0x00: - DrawTilePtr = DrawTile16Add; - DrawClippedTilePtr = DrawClippedTile16Add; - DrawLargePixelPtr = DrawLargePixel16Add; - break; - case 0x40: - if (GFX.r2130 & 2) - { - DrawTilePtr = DrawTile16Add1_2; - DrawClippedTilePtr = DrawClippedTile16Add1_2; - } - else - { - // Fixed colour addition - DrawTilePtr = DrawTile16FixedAdd1_2; - DrawClippedTilePtr = DrawClippedTile16FixedAdd1_2; - } - DrawLargePixelPtr = DrawLargePixel16Add1_2; - break; - case 0x80: - DrawTilePtr = DrawTile16Sub; - DrawClippedTilePtr = DrawClippedTile16Sub; - DrawLargePixelPtr = DrawLargePixel16Sub; - break; - case 0xC0: - if (GFX.r2130 & 2) - { - DrawTilePtr = DrawTile16Sub1_2; - DrawClippedTilePtr = DrawClippedTile16Sub1_2; - } - else - { - // Fixed colour substraction - DrawTilePtr = DrawTile16FixedSub1_2; - DrawClippedTilePtr = DrawClippedTile16FixedSub1_2; - } - DrawLargePixelPtr = DrawLargePixel16Sub1_2; - break; - } - } + if (normal) + { + if (IPPU.HalfWidthPixels) + { + DrawTilePtr = DrawTile16HalfWidth; + DrawClippedTilePtr = DrawClippedTile16HalfWidth; + DrawLargePixelPtr = DrawLargePixel16HalfWidth; + } + else + { + DrawTilePtr = DrawTile16; + DrawClippedTilePtr = DrawClippedTile16; + DrawLargePixelPtr = DrawLargePixel16; + } + } + else + { + switch (GFX.r2131 & 0xC0) + { + case 0x00: + DrawTilePtr = DrawTile16Add; + DrawClippedTilePtr = DrawClippedTile16Add; + DrawLargePixelPtr = DrawLargePixel16Add; + break; + case 0x40: + if (GFX.r2130 & 2) + { + DrawTilePtr = DrawTile16Add1_2; + DrawClippedTilePtr = DrawClippedTile16Add1_2; + } + else + { + // Fixed colour addition + DrawTilePtr = DrawTile16FixedAdd1_2; + DrawClippedTilePtr = DrawClippedTile16FixedAdd1_2; + } + DrawLargePixelPtr = DrawLargePixel16Add1_2; + break; + case 0x80: + DrawTilePtr = DrawTile16Sub; + DrawClippedTilePtr = DrawClippedTile16Sub; + DrawLargePixelPtr = DrawLargePixel16Sub; + break; + case 0xC0: + if (GFX.r2130 & 2) + { + DrawTilePtr = DrawTile16Sub1_2; + DrawClippedTilePtr = DrawClippedTile16Sub1_2; + } + else + { + // Fixed colour substraction + DrawTilePtr = DrawTile16FixedSub1_2; + DrawClippedTilePtr = DrawClippedTile16FixedSub1_2; + } + DrawLargePixelPtr = DrawLargePixel16Sub1_2; + break; + } + } } -void S9xSetupOBJ () +void S9xSetupOBJ() { #ifdef MK_DEBUG_RTO - if(Settings.BGLayering) fprintf(stderr, "Entering SetupOBJS()\n"); + if (Settings.BGLayering) fprintf(stderr, "Entering SetupOBJS()\n"); #endif - int SmallWidth, SmallHeight; - int LargeWidth, LargeHeight; - - switch (PPU.OBJSizeSelect) - { - case 0: - SmallWidth = SmallHeight = 8; - LargeWidth = LargeHeight = 16; - break; - case 1: - SmallWidth = SmallHeight = 8; - LargeWidth = LargeHeight = 32; - break; - case 2: - SmallWidth = SmallHeight = 8; - LargeWidth = LargeHeight = 64; - break; - case 3: - SmallWidth = SmallHeight = 16; - LargeWidth = LargeHeight = 32; - break; - case 4: - SmallWidth = SmallHeight = 16; - LargeWidth = LargeHeight = 64; - break; - default: - case 5: - SmallWidth = SmallHeight = 32; - LargeWidth = LargeHeight = 64; - break; - case 6: - SmallWidth = 16; SmallHeight = 32; - LargeWidth = 32; LargeHeight = 64; - break; - case 7: - SmallWidth = 16; SmallHeight = 32; - LargeWidth = LargeHeight = 32; - break; - } - if(IPPU.InterlaceSprites) - { - SmallHeight>>=1; LargeHeight>>=1; - } + int SmallWidth, SmallHeight; + int LargeWidth, LargeHeight; + + switch (PPU.OBJSizeSelect) + { + case 0: + SmallWidth = SmallHeight = 8; + LargeWidth = LargeHeight = 16; + break; + case 1: + SmallWidth = SmallHeight = 8; + LargeWidth = LargeHeight = 32; + break; + case 2: + SmallWidth = SmallHeight = 8; + LargeWidth = LargeHeight = 64; + break; + case 3: + SmallWidth = SmallHeight = 16; + LargeWidth = LargeHeight = 32; + break; + case 4: + SmallWidth = SmallHeight = 16; + LargeWidth = LargeHeight = 64; + break; + default: + case 5: + SmallWidth = SmallHeight = 32; + LargeWidth = LargeHeight = 64; + break; + case 6: + SmallWidth = 16; + SmallHeight = 32; + LargeWidth = 32; + LargeHeight = 64; + break; + case 7: + SmallWidth = 16; + SmallHeight = 32; + LargeWidth = LargeHeight = 32; + break; + } + if (IPPU.InterlaceSprites) + { + SmallHeight >>= 1; + LargeHeight >>= 1; + } #ifdef MK_DEBUG_RTO - if(Settings.BGLayering) fprintf(stderr, "Sizes are %dx%d and %dx%d\n", SmallWidth, SmallHeight, LargeWidth, LargeHeight); + if (Settings.BGLayering) fprintf(stderr, "Sizes are %dx%d and %dx%d\n", + SmallWidth, SmallHeight, LargeWidth, LargeHeight); #endif - /* OK, we have three cases here. Either there's no priority, priority is - * normal FirstSprite, or priority is FirstSprite+Y. The first two are - * easy, the last is somewhat more ... interesting. So we split them up. */ + /* OK, we have three cases here. Either there's no priority, priority is + * normal FirstSprite, or priority is FirstSprite+Y. The first two are + * easy, the last is somewhat more ... interesting. So we split them up. */ - int Height; - uint8 S; + int Height; + uint8 S; #ifdef MK_DEBUG_RTO - if(Settings.BGLayering) fprintf(stderr, "Priority rotation=%d, OAMAddr=%d -> ", PPU.OAMPriorityRotation, PPU.OAMAddr*2 | (PPU.OAMFlip&1)); + if (Settings.BGLayering) fprintf(stderr, "Priority rotation=%d, OAMAddr=%d -> ", + PPU.OAMPriorityRotation, PPU.OAMAddr * 2 | (PPU.OAMFlip & 1)); #endif - if(!PPU.OAMPriorityRotation || !(PPU.OAMFlip&PPU.OAMAddr&1)){ + if (!PPU.OAMPriorityRotation || !(PPU.OAMFlip & PPU.OAMAddr & 1)) + { #ifdef MK_DEBUG_RTO - if(Settings.BGLayering) fprintf(stderr, "normal FirstSprite = %02x\n", PPU.FirstSprite); + if (Settings.BGLayering) fprintf(stderr, "normal FirstSprite = %02x\n", + PPU.FirstSprite); #endif - /* normal case */ - uint8 LineOBJ[SNES_HEIGHT_EXTENDED]; - memset(LineOBJ, 0, sizeof(LineOBJ)); + /* normal case */ + uint8 LineOBJ[SNES_HEIGHT_EXTENDED]; + memset(LineOBJ, 0, sizeof(LineOBJ)); int i; - for(i=0; i-GFX.OBJWidths[S] && HPos<=256) - { - if(HPos<0){ - GFX.OBJVisibleTiles[S]=(GFX.OBJWidths[S]+HPos+7)>>3; - } else if(HPos+GFX.OBJWidths[S]>=257){ - GFX.OBJVisibleTiles[S]=(257-HPos+7)>>3; - } else { - GFX.OBJVisibleTiles[S]=GFX.OBJWidths[S]>>3; - } - uint8 line,Y; - for(line=0, Y=(uint8)(PPU.OBJ[S].VPos&0xff); line=SNES_HEIGHT_EXTENDED) continue; - if(LineOBJ[Y]>=32){ - GFX.OBJLines[Y].RTOFlags|=0x40; + for (i = 0; i < SNES_HEIGHT_EXTENDED; i++) + { + GFX.OBJLines[i].RTOFlags = 0; + GFX.OBJLines[i].Tiles = 34; + } + uint8 FirstSprite = PPU.FirstSprite; + S = FirstSprite; + do + { + if (PPU.OBJ[S].Size) + { + GFX.OBJWidths[S] = LargeWidth; + Height = LargeHeight; + } + else + { + GFX.OBJWidths[S] = SmallWidth; + Height = SmallHeight; + } + int HPos = PPU.OBJ[S].HPos; + if (HPos == -256) HPos = 256; + if (HPos > -GFX.OBJWidths[S] && HPos <= 256) + { + if (HPos < 0) + GFX.OBJVisibleTiles[S] = (GFX.OBJWidths[S] + HPos + 7) >> 3; + else if (HPos + GFX.OBJWidths[S] >= 257) + GFX.OBJVisibleTiles[S] = (257 - HPos + 7) >> 3; + else + GFX.OBJVisibleTiles[S] = GFX.OBJWidths[S] >> 3; + uint8 line, Y; + for (line = 0, Y = (uint8)(PPU.OBJ[S].VPos & 0xff); line < Height; Y++, line++) + { + if (Y >= SNES_HEIGHT_EXTENDED) continue; + if (LineOBJ[Y] >= 32) + { + GFX.OBJLines[Y].RTOFlags |= 0x40; #ifdef MK_DEBUG_RTO - if(Settings.BGLayering) fprintf(stderr, "%d: OBJ %02x ranged over\n", Y, S); + if (Settings.BGLayering) fprintf(stderr, "%d: OBJ %02x ranged over\n", Y, S); #endif - continue; - } - GFX.OBJLines[Y].Tiles-=GFX.OBJVisibleTiles[S]; - if(GFX.OBJLines[Y].Tiles<0) GFX.OBJLines[Y].RTOFlags|=0x80; - GFX.OBJLines[Y].OBJ[LineOBJ[Y]].Sprite=S; - if(PPU.OBJ[S].VFlip){ - // Yes, Width not Height. It so happens that the - // sprites with H=2*W flip as two WxW sprites. - GFX.OBJLines[Y].OBJ[LineOBJ[Y]].Line=line^(GFX.OBJWidths[S]-1); - } else { - GFX.OBJLines[Y].OBJ[LineOBJ[Y]].Line=line; - } - LineOBJ[Y]++; - } - } - S=(S+1)&0x7F; - } while(S!=FirstSprite); + continue; + } + GFX.OBJLines[Y].Tiles -= GFX.OBJVisibleTiles[S]; + if (GFX.OBJLines[Y].Tiles < 0) GFX.OBJLines[Y].RTOFlags |= 0x80; + GFX.OBJLines[Y].OBJ[LineOBJ[Y]].Sprite = S; + if (PPU.OBJ[S].VFlip) + { + // Yes, Width not Height. It so happens that the + // sprites with H=2*W flip as two WxW sprites. + GFX.OBJLines[Y].OBJ[LineOBJ[Y]].Line = line ^ (GFX.OBJWidths[S] - 1); + } + else + GFX.OBJLines[Y].OBJ[LineOBJ[Y]].Line = line; + LineOBJ[Y]++; + } + } + S = (S + 1) & 0x7F; + } + while (S != FirstSprite); int Y; - for (Y = 0; Y < SNES_HEIGHT_EXTENDED; Y++) { - if (LineOBJ[Y] < 32) // Add the sentinel - GFX.OBJLines[Y].OBJ[LineOBJ[Y]].Sprite = -1; - } - for(Y = 1; Y-GFX.OBJWidths[S] && HPos<=256) - { - if(HPos<0){ - GFX.OBJVisibleTiles[S]=(GFX.OBJWidths[S]+HPos+7)>>3; - } else if(HPos+GFX.OBJWidths[S]>=257){ - GFX.OBJVisibleTiles[S]=(257-HPos+7)>>3; - } else { - GFX.OBJVisibleTiles[S]=GFX.OBJWidths[S]>>3; - } - uint8 line,Y; - for(line=0, Y=(uint8)(PPU.OBJ[S].VPos&0xff); line=SNES_HEIGHT_EXTENDED) continue; - if (!AnyOBJOnLine[Y]) { - memset(OBJOnLine[Y], 0, 128); - AnyOBJOnLine[Y] = TRUE; - } - if(PPU.OBJ[S].VFlip){ - // Yes, Width not Height. It so happens that the - // sprites with H=2*W flip as two WxW sprites. - OBJOnLine[Y][S]=(line^(GFX.OBJWidths[S]-1)) | 0x80; - } else { - OBJOnLine[Y][S]=line | 0x80; - } - } - } - } - - /* Now go through and pull out those OBJ that are actually visible. */ - int j,Y; - for(Y=0; Y=32){ - GFX.OBJLines[Y].RTOFlags|=0x40; - #ifdef MK_DEBUG_RTO - if(Settings.BGLayering) fprintf(stderr, "%d: OBJ %02x ranged over\n", Y, S); - #endif - break; - } - GFX.OBJLines[Y].Tiles-=GFX.OBJVisibleTiles[S]; - if(GFX.OBJLines[Y].Tiles<0) GFX.OBJLines[Y].RTOFlags|=0x80; - GFX.OBJLines[Y].OBJ[j].Sprite=S; - GFX.OBJLines[Y].OBJ[j++].Line=OBJOnLine[Y][S]&~0x80; - } - S=(S+1)&0x7F; - } while(S!=FirstSprite); - } - if(j<32) GFX.OBJLines[Y].OBJ[j].Sprite=-1; - } - } + /* First, find out which sprites are on which lines */ + uint8 OBJOnLine[SNES_HEIGHT_EXTENDED][128]; + // memset(OBJOnLine, 0, sizeof(OBJOnLine)); + /* Hold on here, that's a lot of bytes to initialise at once! + * So we only initialise them per line, as needed. [Neb] + * Bonus: We can quickly avoid looping if a line has no OBJs. + */ + bool8 AnyOBJOnLine[SNES_HEIGHT_EXTENDED]; + memset(AnyOBJOnLine, FALSE, sizeof(AnyOBJOnLine)); // better + + for (S = 0; S < 128; S++) + { + if (PPU.OBJ[S].Size) + { + GFX.OBJWidths[S] = LargeWidth; + Height = LargeHeight; + } + else + { + GFX.OBJWidths[S] = SmallWidth; + Height = SmallHeight; + } + int HPos = PPU.OBJ[S].HPos; + if (HPos == -256) HPos = 256; + if (HPos > -GFX.OBJWidths[S] && HPos <= 256) + { + if (HPos < 0) + GFX.OBJVisibleTiles[S] = (GFX.OBJWidths[S] + HPos + 7) >> 3; + else if (HPos + GFX.OBJWidths[S] >= 257) + GFX.OBJVisibleTiles[S] = (257 - HPos + 7) >> 3; + else + GFX.OBJVisibleTiles[S] = GFX.OBJWidths[S] >> 3; + uint8 line, Y; + for (line = 0, Y = (uint8)(PPU.OBJ[S].VPos & 0xff); line < Height; Y++, line++) + { + if (Y >= SNES_HEIGHT_EXTENDED) continue; + if (!AnyOBJOnLine[Y]) + { + memset(OBJOnLine[Y], 0, 128); + AnyOBJOnLine[Y] = TRUE; + } + if (PPU.OBJ[S].VFlip) + { + // Yes, Width not Height. It so happens that the + // sprites with H=2*W flip as two WxW sprites. + OBJOnLine[Y][S] = (line ^ (GFX.OBJWidths[S] - 1)) | 0x80; + } + else + OBJOnLine[Y][S] = line | 0x80; + } + } + } + + /* Now go through and pull out those OBJ that are actually visible. */ + int j, Y; + for (Y = 0; Y < SNES_HEIGHT_EXTENDED; Y++) + { + GFX.OBJLines[Y].RTOFlags = Y ? 0 : GFX.OBJLines[Y - 1].RTOFlags; + + GFX.OBJLines[Y].Tiles = 34; + j = 0; + if (AnyOBJOnLine[Y]) + { + uint8 FirstSprite = (PPU.FirstSprite + Y) & 0x7F; + S = FirstSprite; + do + { + if (OBJOnLine[Y][S]) + { + if (j >= 32) + { + GFX.OBJLines[Y].RTOFlags |= 0x40; +#ifdef MK_DEBUG_RTO + if (Settings.BGLayering) fprintf(stderr, "%d: OBJ %02x ranged over\n", Y, S); +#endif + break; + } + GFX.OBJLines[Y].Tiles -= GFX.OBJVisibleTiles[S]; + if (GFX.OBJLines[Y].Tiles < 0) GFX.OBJLines[Y].RTOFlags |= 0x80; + GFX.OBJLines[Y].OBJ[j].Sprite = S; + GFX.OBJLines[Y].OBJ[j++].Line = OBJOnLine[Y][S] & ~0x80; + } + S = (S + 1) & 0x7F; + } + while (S != FirstSprite); + } + if (j < 32) GFX.OBJLines[Y].OBJ[j].Sprite = -1; + } + } #ifdef MK_DEBUG_RTO - if(Settings.BGLayering) { - fprintf(stderr, "Sprites per line:\n"); - for(int xxx=0; xxx=0; j++){ - fprintf(stderr, " %02x.%d", GFX.OBJLines[xxx].OBJ[j].Sprite, GFX.OBJLines[xxx].OBJ[j].Line); - } - fprintf(stderr, "\n"); - } - - fprintf(stderr, "Exiting SetupObj()\n"); - } + if (Settings.BGLayering) + { + fprintf(stderr, "Sprites per line:\n"); + for (int xxx = 0; xxx < SNES_HEIGHT_EXTENDED; xxx++) + { + fprintf(stderr, "Line %d: RTO=%02x Tiles=%d", xxx, GFX.OBJLines[xxx].RTOFlags, + 34 - GFX.OBJLines[xxx].Tiles); + for (int j = 0; j < 32 && GFX.OBJLines[xxx].OBJ[j].Sprite >= 0; j++) + fprintf(stderr, " %02x.%d", GFX.OBJLines[xxx].OBJ[j].Sprite, + GFX.OBJLines[xxx].OBJ[j].Line); + fprintf(stderr, "\n"); + } + + fprintf(stderr, "Exiting SetupObj()\n"); + } #endif - IPPU.OBJChanged = FALSE; + IPPU.OBJChanged = FALSE; } -static void DrawOBJS (bool8 OnMain, uint8 D) +static void DrawOBJS(bool8 OnMain, uint8 D) { #ifdef ACCUMULATE_JOYPAD -/* - * This call allows NDSSFC to synchronise the DS controller more often. - * If porting a later version of Snes9x into NDSSFC, it is essential to - * preserve it. - */ - NDSSFCAccumulateJoypad (); + /* + * This call allows NDSSFC to synchronise the DS controller more often. + * If porting a later version of Snes9x into NDSSFC, it is essential to + * preserve it. + */ + NDSSFCAccumulateJoypad(); #endif #ifdef MK_DEBUG_RTO - if(Settings.BGLayering) fprintf(stderr, "Entering DrawOBJS() for %d-%d\n", GFX.StartY, GFX.EndY); + if (Settings.BGLayering) fprintf(stderr, "Entering DrawOBJS() for %d-%d\n", + GFX.StartY, GFX.EndY); #endif - CHECK_SOUND(); - - BG.BitShift = 4; - BG.TileShift = 5; - BG.TileAddress = PPU.OBJNameBase; - BG.StartPalette = 128; - BG.PaletteShift = 4; - BG.PaletteMask = 7; - BG.Buffer = IPPU.TileCache [TILE_4BIT]; - BG.Buffered = IPPU.TileCached [TILE_4BIT]; - BG.NameSelect = PPU.OBJNameSelect; - BG.DirectColourMode = FALSE; - - GFX.PixSize = 1; - - struct { - uint16 Pos; - bool8 Value; - } Windows[7]; - int clipcount = GFX.pCurrentClip->Count [4]; - if (!clipcount){ - Windows[0].Pos=0; - Windows[0].Value=TRUE; - Windows[1].Pos=256; - Windows[1].Value=FALSE; - Windows[2].Pos=1000; - Windows[2].Value=FALSE; - } else { - Windows[0].Pos=1000; - Windows[0].Value=FALSE; - int clip,i; - for(clip=0, i=1; clipRight[clip][4]<=GFX.pCurrentClip->Left[clip][4]) continue; - int j; - for(j=0; jLeft[clip][4]; j++); - if(jLeft[clip][4]){ - Windows[j].Value = TRUE; - } else { - // memmove required: Overlapping addresses [Neb] - if(jLeft[clip][4]; - Windows[j].Value = TRUE; - i++; - } - for(j=0; jRight[clip][4]; j++); - if(j>=i || Windows[j].Pos!=GFX.pCurrentClip->Right[clip][4]){ - // memmove required: Overlapping addresses [Neb] - if(jRight[clip][4]; - Windows[j].Value = FALSE; - i++; - } - } - } + CHECK_SOUND(); + + BG.BitShift = 4; + BG.TileShift = 5; + BG.TileAddress = PPU.OBJNameBase; + BG.StartPalette = 128; + BG.PaletteShift = 4; + BG.PaletteMask = 7; + BG.Buffer = IPPU.TileCache [TILE_4BIT]; + BG.Buffered = IPPU.TileCached [TILE_4BIT]; + BG.NameSelect = PPU.OBJNameSelect; + BG.DirectColourMode = FALSE; + + GFX.PixSize = 1; + + struct + { + uint16 Pos; + bool8 Value; + } Windows[7]; + int clipcount = GFX.pCurrentClip->Count [4]; + if (!clipcount) + { + Windows[0].Pos = 0; + Windows[0].Value = TRUE; + Windows[1].Pos = 256; + Windows[1].Value = FALSE; + Windows[2].Pos = 1000; + Windows[2].Value = FALSE; + } + else + { + Windows[0].Pos = 1000; + Windows[0].Value = FALSE; + int clip, i; + for (clip = 0, i = 1; clip < clipcount; clip++) + { + if (GFX.pCurrentClip->Right[clip][4] <= GFX.pCurrentClip->Left[clip][4]) + continue; + int j; + for (j = 0; j < i && Windows[j].Pos < GFX.pCurrentClip->Left[clip][4]; j++); + if (j < i && Windows[j].Pos == GFX.pCurrentClip->Left[clip][4]) + Windows[j].Value = TRUE; + else + { + // memmove required: Overlapping addresses [Neb] + if (j < i) memmove(&Windows[j + 1], &Windows[j], sizeof(Windows[0]) * (i - j)); + Windows[j].Pos = GFX.pCurrentClip->Left[clip][4]; + Windows[j].Value = TRUE; + i++; + } + for (j = 0; j < i && Windows[j].Pos < GFX.pCurrentClip->Right[clip][4]; j++); + if (j >= i || Windows[j].Pos != GFX.pCurrentClip->Right[clip][4]) + { + // memmove required: Overlapping addresses [Neb] + if (j < i) memmove(&Windows[j + 1], &Windows[j], sizeof(Windows[0]) * (i - j)); + Windows[j].Pos = GFX.pCurrentClip->Right[clip][4]; + Windows[j].Value = FALSE; + i++; + } + } + } #ifdef MK_DEBUG_RTO -if(Settings.BGLayering) { - fprintf(stderr, "Windows:\n"); - for(int xxx=0; xxx<6; xxx++){ fprintf(stderr, "%d: %d = %d\n", xxx, Windows[xxx].Pos, Windows[xxx].Value); } -} + if (Settings.BGLayering) + { + fprintf(stderr, "Windows:\n"); + for (int xxx = 0; xxx < 6; xxx++) + fprintf(stderr, "%d: %d = %d\n", xxx, Windows[xxx].Pos, Windows[xxx].Value); + } #endif - if (Settings.SupportHiRes) - { - if (PPU.BGMode == 5 || PPU.BGMode == 6) - { - // Bah, OnMain is never used except to determine if calling - // SelectTileRenderer is necessary. So let's hack it to false here - // to stop SelectTileRenderer from being called when it causes - // problems. - OnMain = FALSE; - GFX.PixSize = 2; - if (IPPU.DoubleHeightPixels) - { + if (Settings.SupportHiRes) + { + if (PPU.BGMode == 5 || PPU.BGMode == 6) + { + // Bah, OnMain is never used except to determine if calling + // SelectTileRenderer is necessary. So let's hack it to false here + // to stop SelectTileRenderer from being called when it causes + // problems. + OnMain = FALSE; + GFX.PixSize = 2; + if (IPPU.DoubleHeightPixels) + { DrawTilePtr = DrawTile16x2x2; DrawClippedTilePtr = DrawClippedTile16x2x2; - } - else - { + } + else + { DrawTilePtr = DrawTile16x2; DrawClippedTilePtr = DrawClippedTile16x2; - } - } - else - { + } + } + else + { DrawTilePtr = DrawTile16; DrawClippedTilePtr = DrawClippedTile16; - } - } - else // if (!Settings.SupportHiRes) - { - if (PPU.BGMode == 5 || PPU.BGMode == 6) - { - // Bah, OnMain is never used except to determine if calling - // SelectTileRenderer is necessary. So let's hack it to false here - // to stop SelectTileRenderer from being called when it causes - // problems. - OnMain = FALSE; - } - DrawTilePtr = DrawTile16; - DrawClippedTilePtr = DrawClippedTile16; - } - GFX.Z1 = D + 2; - - uint32 Y,Offset; - for(Y=GFX.StartY, Offset=Y*GFX.PPL; Y<=GFX.EndY; Y++, Offset+=GFX.PPL){ + } + } + else // if (!Settings.SupportHiRes) + { + if (PPU.BGMode == 5 || PPU.BGMode == 6) + { + // Bah, OnMain is never used except to determine if calling + // SelectTileRenderer is necessary. So let's hack it to false here + // to stop SelectTileRenderer from being called when it causes + // problems. + OnMain = FALSE; + } + DrawTilePtr = DrawTile16; + DrawClippedTilePtr = DrawClippedTile16; + } + GFX.Z1 = D + 2; + + uint32 Y, Offset; + for (Y = GFX.StartY, Offset = Y * GFX.PPL; Y <= GFX.EndY; + Y++, Offset += GFX.PPL) + { #ifdef MK_DEBUG_RTO - bool8 Flag=0; + bool8 Flag = 0; #endif - int I = 0; + int I = 0; #ifdef MK_DISABLE_TIME_OVER - int tiles=0; + int tiles = 0; #else - int tiles=GFX.OBJLines[Y].Tiles; + int tiles = GFX.OBJLines[Y].Tiles; #endif int S; - for (S = GFX.OBJLines[Y].OBJ[I].Sprite; S >= 0 && I<32; S = GFX.OBJLines[Y].OBJ[++I].Sprite) - { - tiles+=GFX.OBJVisibleTiles[S]; - if(tiles<=0){ + for (S = GFX.OBJLines[Y].OBJ[I].Sprite; S >= 0 + && I < 32; S = GFX.OBJLines[Y].OBJ[++I].Sprite) + { + tiles += GFX.OBJVisibleTiles[S]; + if (tiles <= 0) + { #ifdef MK_DEBUG_RTO -if(Settings.BGLayering) { - if(!Flag){ Flag=1; fprintf(stderr, "Line %d:", Y); } - fprintf(stderr, " [%02x]", S); -} + if (Settings.BGLayering) + { + if (!Flag) + { + Flag = 1; + fprintf(stderr, "Line %d:", Y); + } + fprintf(stderr, " [%02x]", S); + } #endif - continue; - } + continue; + } #ifdef MK_DEBUG_RTO -if(Settings.BGLayering) { - if(!Flag){ Flag=1; fprintf(stderr, "Line %d:", Y); } - fprintf(stderr, " %02x", S); -} + if (Settings.BGLayering) + { + if (!Flag) + { + Flag = 1; + fprintf(stderr, "Line %d:", Y); + } + fprintf(stderr, " %02x", S); + } #endif - if (OnMain && SUB_OR_ADD(4)) - { - SelectTileRenderer (!GFX.Pseudo && PPU.OBJ [S].Palette < 4); - } - - int BaseTile = (((GFX.OBJLines[Y].OBJ[I].Line<<1) + (PPU.OBJ[S].Name&0xf0))&0xf0) | (PPU.OBJ[S].Name&0x100) | (PPU.OBJ[S].Palette << 10); - int TileX = PPU.OBJ[S].Name&0x0f; - int TileLine = (GFX.OBJLines[Y].OBJ[I].Line&7)*8; - int TileInc = 1; - - if (PPU.OBJ[S].HFlip) - { - TileX = (TileX + (GFX.OBJWidths[S] >> 3) - 1) & 0x0f; - BaseTile |= H_FLIP; - TileInc = -1; - } - - GFX.Z2 = (PPU.OBJ[S].Priority + 1) * 4 + D; - - bool8 WinStat=TRUE; - int WinIdx=0, NextPos=-1000; - int X=PPU.OBJ[S].HPos; if(X==-256) X=256; - int t,O; - for(t=tiles, O=Offset+X*GFX.PixSize; X<=256 && X> 3) - 1) & 0x0f; + BaseTile |= H_FLIP; + TileInc = -1; + } + + GFX.Z2 = (PPU.OBJ[S].Priority + 1) * 4 + D; + + bool8 WinStat = TRUE; + int WinIdx = 0, NextPos = -1000; + int X = PPU.OBJ[S].HPos; + if (X == -256) X = 256; + int t, O; + for (t = tiles, O = Offset + X * GFX.PixSize; X <= 256 + && X < PPU.OBJ[S].HPos + GFX.OBJWidths[S]; + TileX = (TileX + TileInc) & 0x0f, X += 8, O += 8 * GFX.PixSize) + { #ifdef MK_DEBUG_RTO -if(Settings.BGLayering) { - if(X<-7) continue; - if((t-1)<0) fprintf(stderr, "-[%d]", 35-t); - else fprintf(stderr, "-%d", 35-t); -} + if (Settings.BGLayering) + { + if (X < -7) continue; + if ((t - 1) < 0) fprintf(stderr, "-[%d]", 35 - t); + else fprintf(stderr, "-%d", 35 - t); + } #endif - if(X<-7 || --t<0 || X==256) continue; - if(X>=NextPos){ - for(; WinIdx<7 && Windows[WinIdx].Pos<=X; WinIdx++); - if(WinIdx==0) WinStat=FALSE; - else WinStat=Windows[WinIdx-1].Value; - NextPos=(WinIdx<7)?Windows[WinIdx].Pos:1000; - } - - if(X+8X+8) NextPos=X+8; - } - } - } - } + if (X < -7 || --t < 0 || X == 256) continue; + if (X >= NextPos) + { + for (; WinIdx < 7 && Windows[WinIdx].Pos <= X; WinIdx++); + if (WinIdx == 0) WinStat = FALSE; + else WinStat = Windows[WinIdx - 1].Value; + NextPos = (WinIdx < 7) ? Windows[WinIdx].Pos : 1000; + } + + if (X + 8 < NextPos) + { + if (WinStat)(*DrawTilePtr)(BaseTile | TileX, O, TileLine, 1); + } + else + { + int x = X; + while (x < X + 8) + { + if (WinStat)(*DrawClippedTilePtr)(BaseTile | TileX, O, x - X, NextPos - x, + TileLine, 1); + x = NextPos; + for (; WinIdx < 7 && Windows[WinIdx].Pos <= x; WinIdx++); + if (WinIdx == 0) WinStat = FALSE; + else WinStat = Windows[WinIdx - 1].Value; + NextPos = (WinIdx < 7) ? Windows[WinIdx].Pos : 1000; + if (NextPos > X + 8) NextPos = X + 8; + } + } + } + } #ifdef MK_DEBUG_RTO - if(Settings.BGLayering) if(Flag) fprintf(stderr, "\n"); + if (Settings.BGLayering) if (Flag) fprintf(stderr, "\n"); #endif - } + } #ifdef MK_DEBUG_RTO - if(Settings.BGLayering) fprintf(stderr, "Exiting DrawOBJS() for %d-%d\n", GFX.StartY, GFX.EndY); + if (Settings.BGLayering) fprintf(stderr, "Exiting DrawOBJS() for %d-%d\n", + GFX.StartY, GFX.EndY); #endif } -static void DrawBackgroundMosaic (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) -{ - CHECK_SOUND(); +static void DrawBackgroundMosaic(uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) +{ + CHECK_SOUND(); + + uint32 Tile; + uint16* SC0; + uint16* SC1; + uint16* SC2; + uint16* SC3; + uint8 depths [2] = {Z1, Z2}; + + if (BGMode == 0) + BG.StartPalette = bg << 5; + else + BG.StartPalette = 0; + + SC0 = (uint16*) &Memory.VRAM[PPU.BG[bg].SCBase << 1]; + + if (PPU.BG[bg].SCSize & 1) + SC1 = SC0 + 1024; + else + SC1 = SC0; + + if (((uint8*)SC1 - Memory.VRAM) >= 0x10000) + SC1 -= 0x08000; + + + if (PPU.BG[bg].SCSize & 2) + SC2 = SC1 + 1024; + else + SC2 = SC0; + + if (((uint8*)SC2 - Memory.VRAM) >= 0x10000) + SC2 -= 0x08000; + + + if (PPU.BG[bg].SCSize & 1) + SC3 = SC2 + 1024; + else + SC3 = SC2; + + if (((uint8*)SC3 - Memory.VRAM) >= 0x10000) + SC3 -= 0x08000; + + uint32 Lines; + uint32 OffsetMask; + uint32 OffsetShift; + + if (BG.TileSize == 16) + { + OffsetMask = 0x3ff; + OffsetShift = 4; + } + else + { + OffsetMask = 0x1ff; + OffsetShift = 3; + } + + int m5 = (BGMode == 5 || BGMode == 6) ? 1 : 0; + + uint32 Y; + for (Y = GFX.StartY; Y <= GFX.EndY; Y += Lines) + { + uint32 VOffset = LineData [Y].BG[bg].VOffset; + uint32 HOffset = LineData [Y].BG[bg].HOffset; + uint32 MosaicOffset = Y % PPU.Mosaic; + + for (Lines = 1; Lines < PPU.Mosaic - MosaicOffset; Lines++) + if ((VOffset != LineData [Y + Lines].BG[bg].VOffset) || + (HOffset != LineData [Y + Lines].BG[bg].HOffset)) + break; + + uint32 MosaicLine = VOffset + Y - MosaicOffset; + + if (Y + Lines > GFX.EndY) + Lines = GFX.EndY + 1 - Y; + uint32 VirtAlign = (MosaicLine & 7) << 3; + + uint16* b1; + uint16* b2; + + uint32 ScreenLine = MosaicLine >> OffsetShift; + uint32 Rem16 = MosaicLine & 15; + + if (ScreenLine & 0x20) + b1 = SC2, b2 = SC3; + else + b1 = SC0, b2 = SC1; + + b1 += (ScreenLine & 0x1f) << 5; + b2 += (ScreenLine & 0x1f) << 5; + uint16* t; + uint32 Left = 0; + uint32 Right = 256 << m5; + + HOffset <<= m5; + + uint32 ClipCount = GFX.pCurrentClip->Count [bg]; + uint32 HPos = HOffset; + uint32 PixWidth = (PPU.Mosaic << m5); + + + if (!ClipCount) + ClipCount = 1; + + uint32 clip; + for (clip = 0; clip < ClipCount; clip++) + { + if (GFX.pCurrentClip->Count [bg]) + { + Left = GFX.pCurrentClip->Left [clip][bg] << m5; + Right = GFX.pCurrentClip->Right [clip][bg] << m5; + + uint32 r = Left % (PPU.Mosaic << m5); + HPos = HOffset + Left; + PixWidth = (PPU.Mosaic << m5) - r; + } + uint32 s = Y * GFX.PPL + Left * GFX.PixSize; + uint32 x; + for (x = Left; x < Right; x += PixWidth, + s += (IPPU.HalfWidthPixels ? PixWidth >> 1 : PixWidth) * GFX.PixSize, + HPos += PixWidth, PixWidth = (PPU.Mosaic << m5)) + { + uint32 Quot = (HPos & OffsetMask) >> 3; + + if (x + PixWidth >= Right) + PixWidth = Right - x; + + if (BG.TileSize == 8 && !m5) + { + if (Quot > 31) + t = b2 + (Quot & 0x1f); + else + t = b1 + Quot; + } + else + { + if (Quot > 63) + t = b2 + ((Quot >> 1) & 0x1f); + else + t = b1 + (Quot >> 1); + } + + Tile = READ_2BYTES(t); + GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; + + // Draw tile... + if (BG.TileSize != 8) + { + if (Tile & H_FLIP) + { + // Horizontal flip, but what about vertical flip ? + if (Tile & V_FLIP) + { + // Both horzontal & vertical flip + if (Rem16 < 8) + { + (*DrawLargePixelPtr)(Tile + 17 - (Quot & 1), s, + HPos & 7, PixWidth, + VirtAlign, Lines); + } + else + { + (*DrawLargePixelPtr)(Tile + 1 - (Quot & 1), s, + HPos & 7, PixWidth, + VirtAlign, Lines); + } + } + else + { + // Horizontal flip only + if (Rem16 > 7) + { + (*DrawLargePixelPtr)(Tile + 17 - (Quot & 1), s, + HPos & 7, PixWidth, + VirtAlign, Lines); + } + else + { + (*DrawLargePixelPtr)(Tile + 1 - (Quot & 1), s, + HPos & 7, PixWidth, + VirtAlign, Lines); + } + } + } + else + { + // No horizontal flip, but is there a vertical flip ? + if (Tile & V_FLIP) + { + // Vertical flip only + if (Rem16 < 8) + { + (*DrawLargePixelPtr)(Tile + 16 + (Quot & 1), s, + HPos & 7, PixWidth, + VirtAlign, Lines); + } + else + { + (*DrawLargePixelPtr)(Tile + (Quot & 1), s, + HPos & 7, PixWidth, + VirtAlign, Lines); + } + } + else + { + // Normal unflipped + if (Rem16 > 7) + { + (*DrawLargePixelPtr)(Tile + 16 + (Quot & 1), s, + HPos & 7, PixWidth, + VirtAlign, Lines); + } + else + { + (*DrawLargePixelPtr)(Tile + (Quot & 1), s, + HPos & 7, PixWidth, + VirtAlign, Lines); + } + } + } + } + else + (*DrawLargePixelPtr)(Tile + (Quot & 1) * m5, s, HPos & 7, PixWidth, + VirtAlign, Lines); + } + } + } +} + +static void DrawBackgroundOffset(uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) +{ + CHECK_SOUND(); + + uint32 Tile; + uint16* SC0; + uint16* SC1; + uint16* SC2; + uint16* SC3; + uint16* BPS0; + uint16* BPS1; + uint16* BPS2; + uint16* BPS3; + uint32 Width; + int VOffsetOffset = BGMode == 4 ? 0 : 32; + uint8 depths [2] = {Z1, Z2}; + + BG.StartPalette = 0; + + BPS0 = (uint16*) &Memory.VRAM[PPU.BG[2].SCBase << 1]; + + if (PPU.BG[2].SCSize & 1) + BPS1 = BPS0 + 1024; + else + BPS1 = BPS0; + + if (PPU.BG[2].SCSize & 2) + BPS2 = BPS1 + 1024; + else + BPS2 = BPS0; + + if (PPU.BG[2].SCSize & 1) + BPS3 = BPS2 + 1024; + else + BPS3 = BPS2; + + SC0 = (uint16*) &Memory.VRAM[PPU.BG[bg].SCBase << 1]; + + if (PPU.BG[bg].SCSize & 1) + SC1 = SC0 + 1024; + else + SC1 = SC0; + + if (((uint8*)SC1 - Memory.VRAM) >= 0x10000) + SC1 -= 0x08000; + + + if (PPU.BG[bg].SCSize & 2) + SC2 = SC1 + 1024; + else + SC2 = SC0; + + if (((uint8*)SC2 - Memory.VRAM) >= 0x10000) + SC2 -= 0x08000; + + + if (PPU.BG[bg].SCSize & 1) + SC3 = SC2 + 1024; + else + SC3 = SC2; + + if (((uint8*)SC3 - Memory.VRAM) >= 0x10000) + SC3 -= 0x08000; + + + static const int Lines = 1; + int OffsetMask; + int OffsetShift; + int OffsetEnableMask = 1 << (bg + 13); + + if (BG.TileSize == 16) + { + OffsetMask = 0x3ff; + OffsetShift = 4; + } + else + { + OffsetMask = 0x1ff; + OffsetShift = 3; + } + + uint32 Y; + for (Y = GFX.StartY; Y <= GFX.EndY; Y++) + { + uint32 VOff = LineData [Y].BG[2].VOffset - 1; + // uint32 VOff = LineData [Y].BG[2].VOffset; + uint32 HOff = LineData [Y].BG[2].HOffset; + + int VirtAlign; + int ScreenLine = VOff >> 3; + int t1; + int t2; + uint16* s0; + uint16* s1; + uint16* s2; + + if (ScreenLine & 0x20) + s1 = BPS2, s2 = BPS3; + else + s1 = BPS0, s2 = BPS1; + + s1 += (ScreenLine & 0x1f) << 5; + s2 += (ScreenLine & 0x1f) << 5; + + if (BGMode != 4) + { + if ((ScreenLine & 0x1f) == 0x1f) + { + if (ScreenLine & 0x20) + VOffsetOffset = BPS0 - BPS2 - 0x1f * 32; + else + VOffsetOffset = BPS2 - BPS0 - 0x1f * 32; + } + else + VOffsetOffset = 32; + } + + int clipcount = GFX.pCurrentClip->Count [bg]; + if (!clipcount) + clipcount = 1; + + int clip; + for (clip = 0; clip < clipcount; clip++) + { + uint32 Left; + uint32 Right; + + if (!GFX.pCurrentClip->Count [bg]) + { + Left = 0; + Right = 256; + } + else + { + Left = GFX.pCurrentClip->Left [clip][bg]; + Right = GFX.pCurrentClip->Right [clip][bg]; + + if (Right <= Left) + continue; + } + + uint32 VOffset; + uint32 HOffset; + //added: + uint32 LineHOffset = LineData [Y].BG[bg].HOffset; + + uint32 Offset; + uint32 HPos; + uint32 Quot; + uint32 Count; + uint16* t; + uint32 Quot2; + uint32 VCellOffset; + uint32 HCellOffset; + uint16* b1; + uint16* b2; + uint32 TotalCount = 0; + uint32 MaxCount = 8; + + uint32 s = Left * GFX.PixSize + Y * GFX.PPL; + bool8 left_hand_edge = (Left == 0); + Width = Right - Left; + + if (Left & 7) + MaxCount = 8 - (Left & 7); + + while (Left < Right) + { + if (left_hand_edge) + { + // The SNES offset-per-tile background mode has a + // hardware limitation that the offsets cannot be set + // for the tile at the left-hand edge of the screen. + VOffset = LineData [Y].BG[bg].VOffset; + + //MKendora; use temp var to reduce memory accesses + //HOffset = LineData [Y].BG[bg].HOffset; + + HOffset = LineHOffset; + //End MK + + left_hand_edge = FALSE; + } + else + + { + // All subsequent offset tile data is shifted left by one, + // hence the - 1 below. + + Quot2 = ((HOff + Left - 1) & OffsetMask) >> 3; + + if (Quot2 > 31) + s0 = s2 + (Quot2 & 0x1f); + else + s0 = s1 + Quot2; + + HCellOffset = READ_2BYTES(s0); + + if (BGMode == 4) + { + VOffset = LineData [Y].BG[bg].VOffset; + + //MKendora another mem access hack + //HOffset = LineData [Y].BG[bg].HOffset; + HOffset = LineHOffset; + //end MK + + if ((HCellOffset & OffsetEnableMask)) + { + if (HCellOffset & 0x8000) + VOffset = HCellOffset + 1; + else + HOffset = HCellOffset; + } + } + else + { + VCellOffset = READ_2BYTES(s0 + VOffsetOffset); + if ((VCellOffset & OffsetEnableMask)) + VOffset = VCellOffset + 1; + else + VOffset = LineData [Y].BG[bg].VOffset; + + //MKendora Strike Gunner fix + if ((HCellOffset & OffsetEnableMask)) + { + //HOffset= HCellOffset; + + HOffset = (HCellOffset & ~7) | (LineHOffset & 7); + //HOffset |= LineData [Y].BG[bg].HOffset&7; + } + else + HOffset = LineHOffset; + //HOffset = LineData [Y].BG[bg].HOffset - + //Settings.StrikeGunnerOffsetHack; + //HOffset &= (~7); + //end MK + } + } + VirtAlign = ((Y + VOffset) & 7) << 3; + ScreenLine = (VOffset + Y) >> OffsetShift; + + if (((VOffset + Y) & 15) > 7) + { + t1 = 16; + t2 = 0; + } + else + { + t1 = 0; + t2 = 16; + } + + if (ScreenLine & 0x20) + b1 = SC2, b2 = SC3; + else + b1 = SC0, b2 = SC1; + + b1 += (ScreenLine & 0x1f) << 5; + b2 += (ScreenLine & 0x1f) << 5; + + HPos = (HOffset + Left) & OffsetMask; + + Quot = HPos >> 3; + + if (BG.TileSize == 8) + { + if (Quot > 31) + t = b2 + (Quot & 0x1f); + else + t = b1 + Quot; + } + else + { + if (Quot > 63) + t = b2 + ((Quot >> 1) & 0x1f); + else + t = b1 + (Quot >> 1); + } + + if (MaxCount + TotalCount > Width) + MaxCount = Width - TotalCount; + + Offset = HPos & 7; + + //Count =1; + Count = 8 - Offset; + if (Count > MaxCount) + Count = MaxCount; + + s -= (IPPU.HalfWidthPixels ? Offset >> 1 : Offset) * GFX.PixSize; + Tile = READ_2BYTES(t); + GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; + + if (BG.TileSize == 8) + (*DrawClippedTilePtr)(Tile, s, Offset, Count, VirtAlign, Lines); + else + { + if (!(Tile & (V_FLIP | H_FLIP))) + { + // Normal, unflipped + (*DrawClippedTilePtr)(Tile + t1 + (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + else if (Tile & H_FLIP) + { + if (Tile & V_FLIP) + { + // H & V flip + (*DrawClippedTilePtr)(Tile + t2 + 1 - (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + else + { + // H flip only + (*DrawClippedTilePtr)(Tile + t1 + 1 - (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + } + else + { + // V flip only + (*DrawClippedTilePtr)(Tile + t2 + (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + } + + Left += Count; + TotalCount += Count; + s += (IPPU.HalfWidthPixels ? (Offset + Count) >> 1 : (Offset + Count)) * + GFX.PixSize; + MaxCount = 8; + } + } + } +} + +static void DrawBackgroundMode5(uint32 bg, uint8 Z1, uint8 Z2) +{ + CHECK_SOUND(); + + if (IPPU.Interlace) + { + GFX.Pitch = GFX.RealPitch; + GFX.PPL = GFX.PPLx2 >> 1; + } + GFX.PixSize = 1; + uint8 depths [2] = {Z1, Z2}; + + uint32 Tile; + uint16* SC0; + uint16* SC1; + uint16* SC2; + uint16* SC3; + uint32 Width; + + BG.StartPalette = 0; + + SC0 = (uint16*) &Memory.VRAM[PPU.BG[bg].SCBase << 1]; + + if ((PPU.BG[bg].SCSize & 1)) + SC1 = SC0 + 1024; + else + SC1 = SC0; + + if ((SC1 - (unsigned short*)Memory.VRAM) > 0x10000) + SC1 = (uint16*)&Memory.VRAM[(((uint8*)SC1) - Memory.VRAM) % 0x10000]; + + if ((PPU.BG[bg].SCSize & 2)) + SC2 = SC1 + 1024; + else SC2 = SC0; + + if (((uint8*)SC2 - Memory.VRAM) >= 0x10000) + SC2 -= 0x08000; + + + + if ((PPU.BG[bg].SCSize & 1)) + SC3 = SC2 + 1024; + else + SC3 = SC2; + + if (((uint8*)SC3 - Memory.VRAM) >= 0x10000) + SC3 -= 0x08000; + + + + int Lines; + int VOffsetMask; + int VOffsetShift; + + if (BG.TileSize == 16) + { + VOffsetMask = 0x3ff; + VOffsetShift = 4; + } + else + { + VOffsetMask = 0x1ff; + VOffsetShift = 3; + } + int endy = IPPU.Interlace ? 1 + (GFX.EndY << 1) : GFX.EndY; + + int Y; + for (Y = IPPU.Interlace ? GFX.StartY << 1 : GFX.StartY; Y <= endy; Y += Lines) + { + int y = IPPU.Interlace ? (Y >> 1) : Y; + uint32 VOffset = LineData [y].BG[bg].VOffset; + uint32 HOffset = LineData [y].BG[bg].HOffset; + int VirtAlign = (Y + VOffset) & 7; + + for (Lines = 1; Lines < 8 - VirtAlign; Lines++) + if ((VOffset != LineData [y + Lines].BG[bg].VOffset) || + (HOffset != LineData [y + Lines].BG[bg].HOffset)) + break; + + HOffset <<= 1; + if (Y + Lines > endy) + Lines = endy + 1 - Y; + VirtAlign <<= 3; + + int ScreenLine = (VOffset + Y) >> VOffsetShift; + int t1; + int t2; + if (((VOffset + Y) & 15) > 7) + { + t1 = 16; + t2 = 0; + } + else + { + t1 = 0; + t2 = 16; + } + uint16* b1; + uint16* b2; + + if (ScreenLine & 0x20) + b1 = SC2, b2 = SC3; + else + b1 = SC0, b2 = SC1; + + b1 += (ScreenLine & 0x1f) << 5; + b2 += (ScreenLine & 0x1f) << 5; + + int clipcount = GFX.pCurrentClip->Count [bg]; + if (!clipcount) + clipcount = 1; + + int clip; + for (clip = 0; clip < clipcount; clip++) + { + int Left; + int Right; + + if (!GFX.pCurrentClip->Count [bg]) + { + Left = 0; + Right = 512; + } + else + { + Left = GFX.pCurrentClip->Left [clip][bg] * 2; + Right = GFX.pCurrentClip->Right [clip][bg] * 2; + + if (Right <= Left) + continue; + } + + uint32 s = (IPPU.HalfWidthPixels ? Left >> 1 : Left) * GFX.PixSize + Y * + GFX.PPL; + uint32 HPos = (HOffset + Left * GFX.PixSize) & 0x3ff; + + uint32 Quot = HPos >> 3; + uint32 Count = 0; + + uint16* t; + if (Quot > 63) + t = b2 + ((Quot >> 1) & 0x1f); + else + t = b1 + (Quot >> 1); + + Width = Right - Left; + // Left hand edge clipped tile + if (HPos & 7) + { + int Offset = (HPos & 7); + Count = 8 - Offset; + if (Count > Width) + Count = Width; + s -= (IPPU.HalfWidthPixels ? Offset >> 1 : Offset); + Tile = READ_2BYTES(t); + GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; + + if (BG.TileSize == 8) + { + if (!(Tile & H_FLIP)) + { + // Normal, unflipped + (*DrawHiResClippedTilePtr)(Tile + (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + else + { + // H flip + (*DrawHiResClippedTilePtr)(Tile + 1 - (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + } + else + { + if (!(Tile & (V_FLIP | H_FLIP))) + { + // Normal, unflipped + (*DrawHiResClippedTilePtr)(Tile + t1 + (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + else if (Tile & H_FLIP) + { + if (Tile & V_FLIP) + { + // H & V flip + (*DrawHiResClippedTilePtr)(Tile + t2 + 1 - (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + else + { + // H flip only + (*DrawHiResClippedTilePtr)(Tile + t1 + 1 - (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + } + else + { + // V flip only + (*DrawHiResClippedTilePtr)(Tile + t2 + (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + } + + t += Quot & 1; + if (Quot == 63) + t = b2; + else if (Quot == 127) + t = b1; + Quot++; + s += (IPPU.HalfWidthPixels ? 4 : 8); + } + + // Middle, unclipped tiles + Count = Width - Count; + int Middle = Count >> 3; + Count &= 7; + + int C; + for (C = Middle; C > 0; s += (IPPU.HalfWidthPixels ? 4 : 8), Quot++, C--) + { + Tile = READ_2BYTES(t); + GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; + if (BG.TileSize == 8) + { + if (!(Tile & H_FLIP)) + { + // Normal, unflipped + (*DrawHiResTilePtr)(Tile + (Quot & 1), + s, VirtAlign, Lines); + } + else + { + // H flip + (*DrawHiResTilePtr)(Tile + 1 - (Quot & 1), + s, VirtAlign, Lines); + } + } + else + { + if (!(Tile & (V_FLIP | H_FLIP))) + { + // Normal, unflipped + (*DrawHiResTilePtr)(Tile + t1 + (Quot & 1), + s, VirtAlign, Lines); + } + else if (Tile & H_FLIP) + { + if (Tile & V_FLIP) + { + // H & V flip + (*DrawHiResTilePtr)(Tile + t2 + 1 - (Quot & 1), + s, VirtAlign, Lines); + } + else + { + // H flip only + (*DrawHiResTilePtr)(Tile + t1 + 1 - (Quot & 1), + s, VirtAlign, Lines); + } + } + else + { + // V flip only + (*DrawHiResTilePtr)(Tile + t2 + (Quot & 1), + s, VirtAlign, Lines); + } + } + + t += Quot & 1; + if (Quot == 63) + t = b2; + else if (Quot == 127) + t = b1; + } + + // Right-hand edge clipped tiles + if (Count) + { + Tile = READ_2BYTES(t); + GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; + if (BG.TileSize == 8) + { + if (!(Tile & H_FLIP)) + { + // Normal, unflipped + (*DrawHiResClippedTilePtr)(Tile + (Quot & 1), + s, 0, Count, VirtAlign, Lines); + } + else + { + // H flip + (*DrawHiResClippedTilePtr)(Tile + 1 - (Quot & 1), + s, 0, Count, VirtAlign, Lines); + } + } + else + { + if (!(Tile & (V_FLIP | H_FLIP))) + { + // Normal, unflipped + (*DrawHiResClippedTilePtr)(Tile + t1 + (Quot & 1), + s, 0, Count, VirtAlign, Lines); + } + else if (Tile & H_FLIP) + { + if (Tile & V_FLIP) + { + // H & V flip + (*DrawHiResClippedTilePtr)(Tile + t2 + 1 - (Quot & 1), + s, 0, Count, VirtAlign, Lines); + } + else + { + // H flip only + (*DrawHiResClippedTilePtr)(Tile + t1 + 1 - (Quot & 1), + s, 0, Count, VirtAlign, Lines); + } + } + else + { + // V flip only + (*DrawHiResClippedTilePtr)(Tile + t2 + (Quot & 1), + s, 0, Count, VirtAlign, Lines); + } + } + } + } + } + GFX.Pitch = IPPU.DoubleHeightPixels ? GFX.RealPitch * 2 : GFX.RealPitch; + GFX.PPL = IPPU.DoubleHeightPixels ? GFX.PPLx2 : (GFX.PPLx2 >> 1); + +} + +static void DrawBackground(uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) +{ +#ifdef ACCUMULATE_JOYPAD + /* + * This call allows NDSSFC to synchronise the DS controller more often. + * If porting a later version of Snes9x into NDSSFC, it is essential to + * preserve it. + */ + NDSSFCAccumulateJoypad(); +#endif + GFX.PixSize = 1; + + BG.TileSize = BGSizes [PPU.BG[bg].BGSize]; + BG.BitShift = BitShifts[BGMode][bg]; + BG.TileShift = TileShifts[BGMode][bg]; + BG.TileAddress = PPU.BG[bg].NameBase << 1; + BG.NameSelect = 0; + BG.Buffer = IPPU.TileCache [Depths [BGMode][bg]]; + BG.Buffered = IPPU.TileCached [Depths [BGMode][bg]]; + BG.PaletteShift = PaletteShifts[BGMode][bg]; + BG.PaletteMask = PaletteMasks[BGMode][bg]; + BG.DirectColourMode = (BGMode == 3 || BGMode == 4) && bg == 0 && + (GFX.r2130 & 1); + + if (PPU.BGMosaic [bg] && PPU.Mosaic > 1) + { + DrawBackgroundMosaic(BGMode, bg, Z1, Z2); + return; + + } + switch (BGMode) + { + case 2: + case 4: // Used by Puzzle Bobble + DrawBackgroundOffset(BGMode, bg, Z1, Z2); + return; + + case 5: + case 6: // XXX: is also offset per tile. + // if (Settings.SupportHiRes) + // { + if (!Settings.SupportHiRes) + SelectTileRenderer(TRUE /* normal */); + DrawBackgroundMode5(bg, Z1, Z2); + return; + // } + break; + } + CHECK_SOUND(); + + uint32 Tile; + uint16* SC0; + uint16* SC1; + uint16* SC2; + uint16* SC3; + uint32 Width; + uint8 depths [2] = {Z1, Z2}; + + if (BGMode == 0) + BG.StartPalette = bg << 5; + else BG.StartPalette = 0; + + SC0 = (uint16*) &Memory.VRAM[PPU.BG[bg].SCBase << 1]; + + if (PPU.BG[bg].SCSize & 1) + SC1 = SC0 + 1024; + else + SC1 = SC0; + + if (SC1 >= (unsigned short*)(Memory.VRAM + 0x10000)) + SC1 = (uint16*)&Memory.VRAM[((uint8*)SC1 - &Memory.VRAM[0]) % 0x10000]; + + if (PPU.BG[bg].SCSize & 2) + SC2 = SC1 + 1024; + else + SC2 = SC0; + + if (((uint8*)SC2 - Memory.VRAM) >= 0x10000) + SC2 -= 0x08000; + + if (PPU.BG[bg].SCSize & 1) + SC3 = SC2 + 1024; + else + SC3 = SC2; + + if (((uint8*)SC3 - Memory.VRAM) >= 0x10000) + SC3 -= 0x08000; + - uint32 Tile; - uint16 *SC0; - uint16 *SC1; - uint16 *SC2; - uint16 *SC3; - uint8 depths [2] = {Z1, Z2}; - - if (BGMode == 0) - BG.StartPalette = bg << 5; - else - BG.StartPalette = 0; - SC0 = (uint16 *) &Memory.VRAM[PPU.BG[bg].SCBase << 1]; + int Lines; + int OffsetMask; + int OffsetShift; - if (PPU.BG[bg].SCSize & 1) - SC1 = SC0 + 1024; - else - SC1 = SC0; + if (BG.TileSize == 16) + { + OffsetMask = 0x3ff; + OffsetShift = 4; + } + else + { + OffsetMask = 0x1ff; + OffsetShift = 3; + } - if(((uint8*)SC1-Memory.VRAM)>=0x10000) - SC1-=0x08000; + uint32 Y; + for (Y = GFX.StartY; Y <= GFX.EndY; Y += Lines) + { + uint32 VOffset = LineData [Y].BG[bg].VOffset; + uint32 HOffset = LineData [Y].BG[bg].HOffset; + int VirtAlign = (Y + VOffset) & 7; + for (Lines = 1; Lines < 8 - VirtAlign; Lines++) + if ((VOffset != LineData [Y + Lines].BG[bg].VOffset) || + (HOffset != LineData [Y + Lines].BG[bg].HOffset)) + break; - if (PPU.BG[bg].SCSize & 2) - SC2 = SC1 + 1024; - else - SC2 = SC0; + if (Y + Lines > GFX.EndY) + Lines = GFX.EndY + 1 - Y; - if(((uint8*)SC2-Memory.VRAM)>=0x10000) - SC2-=0x08000; + VirtAlign <<= 3; + uint32 ScreenLine = (VOffset + Y) >> OffsetShift; + uint32 t1; + uint32 t2; + if (((VOffset + Y) & 15) > 7) + { + t1 = 16; + t2 = 0; + } + else + { + t1 = 0; + t2 = 16; + } + uint16* b1; + uint16* b2; - if (PPU.BG[bg].SCSize & 1) - SC3 = SC2 + 1024; - else - SC3 = SC2; + if (ScreenLine & 0x20) + b1 = SC2, b2 = SC3; + else + b1 = SC0, b2 = SC1; - if(((uint8*)SC3-Memory.VRAM)>=0x10000) - SC3-=0x08000; + b1 += (ScreenLine & 0x1f) << 5; + b2 += (ScreenLine & 0x1f) << 5; - uint32 Lines; - uint32 OffsetMask; - uint32 OffsetShift; + int clipcount = GFX.pCurrentClip->Count [bg]; + if (!clipcount) + clipcount = 1; + int clip; + for (clip = 0; clip < clipcount; clip++) + { + uint32 Left; + uint32 Right; - if (BG.TileSize == 16) - { - OffsetMask = 0x3ff; - OffsetShift = 4; - } - else - { - OffsetMask = 0x1ff; - OffsetShift = 3; - } + if (!GFX.pCurrentClip->Count [bg]) + { + Left = 0; + Right = 256; + } + else + { + Left = GFX.pCurrentClip->Left [clip][bg]; + Right = GFX.pCurrentClip->Right [clip][bg]; - int m5 = (BGMode == 5 || BGMode == 6) ? 1 : 0; + if (Right <= Left) + continue; + } - uint32 Y; - for (Y = GFX.StartY; Y <= GFX.EndY; Y += Lines) - { - uint32 VOffset = LineData [Y].BG[bg].VOffset; - uint32 HOffset = LineData [Y].BG[bg].HOffset; - uint32 MosaicOffset = Y % PPU.Mosaic; - - for (Lines = 1; Lines < PPU.Mosaic - MosaicOffset; Lines++) - if ((VOffset != LineData [Y + Lines].BG[bg].VOffset) || - (HOffset != LineData [Y + Lines].BG[bg].HOffset)) - break; - - uint32 MosaicLine = VOffset + Y - MosaicOffset; - - if (Y + Lines > GFX.EndY) - Lines = GFX.EndY + 1 - Y; - uint32 VirtAlign = (MosaicLine & 7) << 3; - - uint16 *b1; - uint16 *b2; - - uint32 ScreenLine = MosaicLine >> OffsetShift; - uint32 Rem16 = MosaicLine & 15; - - if (ScreenLine & 0x20) - b1 = SC2, b2 = SC3; - else - b1 = SC0, b2 = SC1; - - b1 += (ScreenLine & 0x1f) << 5; - b2 += (ScreenLine & 0x1f) << 5; - uint16 *t; - uint32 Left = 0; - uint32 Right = 256 << m5; - - HOffset <<= m5; - - uint32 ClipCount = GFX.pCurrentClip->Count [bg]; - uint32 HPos = HOffset; - uint32 PixWidth = (PPU.Mosaic << m5); - - - if (!ClipCount) - ClipCount = 1; - - uint32 clip; - for (clip = 0; clip < ClipCount; clip++) - { - if (GFX.pCurrentClip->Count [bg]) - { - Left = GFX.pCurrentClip->Left [clip][bg] << m5; - Right = GFX.pCurrentClip->Right [clip][bg] << m5; - - uint32 r = Left % (PPU.Mosaic << m5); - HPos = HOffset + Left; - PixWidth = (PPU.Mosaic << m5) - r; - } - uint32 s = Y * GFX.PPL + Left * GFX.PixSize; - uint32 x; - for (x = Left; x < Right; x += PixWidth, - s += (IPPU.HalfWidthPixels ? PixWidth >> 1 : PixWidth) * GFX.PixSize, - HPos += PixWidth, PixWidth = (PPU.Mosaic << m5)) - { - uint32 Quot = (HPos & OffsetMask) >> 3; - - if (x + PixWidth >= Right) - PixWidth = Right - x; - - if (BG.TileSize == 8 && !m5) - { - if (Quot > 31) - t = b2 + (Quot & 0x1f); - else - t = b1 + Quot; - } - else - { - if (Quot > 63) - t = b2 + ((Quot >> 1) & 0x1f); - else - t = b1 + (Quot >> 1); - } - - Tile = READ_2BYTES (t); - GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; - - // Draw tile... - if (BG.TileSize != 8) - { - if (Tile & H_FLIP) - { - // Horizontal flip, but what about vertical flip ? - if (Tile & V_FLIP) - { - // Both horzontal & vertical flip - if (Rem16 < 8) - { - (*DrawLargePixelPtr) (Tile + 17 - (Quot & 1), s, - HPos & 7, PixWidth, - VirtAlign, Lines); - } - else - { - (*DrawLargePixelPtr) (Tile + 1 - (Quot & 1), s, - HPos & 7, PixWidth, - VirtAlign, Lines); - } - } - else - { - // Horizontal flip only - if (Rem16 > 7) - { - (*DrawLargePixelPtr) (Tile + 17 - (Quot & 1), s, - HPos & 7, PixWidth, - VirtAlign, Lines); - } - else - { - (*DrawLargePixelPtr) (Tile + 1 - (Quot & 1), s, - HPos & 7, PixWidth, - VirtAlign, Lines); - } - } - } - else - { - // No horizontal flip, but is there a vertical flip ? - if (Tile & V_FLIP) - { - // Vertical flip only - if (Rem16 < 8) - { - (*DrawLargePixelPtr) (Tile + 16 + (Quot & 1), s, - HPos & 7, PixWidth, - VirtAlign, Lines); - } - else - { - (*DrawLargePixelPtr) (Tile + (Quot & 1), s, - HPos & 7, PixWidth, - VirtAlign, Lines); - } - } - else - { - // Normal unflipped - if (Rem16 > 7) - { - (*DrawLargePixelPtr) (Tile + 16 + (Quot & 1), s, - HPos & 7, PixWidth, - VirtAlign, Lines); - } - else - { - (*DrawLargePixelPtr) (Tile + (Quot & 1), s, - HPos & 7, PixWidth, - VirtAlign, Lines); - } - } - } - } - else - (*DrawLargePixelPtr) (Tile + (Quot & 1) * m5, s, HPos & 7, PixWidth, - VirtAlign, Lines); - } - } - } -} + uint32 s = Left * GFX.PixSize + Y * GFX.PPL; + uint32 HPos = (HOffset + Left) & OffsetMask; -static void DrawBackgroundOffset (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) -{ - CHECK_SOUND(); - - uint32 Tile; - uint16 *SC0; - uint16 *SC1; - uint16 *SC2; - uint16 *SC3; - uint16 *BPS0; - uint16 *BPS1; - uint16 *BPS2; - uint16 *BPS3; - uint32 Width; - int VOffsetOffset = BGMode == 4 ? 0 : 32; - uint8 depths [2] = {Z1, Z2}; - - BG.StartPalette = 0; - - BPS0 = (uint16 *) &Memory.VRAM[PPU.BG[2].SCBase << 1]; - - if (PPU.BG[2].SCSize & 1) - BPS1 = BPS0 + 1024; - else - BPS1 = BPS0; - - if (PPU.BG[2].SCSize & 2) - BPS2 = BPS1 + 1024; - else - BPS2 = BPS0; - - if (PPU.BG[2].SCSize & 1) - BPS3 = BPS2 + 1024; - else - BPS3 = BPS2; - - SC0 = (uint16 *) &Memory.VRAM[PPU.BG[bg].SCBase << 1]; - - if (PPU.BG[bg].SCSize & 1) - SC1 = SC0 + 1024; - else - SC1 = SC0; - - if(((uint8*)SC1-Memory.VRAM)>=0x10000) - SC1-=0x08000; - - - if (PPU.BG[bg].SCSize & 2) - SC2 = SC1 + 1024; - else - SC2 = SC0; - - if(((uint8*)SC2-Memory.VRAM)>=0x10000) - SC2-=0x08000; - - - if (PPU.BG[bg].SCSize & 1) - SC3 = SC2 + 1024; - else - SC3 = SC2; - - if(((uint8*)SC3-Memory.VRAM)>=0x10000) - SC3-=0x08000; - - - static const int Lines = 1; - int OffsetMask; - int OffsetShift; - int OffsetEnableMask = 1 << (bg + 13); - - if (BG.TileSize == 16) - { - OffsetMask = 0x3ff; - OffsetShift = 4; - } - else - { - OffsetMask = 0x1ff; - OffsetShift = 3; - } + uint32 Quot = HPos >> 3; + uint32 Count = 0; - uint32 Y; - for (Y = GFX.StartY; Y <= GFX.EndY; Y++) - { - uint32 VOff = LineData [Y].BG[2].VOffset - 1; -// uint32 VOff = LineData [Y].BG[2].VOffset; - uint32 HOff = LineData [Y].BG[2].HOffset; - - int VirtAlign; - int ScreenLine = VOff >> 3; - int t1; - int t2; - uint16 *s0; - uint16 *s1; - uint16 *s2; - - if (ScreenLine & 0x20) - s1 = BPS2, s2 = BPS3; - else - s1 = BPS0, s2 = BPS1; - - s1 += (ScreenLine & 0x1f) << 5; - s2 += (ScreenLine & 0x1f) << 5; - - if(BGMode != 4) - { - if((ScreenLine & 0x1f) == 0x1f) - { - if(ScreenLine & 0x20) - VOffsetOffset = BPS0 - BPS2 - 0x1f*32; - else - VOffsetOffset = BPS2 - BPS0 - 0x1f*32; - } - else - { - VOffsetOffset = 32; - } - } - - int clipcount = GFX.pCurrentClip->Count [bg]; - if (!clipcount) - clipcount = 1; + uint16* t; + if (BG.TileSize == 8) + { + if (Quot > 31) + t = b2 + (Quot & 0x1f); + else + t = b1 + Quot; + } + else + { + if (Quot > 63) + t = b2 + ((Quot >> 1) & 0x1f); + else + t = b1 + (Quot >> 1); + } - int clip; - for (clip = 0; clip < clipcount; clip++) - { - uint32 Left; - uint32 Right; - - if (!GFX.pCurrentClip->Count [bg]) - { - Left = 0; - Right = 256; - } - else - { - Left = GFX.pCurrentClip->Left [clip][bg]; - Right = GFX.pCurrentClip->Right [clip][bg]; - - if (Right <= Left) - continue; - } - - uint32 VOffset; - uint32 HOffset; - //added: - uint32 LineHOffset=LineData [Y].BG[bg].HOffset; - - uint32 Offset; - uint32 HPos; - uint32 Quot; - uint32 Count; - uint16 *t; - uint32 Quot2; - uint32 VCellOffset; - uint32 HCellOffset; - uint16 *b1; - uint16 *b2; - uint32 TotalCount = 0; - uint32 MaxCount = 8; - - uint32 s = Left * GFX.PixSize + Y * GFX.PPL; - bool8 left_hand_edge = (Left == 0); - Width = Right - Left; - - if (Left & 7) - MaxCount = 8 - (Left & 7); - - while (Left < Right) - { - if (left_hand_edge) - { - // The SNES offset-per-tile background mode has a - // hardware limitation that the offsets cannot be set - // for the tile at the left-hand edge of the screen. - VOffset = LineData [Y].BG[bg].VOffset; - - //MKendora; use temp var to reduce memory accesses - //HOffset = LineData [Y].BG[bg].HOffset; - - HOffset = LineHOffset; - //End MK - - left_hand_edge = FALSE; - } - else - - { - // All subsequent offset tile data is shifted left by one, - // hence the - 1 below. - - Quot2 = ((HOff + Left - 1) & OffsetMask) >> 3; - - if (Quot2 > 31) - s0 = s2 + (Quot2 & 0x1f); - else - s0 = s1 + Quot2; - - HCellOffset = READ_2BYTES (s0); - - if (BGMode == 4) - { - VOffset = LineData [Y].BG[bg].VOffset; - - //MKendora another mem access hack - //HOffset = LineData [Y].BG[bg].HOffset; - HOffset=LineHOffset; - //end MK - - if ((HCellOffset & OffsetEnableMask)) - { - if (HCellOffset & 0x8000) - VOffset = HCellOffset + 1; - else - HOffset = HCellOffset; - } - } - else - { - VCellOffset = READ_2BYTES (s0 + VOffsetOffset); - if ((VCellOffset & OffsetEnableMask)) - VOffset = VCellOffset + 1; - else - VOffset = LineData [Y].BG[bg].VOffset; - - //MKendora Strike Gunner fix - if ((HCellOffset & OffsetEnableMask)) - { - //HOffset= HCellOffset; - - HOffset = (HCellOffset & ~7)|(LineHOffset&7); - //HOffset |= LineData [Y].BG[bg].HOffset&7; - } - else - HOffset=LineHOffset; - //HOffset = LineData [Y].BG[bg].HOffset - - //Settings.StrikeGunnerOffsetHack; - //HOffset &= (~7); - //end MK - } - } - VirtAlign = ((Y + VOffset) & 7) << 3; - ScreenLine = (VOffset + Y) >> OffsetShift; - - if (((VOffset + Y) & 15) > 7) - { - t1 = 16; - t2 = 0; - } - else - { - t1 = 0; - t2 = 16; - } - - if (ScreenLine & 0x20) - b1 = SC2, b2 = SC3; - else - b1 = SC0, b2 = SC1; - - b1 += (ScreenLine & 0x1f) << 5; - b2 += (ScreenLine & 0x1f) << 5; - - HPos = (HOffset + Left) & OffsetMask; - - Quot = HPos >> 3; - - if (BG.TileSize == 8) - { - if (Quot > 31) - t = b2 + (Quot & 0x1f); - else - t = b1 + Quot; - } - else - { - if (Quot > 63) - t = b2 + ((Quot >> 1) & 0x1f); - else - t = b1 + (Quot >> 1); - } - - if (MaxCount + TotalCount > Width) - MaxCount = Width - TotalCount; - - Offset = HPos & 7; - - //Count =1; - Count = 8 - Offset; - if (Count > MaxCount) - Count = MaxCount; - - s -= (IPPU.HalfWidthPixels ? Offset >> 1 : Offset) * GFX.PixSize; - Tile = READ_2BYTES(t); - GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; - - if (BG.TileSize == 8) - (*DrawClippedTilePtr) (Tile, s, Offset, Count, VirtAlign, Lines); - else - { - if (!(Tile & (V_FLIP | H_FLIP))) - { - // Normal, unflipped - (*DrawClippedTilePtr) (Tile + t1 + (Quot & 1), - s, Offset, Count, VirtAlign, Lines); - } - else - if (Tile & H_FLIP) - { - if (Tile & V_FLIP) - { - // H & V flip - (*DrawClippedTilePtr) (Tile + t2 + 1 - (Quot & 1), - s, Offset, Count, VirtAlign, Lines); - } - else - { - // H flip only - (*DrawClippedTilePtr) (Tile + t1 + 1 - (Quot & 1), - s, Offset, Count, VirtAlign, Lines); - } - } - else - { - // V flip only - (*DrawClippedTilePtr) (Tile + t2 + (Quot & 1), - s, Offset, Count, VirtAlign, Lines); - } - } - - Left += Count; - TotalCount += Count; - s += (IPPU.HalfWidthPixels ? (Offset + Count) >> 1 : (Offset + Count)) * GFX.PixSize; - MaxCount = 8; - } - } - } -} + Width = Right - Left; + // Left hand edge clipped tile + if (HPos & 7) + { + uint32 Offset = (HPos & 7); + Count = 8 - Offset; + if (Count > Width) + Count = Width; + s -= Offset * GFX.PixSize; + Tile = READ_2BYTES(t); + GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; + + if (BG.TileSize == 8) + { + (*DrawClippedTilePtr)(Tile, s, Offset, Count, VirtAlign, + Lines); + } + else + { + if (!(Tile & (V_FLIP | H_FLIP))) + { + // Normal, unflipped + (*DrawClippedTilePtr)(Tile + t1 + (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + else if (Tile & H_FLIP) + { + if (Tile & V_FLIP) + { + // H & V flip + (*DrawClippedTilePtr)(Tile + t2 + 1 - (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + else + { + // H flip only + (*DrawClippedTilePtr)(Tile + t1 + 1 - (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + } + else + { + // V flip only + (*DrawClippedTilePtr)(Tile + t2 + (Quot & 1), s, + Offset, Count, VirtAlign, Lines); + } + } -static void DrawBackgroundMode5 (uint32 bg, uint8 Z1, uint8 Z2) -{ - CHECK_SOUND(); - - if(IPPU.Interlace) - { - GFX.Pitch = GFX.RealPitch; - GFX.PPL = GFX.PPLx2 >> 1; - } - GFX.PixSize = 1; - uint8 depths [2] = {Z1, Z2}; - - uint32 Tile; - uint16 *SC0; - uint16 *SC1; - uint16 *SC2; - uint16 *SC3; - uint32 Width; - - BG.StartPalette = 0; - - SC0 = (uint16 *) &Memory.VRAM[PPU.BG[bg].SCBase << 1]; - - if ((PPU.BG[bg].SCSize & 1)) - SC1 = SC0 + 1024; - else - SC1 = SC0; - - if((SC1-(unsigned short*)Memory.VRAM)>0x10000) - SC1=(uint16*)&Memory.VRAM[(((uint8*)SC1)-Memory.VRAM)%0x10000]; - - if ((PPU.BG[bg].SCSize & 2)) - SC2 = SC1 + 1024; - else SC2 = SC0; - - if(((uint8*)SC2-Memory.VRAM)>=0x10000) - SC2-=0x08000; - - - - if ((PPU.BG[bg].SCSize & 1)) - SC3 = SC2 + 1024; - else - SC3 = SC2; - - if(((uint8*)SC3-Memory.VRAM)>=0x10000) - SC3-=0x08000; - - - - int Lines; - int VOffsetMask; - int VOffsetShift; - - if (BG.TileSize == 16) - { - VOffsetMask = 0x3ff; - VOffsetShift = 4; - } - else - { - VOffsetMask = 0x1ff; - VOffsetShift = 3; - } - int endy = IPPU.Interlace ? 1 + (GFX.EndY << 1) : GFX.EndY; - - int Y; - for (Y = IPPU.Interlace ? GFX.StartY << 1 : GFX.StartY; Y <= endy; Y += Lines) - { - int y = IPPU.Interlace ? (Y >> 1) : Y; - uint32 VOffset = LineData [y].BG[bg].VOffset; - uint32 HOffset = LineData [y].BG[bg].HOffset; - int VirtAlign = (Y + VOffset) & 7; - - for (Lines = 1; Lines < 8 - VirtAlign; Lines++) - if ((VOffset != LineData [y + Lines].BG[bg].VOffset) || - (HOffset != LineData [y + Lines].BG[bg].HOffset)) - break; - - HOffset <<= 1; - if (Y + Lines > endy) - Lines = endy + 1 - Y; - VirtAlign <<= 3; - - int ScreenLine = (VOffset + Y) >> VOffsetShift; - int t1; - int t2; - if (((VOffset + Y) & 15) > 7) - { - t1 = 16; - t2 = 0; - } - else - { - t1 = 0; - t2 = 16; - } - uint16 *b1; - uint16 *b2; - - if (ScreenLine & 0x20) - b1 = SC2, b2 = SC3; - else - b1 = SC0, b2 = SC1; - - b1 += (ScreenLine & 0x1f) << 5; - b2 += (ScreenLine & 0x1f) << 5; - - int clipcount = GFX.pCurrentClip->Count [bg]; - if (!clipcount) - clipcount = 1; - - int clip; - for (clip = 0; clip < clipcount; clip++) - { - int Left; - int Right; - - if (!GFX.pCurrentClip->Count [bg]) - { - Left = 0; - Right = 512; - } - else - { - Left = GFX.pCurrentClip->Left [clip][bg] * 2; - Right = GFX.pCurrentClip->Right [clip][bg] * 2; - - if (Right <= Left) - continue; - } - - uint32 s = (IPPU.HalfWidthPixels ? Left >> 1 : Left) * GFX.PixSize + Y * GFX.PPL; - uint32 HPos = (HOffset + Left * GFX.PixSize) & 0x3ff; - - uint32 Quot = HPos >> 3; - uint32 Count = 0; - - uint16 *t; - if (Quot > 63) - t = b2 + ((Quot >> 1) & 0x1f); - else - t = b1 + (Quot >> 1); - - Width = Right - Left; - // Left hand edge clipped tile - if (HPos & 7) - { - int Offset = (HPos & 7); - Count = 8 - Offset; - if (Count > Width) - Count = Width; - s -= (IPPU.HalfWidthPixels ? Offset >> 1 : Offset); - Tile = READ_2BYTES (t); - GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; - - if (BG.TileSize == 8) - { - if (!(Tile & H_FLIP)) - { - // Normal, unflipped - (*DrawHiResClippedTilePtr) (Tile + (Quot & 1), - s, Offset, Count, VirtAlign, Lines); - } - else - { - // H flip - (*DrawHiResClippedTilePtr) (Tile + 1 - (Quot & 1), - s, Offset, Count, VirtAlign, Lines); - } - } - else - { - if (!(Tile & (V_FLIP | H_FLIP))) - { - // Normal, unflipped - (*DrawHiResClippedTilePtr) (Tile + t1 + (Quot & 1), - s, Offset, Count, VirtAlign, Lines); - } - else - if (Tile & H_FLIP) - { - if (Tile & V_FLIP) - { - // H & V flip - (*DrawHiResClippedTilePtr) (Tile + t2 + 1 - (Quot & 1), - s, Offset, Count, VirtAlign, Lines); - } - else - { - // H flip only - (*DrawHiResClippedTilePtr) (Tile + t1 + 1 - (Quot & 1), - s, Offset, Count, VirtAlign, Lines); - } - } - else - { - // V flip only - (*DrawHiResClippedTilePtr) (Tile + t2 + (Quot & 1), - s, Offset, Count, VirtAlign, Lines); - } - } - - t += Quot & 1; - if (Quot == 63) - t = b2; - else if (Quot == 127) - t = b1; - Quot++; - s += (IPPU.HalfWidthPixels ? 4 : 8); - } - - // Middle, unclipped tiles - Count = Width - Count; - int Middle = Count >> 3; - Count &= 7; - - int C; - for (C = Middle; C > 0; s += (IPPU.HalfWidthPixels ? 4 : 8), Quot++, C--) - { - Tile = READ_2BYTES(t); - GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; - if (BG.TileSize == 8) - { - if (!(Tile & H_FLIP)) - { - // Normal, unflipped - (*DrawHiResTilePtr) (Tile + (Quot & 1), - s, VirtAlign, Lines); - } - else - { - // H flip - (*DrawHiResTilePtr) (Tile + 1 - (Quot & 1), - s, VirtAlign, Lines); - } - } - else - { - if (!(Tile & (V_FLIP | H_FLIP))) - { - // Normal, unflipped - (*DrawHiResTilePtr) (Tile + t1 + (Quot & 1), - s, VirtAlign, Lines); - } - else - if (Tile & H_FLIP) - { - if (Tile & V_FLIP) - { - // H & V flip - (*DrawHiResTilePtr) (Tile + t2 + 1 - (Quot & 1), - s, VirtAlign, Lines); - } - else - { - // H flip only - (*DrawHiResTilePtr) (Tile + t1 + 1 - (Quot & 1), - s, VirtAlign, Lines); - } - } - else - { - // V flip only - (*DrawHiResTilePtr) (Tile + t2 + (Quot & 1), - s, VirtAlign, Lines); - } - } - - t += Quot & 1; - if (Quot == 63) - t = b2; - else - if (Quot == 127) - t = b1; - } - - // Right-hand edge clipped tiles - if (Count) - { - Tile = READ_2BYTES(t); - GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; - if (BG.TileSize == 8) - { - if (!(Tile & H_FLIP)) - { - // Normal, unflipped - (*DrawHiResClippedTilePtr) (Tile + (Quot & 1), - s, 0, Count, VirtAlign, Lines); - } - else - { - // H flip - (*DrawHiResClippedTilePtr) (Tile + 1 - (Quot & 1), - s, 0, Count, VirtAlign, Lines); - } - } - else - { - if (!(Tile & (V_FLIP | H_FLIP))) - { - // Normal, unflipped - (*DrawHiResClippedTilePtr) (Tile + t1 + (Quot & 1), - s, 0, Count, VirtAlign, Lines); - } - else - if (Tile & H_FLIP) - { - if (Tile & V_FLIP) - { - // H & V flip - (*DrawHiResClippedTilePtr) (Tile + t2 + 1 - (Quot & 1), - s, 0, Count, VirtAlign, Lines); - } - else - { - // H flip only - (*DrawHiResClippedTilePtr) (Tile + t1 + 1 - (Quot & 1), - s, 0, Count, VirtAlign, Lines); - } - } - else - { - // V flip only - (*DrawHiResClippedTilePtr) (Tile + t2 + (Quot & 1), - s, 0, Count, VirtAlign, Lines); - } - } - } - } - } - GFX.Pitch = IPPU.DoubleHeightPixels ? GFX.RealPitch * 2 : GFX.RealPitch; - GFX.PPL = IPPU.DoubleHeightPixels ? GFX.PPLx2 : (GFX.PPLx2 >> 1); + if (BG.TileSize == 8) + { + t++; + if (Quot == 31) + t = b2; + else if (Quot == 63) + t = b1; + } + else + { + t += Quot & 1; + if (Quot == 63) + t = b2; + else if (Quot == 127) + t = b1; + } + Quot++; + s += (IPPU.HalfWidthPixels ? 4 : 8) * GFX.PixSize; + } -} + // Middle, unclipped tiles + Count = Width - Count; + int Middle = Count >> 3; + Count &= 7; + int C; + for (C = Middle; C > 0; + s += (IPPU.HalfWidthPixels ? 4 : 8) * GFX.PixSize, Quot++, C--) + { + Tile = READ_2BYTES(t); + GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; -static void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) -{ -#ifdef ACCUMULATE_JOYPAD -/* - * This call allows NDSSFC to synchronise the DS controller more often. - * If porting a later version of Snes9x into NDSSFC, it is essential to - * preserve it. - */ - NDSSFCAccumulateJoypad (); -#endif - GFX.PixSize = 1; - - BG.TileSize = BGSizes [PPU.BG[bg].BGSize]; - BG.BitShift = BitShifts[BGMode][bg]; - BG.TileShift = TileShifts[BGMode][bg]; - BG.TileAddress = PPU.BG[bg].NameBase << 1; - BG.NameSelect = 0; - BG.Buffer = IPPU.TileCache [Depths [BGMode][bg]]; - BG.Buffered = IPPU.TileCached [Depths [BGMode][bg]]; - BG.PaletteShift = PaletteShifts[BGMode][bg]; - BG.PaletteMask = PaletteMasks[BGMode][bg]; - BG.DirectColourMode = (BGMode == 3 || BGMode == 4) && bg == 0 && - (GFX.r2130 & 1); - - if (PPU.BGMosaic [bg] && PPU.Mosaic > 1) - { - DrawBackgroundMosaic (BGMode, bg, Z1, Z2); - return; - - } - switch (BGMode) - { - case 2: - case 4: // Used by Puzzle Bobble - DrawBackgroundOffset (BGMode, bg, Z1, Z2); - return; - - case 5: - case 6: // XXX: is also offset per tile. -// if (Settings.SupportHiRes) -// { - if (!Settings.SupportHiRes) - SelectTileRenderer(TRUE /* normal */); - DrawBackgroundMode5 (bg, Z1, Z2); - return; -// } - break; - } - CHECK_SOUND(); - - uint32 Tile; - uint16 *SC0; - uint16 *SC1; - uint16 *SC2; - uint16 *SC3; - uint32 Width; - uint8 depths [2] = {Z1, Z2}; - - if (BGMode == 0) - BG.StartPalette = bg << 5; - else BG.StartPalette = 0; - - SC0 = (uint16 *) &Memory.VRAM[PPU.BG[bg].SCBase << 1]; - - if (PPU.BG[bg].SCSize & 1) - SC1 = SC0 + 1024; - else - SC1 = SC0; - - if(SC1>=(unsigned short*)(Memory.VRAM+0x10000)) - SC1=(uint16*)&Memory.VRAM[((uint8*)SC1-&Memory.VRAM[0])%0x10000]; - - if (PPU.BG[bg].SCSize & 2) - SC2 = SC1 + 1024; - else - SC2 = SC0; - - if(((uint8*)SC2-Memory.VRAM)>=0x10000) - SC2-=0x08000; - - if (PPU.BG[bg].SCSize & 1) - SC3 = SC2 + 1024; - else - SC3 = SC2; - - if(((uint8*)SC3-Memory.VRAM)>=0x10000) - SC3-=0x08000; - - - - int Lines; - int OffsetMask; - int OffsetShift; - - if (BG.TileSize == 16) - { - OffsetMask = 0x3ff; - OffsetShift = 4; - } - else - { - OffsetMask = 0x1ff; - OffsetShift = 3; - } - - uint32 Y; - for (Y = GFX.StartY; Y <= GFX.EndY; Y += Lines) - { - uint32 VOffset = LineData [Y].BG[bg].VOffset; - uint32 HOffset = LineData [Y].BG[bg].HOffset; - int VirtAlign = (Y + VOffset) & 7; - - for (Lines = 1; Lines < 8 - VirtAlign; Lines++) - if ((VOffset != LineData [Y + Lines].BG[bg].VOffset) || - (HOffset != LineData [Y + Lines].BG[bg].HOffset)) - break; - - if (Y + Lines > GFX.EndY) - Lines = GFX.EndY + 1 - Y; - - VirtAlign <<= 3; - - uint32 ScreenLine = (VOffset + Y) >> OffsetShift; - uint32 t1; - uint32 t2; - if (((VOffset + Y) & 15) > 7) - { - t1 = 16; - t2 = 0; - } - else - { - t1 = 0; - t2 = 16; - } - uint16 *b1; - uint16 *b2; - - if (ScreenLine & 0x20) - b1 = SC2, b2 = SC3; - else - b1 = SC0, b2 = SC1; - - b1 += (ScreenLine & 0x1f) << 5; - b2 += (ScreenLine & 0x1f) << 5; - - int clipcount = GFX.pCurrentClip->Count [bg]; - if (!clipcount) - clipcount = 1; - int clip; - for (clip = 0; clip < clipcount; clip++) - { - uint32 Left; - uint32 Right; - - if (!GFX.pCurrentClip->Count [bg]) - { - Left = 0; - Right = 256; - } - else - { - Left = GFX.pCurrentClip->Left [clip][bg]; - Right = GFX.pCurrentClip->Right [clip][bg]; - - if (Right <= Left) - continue; - } - - uint32 s = Left * GFX.PixSize + Y * GFX.PPL; - uint32 HPos = (HOffset + Left) & OffsetMask; - - uint32 Quot = HPos >> 3; - uint32 Count = 0; - - uint16 *t; - if (BG.TileSize == 8) - { - if (Quot > 31) - t = b2 + (Quot & 0x1f); - else - t = b1 + Quot; - } - else - { - if (Quot > 63) - t = b2 + ((Quot >> 1) & 0x1f); - else - t = b1 + (Quot >> 1); - } - - Width = Right - Left; - // Left hand edge clipped tile - if (HPos & 7) - { - uint32 Offset = (HPos & 7); - Count = 8 - Offset; - if (Count > Width) - Count = Width; - s -= Offset * GFX.PixSize; - Tile = READ_2BYTES(t); - GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; - - if (BG.TileSize == 8) - { - (*DrawClippedTilePtr) (Tile, s, Offset, Count, VirtAlign, - Lines); - } - else - { - if (!(Tile & (V_FLIP | H_FLIP))) - { - // Normal, unflipped - (*DrawClippedTilePtr) (Tile + t1 + (Quot & 1), - s, Offset, Count, VirtAlign, Lines); - } - else - if (Tile & H_FLIP) - { - if (Tile & V_FLIP) - { - // H & V flip - (*DrawClippedTilePtr) (Tile + t2 + 1 - (Quot & 1), - s, Offset, Count, VirtAlign, Lines); - } - else - { - // H flip only - (*DrawClippedTilePtr) (Tile + t1 + 1 - (Quot & 1), - s, Offset, Count, VirtAlign, Lines); - } - } - else - { - // V flip only - (*DrawClippedTilePtr) (Tile + t2 + (Quot & 1), s, - Offset, Count, VirtAlign, Lines); - } - } - - if (BG.TileSize == 8) - { - t++; - if (Quot == 31) - t = b2; - else if (Quot == 63) - t = b1; - } - else - { - t += Quot & 1; - if (Quot == 63) - t = b2; - else if (Quot == 127) - t = b1; - } - Quot++; - s += (IPPU.HalfWidthPixels ? 4 : 8) * GFX.PixSize; - } - - // Middle, unclipped tiles - Count = Width - Count; - int Middle = Count >> 3; - Count &= 7; - int C; - for (C = Middle; C > 0; s += (IPPU.HalfWidthPixels ? 4 : 8) * GFX.PixSize, Quot++, C--) - { - Tile = READ_2BYTES(t); - GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; - - if (BG.TileSize != 8) - { - if (Tile & H_FLIP) - { - // Horizontal flip, but what about vertical flip ? - if (Tile & V_FLIP) - { - // Both horzontal & vertical flip - (*DrawTilePtr) (Tile + t2 + 1 - (Quot & 1), s, - VirtAlign, Lines); - } - else - { - // Horizontal flip only - (*DrawTilePtr) (Tile + t1 + 1 - (Quot & 1), s, - VirtAlign, Lines); - } - } - else - { - // No horizontal flip, but is there a vertical flip ? - if (Tile & V_FLIP) - { - // Vertical flip only - (*DrawTilePtr) (Tile + t2 + (Quot & 1), s, - VirtAlign, Lines); - } - else - { - // Normal unflipped - (*DrawTilePtr) (Tile + t1 + (Quot & 1), s, - VirtAlign, Lines); - } - } - } - else - { - (*DrawTilePtr) (Tile, s, VirtAlign, Lines); - } - - if (BG.TileSize == 8) - { - t++; - if (Quot == 31) - t = b2; - else - if (Quot == 63) - t = b1; - } - else - { - t += Quot & 1; - if (Quot == 63) - t = b2; - else - if (Quot == 127) - t = b1; - } - } - // Right-hand edge clipped tiles - if (Count) - { - Tile = READ_2BYTES(t); - GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; - - if (BG.TileSize == 8) - (*DrawClippedTilePtr) (Tile, s, 0, Count, VirtAlign, - Lines); - else - { - if (!(Tile & (V_FLIP | H_FLIP))) - { - // Normal, unflipped - (*DrawClippedTilePtr) (Tile + t1 + (Quot & 1), s, 0, - Count, VirtAlign, Lines); - } - else if (Tile & H_FLIP) - { - if (Tile & V_FLIP) - { - // H & V flip - (*DrawClippedTilePtr) (Tile + t2 + 1 - (Quot & 1), - s, 0, Count, VirtAlign, - Lines); - } - else - { - // H flip only - (*DrawClippedTilePtr) (Tile + t1 + 1 - (Quot & 1), - s, 0, Count, VirtAlign, - Lines); - } - } - else - { - // V flip only - (*DrawClippedTilePtr) (Tile + t2 + (Quot & 1), - s, 0, Count, VirtAlign, - Lines); - } - } - } - } - } + if (BG.TileSize != 8) + { + if (Tile & H_FLIP) + { + // Horizontal flip, but what about vertical flip ? + if (Tile & V_FLIP) + { + // Both horzontal & vertical flip + (*DrawTilePtr)(Tile + t2 + 1 - (Quot & 1), s, + VirtAlign, Lines); + } + else + { + // Horizontal flip only + (*DrawTilePtr)(Tile + t1 + 1 - (Quot & 1), s, + VirtAlign, Lines); + } + } + else + { + // No horizontal flip, but is there a vertical flip ? + if (Tile & V_FLIP) + { + // Vertical flip only + (*DrawTilePtr)(Tile + t2 + (Quot & 1), s, + VirtAlign, Lines); + } + else + { + // Normal unflipped + (*DrawTilePtr)(Tile + t1 + (Quot & 1), s, + VirtAlign, Lines); + } + } + } + else + (*DrawTilePtr)(Tile, s, VirtAlign, Lines); + + if (BG.TileSize == 8) + { + t++; + if (Quot == 31) + t = b2; + else if (Quot == 63) + t = b1; + } + else + { + t += Quot & 1; + if (Quot == 63) + t = b2; + else if (Quot == 127) + t = b1; + } + } + // Right-hand edge clipped tiles + if (Count) + { + Tile = READ_2BYTES(t); + GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; + + if (BG.TileSize == 8) + (*DrawClippedTilePtr)(Tile, s, 0, Count, VirtAlign, + Lines); + else + { + if (!(Tile & (V_FLIP | H_FLIP))) + { + // Normal, unflipped + (*DrawClippedTilePtr)(Tile + t1 + (Quot & 1), s, 0, + Count, VirtAlign, Lines); + } + else if (Tile & H_FLIP) + { + if (Tile & V_FLIP) + { + // H & V flip + (*DrawClippedTilePtr)(Tile + t2 + 1 - (Quot & 1), + s, 0, Count, VirtAlign, + Lines); + } + else + { + // H flip only + (*DrawClippedTilePtr)(Tile + t1 + 1 - (Quot & 1), + s, 0, Count, VirtAlign, + Lines); + } + } + else + { + // V flip only + (*DrawClippedTilePtr)(Tile + t2 + (Quot & 1), + s, 0, Count, VirtAlign, + Lines); + } + } + } + } + } } #define RENDER_BACKGROUND_MODE7(TYPE,FUNC) \ @@ -2514,12 +2586,12 @@ static void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) uint8 *VRAM1 = Memory.VRAM + 1; \ if (GFX.r2130 & 1) \ { \ - if (IPPU.DirectColourMapsNeedRebuild) \ - S9xBuildDirectColourMaps (); \ - ScreenColors = DirectColourMaps [0]; \ + if (IPPU.DirectColourMapsNeedRebuild) \ + S9xBuildDirectColourMaps (); \ + ScreenColors = DirectColourMaps [0]; \ } \ else \ - ScreenColors = IPPU.ScreenColors; \ + ScreenColors = IPPU.ScreenColors; \ \ int aa, cc; \ int dir; \ @@ -2529,7 +2601,7 @@ static void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) uint32 ClipCount = GFX.pCurrentClip->Count [bg]; \ \ if (!ClipCount) \ - ClipCount = 1; \ + ClipCount = 1; \ \ Screen += GFX.StartY * GFX.Pitch; \ uint8 *Depth = GFX.DB + GFX.StartY * GFX.PPL; \ @@ -2538,166 +2610,166 @@ static void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) uint32 Line; \ for (Line = GFX.StartY; Line <= GFX.EndY; Line++, Screen += GFX.Pitch, Depth += GFX.PPL, l++) \ { \ - int yy; \ + int yy; \ \ - int32 HOffset = ((int32) LineData [Line].BG[0].HOffset << M7) >> M7; \ - int32 VOffset = ((int32) LineData [Line].BG[0].VOffset << M7) >> M7; \ + int32 HOffset = ((int32) LineData [Line].BG[0].HOffset << M7) >> M7; \ + int32 VOffset = ((int32) LineData [Line].BG[0].VOffset << M7) >> M7; \ \ - int32 CentreX = ((int32) l->CentreX << M7) >> M7; \ - int32 CentreY = ((int32) l->CentreY << M7) >> M7; \ + int32 CentreX = ((int32) l->CentreX << M7) >> M7; \ + int32 CentreY = ((int32) l->CentreY << M7) >> M7; \ \ - if (PPU.Mode7VFlip) \ - yy = 255 - (int) Line; \ - else \ - yy = Line; \ + if (PPU.Mode7VFlip) \ + yy = 255 - (int) Line; \ + else \ + yy = Line; \ \ yy += CLIP_10_BIT_SIGNED(VOffset - CentreY); \ \ int BB = l->MatrixB * yy + (CentreX << 8); \ - int DD = l->MatrixD * yy + (CentreY << 8); \ + int DD = l->MatrixD * yy + (CentreY << 8); \ \ uint32 clip; \ for (clip = 0; clip < ClipCount; clip++) \ - { \ - if (GFX.pCurrentClip->Count [bg]) \ - { \ - Left = GFX.pCurrentClip->Left [clip][bg]; \ - Right = GFX.pCurrentClip->Right [clip][bg]; \ - if (Right <= Left) \ - continue; \ - } \ - TYPE *p = (TYPE *) Screen + Left; \ - uint8 *d = Depth + Left; \ + { \ + if (GFX.pCurrentClip->Count [bg]) \ + { \ + Left = GFX.pCurrentClip->Left [clip][bg]; \ + Right = GFX.pCurrentClip->Right [clip][bg]; \ + if (Right <= Left) \ + continue; \ + } \ + TYPE *p = (TYPE *) Screen + Left; \ + uint8 *d = Depth + Left; \ \ - if (PPU.Mode7HFlip) \ - { \ - startx = Right - 1; \ - endx = Left - 1; \ - dir = -1; \ - aa = -l->MatrixA; \ - cc = -l->MatrixC; \ - } \ - else \ - { \ - startx = Left; \ - endx = Right; \ - dir = 1; \ - aa = l->MatrixA; \ - cc = l->MatrixC; \ - } \ + if (PPU.Mode7HFlip) \ + { \ + startx = Right - 1; \ + endx = Left - 1; \ + dir = -1; \ + aa = -l->MatrixA; \ + cc = -l->MatrixC; \ + } \ + else \ + { \ + startx = Left; \ + endx = Right; \ + dir = 1; \ + aa = l->MatrixA; \ + cc = l->MatrixC; \ + } \ \ - int xx = startx + CLIP_10_BIT_SIGNED(HOffset - CentreX); \ - int AA = l->MatrixA * xx; \ - int CC = l->MatrixC * xx; \ + int xx = startx + CLIP_10_BIT_SIGNED(HOffset - CentreX); \ + int AA = l->MatrixA * xx; \ + int CC = l->MatrixC * xx; \ \ - if (!PPU.Mode7Repeat) \ - { \ + if (!PPU.Mode7Repeat) \ + { \ int x; \ for (x = startx; x != endx; x += dir, AA += aa, CC += cc, p++, d++) \ - { \ - int X = ((AA + BB) >> 8) & 0x3ff; \ - int Y = ((CC + DD) >> 8) & 0x3ff; \ - uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ - uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ - GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ - if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \ - { \ - *p = (FUNC); \ - *d = GFX.Z1; \ - } \ - } \ - } \ - else \ - { \ + { \ + int X = ((AA + BB) >> 8) & 0x3ff; \ + int Y = ((CC + DD) >> 8) & 0x3ff; \ + uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ + uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ + GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ + if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \ + { \ + *p = (FUNC); \ + *d = GFX.Z1; \ + } \ + } \ + } \ + else \ + { \ int x; \ for (x = startx; x != endx; x += dir, AA += aa, CC += cc, p++, d++) \ - { \ - int X = ((AA + BB) >> 8); \ - int Y = ((CC + DD) >> 8); \ + { \ + int X = ((AA + BB) >> 8); \ + int Y = ((CC + DD) >> 8); \ \ - if (((X | Y) & ~0x3ff) == 0) \ - { \ - uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ - uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ - GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ - if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \ - { \ - *p = (FUNC); \ - *d = GFX.Z1; \ - } \ - } \ - else \ - { \ - if (PPU.Mode7Repeat == 3) \ - { \ - X = (x + HOffset) & 7; \ - Y = (yy + CentreY) & 7; \ - uint32 b = *(VRAM1 + ((Y & 7) << 4) + ((X & 7) << 1)); \ - GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ - if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \ - { \ - *p = (FUNC); \ - *d = GFX.Z1; \ - } \ - } \ - } \ - } \ - } \ - } \ + if (((X | Y) & ~0x3ff) == 0) \ + { \ + uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ + uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ + GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ + if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \ + { \ + *p = (FUNC); \ + *d = GFX.Z1; \ + } \ + } \ + else \ + { \ + if (PPU.Mode7Repeat == 3) \ + { \ + X = (x + HOffset) & 7; \ + Y = (yy + CentreY) & 7; \ + uint32 b = *(VRAM1 + ((Y & 7) << 4) + ((X & 7) << 1)); \ + GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ + if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \ + { \ + *p = (FUNC); \ + *d = GFX.Z1; \ + } \ + } \ + } \ + } \ + } \ + } \ } -static void DrawBGMode7Background (uint8 *Screen, int bg) +static void DrawBGMode7Background(uint8* Screen, int bg) { - RENDER_BACKGROUND_MODE7 (uint8, (uint8) (b & GFX.Mode7Mask)) + RENDER_BACKGROUND_MODE7(uint8, (uint8)(b & GFX.Mode7Mask)) } -static void DrawBGMode7Background16 (uint8 *Screen, int bg) +static void DrawBGMode7Background16(uint8* Screen, int bg) { - RENDER_BACKGROUND_MODE7 (uint16, ScreenColors [b & GFX.Mode7Mask]); + RENDER_BACKGROUND_MODE7(uint16, ScreenColors [b & GFX.Mode7Mask]); } -static void DrawBGMode7Background16Add (uint8 *Screen, int bg) +static void DrawBGMode7Background16Add(uint8* Screen, int bg) { - RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ? - (*(d + GFX.DepthDelta) != 1 ? - COLOR_ADD (ScreenColors [b & GFX.Mode7Mask], - p [GFX.Delta]) : - COLOR_ADD (ScreenColors [b & GFX.Mode7Mask], - GFX.FixedColour)) : - ScreenColors [b & GFX.Mode7Mask]); + RENDER_BACKGROUND_MODE7(uint16, *(d + GFX.DepthDelta) ? + (*(d + GFX.DepthDelta) != 1 ? + COLOR_ADD(ScreenColors [b & GFX.Mode7Mask], + p [GFX.Delta]) : + COLOR_ADD(ScreenColors [b & GFX.Mode7Mask], + GFX.FixedColour)) : + ScreenColors [b & GFX.Mode7Mask]); } -static void DrawBGMode7Background16Add1_2 (uint8 *Screen, int bg) +static void DrawBGMode7Background16Add1_2(uint8* Screen, int bg) { - RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ? - (*(d + GFX.DepthDelta) != 1 ? - COLOR_ADD1_2 (ScreenColors [b & GFX.Mode7Mask], - p [GFX.Delta]) : - COLOR_ADD (ScreenColors [b & GFX.Mode7Mask], - GFX.FixedColour)) : - ScreenColors [b & GFX.Mode7Mask]); + RENDER_BACKGROUND_MODE7(uint16, *(d + GFX.DepthDelta) ? + (*(d + GFX.DepthDelta) != 1 ? + COLOR_ADD1_2(ScreenColors [b & GFX.Mode7Mask], + p [GFX.Delta]) : + COLOR_ADD(ScreenColors [b & GFX.Mode7Mask], + GFX.FixedColour)) : + ScreenColors [b & GFX.Mode7Mask]); } -static void DrawBGMode7Background16Sub (uint8 *Screen, int bg) +static void DrawBGMode7Background16Sub(uint8* Screen, int bg) { - RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ? - (*(d + GFX.DepthDelta) != 1 ? - COLOR_SUB (ScreenColors [b & GFX.Mode7Mask], - p [GFX.Delta]) : - COLOR_SUB (ScreenColors [b & GFX.Mode7Mask], - GFX.FixedColour)) : - ScreenColors [b & GFX.Mode7Mask]); + RENDER_BACKGROUND_MODE7(uint16, *(d + GFX.DepthDelta) ? + (*(d + GFX.DepthDelta) != 1 ? + COLOR_SUB(ScreenColors [b & GFX.Mode7Mask], + p [GFX.Delta]) : + COLOR_SUB(ScreenColors [b & GFX.Mode7Mask], + GFX.FixedColour)) : + ScreenColors [b & GFX.Mode7Mask]); } -static void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg) +static void DrawBGMode7Background16Sub1_2(uint8* Screen, int bg) { - RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ? - (*(d + GFX.DepthDelta) != 1 ? - COLOR_SUB1_2 (ScreenColors [b & GFX.Mode7Mask], - p [GFX.Delta]) : - COLOR_SUB (ScreenColors [b & GFX.Mode7Mask], - GFX.FixedColour)) : - ScreenColors [b & GFX.Mode7Mask]); + RENDER_BACKGROUND_MODE7(uint16, *(d + GFX.DepthDelta) ? + (*(d + GFX.DepthDelta) != 1 ? + COLOR_SUB1_2(ScreenColors [b & GFX.Mode7Mask], + p [GFX.Delta]) : + COLOR_SUB(ScreenColors [b & GFX.Mode7Mask], + GFX.FixedColour)) : + ScreenColors [b & GFX.Mode7Mask]); } #define RENDER_BACKGROUND_MODE7_i(TYPE,FUNC,COLORFUNC) \ @@ -2750,8 +2822,8 @@ static void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg) else \ yy = Line; \ \ - \ - yy += CLIP_10_BIT_SIGNED(VOffset - CentreY); \ + \ + yy += CLIP_10_BIT_SIGNED(VOffset - CentreY); \ bool8 simpleCase = FALSE; \ int BB; \ int DD; \ @@ -2799,8 +2871,8 @@ static void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg) cc = l->MatrixC; \ } \ int xx; \ - \ - xx = startx + CLIP_10_BIT_SIGNED(HOffset - CentreX); \ + \ + xx = startx + CLIP_10_BIT_SIGNED(HOffset - CentreX); \ int AA, CC = 0; \ if (simpleCase) \ { \ @@ -2822,7 +2894,7 @@ static void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg) int Y = (DD >> 8) & 0x3ff; \ uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ - GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ + GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \ { \ TYPE theColor = COLORFUNC; \ @@ -2830,7 +2902,7 @@ static void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg) *d = GFX.Z1; \ } \ AA += aa, p++, d++; \ - x += dir; \ + x += dir; \ } while (x != endx); \ } \ else \ @@ -2843,8 +2915,8 @@ static void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg) if (((X | Y) & ~0x3ff) == 0) \ { \ uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ - uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ - GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ + uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ + GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \ { \ TYPE theColor = COLORFUNC; \ @@ -2856,9 +2928,9 @@ static void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg) { \ X = (x + HOffset) & 7; \ Y = (yy + CentreY) & 7; \ - uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ - uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ - GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ + uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ + uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ + GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \ { \ TYPE theColor = COLORFUNC; \ @@ -2867,7 +2939,7 @@ static void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg) } \ } \ AA += aa; p++; d++; \ - x += dir; \ + x += dir; \ } while (x != endx); \ } \ } \ @@ -2895,8 +2967,8 @@ static void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg) uint32 X = xPix & 0x3ff; \ uint32 Y = yPix & 0x3ff; \ uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ - uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ - GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ + uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ + GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \ { \ /* X10 and Y01 are the X and Y coordinates of the next source point over. */ \ @@ -2970,8 +3042,8 @@ static void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg) uint32 X = ((AA + BB) >> 8) & 0x3ff; \ uint32 Y = ((CC + DD) >> 8) & 0x3ff; \ uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ - uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ - GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ + uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ + GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \ { \ /* X, Y, X10, Y10, etc. are the coordinates of the four pixels within the */ \ @@ -3015,8 +3087,8 @@ static void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg) if (((X | Y) & ~0x3ff) == 0) \ { \ uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ - uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ - GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ + uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ + GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \ { \ /* X10 and Y01 are the X and Y coordinates of the next source point over. */ \ @@ -3059,8 +3131,8 @@ static void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg) { \ X = (x + HOffset) & 7; \ Y = (yy + CentreY) & 7; \ - uint32 b = *(VRAM1 + ((Y & 7) << 4) + ((X & 7) << 1)); \ - GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ + uint32 b = *(VRAM1 + ((Y & 7) << 4) + ((X & 7) << 1)); \ + GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \ { \ TYPE theColor = COLORFUNC; \ @@ -3076,65 +3148,65 @@ static void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg) STATIC uint32 Q_INTERPOLATE(uint32 A, uint32 B, uint32 C, uint32 D) { - register uint32 x = ((A >> 2) & HIGH_BITS_SHIFTED_TWO_MASK) + - ((B >> 2) & HIGH_BITS_SHIFTED_TWO_MASK) + - ((C >> 2) & HIGH_BITS_SHIFTED_TWO_MASK) + - ((D >> 2) & HIGH_BITS_SHIFTED_TWO_MASK); - register uint32 y = (A & TWO_LOW_BITS_MASK) + - (B & TWO_LOW_BITS_MASK) + - (C & TWO_LOW_BITS_MASK) + - (D & TWO_LOW_BITS_MASK); - y = (y>>2) & TWO_LOW_BITS_MASK; - return x+y; + register uint32 x = ((A >> 2) & HIGH_BITS_SHIFTED_TWO_MASK) + + ((B >> 2) & HIGH_BITS_SHIFTED_TWO_MASK) + + ((C >> 2) & HIGH_BITS_SHIFTED_TWO_MASK) + + ((D >> 2) & HIGH_BITS_SHIFTED_TWO_MASK); + register uint32 y = (A & TWO_LOW_BITS_MASK) + + (B & TWO_LOW_BITS_MASK) + + (C & TWO_LOW_BITS_MASK) + + (D & TWO_LOW_BITS_MASK); + y = (y >> 2) & TWO_LOW_BITS_MASK; + return x + y; } -static void DrawBGMode7Background16_i (uint8 *Screen, int bg) +static void DrawBGMode7Background16_i(uint8* Screen, int bg) { - RENDER_BACKGROUND_MODE7_i (uint16, theColor, (ScreenColors[b & GFX.Mode7Mask])); + RENDER_BACKGROUND_MODE7_i(uint16, theColor, (ScreenColors[b & GFX.Mode7Mask])); } -static void DrawBGMode7Background16Add_i (uint8 *Screen, int bg) +static void DrawBGMode7Background16Add_i(uint8* Screen, int bg) { - RENDER_BACKGROUND_MODE7_i (uint16, *(d + GFX.DepthDelta) ? - (*(d + GFX.DepthDelta) != 1 ? - (COLOR_ADD (theColor, - p [GFX.Delta])) : - (COLOR_ADD (theColor, - GFX.FixedColour))) : - theColor, (ScreenColors[b & GFX.Mode7Mask])); + RENDER_BACKGROUND_MODE7_i(uint16, *(d + GFX.DepthDelta) ? + (*(d + GFX.DepthDelta) != 1 ? + (COLOR_ADD(theColor, + p [GFX.Delta])) : + (COLOR_ADD(theColor, + GFX.FixedColour))) : + theColor, (ScreenColors[b & GFX.Mode7Mask])); } -static void DrawBGMode7Background16Add1_2_i (uint8 *Screen, int bg) +static void DrawBGMode7Background16Add1_2_i(uint8* Screen, int bg) { - RENDER_BACKGROUND_MODE7_i (uint16, *(d + GFX.DepthDelta) ? - (*(d + GFX.DepthDelta) != 1 ? - COLOR_ADD1_2 (theColor, - p [GFX.Delta]) : - COLOR_ADD (theColor, - GFX.FixedColour)) : - theColor, (ScreenColors[b & GFX.Mode7Mask])); + RENDER_BACKGROUND_MODE7_i(uint16, *(d + GFX.DepthDelta) ? + (*(d + GFX.DepthDelta) != 1 ? + COLOR_ADD1_2(theColor, + p [GFX.Delta]) : + COLOR_ADD(theColor, + GFX.FixedColour)) : + theColor, (ScreenColors[b & GFX.Mode7Mask])); } -static void DrawBGMode7Background16Sub_i (uint8 *Screen, int bg) +static void DrawBGMode7Background16Sub_i(uint8* Screen, int bg) { - RENDER_BACKGROUND_MODE7_i (uint16, *(d + GFX.DepthDelta) ? - (*(d + GFX.DepthDelta) != 1 ? - COLOR_SUB (theColor, - p [GFX.Delta]) : - COLOR_SUB (theColor, - GFX.FixedColour)) : - theColor, (ScreenColors[b & GFX.Mode7Mask])); + RENDER_BACKGROUND_MODE7_i(uint16, *(d + GFX.DepthDelta) ? + (*(d + GFX.DepthDelta) != 1 ? + COLOR_SUB(theColor, + p [GFX.Delta]) : + COLOR_SUB(theColor, + GFX.FixedColour)) : + theColor, (ScreenColors[b & GFX.Mode7Mask])); } -static void DrawBGMode7Background16Sub1_2_i (uint8 *Screen, int bg) +static void DrawBGMode7Background16Sub1_2_i(uint8* Screen, int bg) { - RENDER_BACKGROUND_MODE7_i (uint16, *(d + GFX.DepthDelta) ? - (*(d + GFX.DepthDelta) != 1 ? - COLOR_SUB1_2 (theColor, - p [GFX.Delta]) : - COLOR_SUB (theColor, - GFX.FixedColour)) : - theColor, (ScreenColors[b & GFX.Mode7Mask])); + RENDER_BACKGROUND_MODE7_i(uint16, *(d + GFX.DepthDelta) ? + (*(d + GFX.DepthDelta) != 1 ? + COLOR_SUB1_2(theColor, + p [GFX.Delta]) : + COLOR_SUB(theColor, + GFX.FixedColour)) : + theColor, (ScreenColors[b & GFX.Mode7Mask])); } #define _BUILD_SETUP(F) \ @@ -3153,14 +3225,14 @@ MAX_BLUE = MAX_BLUE_##F; \ GREEN_HI_BIT = ((MAX_GREEN_##F + 1) >> 1); \ SPARE_RGB_BIT_MASK = SPARE_RGB_BIT_MASK_##F; \ RGB_LOW_BITS_MASK = (RED_LOW_BIT_MASK_##F | \ - GREEN_LOW_BIT_MASK_##F | \ - BLUE_LOW_BIT_MASK_##F); \ + GREEN_LOW_BIT_MASK_##F | \ + BLUE_LOW_BIT_MASK_##F); \ RGB_HI_BITS_MASK = (RED_HI_BIT_MASK_##F | \ - GREEN_HI_BIT_MASK_##F | \ - BLUE_HI_BIT_MASK_##F); \ + GREEN_HI_BIT_MASK_##F | \ + BLUE_HI_BIT_MASK_##F); \ RGB_HI_BITS_MASKx2 = ((RED_HI_BIT_MASK_##F | \ - GREEN_HI_BIT_MASK_##F | \ - BLUE_HI_BIT_MASK_##F) << 1); \ + GREEN_HI_BIT_MASK_##F | \ + BLUE_HI_BIT_MASK_##F) << 1); \ RGB_REMOVE_LOW_BITS_MASK = ~RGB_LOW_BITS_MASK; \ FIRST_COLOR_MASK = FIRST_COLOR_MASK_##F; \ SECOND_COLOR_MASK = SECOND_COLOR_MASK_##F; \ @@ -3171,175 +3243,176 @@ TWO_LOW_BITS_MASK = RGB_LOW_BITS_MASK | (RGB_LOW_BITS_MASK << 1); \ HIGH_BITS_SHIFTED_TWO_MASK = (( (FIRST_COLOR_MASK | SECOND_COLOR_MASK | THIRD_COLOR_MASK) & \ ~TWO_LOW_BITS_MASK ) >> 2); -static void RenderScreen (uint8 *Screen, bool8 sub, bool8 force_no_add, uint8 D) +static void RenderScreen(uint8* Screen, bool8 sub, bool8 force_no_add, uint8 D) { - bool8 BG0; - bool8 BG1; - bool8 BG2; - bool8 BG3; - bool8 OB; - - GFX.S = Screen; - - if (!sub) - { - GFX.pCurrentClip = &IPPU.Clip [0]; - BG0 = ON_MAIN (0); - BG1 = ON_MAIN (1); - BG2 = ON_MAIN (2); - BG3 = ON_MAIN (3); - OB = ON_MAIN (4); - } - else - { - GFX.pCurrentClip = &IPPU.Clip [1]; - BG0 = ON_SUB (0); - BG1 = ON_SUB (1); - BG2 = ON_SUB (2); - BG3 = ON_SUB (3); - OB = ON_SUB (4); - } - - sub |= force_no_add; - - switch (PPU.BGMode) { - case 0: - case 1: - if (OB) - { - SelectTileRenderer (sub || !SUB_OR_ADD(4)); - DrawOBJS (!sub, D); - } - if (BG0) - { - SelectTileRenderer (sub || !SUB_OR_ADD(0)); - DrawBackground (PPU.BGMode, 0, D + 10, D + 14); - } - if (BG1) - { - SelectTileRenderer (sub || !SUB_OR_ADD(1)); - DrawBackground (PPU.BGMode, 1, D + 9, D + 13); - } - if (BG2) - { - SelectTileRenderer (sub || !SUB_OR_ADD(2)); - DrawBackground (PPU.BGMode, 2, D + 3, - PPU.BG3Priority ? D + 17 : D + 6); - } - if (BG3 && PPU.BGMode == 0) - { - SelectTileRenderer (sub || !SUB_OR_ADD(3)); - DrawBackground (PPU.BGMode, 3, D + 2, D + 5); - } - break; - case 2: - case 3: - case 4: - case 5: - case 6: - if (OB) - { - SelectTileRenderer (sub || !SUB_OR_ADD(4)); - DrawOBJS (!sub, D); - } - if (BG0) - { - SelectTileRenderer (sub || !SUB_OR_ADD(0)); - DrawBackground (PPU.BGMode, 0, D + 5, D + 13); - } - if (BG1 && PPU.BGMode != 6) - { - SelectTileRenderer (sub || !SUB_OR_ADD(1)); - DrawBackground (PPU.BGMode, 1, D + 2, D + 9); - } - break; - case 7: - if (OB) - { - SelectTileRenderer (sub || !SUB_OR_ADD(4)); - DrawOBJS (!sub, D); - } - if (BG0 || ((Memory.FillRAM [0x2133] & 0x40) && BG1)) - { - int bg; - - if ((Memory.FillRAM [0x2133] & 0x40)&&BG1) - { - GFX.Mode7Mask = 0x7f; - GFX.Mode7PriorityMask = 0x80; - Mode7Depths [0] = (BG0?5:1) + D; - Mode7Depths [1] = 9 + D; - bg = 1; - } - else - { - GFX.Mode7Mask = 0xff; - GFX.Mode7PriorityMask = 0; - Mode7Depths [0] = 5 + D; - Mode7Depths [1] = 5 + D; - bg = 0; - } - if (sub || !SUB_OR_ADD(0)) - { - if (!Settings.Mode7Interpolate) - DrawBGMode7Background16 (Screen, bg); - else - DrawBGMode7Background16_i (Screen, bg); - } - else - { - if (GFX.r2131 & 0x80) - { - if (GFX.r2131 & 0x40) - { - if (!Settings.Mode7Interpolate) - DrawBGMode7Background16Sub1_2 (Screen, bg); - else - DrawBGMode7Background16Sub1_2_i (Screen, bg); - } - else - { - if (!Settings.Mode7Interpolate) - DrawBGMode7Background16Sub (Screen, bg); - else - DrawBGMode7Background16Sub_i (Screen, bg); - } - } - else - { - if (GFX.r2131 & 0x40) - { - if (!Settings.Mode7Interpolate) - DrawBGMode7Background16Add1_2 (Screen, bg); - else - DrawBGMode7Background16Add1_2_i (Screen, bg); - } - else - { - if (!Settings.Mode7Interpolate) - DrawBGMode7Background16Add (Screen, bg); - else - DrawBGMode7Background16Add_i (Screen, bg); - } - } - } - } - break; - default: - break; - } + bool8 BG0; + bool8 BG1; + bool8 BG2; + bool8 BG3; + bool8 OB; + + GFX.S = Screen; + + if (!sub) + { + GFX.pCurrentClip = &IPPU.Clip [0]; + BG0 = ON_MAIN(0); + BG1 = ON_MAIN(1); + BG2 = ON_MAIN(2); + BG3 = ON_MAIN(3); + OB = ON_MAIN(4); + } + else + { + GFX.pCurrentClip = &IPPU.Clip [1]; + BG0 = ON_SUB(0); + BG1 = ON_SUB(1); + BG2 = ON_SUB(2); + BG3 = ON_SUB(3); + OB = ON_SUB(4); + } + + sub |= force_no_add; + + switch (PPU.BGMode) + { + case 0: + case 1: + if (OB) + { + SelectTileRenderer(sub || !SUB_OR_ADD(4)); + DrawOBJS(!sub, D); + } + if (BG0) + { + SelectTileRenderer(sub || !SUB_OR_ADD(0)); + DrawBackground(PPU.BGMode, 0, D + 10, D + 14); + } + if (BG1) + { + SelectTileRenderer(sub || !SUB_OR_ADD(1)); + DrawBackground(PPU.BGMode, 1, D + 9, D + 13); + } + if (BG2) + { + SelectTileRenderer(sub || !SUB_OR_ADD(2)); + DrawBackground(PPU.BGMode, 2, D + 3, + PPU.BG3Priority ? D + 17 : D + 6); + } + if (BG3 && PPU.BGMode == 0) + { + SelectTileRenderer(sub || !SUB_OR_ADD(3)); + DrawBackground(PPU.BGMode, 3, D + 2, D + 5); + } + break; + case 2: + case 3: + case 4: + case 5: + case 6: + if (OB) + { + SelectTileRenderer(sub || !SUB_OR_ADD(4)); + DrawOBJS(!sub, D); + } + if (BG0) + { + SelectTileRenderer(sub || !SUB_OR_ADD(0)); + DrawBackground(PPU.BGMode, 0, D + 5, D + 13); + } + if (BG1 && PPU.BGMode != 6) + { + SelectTileRenderer(sub || !SUB_OR_ADD(1)); + DrawBackground(PPU.BGMode, 1, D + 2, D + 9); + } + break; + case 7: + if (OB) + { + SelectTileRenderer(sub || !SUB_OR_ADD(4)); + DrawOBJS(!sub, D); + } + if (BG0 || ((Memory.FillRAM [0x2133] & 0x40) && BG1)) + { + int bg; + + if ((Memory.FillRAM [0x2133] & 0x40) && BG1) + { + GFX.Mode7Mask = 0x7f; + GFX.Mode7PriorityMask = 0x80; + Mode7Depths [0] = (BG0 ? 5 : 1) + D; + Mode7Depths [1] = 9 + D; + bg = 1; + } + else + { + GFX.Mode7Mask = 0xff; + GFX.Mode7PriorityMask = 0; + Mode7Depths [0] = 5 + D; + Mode7Depths [1] = 5 + D; + bg = 0; + } + if (sub || !SUB_OR_ADD(0)) + { + if (!Settings.Mode7Interpolate) + DrawBGMode7Background16(Screen, bg); + else + DrawBGMode7Background16_i(Screen, bg); + } + else + { + if (GFX.r2131 & 0x80) + { + if (GFX.r2131 & 0x40) + { + if (!Settings.Mode7Interpolate) + DrawBGMode7Background16Sub1_2(Screen, bg); + else + DrawBGMode7Background16Sub1_2_i(Screen, bg); + } + else + { + if (!Settings.Mode7Interpolate) + DrawBGMode7Background16Sub(Screen, bg); + else + DrawBGMode7Background16Sub_i(Screen, bg); + } + } + else + { + if (GFX.r2131 & 0x40) + { + if (!Settings.Mode7Interpolate) + DrawBGMode7Background16Add1_2(Screen, bg); + else + DrawBGMode7Background16Add1_2_i(Screen, bg); + } + else + { + if (!Settings.Mode7Interpolate) + DrawBGMode7Background16Add(Screen, bg); + else + DrawBGMode7Background16Add_i(Screen, bg); + } + } + } + } + break; + default: + break; + } } #include "font.h" -void DisplayChar (uint8 *Screen, uint8 c) +void DisplayChar(uint8* Screen, uint8 c) { int line = (((c & 0x7f) - 32) >> 4) * font_height; int offset = (((c & 0x7f) - 32) & 15) * font_width; int h, w; - uint16 *s = (uint16 *) Screen; + uint16* s = (uint16*) Screen; for (h = 0; h < font_height; h++, line++, - s += GFX.PPL - font_width) + s += GFX.PPL - font_width) { for (w = 0; w < font_width; w++, s++) { @@ -3358,628 +3431,626 @@ void DisplayChar (uint8 *Screen, uint8 c) *s= BUILD_PIXEL(0,31,31); else *s = 0xffff; */ - *s=Settings.DisplayColor; + *s = Settings.DisplayColor; } - else - if (p == '.') - *s = BLACK; + else if (p == '.') + *s = BLACK; } } } -static void S9xDisplayFrameRate () +static void S9xDisplayFrameRate() { - uint8 *Screen = GFX.Screen + 2 + - (IPPU.RenderedScreenHeight - font_height - 1) * GFX.Pitch2; - char string [10]; - int len = 5; - - sprintf (string, "%02d/%02d", IPPU.DisplayedRenderedFrameCount, - (int) Memory.ROMFramesPerSecond); - - int i; - for (i = 0; i < len; i++) - { - DisplayChar (Screen, string [i]); - Screen += (font_width - 1) * sizeof (uint16); - } + uint8* Screen = GFX.Screen + 2 + + (IPPU.RenderedScreenHeight - font_height - 1) * GFX.Pitch2; + char string [10]; + int len = 5; + + sprintf(string, "%02d/%02d", IPPU.DisplayedRenderedFrameCount, + (int) Memory.ROMFramesPerSecond); + + int i; + for (i = 0; i < len; i++) + { + DisplayChar(Screen, string [i]); + Screen += (font_width - 1) * sizeof(uint16); + } } -static void S9xDisplayString (const char *string) +static void S9xDisplayString(const char* string) { - uint8 *Screen = GFX.Screen + 2 + - (IPPU.RenderedScreenHeight - font_height * 5) * GFX.Pitch2; - int len = strlen (string); - int max_chars = IPPU.RenderedScreenWidth / (font_width - 1); - int char_count = 0; - int i; - - for (i = 0; i < len; i++, char_count++) - { - if (char_count >= max_chars || string [i] < 32) - { - Screen -= (font_width - 1) * max_chars * sizeof (uint16); - Screen += font_height * GFX.Pitch; - if (Screen >= GFX.Screen + GFX.Pitch * IPPU.RenderedScreenHeight) - break; - char_count -= max_chars; - } - if (string [i] < 32) - continue; - DisplayChar (Screen, string [i]); - Screen += (font_width - 1) * sizeof (uint16); - } + uint8* Screen = GFX.Screen + 2 + + (IPPU.RenderedScreenHeight - font_height * 5) * GFX.Pitch2; + int len = strlen(string); + int max_chars = IPPU.RenderedScreenWidth / (font_width - 1); + int char_count = 0; + int i; + + for (i = 0; i < len; i++, char_count++) + { + if (char_count >= max_chars || string [i] < 32) + { + Screen -= (font_width - 1) * max_chars * sizeof(uint16); + Screen += font_height * GFX.Pitch; + if (Screen >= GFX.Screen + GFX.Pitch * IPPU.RenderedScreenHeight) + break; + char_count -= max_chars; + } + if (string [i] < 32) + continue; + DisplayChar(Screen, string [i]); + Screen += (font_width - 1) * sizeof(uint16); + } } -void S9xUpdateScreen () +void S9xUpdateScreen() { - int32 x2 = 1; - - GFX.S = GFX.Screen; - GFX.r2131 = Memory.FillRAM [0x2131]; - GFX.r212c = Memory.FillRAM [0x212c]; - GFX.r212d = Memory.FillRAM [0x212d]; - GFX.r2130 = Memory.FillRAM [0x2130]; + int32 x2 = 1; + + GFX.S = GFX.Screen; + GFX.r2131 = Memory.FillRAM [0x2131]; + GFX.r212c = Memory.FillRAM [0x212c]; + GFX.r212d = Memory.FillRAM [0x212d]; + GFX.r2130 = Memory.FillRAM [0x2130]; #ifdef JP_FIX - GFX.Pseudo = (Memory.FillRAM [0x2133] & 8) != 0 && - (GFX.r212c & 15) != (GFX.r212d & 15) && - (GFX.r2131 == 0x3f); + GFX.Pseudo = (Memory.FillRAM [0x2133] & 8) != 0 && + (GFX.r212c & 15) != (GFX.r212d & 15) && + (GFX.r2131 == 0x3f); #else - GFX.Pseudo = (Memory.FillRAM [0x2133] & 8) != 0 && - (GFX.r212c & 15) != (GFX.r212d & 15) && - (GFX.r2131 & 0x3f) == 0; + GFX.Pseudo = (Memory.FillRAM [0x2133] & 8) != 0 && + (GFX.r212c & 15) != (GFX.r212d & 15) && + (GFX.r2131 & 0x3f) == 0; #endif - - if (IPPU.OBJChanged) - S9xSetupOBJ (); - - if (PPU.RecomputeClipWindows) - { - ComputeClipWindows (); - PPU.RecomputeClipWindows = FALSE; - } - - GFX.StartY = IPPU.PreviousLine; - if ((GFX.EndY = IPPU.CurrentLine - 1) >= PPU.ScreenHeight) - GFX.EndY = PPU.ScreenHeight - 1; - - // XXX: Check ForceBlank? Or anything else? - PPU.RangeTimeOver |= GFX.OBJLines[GFX.EndY].RTOFlags; - - uint32 starty = GFX.StartY; - uint32 endy = GFX.EndY; - - if (Settings.SupportHiRes && - (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.Interlace || IPPU.DoubleHeightPixels)) - { - if (PPU.BGMode == 5 || PPU.BGMode == 6|| IPPU.Interlace) - { - IPPU.RenderedScreenWidth = 512; - x2 = 2; - } - - if (IPPU.DoubleHeightPixels) - { - starty = GFX.StartY * 2; - endy = GFX.EndY * 2 + 1; - } - - if ((PPU.BGMode == 5 || PPU.BGMode == 6) && !IPPU.DoubleWidthPixels) - { - // The game has switched from lo-res to hi-res mode part way down - // the screen. Scale any existing lo-res pixels on screen + + if (IPPU.OBJChanged) + S9xSetupOBJ(); + + if (PPU.RecomputeClipWindows) + { + ComputeClipWindows(); + PPU.RecomputeClipWindows = FALSE; + } + + GFX.StartY = IPPU.PreviousLine; + if ((GFX.EndY = IPPU.CurrentLine - 1) >= PPU.ScreenHeight) + GFX.EndY = PPU.ScreenHeight - 1; + + // XXX: Check ForceBlank? Or anything else? + PPU.RangeTimeOver |= GFX.OBJLines[GFX.EndY].RTOFlags; + + uint32 starty = GFX.StartY; + uint32 endy = GFX.EndY; + + if (Settings.SupportHiRes && + (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.Interlace + || IPPU.DoubleHeightPixels)) + { + if (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.Interlace) + { + IPPU.RenderedScreenWidth = 512; + x2 = 2; + } + + if (IPPU.DoubleHeightPixels) + { + starty = GFX.StartY * 2; + endy = GFX.EndY * 2 + 1; + } + + if ((PPU.BGMode == 5 || PPU.BGMode == 6) && !IPPU.DoubleWidthPixels) + { + // The game has switched from lo-res to hi-res mode part way down + // the screen. Scale any existing lo-res pixels on screen register uint32 y; for (y = 0; y < starty; y++) { - register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + 255; - register uint16 *q = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + 510; + register uint16* p = (uint16*)(GFX.Screen + y * GFX.Pitch2) + 255; + register uint16* q = (uint16*)(GFX.Screen + y * GFX.Pitch2) + 510; register int x; for (x = 255; x >= 0; x--, p--, q -= 2) - *q = *(q + 1) = *p; - } - IPPU.DoubleWidthPixels = TRUE; - IPPU.HalfWidthPixels = FALSE; - } - // BJ: And we have to change the height if Interlace gets set, - // too. - if (IPPU.Interlace && !IPPU.DoubleHeightPixels) - { - starty = GFX.StartY * 2; - endy = GFX.EndY * 2 + 1; - IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1; - IPPU.DoubleHeightPixels = TRUE; - GFX.Pitch2 = GFX.RealPitch; - GFX.Pitch = GFX.RealPitch * 2; - GFX.PPL = GFX.PPLx2 = GFX.RealPitch; + * q = *(q + 1) = *p; + } + IPPU.DoubleWidthPixels = TRUE; + IPPU.HalfWidthPixels = FALSE; + } + // BJ: And we have to change the height if Interlace gets set, + // too. + if (IPPU.Interlace && !IPPU.DoubleHeightPixels) + { + starty = GFX.StartY * 2; + endy = GFX.EndY * 2 + 1; + IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1; + IPPU.DoubleHeightPixels = TRUE; + GFX.Pitch2 = GFX.RealPitch; + GFX.Pitch = GFX.RealPitch * 2; + GFX.PPL = GFX.PPLx2 = GFX.RealPitch; + + + // The game has switched from non-interlaced to interlaced mode + // part way down the screen. Scale everything. + register int32 y; + for (y = (int32) GFX.StartY - 1; y >= 0; y--) + { + // memmove converted: Same malloc, different addresses, and identical addresses at line 0 [Neb] + // DS2 DMA notes: This code path is unused [Neb] + memcpy(GFX.Screen + y * 2 * GFX.Pitch2, + GFX.Screen + y * GFX.Pitch2, + GFX.Pitch2); + // memmove converted: Same malloc, different addresses [Neb] + memcpy(GFX.Screen + (y * 2 + 1) * GFX.Pitch2, + GFX.Screen + y * GFX.Pitch2, + GFX.Pitch2); + } + } + } + else if (!Settings.SupportHiRes) + { + if (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.Interlace) + { + if (!IPPU.HalfWidthPixels) + { + // The game has switched from lo-res to hi-res mode part way down + // the screen. Hi-res pixels must now be drawn at half width. + IPPU.HalfWidthPixels = TRUE; + } + } + else + { + if (IPPU.HalfWidthPixels) + { + // The game has switched from hi-res to lo-res mode part way down + // the screen. Lo-res pixels must now be drawn at FULL width. + IPPU.HalfWidthPixels = FALSE; + } + } + } - - // The game has switched from non-interlaced to interlaced mode - // part way down the screen. Scale everything. - register int32 y; - for (y = (int32) GFX.StartY - 1; y >= 0; y--) - { - // memmove converted: Same malloc, different addresses, and identical addresses at line 0 [Neb] - // DS2 DMA notes: This code path is unused [Neb] - memcpy (GFX.Screen + y * 2 * GFX.Pitch2, - GFX.Screen + y * GFX.Pitch2, - GFX.Pitch2); - // memmove converted: Same malloc, different addresses [Neb] - memcpy (GFX.Screen + (y * 2 + 1) * GFX.Pitch2, - GFX.Screen + y * GFX.Pitch2, - GFX.Pitch2); - } - } - } - else if (!Settings.SupportHiRes) - { - if (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.Interlace) - { - if (!IPPU.HalfWidthPixels) - { - // The game has switched from lo-res to hi-res mode part way down - // the screen. Hi-res pixels must now be drawn at half width. - IPPU.HalfWidthPixels = TRUE; - } - } - else - { - if (IPPU.HalfWidthPixels) - { - // The game has switched from hi-res to lo-res mode part way down - // the screen. Lo-res pixels must now be drawn at FULL width. - IPPU.HalfWidthPixels = FALSE; - } - } - } - - uint32 black = BLACK | (BLACK << 16); - - if (Settings.Transparency) - { - if (GFX.Pseudo) - { - GFX.r2131 = 0x5f; - GFX.r212c &= (Memory.FillRAM [0x212d] | 0xf0); - GFX.r212d |= (Memory.FillRAM [0x212c] & 0x0f); - GFX.r2130 |= 2; - } - - if (!PPU.ForcedBlanking && ADD_OR_SUB_ON_ANYTHING && - (GFX.r2130 & 0x30) != 0x30 && - !((GFX.r2130 & 0x30) == 0x10 && IPPU.Clip[1].Count[5] == 0)) - { - struct ClipData *pClip; - - GFX.FixedColour = BUILD_PIXEL (IPPU.XB [PPU.FixedColourRed], - IPPU.XB [PPU.FixedColourGreen], - IPPU.XB [PPU.FixedColourBlue]); - - // Clear the z-buffer, marking areas 'covered' by the fixed - // colour as depth 1. - pClip = &IPPU.Clip [1]; - - // Clear the z-buffer - if (pClip->Count [5]) - { - // Colour window enabled. + uint32 black = BLACK | (BLACK << 16); + + if (Settings.Transparency) + { + if (GFX.Pseudo) + { + GFX.r2131 = 0x5f; + GFX.r212c &= (Memory.FillRAM [0x212d] | 0xf0); + GFX.r212d |= (Memory.FillRAM [0x212c] & 0x0f); + GFX.r2130 |= 2; + } + + if (!PPU.ForcedBlanking && ADD_OR_SUB_ON_ANYTHING && + (GFX.r2130 & 0x30) != 0x30 && + !((GFX.r2130 & 0x30) == 0x10 && IPPU.Clip[1].Count[5] == 0)) + { + struct ClipData* pClip; + + GFX.FixedColour = BUILD_PIXEL(IPPU.XB [PPU.FixedColourRed], + IPPU.XB [PPU.FixedColourGreen], + IPPU.XB [PPU.FixedColourBlue]); + + // Clear the z-buffer, marking areas 'covered' by the fixed + // colour as depth 1. + pClip = &IPPU.Clip [1]; + + // Clear the z-buffer + if (pClip->Count [5]) + { + // Colour window enabled. uint32 y; for (y = starty; y <= endy; y++) - { - ZeroMemory (GFX.SubZBuffer + y * GFX.ZPitch, IPPU.RenderedScreenWidth); - ZeroMemory (GFX.ZBuffer + y * GFX.ZPitch, IPPU.RenderedScreenWidth); - - if (IPPU.Clip [0].Count [5]) - { - uint32 *p = (uint32 *) (GFX.SubScreen + y * GFX.Pitch2); - uint32 *q = (uint32 *) ((uint16 *) p + IPPU.RenderedScreenWidth); - while (p < q) - *p++ = black; - } + { + ZeroMemory(GFX.SubZBuffer + y * GFX.ZPitch, IPPU.RenderedScreenWidth); + ZeroMemory(GFX.ZBuffer + y * GFX.ZPitch, IPPU.RenderedScreenWidth); + + if (IPPU.Clip [0].Count [5]) + { + uint32* p = (uint32*)(GFX.SubScreen + y * GFX.Pitch2); + uint32* q = (uint32*)((uint16*) p + IPPU.RenderedScreenWidth); + while (p < q) + *p++ = black; + } uint32 c; for (c = 0; c < pClip->Count [5]; c++) - { - if (pClip->Right [c][5] > pClip->Left [c][5]) - { - memset (GFX.SubZBuffer + y * GFX.ZPitch + pClip->Left [c][5] * x2, - 1, (pClip->Right [c][5] - pClip->Left [c][5]) * x2); - - if (IPPU.Clip [0].Count [5]) - { - // Blast, have to clear the sub-screen to the fixed-colour - // because there is a colour window in effect clipping - // the main screen that will allow the sub-screen - // 'underneath' to show through. - - uint16 *p = (uint16 *) (GFX.SubScreen + y * GFX.Pitch2); - uint16 *q = p + pClip->Right [c][5] * x2; - p += pClip->Left [c][5] * x2; - - while (p < q) - *p++ = (uint16) GFX.FixedColour; - } - } - } - } - } - else - { + { + if (pClip->Right [c][5] > pClip->Left [c][5]) + { + memset(GFX.SubZBuffer + y * GFX.ZPitch + pClip->Left [c][5] * x2, + 1, (pClip->Right [c][5] - pClip->Left [c][5]) * x2); + + if (IPPU.Clip [0].Count [5]) + { + // Blast, have to clear the sub-screen to the fixed-colour + // because there is a colour window in effect clipping + // the main screen that will allow the sub-screen + // 'underneath' to show through. + + uint16* p = (uint16*)(GFX.SubScreen + y * GFX.Pitch2); + uint16* q = p + pClip->Right [c][5] * x2; + p += pClip->Left [c][5] * x2; + + while (p < q) + *p++ = (uint16) GFX.FixedColour; + } + } + } + } + } + else + { uint32 y; for (y = starty; y <= endy; y++) - { - ZeroMemory (GFX.ZBuffer + y * GFX.ZPitch, IPPU.RenderedScreenWidth); - memset (GFX.SubZBuffer + y * GFX.ZPitch, 1, IPPU.RenderedScreenWidth); - - if (IPPU.Clip [0].Count [5]) - { - // Blast, have to clear the sub-screen to the fixed-colour - // because there is a colour window in effect clipping - // the main screen that will allow the sub-screen - // 'underneath' to show through. - - uint32 b = GFX.FixedColour | (GFX.FixedColour << 16); - uint32 *p = (uint32 *) (GFX.SubScreen + y * GFX.Pitch2); - uint32 *q = (uint32 *) ((uint16 *) p + IPPU.RenderedScreenWidth); - - while (p < q) - *p++ = b; - } - } - } - - if (ANYTHING_ON_SUB) - { - GFX.DB = GFX.SubZBuffer; - RenderScreen (GFX.SubScreen, TRUE, TRUE, SUB_SCREEN_DEPTH); - } - - if (IPPU.Clip [0].Count [5]) - { + { + ZeroMemory(GFX.ZBuffer + y * GFX.ZPitch, IPPU.RenderedScreenWidth); + memset(GFX.SubZBuffer + y * GFX.ZPitch, 1, IPPU.RenderedScreenWidth); + + if (IPPU.Clip [0].Count [5]) + { + // Blast, have to clear the sub-screen to the fixed-colour + // because there is a colour window in effect clipping + // the main screen that will allow the sub-screen + // 'underneath' to show through. + + uint32 b = GFX.FixedColour | (GFX.FixedColour << 16); + uint32* p = (uint32*)(GFX.SubScreen + y * GFX.Pitch2); + uint32* q = (uint32*)((uint16*) p + IPPU.RenderedScreenWidth); + + while (p < q) + *p++ = b; + } + } + } + + if (ANYTHING_ON_SUB) + { + GFX.DB = GFX.SubZBuffer; + RenderScreen(GFX.SubScreen, TRUE, TRUE, SUB_SCREEN_DEPTH); + } + + if (IPPU.Clip [0].Count [5]) + { uint32 y; for (y = starty; y <= endy; y++) - { - register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2); - register uint8 *d = GFX.SubZBuffer + y * GFX.ZPitch; - register uint8 *e = d + IPPU.RenderedScreenWidth; - - while (d < e) - { - if (*d > 1) - *p = *(p + GFX.Delta); - else - *p = BLACK; - d++; - p++; - } - } - } - - GFX.DB = GFX.ZBuffer; - RenderScreen (GFX.Screen, FALSE, FALSE, MAIN_SCREEN_DEPTH); - - if (SUB_OR_ADD(5)) - { - uint32 back = IPPU.ScreenColors [0]; - uint32 Left = 0; - uint32 Right = 256; - uint32 Count; - - pClip = &IPPU.Clip [0]; + { + register uint16* p = (uint16*)(GFX.Screen + y * GFX.Pitch2); + register uint8* d = GFX.SubZBuffer + y * GFX.ZPitch; + register uint8* e = d + IPPU.RenderedScreenWidth; + + while (d < e) + { + if (*d > 1) + *p = *(p + GFX.Delta); + else + *p = BLACK; + d++; + p++; + } + } + } + + GFX.DB = GFX.ZBuffer; + RenderScreen(GFX.Screen, FALSE, FALSE, MAIN_SCREEN_DEPTH); + + if (SUB_OR_ADD(5)) + { + uint32 back = IPPU.ScreenColors [0]; + uint32 Left = 0; + uint32 Right = 256; + uint32 Count; + + pClip = &IPPU.Clip [0]; uint32 y; for (y = starty; y <= endy; y++) - { - if (!(Count = pClip->Count [5])) - { - Left = 0; - Right = 256 * x2; - Count = 1; - } - + { + if (!(Count = pClip->Count [5])) + { + Left = 0; + Right = 256 * x2; + Count = 1; + } + uint32 b; for (b = 0; b < Count; b++) - { - if (pClip->Count [5]) - { - Left = pClip->Left [b][5] * x2; - Right = pClip->Right [b][5] * x2; - if (Right <= Left) - continue; - } - - if (GFX.r2131 & 0x80) - { - if (GFX.r2131 & 0x40) - { - // Subtract, halving the result. - register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; - register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; - register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; - register uint8 *e = d + Right; - uint16 back_fixed = COLOR_SUB (back, GFX.FixedColour); - - d += Left; - while (d < e) - { - if (*d == 0) - { - if (*s) - { - if (*s != 1) - *p = COLOR_SUB1_2 (back, *(p + GFX.Delta)); - else - *p = back_fixed; - } - else - *p = (uint16) back; - } - d++; - p++; - s++; - } - } - else - { - // Subtract - register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; - register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; - register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; - register uint8 *e = d + Right; - uint16 back_fixed = COLOR_SUB (back, GFX.FixedColour); - - d += Left; - while (d < e) - { - if (*d == 0) - { - if (*s) - { - if (*s != 1) - *p = COLOR_SUB (back, *(p + GFX.Delta)); - else - *p = back_fixed; - } - else - *p = (uint16) back; - } - d++; - p++; - s++; - } - } - } - else if (GFX.r2131 & 0x40) - { - register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; - register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; - register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; - register uint8 *e = d + Right; - uint16 back_fixed = COLOR_ADD (back, GFX.FixedColour); - d += Left; - while (d < e) - { - if (*d == 0) - { - if (*s) - { - if (*s != 1) - *p = COLOR_ADD1_2 (back, *(p + GFX.Delta)); - else - *p = back_fixed; - } - else - *p = (uint16) back; - } - d++; - p++; - s++; - } - } - else if (back != 0) - { - register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; - register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; - register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; - register uint8 *e = d + Right; - uint16 back_fixed = COLOR_ADD (back, GFX.FixedColour); - d += Left; - while (d < e) - { - if (*d == 0) - { - if (*s) - { - if (*s != 1) - *p = COLOR_ADD (back, *(p + GFX.Delta)); - else - *p = back_fixed; - } - else - *p = (uint16) back; - } - d++; - p++; - s++; - } - } - else - { - if (!pClip->Count [5]) - { - // The backdrop has not been cleared yet - so - // copy the sub-screen to the main screen - // or fill it with the back-drop colour if the - // sub-screen is clear. - register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; - register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; - register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; - register uint8 *e = d + Right; - d += Left; - while (d < e) - { - if (*d == 0) - { - if (*s) - { - if (*s != 1) - *p = *(p + GFX.Delta); - else - *p = GFX.FixedColour; - } - else - *p = (uint16) back; - } - d++; - p++; - s++; - } - } - } - } - } - } // --if (SUB_OR_ADD(5)) - else - { - // Subscreen not being added to back - uint32 back = IPPU.ScreenColors [0] | (IPPU.ScreenColors [0] << 16); - pClip = &IPPU.Clip [0]; - - if (pClip->Count [5]) - { + { + if (pClip->Count [5]) + { + Left = pClip->Left [b][5] * x2; + Right = pClip->Right [b][5] * x2; + if (Right <= Left) + continue; + } + + if (GFX.r2131 & 0x80) + { + if (GFX.r2131 & 0x40) + { + // Subtract, halving the result. + register uint16* p = (uint16*)(GFX.Screen + y * GFX.Pitch2) + Left; + register uint8* d = GFX.ZBuffer + y * GFX.ZPitch; + register uint8* s = GFX.SubZBuffer + y * GFX.ZPitch + Left; + register uint8* e = d + Right; + uint16 back_fixed = COLOR_SUB(back, GFX.FixedColour); + + d += Left; + while (d < e) + { + if (*d == 0) + { + if (*s) + { + if (*s != 1) + *p = COLOR_SUB1_2(back, *(p + GFX.Delta)); + else + *p = back_fixed; + } + else + *p = (uint16) back; + } + d++; + p++; + s++; + } + } + else + { + // Subtract + register uint16* p = (uint16*)(GFX.Screen + y * GFX.Pitch2) + Left; + register uint8* s = GFX.SubZBuffer + y * GFX.ZPitch + Left; + register uint8* d = GFX.ZBuffer + y * GFX.ZPitch; + register uint8* e = d + Right; + uint16 back_fixed = COLOR_SUB(back, GFX.FixedColour); + + d += Left; + while (d < e) + { + if (*d == 0) + { + if (*s) + { + if (*s != 1) + *p = COLOR_SUB(back, *(p + GFX.Delta)); + else + *p = back_fixed; + } + else + *p = (uint16) back; + } + d++; + p++; + s++; + } + } + } + else if (GFX.r2131 & 0x40) + { + register uint16* p = (uint16*)(GFX.Screen + y * GFX.Pitch2) + Left; + register uint8* d = GFX.ZBuffer + y * GFX.ZPitch; + register uint8* s = GFX.SubZBuffer + y * GFX.ZPitch + Left; + register uint8* e = d + Right; + uint16 back_fixed = COLOR_ADD(back, GFX.FixedColour); + d += Left; + while (d < e) + { + if (*d == 0) + { + if (*s) + { + if (*s != 1) + *p = COLOR_ADD1_2(back, *(p + GFX.Delta)); + else + *p = back_fixed; + } + else + *p = (uint16) back; + } + d++; + p++; + s++; + } + } + else if (back != 0) + { + register uint16* p = (uint16*)(GFX.Screen + y * GFX.Pitch2) + Left; + register uint8* d = GFX.ZBuffer + y * GFX.ZPitch; + register uint8* s = GFX.SubZBuffer + y * GFX.ZPitch + Left; + register uint8* e = d + Right; + uint16 back_fixed = COLOR_ADD(back, GFX.FixedColour); + d += Left; + while (d < e) + { + if (*d == 0) + { + if (*s) + { + if (*s != 1) + *p = COLOR_ADD(back, *(p + GFX.Delta)); + else + *p = back_fixed; + } + else + *p = (uint16) back; + } + d++; + p++; + s++; + } + } + else + { + if (!pClip->Count [5]) + { + // The backdrop has not been cleared yet - so + // copy the sub-screen to the main screen + // or fill it with the back-drop colour if the + // sub-screen is clear. + register uint16* p = (uint16*)(GFX.Screen + y * GFX.Pitch2) + Left; + register uint8* d = GFX.ZBuffer + y * GFX.ZPitch; + register uint8* s = GFX.SubZBuffer + y * GFX.ZPitch + Left; + register uint8* e = d + Right; + d += Left; + while (d < e) + { + if (*d == 0) + { + if (*s) + { + if (*s != 1) + *p = *(p + GFX.Delta); + else + *p = GFX.FixedColour; + } + else + *p = (uint16) back; + } + d++; + p++; + s++; + } + } + } + } + } + } // --if (SUB_OR_ADD(5)) + else + { + // Subscreen not being added to back + uint32 back = IPPU.ScreenColors [0] | (IPPU.ScreenColors [0] << 16); + pClip = &IPPU.Clip [0]; + + if (pClip->Count [5]) + { uint32 y; for (y = starty; y <= endy; y++) - { + { uint32 b; for (b = 0; b < pClip->Count [5]; b++) - { - uint32 Left = pClip->Left [b][5] * x2; - uint32 Right = pClip->Right [b][5] * x2; - uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; - uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; - uint8 *e = d + Right; - d += Left; - - while (d < e) - { - if (*d == 0) - *p = (int16) back; - d++; - p++; - } - } - } - } - else - { + { + uint32 Left = pClip->Left [b][5] * x2; + uint32 Right = pClip->Right [b][5] * x2; + uint16* p = (uint16*)(GFX.Screen + y * GFX.Pitch2) + Left; + uint8* d = GFX.ZBuffer + y * GFX.ZPitch; + uint8* e = d + Right; + d += Left; + + while (d < e) + { + if (*d == 0) + *p = (int16) back; + d++; + p++; + } + } + } + } + else + { uint32 y; for (y = starty; y <= endy; y++) - { - uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2); - uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; - uint8 *e = d + 256 * x2; - - while (d < e) - { - if (*d == 0) - *p = (int16) back; - d++; - p++; - } - } - } - } - } //force blanking - else - { - // 16bit and transparency but currently no transparency effects in - // operation. - - uint32 back = IPPU.ScreenColors [0] | (IPPU.ScreenColors [0] << 16); - - if (PPU.ForcedBlanking) - back = black; - - if (IPPU.Clip [0].Count[5]) - { + { + uint16* p = (uint16*)(GFX.Screen + y * GFX.Pitch2); + uint8* d = GFX.ZBuffer + y * GFX.ZPitch; + uint8* e = d + 256 * x2; + + while (d < e) + { + if (*d == 0) + *p = (int16) back; + d++; + p++; + } + } + } + } + } //force blanking + else + { + // 16bit and transparency but currently no transparency effects in + // operation. + + uint32 back = IPPU.ScreenColors [0] | (IPPU.ScreenColors [0] << 16); + + if (PPU.ForcedBlanking) + back = black; + + if (IPPU.Clip [0].Count[5]) + { uint32 y; for (y = starty; y <= endy; y++) - { - uint32 *p = (uint32 *) (GFX.Screen + y * GFX.Pitch2); - uint32 *q = (uint32 *) ((uint16 *) p + IPPU.RenderedScreenWidth); - - while (p < q) - *p++ = black; - + { + uint32* p = (uint32*)(GFX.Screen + y * GFX.Pitch2); + uint32* q = (uint32*)((uint16*) p + IPPU.RenderedScreenWidth); + + while (p < q) + *p++ = black; + uint32 c; for (c = 0; c < IPPU.Clip [0].Count [5]; c++) - { - if (IPPU.Clip [0].Right [c][5] > IPPU.Clip [0].Left [c][5]) - { - uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2); - uint16 *q = p + IPPU.Clip [0].Right [c][5] * x2; - p += IPPU.Clip [0].Left [c][5] * x2; - - while (p < q) - *p++ = (uint16) back; - } - } - } - } - else - { + { + if (IPPU.Clip [0].Right [c][5] > IPPU.Clip [0].Left [c][5]) + { + uint16* p = (uint16*)(GFX.Screen + y * GFX.Pitch2); + uint16* q = p + IPPU.Clip [0].Right [c][5] * x2; + p += IPPU.Clip [0].Left [c][5] * x2; + + while (p < q) + *p++ = (uint16) back; + } + } + } + } + else + { uint32 y; for (y = starty; y <= endy; y++) - { - uint32 *p = (uint32 *) (GFX.Screen + y * GFX.Pitch2); - uint32 *q = (uint32 *) ((uint16 *) p + IPPU.RenderedScreenWidth); - while (p < q) - *p++ = back; - } - } - - if (!PPU.ForcedBlanking) - { + { + uint32* p = (uint32*)(GFX.Screen + y * GFX.Pitch2); + uint32* q = (uint32*)((uint16*) p + IPPU.RenderedScreenWidth); + while (p < q) + *p++ = back; + } + } + + if (!PPU.ForcedBlanking) + { uint32 y; for (y = starty; y <= endy; y++) - { - ZeroMemory (GFX.ZBuffer + y * GFX.ZPitch, IPPU.RenderedScreenWidth); - } - GFX.DB = GFX.ZBuffer; - RenderScreen (GFX.Screen, FALSE, TRUE, SUB_SCREEN_DEPTH); - } - } - } - else - { - } + ZeroMemory(GFX.ZBuffer + y * GFX.ZPitch, IPPU.RenderedScreenWidth); + GFX.DB = GFX.ZBuffer; + RenderScreen(GFX.Screen, FALSE, TRUE, SUB_SCREEN_DEPTH); + } + } + } + else + { + } - if (Settings.SupportHiRes) - { - if (PPU.BGMode != 5 && PPU.BGMode != 6 && IPPU.DoubleWidthPixels) - { - // Mixure of background modes used on screen - scale width - // of all non-mode 5 and 6 pixels. + if (Settings.SupportHiRes) + { + if (PPU.BGMode != 5 && PPU.BGMode != 6 && IPPU.DoubleWidthPixels) + { + // Mixure of background modes used on screen - scale width + // of all non-mode 5 and 6 pixels. register uint32 y; for (y = starty; y <= endy; y++) { - register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + 255; - register uint16 *q = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + 510; + register uint16* p = (uint16*)(GFX.Screen + y * GFX.Pitch2) + 255; + register uint16* q = (uint16*)(GFX.Screen + y * GFX.Pitch2) + 510; register int x; for (x = 255; x >= 0; x--, p--, q -= 2) - *q = *(q + 1) = *p; + * q = *(q + 1) = *p; } - } + } - // Double the height of the pixels just drawn - FIX_INTERLACE(GFX.Screen, FALSE, GFX.ZBuffer); - } + // Double the height of the pixels just drawn + FIX_INTERLACE(GFX.Screen, FALSE, GFX.ZBuffer); + } - IPPU.PreviousLine = IPPU.CurrentLine; + IPPU.PreviousLine = IPPU.CurrentLine; } diff --git a/source/gfx.h b/source/gfx.h index 8280987..55b31bf 100644 --- a/source/gfx.h +++ b/source/gfx.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -93,83 +93,88 @@ #include "port.h" #include "snes9x.h" -void S9xStartScreenRefresh (); -void S9xDrawScanLine (uint8 Line); -void S9xEndScreenRefresh (); -void S9xSetupOBJ (); -void S9xUpdateScreen (); -void RenderLine (uint8 line); -void S9xBuildDirectColourMaps (); +void S9xStartScreenRefresh(); +void S9xDrawScanLine(uint8 Line); +void S9xEndScreenRefresh(); +void S9xSetupOBJ(); +void S9xUpdateScreen(); +void RenderLine(uint8 line); +void S9xBuildDirectColourMaps(); // External port interface which must be implemented or initialised for each // port. extern struct SGFX GFX; -bool8 S9xGraphicsInit (); +bool8 S9xGraphicsInit(); void S9xGraphicsDeinit(); -bool8 S9xInitUpdate (void); -void S9xDeinitUpdate (int width, int height); -void S9xSyncSpeed (); - -struct SGFX{ - // Initialize these variables - uint8 *Screen; - uint8 *SubScreen; - uint8 *ZBuffer; - uint8 *SubZBuffer; - uint32 Pitch; - - // Setup in call to S9xGraphicsInit() - int Delta; - uint16 *X2; - uint16 *ZERO_OR_X2; - uint16 *ZERO; - uint32 RealPitch; // True pitch of Screen buffer. - uint32 Pitch2; // Same as RealPitch except while using speed up hack for Glide. - uint32 ZPitch; // Pitch of ZBuffer - uint32 PPL; // Number of pixels on each of Screen buffer - uint32 PPLx2; - uint32 PixSize; - uint8 S_safety_margin[8]; - uint8 *S; - uint8 DB_safety_margin[8]; - uint8 *DB; - uint32 DepthDelta; - uint8 Z1; // Depth for comparison - uint8 Z2; // Depth to save - uint8 ZSprite; // Used to ensure only 1st sprite is drawn per pixel - uint32 FixedColour; - const char *InfoString; - uint32 InfoStringTimeout; - uint32 StartY; - uint32 EndY; - struct ClipData *pCurrentClip; - uint32 Mode7Mask; - uint32 Mode7PriorityMask; - uint8 OBJWidths[128]; - uint8 OBJVisibleTiles[128]; - struct { - uint8 RTOFlags; - int16 Tiles; - struct { - int8 Sprite; - uint8 Line; - } OBJ[32]; - } OBJLines [SNES_HEIGHT_EXTENDED]; - - uint8 r212c; - uint8 r212d; - uint8 r2130; - uint8 r2131; - bool8 Pseudo; - +bool8 S9xInitUpdate(void); +void S9xDeinitUpdate(int width, int height); +void S9xSyncSpeed(); + +struct SGFX +{ + // Initialize these variables + uint8* Screen; + uint8* SubScreen; + uint8* ZBuffer; + uint8* SubZBuffer; + uint32 Pitch; + + // Setup in call to S9xGraphicsInit() + int Delta; + uint16* X2; + uint16* ZERO_OR_X2; + uint16* ZERO; + uint32 RealPitch; // True pitch of Screen buffer. + uint32 Pitch2; // Same as RealPitch except while using speed up hack for Glide. + uint32 ZPitch; // Pitch of ZBuffer + uint32 PPL; // Number of pixels on each of Screen buffer + uint32 PPLx2; + uint32 PixSize; + uint8 S_safety_margin[8]; + uint8* S; + uint8 DB_safety_margin[8]; + uint8* DB; + uint32 DepthDelta; + uint8 Z1; // Depth for comparison + uint8 Z2; // Depth to save + uint8 ZSprite; // Used to ensure only 1st sprite is drawn per pixel + uint32 FixedColour; + const char* InfoString; + uint32 InfoStringTimeout; + uint32 StartY; + uint32 EndY; + struct ClipData* pCurrentClip; + uint32 Mode7Mask; + uint32 Mode7PriorityMask; + uint8 OBJWidths[128]; + uint8 OBJVisibleTiles[128]; + struct + { + uint8 RTOFlags; + int16 Tiles; + struct + { + int8 Sprite; + uint8 Line; + } OBJ[32]; + } OBJLines [SNES_HEIGHT_EXTENDED]; + + uint8 r212c; + uint8 r212d; + uint8 r2130; + uint8 r2131; + bool8 Pseudo; + }; -struct SLineData { - struct { - uint16 VOffset; - uint16 HOffset; - } BG [4]; +struct SLineData +{ + struct + { + uint16 VOffset; + uint16 HOffset; + } BG [4]; }; #define H_FLIP 0x4000 @@ -178,30 +183,30 @@ struct SLineData { typedef struct { - uint32 TileSize; - uint32 BitShift; - uint32 TileShift; - uint32 TileAddress; - uint32 NameSelect; - uint32 SCBase; - - uint32 StartPalette; - uint32 PaletteShift; - uint32 PaletteMask; - - uint8 *Buffer; - uint8 *Buffered; - bool8 DirectColourMode; -}SBG; + uint32 TileSize; + uint32 BitShift; + uint32 TileShift; + uint32 TileAddress; + uint32 NameSelect; + uint32 SCBase; + + uint32 StartPalette; + uint32 PaletteShift; + uint32 PaletteMask; + + uint8* Buffer; + uint8* Buffered; + bool8 DirectColourMode; +} SBG; struct SLineMatrixData { - short MatrixA; - short MatrixB; - short MatrixC; - short MatrixD; - short CentreX; - short CentreY; + short MatrixA; + short MatrixB; + short MatrixC; + short MatrixD; + short CentreX; + short CentreY; }; extern uint32 odd_high [4][16]; @@ -219,7 +224,7 @@ extern uint8 mul_brightness [16][32]; // Could use BSWAP instruction on Intel port... #define SWAP_DWORD(dw) dw = ((dw & 0xff) << 24) | ((dw & 0xff00) << 8) | \ - ((dw & 0xff0000) >> 8) | ((dw & 0xff000000) >> 24) + ((dw & 0xff0000) >> 8) | ((dw & 0xff000000) >> 24) #ifdef FAST_LSB_WORD_ACCESS #define READ_2BYTES(s) (*(uint16 *) (s)) @@ -228,11 +233,11 @@ extern uint8 mul_brightness [16][32]; #ifdef LSB_FIRST #define READ_2BYTES(s) (*(uint8 *) (s) | (*((uint8 *) (s) + 1) << 8)) #define WRITE_2BYTES(s, d) *(uint8 *) (s) = (d), \ - *((uint8 *) (s) + 1) = (d) >> 8 + *((uint8 *) (s) + 1) = (d) >> 8 #else // else MSB_FISRT #define READ_2BYTES(s) (*(uint8 *) (s) | (*((uint8 *) (s) + 1) << 8)) #define WRITE_2BYTES(s, d) *(uint8 *) (s) = (d), \ - *((uint8 *) (s) + 1) = (d) >> 8 + *((uint8 *) (s) + 1) = (d) >> 8 #endif // LSB_FIRST #endif // i386 @@ -242,19 +247,21 @@ extern uint8 mul_brightness [16][32]; #if defined(OLD_COLOUR_BLENDING) #define COLOR_ADD(C1, C2) \ GFX.X2 [((((C1) & RGB_REMOVE_LOW_BITS_MASK) + \ - ((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1) + \ - ((C1) & (C2) & RGB_LOW_BITS_MASK)] + ((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1) + \ + ((C1) & (C2) & RGB_LOW_BITS_MASK)] #else -static inline uint16 COLOR_ADD (uint16, uint16); +static inline uint16 COLOR_ADD(uint16, uint16); -static inline uint16 COLOR_ADD (uint16 C1, uint16 C2) +static inline uint16 COLOR_ADD(uint16 C1, uint16 C2) { - if (C1 == 0) - return C2; - else if (C2 == 0) - return C1; - else - return GFX.X2 [(((C1 & RGB_REMOVE_LOW_BITS_MASK) + (C2 & RGB_REMOVE_LOW_BITS_MASK)) >> 1) + (C1 & C2 & RGB_LOW_BITS_MASK)] | ((C1 ^ C2) & RGB_LOW_BITS_MASK); + if (C1 == 0) + return C2; + else if (C2 == 0) + return C1; + else + return GFX.X2 [(((C1 & RGB_REMOVE_LOW_BITS_MASK) + (C2 & + RGB_REMOVE_LOW_BITS_MASK)) >> 1) + (C1 & C2 & RGB_LOW_BITS_MASK)] | (( + C1 ^ C2) & RGB_LOW_BITS_MASK); } #endif @@ -266,7 +273,7 @@ static inline uint16 COLOR_ADD (uint16 C1, uint16 C2) #if defined(OLD_COLOUR_BLENDING) #define COLOR_SUB(C1, C2) \ GFX.ZERO_OR_X2 [(((C1) | RGB_HI_BITS_MASKx2) - \ - ((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1] + ((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1] #elif !defined(NEW_COLOUR_BLENDING) #define COLOR_SUB(C1, C2) \ (GFX.ZERO_OR_X2 [(((C1) | RGB_HI_BITS_MASKx2) - \ @@ -277,36 +284,36 @@ inline uint16 COLOR_SUB(uint16, uint16); inline uint16 COLOR_SUB(uint16 C1, uint16 C2) { - uint16 mC1, mC2, v = 0; - - mC1 = C1 & FIRST_COLOR_MASK; - mC2 = C2 & FIRST_COLOR_MASK; - if (mC1 > mC2) v += (mC1 - mC2); - - mC1 = C1 & SECOND_COLOR_MASK; - mC2 = C2 & SECOND_COLOR_MASK; - if (mC1 > mC2) v += (mC1 - mC2); - - mC1 = C1 & THIRD_COLOR_MASK; - mC2 = C2 & THIRD_COLOR_MASK; - if (mC1 > mC2) v += (mC1 - mC2); - - return v; + uint16 mC1, mC2, v = 0; + + mC1 = C1 & FIRST_COLOR_MASK; + mC2 = C2 & FIRST_COLOR_MASK; + if (mC1 > mC2) v += (mC1 - mC2); + + mC1 = C1 & SECOND_COLOR_MASK; + mC2 = C2 & SECOND_COLOR_MASK; + if (mC1 > mC2) v += (mC1 - mC2); + + mC1 = C1 & THIRD_COLOR_MASK; + mC2 = C2 & THIRD_COLOR_MASK; + if (mC1 > mC2) v += (mC1 - mC2); + + return v; } #endif #define COLOR_SUB1_2(C1, C2) \ GFX.ZERO [(((C1) | RGB_HI_BITS_MASKx2) - \ - ((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1] - -typedef void (*NormalTileRenderer) (uint32 Tile, int32 Offset, - uint32 StartLine, uint32 LineCount); -typedef void (*ClippedTileRenderer) (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount); -typedef void (*LargePixelRenderer) (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Pixels, - uint32 StartLine, uint32 LineCount); + ((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1] + +typedef void (*NormalTileRenderer)(uint32 Tile, int32 Offset, + uint32 StartLine, uint32 LineCount); +typedef void (*ClippedTileRenderer)(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount); +typedef void (*LargePixelRenderer)(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount); #endif diff --git a/source/globals.c b/source/globals.c index caf3ee0..b28f88a 100644 --- a/source/globals.c +++ b/source/globals.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -122,12 +122,12 @@ SSA1 SA1; SSoundData SoundData; -SnesModel M1SNES={1,3,2}; -SnesModel M2SNES={2,4,3}; -SnesModel* Model=&M1SNES; +SnesModel M1SNES = {1, 3, 2}; +SnesModel M2SNES = {2, 4, 3}; +SnesModel* Model = &M1SNES; -uint8 *C4RAM = NULL; +uint8* C4RAM = NULL; long OpAddress = 0; @@ -140,7 +140,7 @@ uint8 OpenBus = 0; #ifndef ZSNES_FX struct FxInit_s SuperFX; #else -uint8 *SFXPlotTable = NULL; +uint8* SFXPlotTable = NULL; #endif SPPU PPU; @@ -148,8 +148,8 @@ InternalPPU IPPU; SDMA DMA[8]; -uint8 *HDMAMemPointers [8]; -uint8 *HDMABasePointers [8]; +uint8* HDMAMemPointers [8]; +uint8* HDMABasePointers [8]; SBG BG; @@ -181,156 +181,162 @@ int FilterTaps [8]; unsigned long Z = 0; int Loop [16]; -uint16 SignExtend [2] = { - 0x00, 0xff00 +uint16 SignExtend [2] = +{ + 0x00, 0xff00 }; //modified per anomie Mode 5 findings -int HDMA_ModeByteCounts [8] = { - 1, 2, 2, 4, 4, 4, 2, 4 +int HDMA_ModeByteCounts [8] = +{ + 1, 2, 2, 4, 4, 4, 2, 4 }; uint8 BitShifts[8][4] = { - {2, 2, 2, 2}, // 0 - {4, 4, 2, 0}, // 1 - {4, 4, 0, 0}, // 2 - {8, 4, 0, 0}, // 3 - {8, 2, 0, 0}, // 4 - {4, 2, 0, 0}, // 5 - {4, 0, 0, 0}, // 6 - {8, 0, 0, 0} // 7 + {2, 2, 2, 2}, // 0 + {4, 4, 2, 0}, // 1 + {4, 4, 0, 0}, // 2 + {8, 4, 0, 0}, // 3 + {8, 2, 0, 0}, // 4 + {4, 2, 0, 0}, // 5 + {4, 0, 0, 0}, // 6 + {8, 0, 0, 0} // 7 }; uint8 TileShifts[8][4] = { - {4, 4, 4, 4}, // 0 - {5, 5, 4, 0}, // 1 - {5, 5, 0, 0}, // 2 - {6, 5, 0, 0}, // 3 - {6, 4, 0, 0}, // 4 - {5, 4, 0, 0}, // 5 - {5, 0, 0, 0}, // 6 - {6, 0, 0, 0} // 7 + {4, 4, 4, 4}, // 0 + {5, 5, 4, 0}, // 1 + {5, 5, 0, 0}, // 2 + {6, 5, 0, 0}, // 3 + {6, 4, 0, 0}, // 4 + {5, 4, 0, 0}, // 5 + {5, 0, 0, 0}, // 6 + {6, 0, 0, 0} // 7 }; uint8 PaletteShifts[8][4] = { - {2, 2, 2, 2}, // 0 - {4, 4, 2, 0}, // 1 - {4, 4, 0, 0}, // 2 - {0, 4, 0, 0}, // 3 - {0, 2, 0, 0}, // 4 - {4, 2, 0, 0}, // 5 - {4, 0, 0, 0}, // 6 - {0, 0, 0, 0} // 7 + {2, 2, 2, 2}, // 0 + {4, 4, 2, 0}, // 1 + {4, 4, 0, 0}, // 2 + {0, 4, 0, 0}, // 3 + {0, 2, 0, 0}, // 4 + {4, 2, 0, 0}, // 5 + {4, 0, 0, 0}, // 6 + {0, 0, 0, 0} // 7 }; uint8 PaletteMasks[8][4] = { - {7, 7, 7, 7}, // 0 - {7, 7, 7, 0}, // 1 - {7, 7, 0, 0}, // 2 - {0, 7, 0, 0}, // 3 - {0, 7, 0, 0}, // 4 - {7, 7, 0, 0}, // 5 - {7, 0, 0, 0}, // 6 - {0, 0, 0, 0} // 7 + {7, 7, 7, 7}, // 0 + {7, 7, 7, 0}, // 1 + {7, 7, 0, 0}, // 2 + {0, 7, 0, 0}, // 3 + {0, 7, 0, 0}, // 4 + {7, 7, 0, 0}, // 5 + {7, 0, 0, 0}, // 6 + {0, 0, 0, 0} // 7 }; uint8 Depths[8][4] = { - {TILE_2BIT, TILE_2BIT, TILE_2BIT, TILE_2BIT}, // 0 - {TILE_4BIT, TILE_4BIT, TILE_2BIT, 0}, // 1 - {TILE_4BIT, TILE_4BIT, 0, 0}, // 2 - {TILE_8BIT, TILE_4BIT, 0, 0}, // 3 - {TILE_8BIT, TILE_2BIT, 0, 0}, // 4 - {TILE_4BIT, TILE_2BIT, 0, 0}, // 5 - {TILE_4BIT, 0, 0, 0}, // 6 - {0, 0, 0, 0} // 7 + {TILE_2BIT, TILE_2BIT, TILE_2BIT, TILE_2BIT}, // 0 + {TILE_4BIT, TILE_4BIT, TILE_2BIT, 0}, // 1 + {TILE_4BIT, TILE_4BIT, 0, 0}, // 2 + {TILE_8BIT, TILE_4BIT, 0, 0}, // 3 + {TILE_8BIT, TILE_2BIT, 0, 0}, // 4 + {TILE_4BIT, TILE_2BIT, 0, 0}, // 5 + {TILE_4BIT, 0, 0, 0}, // 6 + {0, 0, 0, 0} // 7 }; -uint8 BGSizes [2] = { - 8, 16 +uint8 BGSizes [2] = +{ + 8, 16 }; uint16 DirectColourMaps [8][256]; long FilterValues[4][2] = { - {0, 0}, - {240, 0}, - {488, -240}, - {460, -208} + {0, 0}, + {240, 0}, + {488, -240}, + {460, -208} }; -int NoiseFreq [32] = { - 0, 16, 21, 25, 31, 42, 50, 63, 84, 100, 125, 167, 200, 250, 333, - 400, 500, 667, 800, 1000, 1300, 1600, 2000, 2700, 3200, 4000, - 5300, 6400, 8000, 10700, 16000, 32000 +int NoiseFreq [32] = +{ + 0, 16, 21, 25, 31, 42, 50, 63, 84, 100, 125, 167, 200, 250, 333, + 400, 500, 667, 800, 1000, 1300, 1600, 2000, 2700, 3200, 4000, + 5300, 6400, 8000, 10700, 16000, 32000 }; -uint32 HeadMask [4] = { +uint32 HeadMask [4] = +{ #ifdef LSB_FIRST - 0xffffffff, 0xffffff00, 0xffff0000, 0xff000000 + 0xffffffff, 0xffffff00, 0xffff0000, 0xff000000 #else - 0xffffffff, 0x00ffffff, 0x0000ffff, 0x000000ff + 0xffffffff, 0x00ffffff, 0x0000ffff, 0x000000ff #endif }; -uint32 TailMask [5] = { +uint32 TailMask [5] = +{ #ifdef LSB_FIRST - 0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff, 0xffffffff + 0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff, 0xffffffff #else - 0x00000000, 0xff000000, 0xffff0000, 0xffffff00, 0xffffffff + 0x00000000, 0xff000000, 0xffff0000, 0xffffff00, 0xffffffff #endif }; uint8 APUROM [64] = { - 0xCD,0xEF,0xBD,0xE8,0x00,0xC6,0x1D,0xD0,0xFC,0x8F,0xAA,0xF4,0x8F, - 0xBB,0xF5,0x78,0xCC,0xF4,0xD0,0xFB,0x2F,0x19,0xEB,0xF4,0xD0,0xFC, - 0x7E,0xF4,0xD0,0x0B,0xE4,0xF5,0xCB,0xF4,0xD7,0x00,0xFC,0xD0,0xF3, - 0xAB,0x01,0x10,0xEF,0x7E,0xF4,0x10,0xEB,0xBA,0xF6,0xDA,0x00,0xBA, - 0xF4,0xC4,0xF4,0xDD,0x5D,0xD0,0xDB,0x1F,0x00,0x00,0xC0,0xFF + 0xCD, 0xEF, 0xBD, 0xE8, 0x00, 0xC6, 0x1D, 0xD0, 0xFC, 0x8F, 0xAA, 0xF4, 0x8F, + 0xBB, 0xF5, 0x78, 0xCC, 0xF4, 0xD0, 0xFB, 0x2F, 0x19, 0xEB, 0xF4, 0xD0, 0xFC, + 0x7E, 0xF4, 0xD0, 0x0B, 0xE4, 0xF5, 0xCB, 0xF4, 0xD7, 0x00, 0xFC, 0xD0, 0xF3, + 0xAB, 0x01, 0x10, 0xEF, 0x7E, 0xF4, 0x10, 0xEB, 0xBA, 0xF6, 0xDA, 0x00, 0xBA, + 0xF4, 0xC4, 0xF4, 0xDD, 0x5D, 0xD0, 0xDB, 0x1F, 0x00, 0x00, 0xC0, 0xFF }; // Raw SPC700 instruction cycle lengths -uint16 S9xAPUCycleLengths [256] = +uint16 S9xAPUCycleLengths [256] = { - /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, */ - /* 00 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 6, 8, - /* 10 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 4, 6, - /* 20 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 5, 4, - /* 30 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 3, 8, - /* 40 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 6, 6, - /* 50 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 4, 5, 2, 2, 4, 3, - /* 60 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 5, 5, - /* 70 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 6, - /* 80 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 2, 4, 5, - /* 90 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2,12, 5, - /* a0 */ 3, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 2, 4, 4, - /* b0 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 4, - /* c0 */ 3, 8, 4, 5, 4, 5, 4, 7, 2, 5, 6, 4, 5, 2, 4, 9, - /* d0 */ 2, 8, 4, 5, 5, 6, 6, 7, 4, 5, 4, 5, 2, 2, 6, 3, - /* e0 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 4, 5, 3, 4, 3, 4, 3, - /* f0 */ 2, 8, 4, 5, 4, 5, 5, 6, 3, 4, 5, 4, 2, 2, 4, 3 + /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, */ + /* 00 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 6, 8, + /* 10 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 4, 6, + /* 20 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 5, 4, + /* 30 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 3, 8, + /* 40 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 6, 6, + /* 50 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 4, 5, 2, 2, 4, 3, + /* 60 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 5, 5, + /* 70 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 6, + /* 80 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 2, 4, 5, + /* 90 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 12, 5, + /* a0 */ 3, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 2, 4, 4, + /* b0 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 4, + /* c0 */ 3, 8, 4, 5, 4, 5, 4, 7, 2, 5, 6, 4, 5, 2, 4, 9, + /* d0 */ 2, 8, 4, 5, 5, 6, 6, 7, 4, 5, 4, 5, 2, 2, 6, 3, + /* e0 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 4, 5, 3, 4, 3, 4, 3, + /* f0 */ 2, 8, 4, 5, 4, 5, 5, 6, 3, 4, 5, 4, 2, 2, 4, 3 }; // Actual data used by CPU emulation, will be scaled by APUReset routine // to be relative to the 65c816 instruction lengths. uint16 S9xAPUCycles [256] = { - /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, */ - /* 00 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 6, 8, - /* 10 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 4, 6, - /* 20 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 5, 4, - /* 30 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 3, 8, - /* 40 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 6, 6, - /* 50 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 4, 5, 2, 2, 4, 3, - /* 60 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 5, 5, - /* 70 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 6, - /* 80 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 2, 4, 5, - /* 90 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2,12, 5, - /* a0 */ 3, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 2, 4, 4, - /* b0 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 4, - /* c0 */ 3, 8, 4, 5, 4, 5, 4, 7, 2, 5, 6, 4, 5, 2, 4, 9, - /* d0 */ 2, 8, 4, 5, 5, 6, 6, 7, 4, 5, 4, 5, 2, 2, 6, 3, - /* e0 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 4, 5, 3, 4, 3, 4, 3, - /* f0 */ 2, 8, 4, 5, 4, 5, 5, 6, 3, 4, 5, 4, 2, 2, 4, 3 + /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, */ + /* 00 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 6, 8, + /* 10 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 4, 6, + /* 20 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 5, 4, + /* 30 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 3, 8, + /* 40 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 6, 6, + /* 50 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 4, 5, 2, 2, 4, 3, + /* 60 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 5, 5, + /* 70 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 6, + /* 80 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 2, 4, 5, + /* 90 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 12, 5, + /* a0 */ 3, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 2, 4, 4, + /* b0 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 4, + /* c0 */ 3, 8, 4, 5, 4, 5, 4, 7, 2, 5, 6, 4, 5, 2, 4, 9, + /* d0 */ 2, 8, 4, 5, 5, 6, 6, 7, 4, 5, 4, 5, 2, 2, 6, 3, + /* e0 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 4, 5, 3, 4, 3, 4, 3, + /* f0 */ 2, 8, 4, 5, 4, 5, 5, 6, 3, 4, 5, 4, 2, 2, 4, 3 }; diff --git a/source/memmap.c b/source/memmap.c index 38411c2..682b98d 100644 --- a/source/memmap.c +++ b/source/memmap.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -125,7 +125,7 @@ #include "fxemu.h" extern struct FxInit_s SuperFX; #else -extern uint8 *SFXPlotTable; +extern uint8* SFXPlotTable; #endif #ifndef SET_UI_COLOR @@ -142,440 +142,443 @@ extern uint8 *SFXPlotTable; #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif -static int retry_count=0; +static int retry_count = 0; static uint8 bytes0x2000 [0x2000]; -int is_bsx(unsigned char *); -int bs_name(unsigned char *); +int is_bsx(unsigned char*); +int bs_name(unsigned char*); int check_char(unsigned); -void S9xDeinterleaveType2 (bool8 reset); -uint32 caCRC32(uint8 *array, uint32 size, register uint32 crc32); - -extern char *rom_filename; - -const uint32 crc32Table[256] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, - 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, - 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, - 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, - 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, - 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, - 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, - 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, - 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, - 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, - 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, - 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, - 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, - 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, - 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, - 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, - 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, - 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +void S9xDeinterleaveType2(bool8 reset); +uint32 caCRC32(uint8* array, uint32 size, register uint32 crc32); + +extern char* rom_filename; + +const uint32 crc32Table[256] = +{ + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; -void S9xDeinterleaveType1(int TotalFileSize, uint8 * base) +void S9xDeinterleaveType1(int TotalFileSize, uint8* base) { - if(Settings.DisplayColor==0xffff) - { - Settings.DisplayColor=BUILD_PIXEL(0,31,0); - SET_UI_COLOR(0,255,0); - } - - int i; - int nblocks = TotalFileSize >> 16; - uint8 blocks [256]; - for (i = 0; i < nblocks; i++) - { - blocks [i * 2] = i + nblocks; - blocks [i * 2 + 1] = i; - } - // DS2 DMA notes: base may or may not be 32-byte aligned - uint8 *tmp = (uint8 *) malloc (0x8000); - if (tmp) - { - for (i = 0; i < nblocks * 2; i++) - { + if (Settings.DisplayColor == 0xffff) + { + Settings.DisplayColor = BUILD_PIXEL(0, 31, 0); + SET_UI_COLOR(0, 255, 0); + } + + int i; + int nblocks = TotalFileSize >> 16; + uint8 blocks [256]; + for (i = 0; i < nblocks; i++) + { + blocks [i * 2] = i + nblocks; + blocks [i * 2 + 1] = i; + } + // DS2 DMA notes: base may or may not be 32-byte aligned + uint8* tmp = (uint8*) malloc(0x8000); + if (tmp) + { + for (i = 0; i < nblocks * 2; i++) + { int j; for (j = i; j < nblocks * 2; j++) - { - if (blocks [j] == i) - { - // memmove converted: Different mallocs [Neb] - memcpy (tmp, &base [blocks [j] * 0x8000], 0x8000); - // memmove converted: Different addresses, or identical for blocks[i] == blocks[j] [Neb] - // DS2 DMA notes: Don't do DMA at all if blocks[i] == blocks[j] - memcpy (&base [blocks [j] * 0x8000], - &base [blocks [i] * 0x8000], 0x8000); - // memmove converted: Different mallocs [Neb] - memcpy (&base [blocks [i] * 0x8000], tmp, 0x8000); - uint8 b = blocks [j]; - blocks [j] = blocks [i]; - blocks [i] = b; - break; - } - } - } - free ((char *) tmp); - } + { + if (blocks [j] == i) + { + // memmove converted: Different mallocs [Neb] + memcpy(tmp, &base [blocks [j] * 0x8000], 0x8000); + // memmove converted: Different addresses, or identical for blocks[i] == blocks[j] [Neb] + // DS2 DMA notes: Don't do DMA at all if blocks[i] == blocks[j] + memcpy(&base [blocks [j] * 0x8000], + &base [blocks [i] * 0x8000], 0x8000); + // memmove converted: Different mallocs [Neb] + memcpy(&base [blocks [i] * 0x8000], tmp, 0x8000); + uint8 b = blocks [j]; + blocks [j] = blocks [i]; + blocks [i] = b; + break; + } + } + } + free((char*) tmp); + } } -void S9xDeinterleaveGD24(int TotalFileSize, uint8 * base) +void S9xDeinterleaveGD24(int TotalFileSize, uint8* base) { - if(TotalFileSize!=0x300000) - return; - - if(Settings.DisplayColor==0xffff) - { - Settings.DisplayColor=BUILD_PIXEL(0,31,31); - SET_UI_COLOR(0,255,255); - } - - // DS2 DMA notes: base may or may not be 32-byte aligned - uint8 *tmp = (uint8 *) malloc (0x80000); - if (tmp) - { - // memmove converted: Different mallocs [Neb] - memcpy(tmp, &base[0x180000], 0x80000); - // memmove converted: Different addresses [Neb] - memcpy(&base[0x180000], &base[0x200000], 0x80000); - // memmove converted: Different addresses [Neb] - memcpy(&base[0x200000], &base[0x280000], 0x80000); - // memmove converted: Different mallocs [Neb] - memcpy(&base[0x280000], tmp, 0x80000); - free ((char *) tmp); - - S9xDeinterleaveType1(TotalFileSize, base); - } + if (TotalFileSize != 0x300000) + return; + + if (Settings.DisplayColor == 0xffff) + { + Settings.DisplayColor = BUILD_PIXEL(0, 31, 31); + SET_UI_COLOR(0, 255, 255); + } + + // DS2 DMA notes: base may or may not be 32-byte aligned + uint8* tmp = (uint8*) malloc(0x80000); + if (tmp) + { + // memmove converted: Different mallocs [Neb] + memcpy(tmp, &base[0x180000], 0x80000); + // memmove converted: Different addresses [Neb] + memcpy(&base[0x180000], &base[0x200000], 0x80000); + // memmove converted: Different addresses [Neb] + memcpy(&base[0x200000], &base[0x280000], 0x80000); + // memmove converted: Different mallocs [Neb] + memcpy(&base[0x280000], tmp, 0x80000); + free((char*) tmp); + + S9xDeinterleaveType1(TotalFileSize, base); + } } -bool8 AllASCII (uint8 *b, int size) +bool8 AllASCII(uint8* b, int size) { int i; - for (i = 0; i < size; i++) - { - if (b[i] < 32 || b[i] > 126) - return (FALSE); - } - return (TRUE); + for (i = 0; i < size; i++) + { + if (b[i] < 32 || b[i] > 126) + return (FALSE); + } + return (TRUE); } -int ScoreHiROM (bool8 skip_header, int32 romoff) +int ScoreHiROM(bool8 skip_header, int32 romoff) { - int score = 0; - int o = skip_header ? 0xff00 + 0x200 : 0xff00; - - o+=romoff; - - if(Memory.ROM [o + 0xd5] & 0x1) - score+=2; - - //Mode23 is SA-1 - if(Memory.ROM [o + 0xd5] == 0x23) - score-=2; - - if(Memory.ROM [o+0xd4] == 0x20) - score +=2; - - if ((Memory.ROM [o + 0xdc] + (Memory.ROM [o + 0xdd] << 8) + - Memory.ROM [o + 0xde] + (Memory.ROM [o + 0xdf] << 8)) == 0xffff) - { - score += 2; - if(0!=(Memory.ROM [o + 0xde] + (Memory.ROM [o + 0xdf] << 8))) - score++; - } - - if (Memory.ROM [o + 0xda] == 0x33) - score += 2; - if ((Memory.ROM [o + 0xd5] & 0xf) < 4) - score += 2; - if (!(Memory.ROM [o + 0xfd] & 0x80)) - score -= 6; - if ((Memory.ROM [o + 0xfc]|(Memory.ROM [o + 0xfd]<<8))>0xFFB0) - score -= 2; //reduced after looking at a scan by Cowering - if (Memory.CalculatedSize > 1024 * 1024 * 3) - score += 4; - if ((1 << (Memory.ROM [o + 0xd7] - 7)) > 48) - score -= 1; - if (!AllASCII (&Memory.ROM [o + 0xb0], 6)) - score -= 1; - if (!AllASCII (&Memory.ROM [o + 0xc0], ROM_NAME_LEN - 1)) - score -= 1; - - return (score); -} - -int ScoreLoROM (bool8 skip_header, int32 romoff) + int score = 0; + int o = skip_header ? 0xff00 + 0x200 : 0xff00; + + o += romoff; + + if (Memory.ROM [o + 0xd5] & 0x1) + score += 2; + + //Mode23 is SA-1 + if (Memory.ROM [o + 0xd5] == 0x23) + score -= 2; + + if (Memory.ROM [o + 0xd4] == 0x20) + score += 2; + + if ((Memory.ROM [o + 0xdc] + (Memory.ROM [o + 0xdd] << 8) + + Memory.ROM [o + 0xde] + (Memory.ROM [o + 0xdf] << 8)) == 0xffff) + { + score += 2; + if (0 != (Memory.ROM [o + 0xde] + (Memory.ROM [o + 0xdf] << 8))) + score++; + } + + if (Memory.ROM [o + 0xda] == 0x33) + score += 2; + if ((Memory.ROM [o + 0xd5] & 0xf) < 4) + score += 2; + if (!(Memory.ROM [o + 0xfd] & 0x80)) + score -= 6; + if ((Memory.ROM [o + 0xfc] | (Memory.ROM [o + 0xfd] << 8)) > 0xFFB0) + score -= 2; //reduced after looking at a scan by Cowering + if (Memory.CalculatedSize > 1024 * 1024 * 3) + score += 4; + if ((1 << (Memory.ROM [o + 0xd7] - 7)) > 48) + score -= 1; + if (!AllASCII(&Memory.ROM [o + 0xb0], 6)) + score -= 1; + if (!AllASCII(&Memory.ROM [o + 0xc0], ROM_NAME_LEN - 1)) + score -= 1; + + return (score); +} + +int ScoreLoROM(bool8 skip_header, int32 romoff) { - int score = 0; - int o = skip_header ? 0x7f00 + 0x200 : 0x7f00; - - o+=romoff; - - if(!(Memory.ROM [o + 0xd5] & 0x1)) - score+=3; - - //Mode23 is SA-1 - if(Memory.ROM [o + 0xd5] == 0x23) - score+=2; - - if ((Memory.ROM [o + 0xdc] + (Memory.ROM [o + 0xdd] << 8) + - Memory.ROM [o + 0xde] + (Memory.ROM [o + 0xdf] << 8)) == 0xffff) - { - score += 2; - if(0!=(Memory.ROM [o + 0xde] + (Memory.ROM [o + 0xdf] << 8))) - score++; - } - - if (Memory.ROM [o + 0xda] == 0x33) - score += 2; - if ((Memory.ROM [o + 0xd5] & 0xf) < 4) - score += 2; - if (Memory.CalculatedSize <= 1024 * 1024 * 16) - score += 2; - if (!(Memory.ROM [o + 0xfd] & 0x80)) - score -= 6; - if ((Memory.ROM [o + 0xfc]|(Memory.ROM [o + 0xfd]<<8))>0xFFB0) - score -= 2;//reduced per Cowering suggestion - if ((1 << (Memory.ROM [o + 0xd7] - 7)) > 48) - score -= 1; - if (!AllASCII (&Memory.ROM [o + 0xb0], 6)) - score -= 1; - if (!AllASCII (&Memory.ROM [o + 0xc0], ROM_NAME_LEN - 1)) - score -= 1; - - return (score); + int score = 0; + int o = skip_header ? 0x7f00 + 0x200 : 0x7f00; + + o += romoff; + + if (!(Memory.ROM [o + 0xd5] & 0x1)) + score += 3; + + //Mode23 is SA-1 + if (Memory.ROM [o + 0xd5] == 0x23) + score += 2; + + if ((Memory.ROM [o + 0xdc] + (Memory.ROM [o + 0xdd] << 8) + + Memory.ROM [o + 0xde] + (Memory.ROM [o + 0xdf] << 8)) == 0xffff) + { + score += 2; + if (0 != (Memory.ROM [o + 0xde] + (Memory.ROM [o + 0xdf] << 8))) + score++; + } + + if (Memory.ROM [o + 0xda] == 0x33) + score += 2; + if ((Memory.ROM [o + 0xd5] & 0xf) < 4) + score += 2; + if (Memory.CalculatedSize <= 1024 * 1024 * 16) + score += 2; + if (!(Memory.ROM [o + 0xfd] & 0x80)) + score -= 6; + if ((Memory.ROM [o + 0xfc] | (Memory.ROM [o + 0xfd] << 8)) > 0xFFB0) + score -= 2;//reduced per Cowering suggestion + if ((1 << (Memory.ROM [o + 0xd7] - 7)) > 48) + score -= 1; + if (!AllASCII(&Memory.ROM [o + 0xb0], 6)) + score -= 1; + if (!AllASCII(&Memory.ROM [o + 0xc0], ROM_NAME_LEN - 1)) + score -= 1; + + return (score); } -char *Safe (const char *s) +char* Safe(const char* s) { - static char *safe; - static int safe_len = 0; - - if(s==NULL) - { - if(safe!=NULL) - { - free((char*)safe); - safe = NULL; - } - return NULL; - } - int len = strlen (s); - if (!safe || len + 1 > safe_len) - { - if (safe) - free ((char *) safe); - safe = (char *) malloc (safe_len = len + 1); - } - - int i; - for (i = 0; i < len; i++) - { - if (s [i] >= 32 && s [i] < 127) - safe [i] = s[i]; - else - safe [i] = '?'; - } - safe [len] = 0; - return (safe); + static char* safe; + static int safe_len = 0; + + if (s == NULL) + { + if (safe != NULL) + { + free((char*)safe); + safe = NULL; + } + return NULL; + } + int len = strlen(s); + if (!safe || len + 1 > safe_len) + { + if (safe) + free((char*) safe); + safe = (char*) malloc(safe_len = len + 1); + } + + int i; + for (i = 0; i < len; i++) + { + if (s [i] >= 32 && s [i] < 127) + safe [i] = s[i]; + else + safe [i] = '?'; + } + safe [len] = 0; + return (safe); } /**********************************************************************************************/ /* Init() */ /* This function allocates and zeroes all the memory needed by the emulator */ /**********************************************************************************************/ -bool8 Init () +bool8 Init() { - // DS2 DMA notes: These would do well to be allocated with 32 extra bytes - // so they can be 32-byte aligned. [Neb] - Memory.RAM = (uint8 *) malloc (0x20000); - Memory.SRAM = (uint8 *) malloc (0x20000); - Memory.VRAM = (uint8 *) malloc (0x10000); + // DS2 DMA notes: These would do well to be allocated with 32 extra bytes + // so they can be 32-byte aligned. [Neb] + Memory.RAM = (uint8*) malloc(0x20000); + Memory.SRAM = (uint8*) malloc(0x20000); + Memory.VRAM = (uint8*) malloc(0x10000); #ifdef DS2_DMA - ROM = (uint8 *) AlignedMalloc (MAX_ROM_SIZE + 0x200 + 0x8000, 32, &PtrAdj.ROM); + ROM = (uint8*) AlignedMalloc(MAX_ROM_SIZE + 0x200 + 0x8000, 32, + &PtrAdj.ROM); #else - Memory.ROM = (uint8 *) malloc (MAX_ROM_SIZE + 0x200 + 0x8000); + Memory.ROM = (uint8*) malloc(MAX_ROM_SIZE + 0x200 + 0x8000); #endif - memset (Memory.RAM, 0, 0x20000); - memset (Memory.SRAM, 0, 0x20000); - memset (Memory.VRAM, 0, 0x10000); - // This needs to be initialised with a ROM first anyway, so don't - // bother memsetting. [Neb] - // memset (ROM, 0, MAX_ROM_SIZE + 0x200 + 0x8000); - - Memory.BSRAM = (uint8 *) malloc (0x80000); - memset (Memory.BSRAM, 0, 0x80000); + memset(Memory.RAM, 0, 0x20000); + memset(Memory.SRAM, 0, 0x20000); + memset(Memory.VRAM, 0, 0x10000); + // This needs to be initialised with a ROM first anyway, so don't + // bother memsetting. [Neb] + // memset (ROM, 0, MAX_ROM_SIZE + 0x200 + 0x8000); + + Memory.BSRAM = (uint8*) malloc(0x80000); + memset(Memory.BSRAM, 0, 0x80000); Memory.FillRAM = NULL; - - IPPU.TileCache [TILE_2BIT] = (uint8 *) malloc (MAX_2BIT_TILES * 128); - IPPU.TileCache [TILE_4BIT] = (uint8 *) malloc (MAX_4BIT_TILES * 128); - IPPU.TileCache [TILE_8BIT] = (uint8 *) malloc (MAX_8BIT_TILES * 128); - - IPPU.TileCached [TILE_2BIT] = (uint8 *) malloc (MAX_2BIT_TILES); - IPPU.TileCached [TILE_4BIT] = (uint8 *) malloc (MAX_4BIT_TILES); - IPPU.TileCached [TILE_8BIT] = (uint8 *) malloc (MAX_8BIT_TILES); - - if (!Memory.RAM || !Memory.SRAM || !Memory.VRAM || !Memory.ROM || !Memory.BSRAM || - !IPPU.TileCache [TILE_2BIT] || !IPPU.TileCache [TILE_4BIT] || - !IPPU.TileCache [TILE_8BIT] || !IPPU.TileCached [TILE_2BIT] || - !IPPU.TileCached [TILE_4BIT] || !IPPU.TileCached [TILE_8BIT]) - { - Deinit (); - return (FALSE); - } - - // FillRAM uses first 32K of ROM image area, otherwise space just - // wasted. Might be read by the SuperFX code. - - Memory.FillRAM = Memory.ROM; - - // Add 0x8000 to ROM image pointer to stop SuperFX code accessing - // unallocated memory (can cause crash on some ports). - Memory.ROM += 0x8000; // still 32-byte aligned - - Memory.C4RAM = Memory.ROM + 0x400000 + 8192 * 8; // still 32-byte aligned - Memory.ROM = Memory.ROM; - Memory.SRAM = Memory.SRAM; - + + IPPU.TileCache [TILE_2BIT] = (uint8*) malloc(MAX_2BIT_TILES * 128); + IPPU.TileCache [TILE_4BIT] = (uint8*) malloc(MAX_4BIT_TILES * 128); + IPPU.TileCache [TILE_8BIT] = (uint8*) malloc(MAX_8BIT_TILES * 128); + + IPPU.TileCached [TILE_2BIT] = (uint8*) malloc(MAX_2BIT_TILES); + IPPU.TileCached [TILE_4BIT] = (uint8*) malloc(MAX_4BIT_TILES); + IPPU.TileCached [TILE_8BIT] = (uint8*) malloc(MAX_8BIT_TILES); + + if (!Memory.RAM || !Memory.SRAM || !Memory.VRAM || !Memory.ROM || !Memory.BSRAM + || + !IPPU.TileCache [TILE_2BIT] || !IPPU.TileCache [TILE_4BIT] || + !IPPU.TileCache [TILE_8BIT] || !IPPU.TileCached [TILE_2BIT] || + !IPPU.TileCached [TILE_4BIT] || !IPPU.TileCached [TILE_8BIT]) + { + Deinit(); + return (FALSE); + } + + // FillRAM uses first 32K of ROM image area, otherwise space just + // wasted. Might be read by the SuperFX code. + + Memory.FillRAM = Memory.ROM; + + // Add 0x8000 to ROM image pointer to stop SuperFX code accessing + // unallocated memory (can cause crash on some ports). + Memory.ROM += 0x8000; // still 32-byte aligned + + Memory.C4RAM = Memory.ROM + 0x400000 + 8192 * 8; // still 32-byte aligned + Memory.ROM = Memory.ROM; + Memory.SRAM = Memory.SRAM; + #ifdef ZSNES_FX - SFXPlotTable = ROM + 0x400000; + SFXPlotTable = ROM + 0x400000; #else - SuperFX.pvRegisters = &Memory.FillRAM [0x3000]; - SuperFX.nRamBanks = 2; // Most only use 1. 1=64KB, 2=128KB=1024Mb - SuperFX.pvRam = Memory.SRAM; - SuperFX.nRomBanks = (2 * 1024 * 1024) / (32 * 1024); - SuperFX.pvRom = (uint8 *) Memory.ROM; + SuperFX.pvRegisters = &Memory.FillRAM [0x3000]; + SuperFX.nRamBanks = 2; // Most only use 1. 1=64KB, 2=128KB=1024Mb + SuperFX.pvRam = Memory.SRAM; + SuperFX.nRomBanks = (2 * 1024 * 1024) / (32 * 1024); + SuperFX.pvRom = (uint8*) Memory.ROM; #endif - ZeroMemory (IPPU.TileCache [TILE_2BIT], MAX_2BIT_TILES * 128); - ZeroMemory (IPPU.TileCache [TILE_4BIT], MAX_4BIT_TILES * 128); - ZeroMemory (IPPU.TileCache [TILE_8BIT], MAX_8BIT_TILES * 128); - - ZeroMemory (IPPU.TileCached [TILE_2BIT], MAX_2BIT_TILES); - ZeroMemory (IPPU.TileCached [TILE_4BIT], MAX_4BIT_TILES); - ZeroMemory (IPPU.TileCached [TILE_8BIT], MAX_8BIT_TILES); - - Memory.SDD1Data = NULL; - Memory.SDD1Index = NULL; - - return (TRUE); + ZeroMemory(IPPU.TileCache [TILE_2BIT], MAX_2BIT_TILES * 128); + ZeroMemory(IPPU.TileCache [TILE_4BIT], MAX_4BIT_TILES * 128); + ZeroMemory(IPPU.TileCache [TILE_8BIT], MAX_8BIT_TILES * 128); + + ZeroMemory(IPPU.TileCached [TILE_2BIT], MAX_2BIT_TILES); + ZeroMemory(IPPU.TileCached [TILE_4BIT], MAX_4BIT_TILES); + ZeroMemory(IPPU.TileCached [TILE_8BIT], MAX_8BIT_TILES); + + Memory.SDD1Data = NULL; + Memory.SDD1Index = NULL; + + return (TRUE); } -void Deinit () +void Deinit() { #ifdef __W32_HEAP - if(_HEAPOK!=_heapchk()) + if (_HEAPOK != _heapchk()) MessageBox(GUI.hWnd, "Deinit", "Heap Corrupt", MB_OK); #endif - if (Memory.RAM) - { - free ((char *) Memory.RAM); + if (Memory.RAM) + { + free((char*) Memory.RAM); Memory.RAM = NULL; - } - if (Memory.SRAM) - { - free ((char *) Memory.SRAM); + } + if (Memory.SRAM) + { + free((char*) Memory.SRAM); Memory.SRAM = NULL; - } - if (Memory.VRAM) - { - free ((char *) Memory.VRAM); + } + if (Memory.VRAM) + { + free((char*) Memory.VRAM); Memory.VRAM = NULL; - } - if (Memory.ROM) - { + } + if (Memory.ROM) + { Memory.ROM -= 0x8000; #ifdef DS2_RAM - AlignedFree ((char *) ROM, PtrAdj.ROM); + AlignedFree((char*) ROM, PtrAdj.ROM); #else - free ((char *) Memory.ROM); + free((char*) Memory.ROM); #endif Memory.ROM = NULL; - } - - if(Memory.BSRAM) - { + } + + if (Memory.BSRAM) + { free((char*) Memory.BSRAM); - Memory.BSRAM=NULL; - } - - if (IPPU.TileCache [TILE_2BIT]) - { - free ((char *) IPPU.TileCache [TILE_2BIT]); - IPPU.TileCache [TILE_2BIT] = NULL; - } - if (IPPU.TileCache [TILE_4BIT]) - { - free ((char *) IPPU.TileCache [TILE_4BIT]); - IPPU.TileCache [TILE_4BIT] = NULL; - } - if (IPPU.TileCache [TILE_8BIT]) - { - free ((char *) IPPU.TileCache [TILE_8BIT]); - IPPU.TileCache [TILE_8BIT] = NULL; - } - - if (IPPU.TileCached [TILE_2BIT]) - { - free ((char *) IPPU.TileCached [TILE_2BIT]); - IPPU.TileCached [TILE_2BIT] = NULL; - } - if (IPPU.TileCached [TILE_4BIT]) - { - free ((char *) IPPU.TileCached [TILE_4BIT]); - IPPU.TileCached [TILE_4BIT] = NULL; - } - if (IPPU.TileCached [TILE_8BIT]) - { - free ((char *) IPPU.TileCached [TILE_8BIT]); - IPPU.TileCached [TILE_8BIT] = NULL; - } - FreeSDD1Data (); - Safe(NULL); + Memory.BSRAM = NULL; + } + + if (IPPU.TileCache [TILE_2BIT]) + { + free((char*) IPPU.TileCache [TILE_2BIT]); + IPPU.TileCache [TILE_2BIT] = NULL; + } + if (IPPU.TileCache [TILE_4BIT]) + { + free((char*) IPPU.TileCache [TILE_4BIT]); + IPPU.TileCache [TILE_4BIT] = NULL; + } + if (IPPU.TileCache [TILE_8BIT]) + { + free((char*) IPPU.TileCache [TILE_8BIT]); + IPPU.TileCache [TILE_8BIT] = NULL; + } + + if (IPPU.TileCached [TILE_2BIT]) + { + free((char*) IPPU.TileCached [TILE_2BIT]); + IPPU.TileCached [TILE_2BIT] = NULL; + } + if (IPPU.TileCached [TILE_4BIT]) + { + free((char*) IPPU.TileCached [TILE_4BIT]); + IPPU.TileCached [TILE_4BIT] = NULL; + } + if (IPPU.TileCached [TILE_8BIT]) + { + free((char*) IPPU.TileCached [TILE_8BIT]); + IPPU.TileCached [TILE_8BIT] = NULL; + } + FreeSDD1Data(); + Safe(NULL); } -void FreeSDD1Data () +void FreeSDD1Data() { - if (Memory.SDD1Index) - { - free ((char *) Memory.SDD1Index); + if (Memory.SDD1Index) + { + free((char*) Memory.SDD1Index); Memory.SDD1Index = NULL; - } - if (Memory.SDD1Data) - { - free ((char *) Memory.SDD1Data); + } + if (Memory.SDD1Data) + { + free((char*) Memory.SDD1Data); Memory.SDD1Data = NULL; - } + } } /**********************************************************************************************/ @@ -583,351 +586,360 @@ void FreeSDD1Data () /* This function loads a Snes-Backup image */ /**********************************************************************************************/ -bool8 LoadROM (const char *filename) +bool8 LoadROM(const char* filename) { - int32 TotalFileSize = 0; - bool8 Interleaved = FALSE; - bool8 Tales = FALSE; - - uint8* RomHeader=Memory.ROM; - - Memory.ExtendedFormat=NOPE; - - - if(CleanUp7110!=NULL) - (*CleanUp7110)(); - - memset (&SNESGameFixes, 0, sizeof(SNESGameFixes)); - SNESGameFixes.SRAMInitialValue = 0x60; - - memset (bytes0x2000, 0, 0x2000); - CPU.TriedInterleavedMode2 = FALSE; - - Memory.CalculatedSize = 0; - retry_count =0; + int32 TotalFileSize = 0; + bool8 Interleaved = FALSE; + bool8 Tales = FALSE; + + uint8* RomHeader = Memory.ROM; + + Memory.ExtendedFormat = NOPE; + + + if (CleanUp7110 != NULL) + (*CleanUp7110)(); + + memset(&SNESGameFixes, 0, sizeof(SNESGameFixes)); + SNESGameFixes.SRAMInitialValue = 0x60; + + memset(bytes0x2000, 0, 0x2000); + CPU.TriedInterleavedMode2 = FALSE; + + Memory.CalculatedSize = 0; + retry_count = 0; again: - Settings.DisplayColor=0xffff; - SET_UI_COLOR(255,255,255); + Settings.DisplayColor = 0xffff; + SET_UI_COLOR(255, 255, 255); TotalFileSize = FileLoader(Memory.ROM, filename, MAX_ROM_SIZE); - if (!TotalFileSize) - return FALSE; // it ends here - else if(!Settings.NoPatch) - CheckForIPSPatch (filename, Memory.HeaderCount != 0, &TotalFileSize); - - //fix hacked games here. - if((strncmp("HONKAKUHA IGO GOSEI", (char*)&Memory.ROM[0x7FC0],19)==0)&&(Memory.ROM[0x7FD5]!=0x31)) - { - Memory.ROM[0x7FD5]=0x31; - Memory.ROM[0x7FD6]=0x02; - Settings.DisplayColor=BUILD_PIXEL(31,0,0); - SET_UI_COLOR(255,0,0); - S9xMessage(S9X_ERROR,S9X_ROM_CONFUSING_FORMAT_INFO, "Warning! Hacked Dump!"); - } - - if((strncmp("HONKAKUHA IGO GOSEI", (char*)&Memory.ROM[0xFFC0],19)==0)&&(Memory.ROM[0xFFD5]!=0x31)) - { - Memory.ROM[0xFFD5]=0x31; - Memory.ROM[0xFFD6]=0x02; - Settings.DisplayColor=BUILD_PIXEL(31,0,0); - SET_UI_COLOR(255,0,0); - S9xMessage(S9X_ERROR,S9X_ROM_CONFUSING_FORMAT_INFO, "Warning! Hacked Dump!"); - } - - if((Memory.ROM[0x7FD5]==0x42)&&(Memory.ROM[0x7FD6]==0x13)&&(strncmp("METAL COMBAT",(char*)&Memory.ROM[0x7FC0],12)==0)) - { - Settings.DisplayColor=BUILD_PIXEL(31,0,0); - SET_UI_COLOR(255,0,0); - S9xMessage(S9X_ERROR,S9X_ROM_CONFUSING_FORMAT_INFO, "Warning! Hacked Dump!"); - } - - int orig_hi_score, orig_lo_score; - int hi_score, lo_score; - - orig_hi_score = hi_score = ScoreHiROM (FALSE, 0); - orig_lo_score = lo_score = ScoreLoROM (FALSE, 0); - - if (Memory.HeaderCount == 0 && !Settings.ForceNoHeader && - ((hi_score > lo_score && ScoreHiROM (TRUE, 0) > hi_score) || - (hi_score <= lo_score && ScoreLoROM (TRUE, 0) > lo_score))) - { + if (!TotalFileSize) + return FALSE; // it ends here + else if (!Settings.NoPatch) + CheckForIPSPatch(filename, Memory.HeaderCount != 0, &TotalFileSize); + + //fix hacked games here. + if ((strncmp("HONKAKUHA IGO GOSEI", (char*)&Memory.ROM[0x7FC0], 19) == 0) + && (Memory.ROM[0x7FD5] != 0x31)) + { + Memory.ROM[0x7FD5] = 0x31; + Memory.ROM[0x7FD6] = 0x02; + Settings.DisplayColor = BUILD_PIXEL(31, 0, 0); + SET_UI_COLOR(255, 0, 0); + S9xMessage(S9X_ERROR, S9X_ROM_CONFUSING_FORMAT_INFO, "Warning! Hacked Dump!"); + } + + if ((strncmp("HONKAKUHA IGO GOSEI", (char*)&Memory.ROM[0xFFC0], 19) == 0) + && (Memory.ROM[0xFFD5] != 0x31)) + { + Memory.ROM[0xFFD5] = 0x31; + Memory.ROM[0xFFD6] = 0x02; + Settings.DisplayColor = BUILD_PIXEL(31, 0, 0); + SET_UI_COLOR(255, 0, 0); + S9xMessage(S9X_ERROR, S9X_ROM_CONFUSING_FORMAT_INFO, "Warning! Hacked Dump!"); + } + + if ((Memory.ROM[0x7FD5] == 0x42) && (Memory.ROM[0x7FD6] == 0x13) + && (strncmp("METAL COMBAT", (char*)&Memory.ROM[0x7FC0], 12) == 0)) + { + Settings.DisplayColor = BUILD_PIXEL(31, 0, 0); + SET_UI_COLOR(255, 0, 0); + S9xMessage(S9X_ERROR, S9X_ROM_CONFUSING_FORMAT_INFO, "Warning! Hacked Dump!"); + } + + int orig_hi_score, orig_lo_score; + int hi_score, lo_score; + + orig_hi_score = hi_score = ScoreHiROM(FALSE, 0); + orig_lo_score = lo_score = ScoreLoROM(FALSE, 0); + + if (Memory.HeaderCount == 0 && !Settings.ForceNoHeader && + ((hi_score > lo_score && ScoreHiROM(TRUE, 0) > hi_score) || + (hi_score <= lo_score && ScoreLoROM(TRUE, 0) > lo_score))) + { #ifdef DS2_DMA - __dcache_writeback_all(); - { - unsigned int i; - for (i = 0; i < TotalFileSize; i += 512) - { - ds2_DMAcopy_32Byte (2 /* channel: emu internal */, Memory.ROM + i, Memory.ROM + i + 512, 512); - ds2_DMA_wait(2); - ds2_DMA_stop(2); - } - } + __dcache_writeback_all(); + { + unsigned int i; + for (i = 0; i < TotalFileSize; i += 512) + { + ds2_DMAcopy_32Byte(2 /* channel: emu internal */, Memory.ROM + i, + Memory.ROM + i + 512, 512); + ds2_DMA_wait(2); + ds2_DMA_stop(2); + } + } #else - // memmove required: Overlapping addresses [Neb] - memmove (Memory.ROM, Memory.ROM + 512, TotalFileSize - 512); + // memmove required: Overlapping addresses [Neb] + memmove(Memory.ROM, Memory.ROM + 512, TotalFileSize - 512); #endif - TotalFileSize -= 512; - S9xMessage (S9X_INFO, S9X_HEADER_WARNING, - "Try specifying the -nhd command line option if the game doesn't work\n"); - //modifying ROM, so we need to rescore - orig_hi_score = hi_score = ScoreHiROM (FALSE, 0); - orig_lo_score = lo_score = ScoreLoROM (FALSE, 0); - } - - Memory.CalculatedSize = TotalFileSize & ~0x1FFF; // round down to lower 0x2000 - ZeroMemory (Memory.ROM + Memory.CalculatedSize, MAX_ROM_SIZE - Memory.CalculatedSize); - - if(Memory.CalculatedSize >0x400000&& - !(Memory.ROM[0x7FD5]==0x32&&((Memory.ROM[0x7FD6]&0xF0)==0x40)) && //exclude S-DD1 - !(Memory.ROM[0xFFD5]==0x3A&&((Memory.ROM[0xFFD6]&0xF0)==0xF0))) //exclude SPC7110 - { - //you might be a Jumbo! - Memory.ExtendedFormat=YEAH; - } - - //If both vectors are invalid, it's type 1 LoROM - - if(Memory.ExtendedFormat==NOPE&&((Memory.ROM[0x7FFC]|(Memory.ROM[0x7FFD]<<8))<0x8000)&&((Memory.ROM[0xFFFC]|(Memory.ROM[0xFFFD]<<8)) <0x8000)) - { - if(Settings.DisplayColor==0xffff) - { - Settings.DisplayColor=BUILD_PIXEL(0,31,0); - SET_UI_COLOR(0,255,0); - } - if(!Settings.ForceInterleaved) + TotalFileSize -= 512; + S9xMessage(S9X_INFO, S9X_HEADER_WARNING, + "Try specifying the -nhd command line option if the game doesn't work\n"); + //modifying ROM, so we need to rescore + orig_hi_score = hi_score = ScoreHiROM(FALSE, 0); + orig_lo_score = lo_score = ScoreLoROM(FALSE, 0); + } + + Memory.CalculatedSize = TotalFileSize & ~0x1FFF; // round down to lower 0x2000 + ZeroMemory(Memory.ROM + Memory.CalculatedSize, + MAX_ROM_SIZE - Memory.CalculatedSize); + + if (Memory.CalculatedSize > 0x400000 && + !(Memory.ROM[0x7FD5] == 0x32 && ((Memory.ROM[0x7FD6] & 0xF0) == 0x40)) + && //exclude S-DD1 + !(Memory.ROM[0xFFD5] == 0x3A + && ((Memory.ROM[0xFFD6] & 0xF0) == 0xF0))) //exclude SPC7110 + { + //you might be a Jumbo! + Memory.ExtendedFormat = YEAH; + } + + //If both vectors are invalid, it's type 1 LoROM + + if (Memory.ExtendedFormat == NOPE + && ((Memory.ROM[0x7FFC] | (Memory.ROM[0x7FFD] << 8)) < 0x8000) + && ((Memory.ROM[0xFFFC] | (Memory.ROM[0xFFFD] << 8)) < 0x8000)) + { + if (Settings.DisplayColor == 0xffff) + { + Settings.DisplayColor = BUILD_PIXEL(0, 31, 0); + SET_UI_COLOR(0, 255, 0); + } + if (!Settings.ForceInterleaved) S9xDeinterleaveType1(TotalFileSize, Memory.ROM); - } + } - //CalculatedSize is now set, so rescore - orig_hi_score = hi_score = ScoreHiROM (FALSE, 0); - orig_lo_score = lo_score = ScoreLoROM (FALSE, 0); + //CalculatedSize is now set, so rescore + orig_hi_score = hi_score = ScoreHiROM(FALSE, 0); + orig_lo_score = lo_score = ScoreLoROM(FALSE, 0); - if(Memory.ExtendedFormat != NOPE) - { - int loromscore, hiromscore, swappedlorom, swappedhirom; - loromscore=ScoreLoROM(FALSE, 0); - hiromscore=ScoreHiROM(FALSE, 0); - swappedlorom=ScoreLoROM(FALSE, 0x400000); - swappedhirom=ScoreHiROM(FALSE, 0x400000); + if (Memory.ExtendedFormat != NOPE) + { + int loromscore, hiromscore, swappedlorom, swappedhirom; + loromscore = ScoreLoROM(FALSE, 0); + hiromscore = ScoreHiROM(FALSE, 0); + swappedlorom = ScoreLoROM(FALSE, 0x400000); + swappedhirom = ScoreHiROM(FALSE, 0x400000); - //set swapped here. + //set swapped here. - if(max(swappedlorom, swappedhirom) >= max(loromscore, hiromscore)) - { + if (max(swappedlorom, swappedhirom) >= max(loromscore, hiromscore)) + { Memory.ExtendedFormat = BIGFIRST; - hi_score=swappedhirom; - lo_score=swappedlorom; - RomHeader=Memory.ROM+0x400000; - } - else - { + hi_score = swappedhirom; + lo_score = swappedlorom; + RomHeader = Memory.ROM + 0x400000; + } + else + { Memory.ExtendedFormat = SMALLFIRST; - lo_score=loromscore; - hi_score=hiromscore; - RomHeader=Memory.ROM; - } + lo_score = loromscore; + hi_score = hiromscore; + RomHeader = Memory.ROM; + } - } + } - Interleaved = Settings.ForceInterleaved || Settings.ForceInterleaved2; - if (Settings.ForceLoROM || (!Settings.ForceHiROM && lo_score >= hi_score)) - { + Interleaved = Settings.ForceInterleaved || Settings.ForceInterleaved2; + if (Settings.ForceLoROM || (!Settings.ForceHiROM && lo_score >= hi_score)) + { Memory.LoROM = TRUE; Memory.HiROM = FALSE; - - // Ignore map type byte if not 0x2x or 0x3x - if ((RomHeader [0x7fd5] & 0xf0) == 0x20 || (RomHeader [0x7fd5] & 0xf0) == 0x30) - { - switch (RomHeader [0x7fd5] & 0xf) - { - case 1: - Interleaved = TRUE; - break; - case 5: - Interleaved = TRUE; - Tales = TRUE; - break; - } - } - } - else - { - if ((RomHeader [0xffd5] & 0xf0) == 0x20 || (RomHeader [0xffd5] & 0xf0) == 0x30) - { - switch (RomHeader [0xffd5] & 0xf) - { - case 0: - case 3: - Interleaved = TRUE; - break; - } - } + + // Ignore map type byte if not 0x2x or 0x3x + if ((RomHeader [0x7fd5] & 0xf0) == 0x20 || (RomHeader [0x7fd5] & 0xf0) == 0x30) + { + switch (RomHeader [0x7fd5] & 0xf) + { + case 1: + Interleaved = TRUE; + break; + case 5: + Interleaved = TRUE; + Tales = TRUE; + break; + } + } + } + else + { + if ((RomHeader [0xffd5] & 0xf0) == 0x20 || (RomHeader [0xffd5] & 0xf0) == 0x30) + { + switch (RomHeader [0xffd5] & 0xf) + { + case 0: + case 3: + Interleaved = TRUE; + break; + } + } Memory.LoROM = FALSE; Memory.HiROM = TRUE; - } - - // More - if (!Settings.ForceHiROM && !Settings.ForceLoROM && - !Settings.ForceInterleaved && !Settings.ForceInterleaved2 && - !Settings.ForceNotInterleaved && !Settings.ForcePAL && - !Settings.ForceSuperFX && !Settings.ForceDSP1 && - !Settings.ForceSA1 && !Settings.ForceC4 && - !Settings.ForceSDD1) - { + } + + // More + if (!Settings.ForceHiROM && !Settings.ForceLoROM && + !Settings.ForceInterleaved && !Settings.ForceInterleaved2 && + !Settings.ForceNotInterleaved && !Settings.ForcePAL && + !Settings.ForceSuperFX && !Settings.ForceDSP1 && + !Settings.ForceSA1 && !Settings.ForceC4 && + !Settings.ForceSDD1) + { #ifdef DETECT_NASTY_FX_INTERLEAVE -//MK: Damn. YI trips a BRK currently. Maybe even on a real cart. + //MK: Damn. YI trips a BRK currently. Maybe even on a real cart. -#ifdef LSB_FIRST - if(strncmp((char *) &ROM [0x7fc0], "YOSHI'S ISLAND", 14) == 0&&(*(uint16*)&ROM[0x7FDE])==57611&&ROM[0x10002]==0xA9) +#ifdef LSB_FIRST + if (strncmp((char*) &ROM [0x7fc0], "YOSHI'S ISLAND", 14) == 0 + && (*(uint16*)&ROM[0x7FDE]) == 57611 && ROM[0x10002] == 0xA9) #else - if(strncmp((char *) &ROM [0x7fc0], "YOSHI'S ISLAND", 14) == 0&&(ROM[0x7FDE]+(ROM[0x7FDF]<<8))==57611&&ROM[0x10002]==0xA9) + if (strncmp((char*) &ROM [0x7fc0], "YOSHI'S ISLAND", 14) == 0 + && (ROM[0x7FDE] + (ROM[0x7FDF] << 8)) == 57611 && ROM[0x10002] == 0xA9) #endif - { - Interleaved=true; - Settings.ForceInterleaved2=true; - } + { + Interleaved = true; + Settings.ForceInterleaved2 = true; + } #endif - if (strncmp ((char *) &Memory.ROM [0x7fc0], "YUYU NO QUIZ DE GO!GO!", 22) == 0) - { + if (strncmp((char*) &Memory.ROM [0x7fc0], "YUYU NO QUIZ DE GO!GO!", 22) == 0) + { Memory.LoROM = TRUE; Memory.HiROM = FALSE; - Interleaved = FALSE; - } - } - - if (!Settings.ForceNotInterleaved && Interleaved) - { - CPU.TriedInterleavedMode2 = TRUE; - S9xMessage (S9X_INFO, S9X_ROM_INTERLEAVED_INFO, - "ROM image is in interleaved format - converting..."); - - if (Tales) - { - if(Memory.ExtendedFormat==BIGFIRST) - { + Interleaved = FALSE; + } + } + + if (!Settings.ForceNotInterleaved && Interleaved) + { + CPU.TriedInterleavedMode2 = TRUE; + S9xMessage(S9X_INFO, S9X_ROM_INTERLEAVED_INFO, + "ROM image is in interleaved format - converting..."); + + if (Tales) + { + if (Memory.ExtendedFormat == BIGFIRST) + { S9xDeinterleaveType1(0x400000, Memory.ROM); - S9xDeinterleaveType1(Memory.CalculatedSize-0x400000, Memory.ROM+0x400000); - } - else - { - S9xDeinterleaveType1(Memory.CalculatedSize-0x400000, Memory.ROM); - S9xDeinterleaveType1(0x400000, Memory.ROM + Memory.CalculatedSize-0x400000); - - } - + S9xDeinterleaveType1(Memory.CalculatedSize - 0x400000, Memory.ROM + 0x400000); + } + else + { + S9xDeinterleaveType1(Memory.CalculatedSize - 0x400000, Memory.ROM); + S9xDeinterleaveType1(0x400000, Memory.ROM + Memory.CalculatedSize - 0x400000); + + } + Memory.LoROM = FALSE; Memory.HiROM = TRUE; - - - } - else if (Settings.ForceInterleaved2) - { - S9xDeinterleaveType2(FALSE); - } - else if (Settings.ForceInterleaveGD24 && Memory.CalculatedSize ==0x300000) - { + + + } + else if (Settings.ForceInterleaved2) + S9xDeinterleaveType2(FALSE); + else if (Settings.ForceInterleaveGD24 && Memory.CalculatedSize == 0x300000) + { bool8 t = Memory.LoROM; - + Memory.LoROM = Memory.HiROM; Memory.HiROM = t; S9xDeinterleaveGD24(Memory.CalculatedSize, Memory.ROM); - } - else - { - if(Settings.DisplayColor==0xffff) - { - Settings.DisplayColor=BUILD_PIXEL(0,31,0); - SET_UI_COLOR(0,255,0); - } + } + else + { + if (Settings.DisplayColor == 0xffff) + { + Settings.DisplayColor = BUILD_PIXEL(0, 31, 0); + SET_UI_COLOR(0, 255, 0); + } bool8 t = Memory.LoROM; - + Memory.LoROM = Memory.HiROM; Memory.HiROM = t; - + S9xDeinterleaveType1(Memory.CalculatedSize, Memory.ROM); - } + } + + hi_score = ScoreHiROM(FALSE, 0); + lo_score = ScoreLoROM(FALSE, 0); - hi_score = ScoreHiROM (FALSE, 0); - lo_score = ScoreLoROM (FALSE, 0); - if ((Memory.HiROM && - (lo_score >= hi_score || hi_score < 0)) || - (Memory.LoROM && - (hi_score > lo_score || lo_score < 0))) - { - if (retry_count == 0) - { - S9xMessage (S9X_INFO, S9X_ROM_CONFUSING_FORMAT_INFO, - "ROM lied about its type! Trying again."); - Settings.ForceNotInterleaved = TRUE; - Settings.ForceInterleaved = FALSE; - retry_count++; - goto again; - } - } - } - - if(Memory.ExtendedFormat==SMALLFIRST) - Tales=true; - - FreeSDD1Data (); - InitROM (Tales); - S9xLoadCheatFile (S9xGetFilename(".cht")); - S9xInitCheatData (); - S9xApplyCheats (); - - S9xReset (); - - return (TRUE); + (lo_score >= hi_score || hi_score < 0)) || + (Memory.LoROM && + (hi_score > lo_score || lo_score < 0))) + { + if (retry_count == 0) + { + S9xMessage(S9X_INFO, S9X_ROM_CONFUSING_FORMAT_INFO, + "ROM lied about its type! Trying again."); + Settings.ForceNotInterleaved = TRUE; + Settings.ForceInterleaved = FALSE; + retry_count++; + goto again; + } + } + } + + if (Memory.ExtendedFormat == SMALLFIRST) + Tales = true; + + FreeSDD1Data(); + InitROM(Tales); + S9xLoadCheatFile(S9xGetFilename(".cht")); + S9xInitCheatData(); + S9xApplyCheats(); + + S9xReset(); + + return (TRUE); } -uint32 FileLoader (uint8* buffer, const char* filename, int32 maxsize) +uint32 FileLoader(uint8* buffer, const char* filename, int32 maxsize) { - - FILE* ROMFile; - int32 TotalFileSize = 0; + + FILE* ROMFile; + int32 TotalFileSize = 0; int len = 0; - - char dir [_MAX_DIR + 1]; - char drive [_MAX_DRIVE + 1]; - char name [_MAX_FNAME + 1]; - char ext [_MAX_EXT + 1]; - char fname [_MAX_PATH + 1]; - - unsigned long FileSize = 0; - - _splitpath (filename, drive, dir, name, ext); - _makepath (fname, drive, dir, name, ext); - + + char dir [_MAX_DIR + 1]; + char drive [_MAX_DRIVE + 1]; + char name [_MAX_FNAME + 1]; + char ext [_MAX_EXT + 1]; + char fname [_MAX_PATH + 1]; + + unsigned long FileSize = 0; + + _splitpath(filename, drive, dir, name, ext); + _makepath(fname, drive, dir, name, ext); + #ifdef __WIN32__ - // memmove required: Overlapping addresses [Neb] - memmove (&ext [0], &ext[1], 4); + // memmove required: Overlapping addresses [Neb] + memmove(&ext [0], &ext[1], 4); #endif if ((ROMFile = fopen(fname, "rb")) == NULL) return (0); - strcpy (Memory.ROMFilename, fname); + strcpy(Memory.ROMFilename, fname); Memory.HeaderCount = 0; - uint8 *ptr = buffer; + uint8* ptr = buffer; bool8 more = FALSE; do { - FileSize = fread (ptr, 1, maxsize + 0x200 - (ptr - Memory.ROM), ROMFile); - fclose (ROMFile); + FileSize = fread(ptr, 1, maxsize + 0x200 - (ptr - Memory.ROM), ROMFile); + fclose(ROMFile); int calc_size = FileSize & ~0x1FFF; // round to the lower 0x2000 if ((FileSize - calc_size == 512 && !Settings.ForceNoHeader) || - Settings.ForceHeader) + Settings.ForceHeader) { // memmove required: Overlapping addresses [Neb] // DS2 DMA notes: Can be split into 512-byte DMA blocks [Neb] @@ -937,13 +949,13 @@ uint32 FileLoader (uint8* buffer, const char* filename, int32 maxsize) unsigned int i; for (i = 0; i < calc_size; i += 512) { - ds2_DMAcopy_32Byte (2 /* channel: emu internal */, ptr + i, ptr + i + 512, 512); + ds2_DMAcopy_32Byte(2 /* channel: emu internal */, ptr + i, ptr + i + 512, 512); ds2_DMA_wait(2); ds2_DMA_stop(2); } } #else - memmove (ptr, ptr + 512, calc_size); + memmove(ptr, ptr + 512, calc_size); #endif Memory.HeaderCount++; FileSize -= 512; @@ -956,52 +968,53 @@ uint32 FileLoader (uint8* buffer, const char* filename, int32 maxsize) // check for multi file roms if ((ptr - Memory.ROM) < (maxsize + 0x200) && - (isdigit (ext [0]) && ext [1] == 0 && ext [0] < '9')) + (isdigit(ext [0]) && ext [1] == 0 && ext [0] < '9')) { more = TRUE; ext [0]++; #ifdef __WIN32__ // memmove required: Overlapping addresses [Neb] - memmove (&ext [1], &ext [0], 4); - ext [0] = '.'; + memmove(&ext [1], &ext [0], 4); + ext [0] = '.'; #endif - _makepath (fname, drive, dir, name, ext); + _makepath(fname, drive, dir, name, ext); } else if (ptr - Memory.ROM < maxsize + 0x200 && - (((len = strlen (name)) == 7 || len == 8) && - strncasecmp (name, "sf", 2) == 0 && - isdigit (name [2]) && isdigit (name [3]) && isdigit (name [4]) && - isdigit (name [5]) && isalpha (name [len - 1]))) + (((len = strlen(name)) == 7 || len == 8) && + strncasecmp(name, "sf", 2) == 0 && + isdigit(name [2]) && isdigit(name [3]) && isdigit(name [4]) && + isdigit(name [5]) && isalpha(name [len - 1]))) { more = TRUE; name [len - 1]++; #ifdef __WIN32__ // memmove required: Overlapping addresses [Neb] - memmove (&ext [1], &ext [0], 4); + memmove(&ext [1], &ext [0], 4); ext [0] = '.'; #endif - _makepath (fname, drive, dir, name, ext); + _makepath(fname, drive, dir, name, ext); } else more = FALSE; - } while (more && (ROMFile = fopen (fname, "rb")) != NULL); - + } + while (more && (ROMFile = fopen(fname, "rb")) != NULL); + - if (Memory.HeaderCount == 0) - S9xMessage (S9X_INFO, S9X_HEADERS_INFO, "No ROM file header found."); - else - { + if (Memory.HeaderCount == 0) + S9xMessage(S9X_INFO, S9X_HEADERS_INFO, "No ROM file header found."); + else + { if (Memory.HeaderCount == 1) - S9xMessage (S9X_INFO, S9X_HEADERS_INFO, - "Found ROM file header (and ignored it)."); - else - S9xMessage (S9X_INFO, S9X_HEADERS_INFO, - "Found multiple ROM file headers (and ignored them)."); - } + S9xMessage(S9X_INFO, S9X_HEADERS_INFO, + "Found ROM file header (and ignored it)."); + else + S9xMessage(S9X_INFO, S9X_HEADERS_INFO, + "Found multiple ROM file headers (and ignored them)."); + } - return TotalFileSize; + return TotalFileSize; } @@ -1011,810 +1024,803 @@ uint32 FileLoader (uint8* buffer, const char* filename, int32 maxsize) /* This function loads a Slotted SNES-Backup image and fills the slot. */ /**********************************************************************************************/ -bool8 LoadMulti (const char *basename, const char *slot1name, const char *slot2name) +bool8 LoadMulti(const char* basename, const char* slot1name, + const char* slot2name) { - unsigned long FileSize = 0; - - if(*basename=='\0') - return FALSE; - - SufamiTurbo=TRUE; - - int32 offset; - - memset (&SNESGameFixes, 0, sizeof(SNESGameFixes)); - SNESGameFixes.SRAMInitialValue = 0x60; - - memset (bytes0x2000, 0, 0x2000); - - CalculatedSize = 0; - - Settings.DisplayColor=0xffff; - SET_UI_COLOR(255,255,255); - - int32 TotalFileSize = FileLoader(ROM, basename, MAX_ROM_SIZE); - - if(0== TotalFileSize) - return FALSE; - else CheckForIPSPatch (basename, HeaderCount != 0, TotalFileSize); - - CalculatedSize=TotalFileSize; - - for(offset=0; offset0x100000||size <0x80000) - return FALSE; - //probably a minicart - return TRUE; - } - return FALSE; + //test not a BIOS + if (!strcmp((char*)file, "BANDAI SFC-ADX") + && strcmp((char*)(file + 0x10), "SFC-ADX BACKUP")) + { + //possible match. + //check size + if (size > 0x100000 || size < 0x80000) + return FALSE; + //probably a minicart + return TRUE; + } + return FALSE; } bool8 SameGameSig(uint8* file, int32 size) { - //preheader sig - if(strcmp((char*)(file+0xFFA0),"1995/12/16 10:2018ZS5J")) - return FALSE; - if(size!=0x100000) - return FALSE; - if(0x133E1C5B==caCRC32(file, size, 0xFFFFFFFF)) - return TRUE; - return FALSE; + //preheader sig + if (strcmp((char*)(file + 0xFFA0), "1995/12/16 10:2018ZS5J")) + return FALSE; + if (size != 0x100000) + return FALSE; + if (0x133E1C5B == caCRC32(file, size, 0xFFFFFFFF)) + return TRUE; + return FALSE; } bool8 GNextSig(uint8* file, int32 size) { - //preheader sig - if(strcmp((char*)(file+0xFFAA),"GNEXT B2ZX3J")) - return FALSE; - if(size!=0x180000) - return FALSE; - if(0x845E420D==caCRC32(file, size, 0xFFFFFFFF)) - return TRUE; - return FALSE; + //preheader sig + if (strcmp((char*)(file + 0xFFAA), "GNEXT B2ZX3J")) + return FALSE; + if (size != 0x180000) + return FALSE; + if (0x845E420D == caCRC32(file, size, 0xFFFFFFFF)) + return TRUE; + return FALSE; } int MultiType(uint8* file, int32 size) { - //check for ST signiture - if(SufamiTurboBIOSSig(file, size)) - return 1; - //check for Same Game signiture - if(SameGameSig(file, size)) - return 2; - //check for G-Next signiture - if(GNextSig(file, size)) - return 3; - return 0; + //check for ST signiture + if (SufamiTurboBIOSSig(file, size)) + return 1; + //check for Same Game signiture + if (SameGameSig(file, size)) + return 2; + //check for G-Next signiture + if (GNextSig(file, size)) + return 3; + return 0; } #endif //compatibility wrapper -void S9xDeinterleaveMode2 () +void S9xDeinterleaveMode2() { S9xDeinterleaveType2(TRUE); } -void S9xDeinterleaveType2 (bool8 reset) +void S9xDeinterleaveType2(bool8 reset) { - if(Settings.DisplayColor==0xffff||Settings.DisplayColor==BUILD_PIXEL(0,31,0)) - { - Settings.DisplayColor=BUILD_PIXEL(31,14,6); - SET_UI_COLOR(255,119,25); - - } - S9xMessage (S9X_INFO, S9X_ROM_INTERLEAVED_INFO, - "ROM image is in interleaved format - converting..."); - - int nblocks = Memory.CalculatedSize >> 16; - int step = 64; - - while (nblocks <= step) - step >>= 1; - - nblocks = step; - uint8 blocks [256]; - int i; - - for (i = 0; i < nblocks * 2; i++) - { - blocks [i] = (i & ~0xF) | ((i & 3) << 2) | - ((i & 12) >> 2); - } + if (Settings.DisplayColor == 0xffff + || Settings.DisplayColor == BUILD_PIXEL(0, 31, 0)) + { + Settings.DisplayColor = BUILD_PIXEL(31, 14, 6); + SET_UI_COLOR(255, 119, 25); + + } + S9xMessage(S9X_INFO, S9X_ROM_INTERLEAVED_INFO, + "ROM image is in interleaved format - converting..."); + + int nblocks = Memory.CalculatedSize >> 16; + int step = 64; + + while (nblocks <= step) + step >>= 1; + + nblocks = step; + uint8 blocks [256]; + int i; + + for (i = 0; i < nblocks * 2; i++) + { + blocks [i] = (i & ~0xF) | ((i & 3) << 2) | + ((i & 12) >> 2); + } #ifdef DS2_DMA - unsigned int TmpAdj; - uint8 *tmp = (uint8 *) AlignedMalloc (0x10000, 32, &TmpAdj); + unsigned int TmpAdj; + uint8* tmp = (uint8*) AlignedMalloc(0x10000, 32, &TmpAdj); #else - uint8 *tmp = (uint8 *) malloc (0x10000); + uint8* tmp = (uint8*) malloc(0x10000); #endif - - if (tmp) - { + + if (tmp) + { #ifdef DS2_DMA - __dcache_writeback_all(); + __dcache_writeback_all(); #endif - for (i = 0; i < nblocks * 2; i++) - { + for (i = 0; i < nblocks * 2; i++) + { int j; for (j = i; j < nblocks * 2; j++) - { - if (blocks [j] == i) - { -#ifdef DS2_DMA - ds2_DMAcopy_32Byte (2 /* channel: emu internal */, tmp, &Memory.ROM [blocks [j] * 0x10000], 0x10000); - ds2_DMA_wait(2); - ds2_DMA_stop(2); - - ds2_DMAcopy_32Byte (2 /* channel: emu internal */, &Memory.ROM [blocks [j] * 0x10000], - &Memory.ROM [blocks [i] * 0x10000], 0x10000); - ds2_DMA_wait(2); - ds2_DMA_stop(2); - - ds2_DMAcopy_32Byte (2 /* channel: emu internal */, &Memory.ROM [blocks [i] * 0x10000], tmp, 0x10000); - ds2_DMA_wait(2); - ds2_DMA_stop(2); + { + if (blocks [j] == i) + { +#ifdef DS2_DMA + ds2_DMAcopy_32Byte(2 /* channel: emu internal */, tmp, + &Memory.ROM [blocks [j] * 0x10000], 0x10000); + ds2_DMA_wait(2); + ds2_DMA_stop(2); + + ds2_DMAcopy_32Byte(2 /* channel: emu internal */, + &Memory.ROM [blocks [j] * 0x10000], + &Memory.ROM [blocks [i] * 0x10000], 0x10000); + ds2_DMA_wait(2); + ds2_DMA_stop(2); + + ds2_DMAcopy_32Byte(2 /* channel: emu internal */, + &Memory.ROM [blocks [i] * 0x10000], tmp, 0x10000); + ds2_DMA_wait(2); + ds2_DMA_stop(2); #else - // memmove converted: Different mallocs [Neb] - memcpy (tmp, &Memory.ROM [blocks [j] * 0x10000], 0x10000); - - // memmove converted: Different addresses, or identical if blocks[i] == blocks[j] [Neb] - memcpy (&Memory.ROM [blocks [j] * 0x10000], - &Memory.ROM [blocks [i] * 0x10000], 0x10000); - // memmove converted: Different mallocs [Neb] - memcpy (&Memory.ROM [blocks [i] * 0x10000], tmp, 0x10000); + // memmove converted: Different mallocs [Neb] + memcpy(tmp, &Memory.ROM [blocks [j] * 0x10000], 0x10000); + + // memmove converted: Different addresses, or identical if blocks[i] == blocks[j] [Neb] + memcpy(&Memory.ROM [blocks [j] * 0x10000], + &Memory.ROM [blocks [i] * 0x10000], 0x10000); + // memmove converted: Different mallocs [Neb] + memcpy(&Memory.ROM [blocks [i] * 0x10000], tmp, 0x10000); #endif - uint8 b = blocks [j]; - blocks [j] = blocks [i]; - blocks [i] = b; - break; - } - } - } - free ((char *) tmp); - tmp=NULL; - } - if(reset) - { - InitROM (FALSE); - S9xReset (); - } + uint8 b = blocks [j]; + blocks [j] = blocks [i]; + blocks [i] = b; + break; + } + } + } + free((char*) tmp); + tmp = NULL; + } + if (reset) + { + InitROM(FALSE); + S9xReset(); + } } //CRC32 for char arrays -uint32 caCRC32(uint8 *array, uint32 size, register uint32 crc32) +uint32 caCRC32(uint8* array, uint32 size, register uint32 crc32) { register uint32 i; - for (i = 0; i < size; i++) - { - crc32 = ((crc32 >> 8) & 0x00FFFFFF) ^ crc32Table[(crc32 ^ array[i]) & 0xFF]; - } - return ~crc32; + for (i = 0; i < size; i++) + crc32 = ((crc32 >> 8) & 0x00FFFFFF) ^ crc32Table[(crc32 ^ array[i]) & 0xFF]; + return ~crc32; } -void InitROM (bool8 Interleaved) +void InitROM(bool8 Interleaved) { #ifndef ZSNES_FX - SuperFX.nRomBanks = Memory.CalculatedSize >> 15; + SuperFX.nRomBanks = Memory.CalculatedSize >> 15; #endif - Settings.MultiPlayer5Master = Settings.MultiPlayer5; - Settings.MouseMaster = Settings.Mouse; - Settings.SuperScopeMaster = Settings.SuperScope; - Settings.DSP1Master = Settings.ForceDSP1; - Settings.SuperFX = FALSE; - Settings.SA1 = FALSE; - Settings.C4 = FALSE; - Settings.SDD1 = FALSE; - Settings.SRTC = FALSE; - Settings.SPC7110=FALSE; - Settings.SPC7110RTC=FALSE; - Settings.BS=FALSE; - Settings.OBC1=FALSE; - Settings.SETA=FALSE; - s7r.DataRomSize = 0; - Memory.CalculatedChecksum=0; - uint8* RomHeader; - - RomHeader=Memory.ROM+0x7FB0; - - if(Memory.ExtendedFormat==BIGFIRST) - RomHeader+=0x400000; - - if(Memory.HiROM) - RomHeader+=0x8000; - - if(!Settings.BS) - { - Settings.BS=(-1!=is_bsx(Memory.ROM+0x7FC0)); - - if(Settings.BS) - { - Memory.LoROM=TRUE; - Memory.HiROM=FALSE; - } - - else - { - Settings.BS=(-1!=is_bsx(Memory.ROM+0xFFC0)); - if(Settings.BS) - { - Memory.HiROM=TRUE; - Memory.LoROM=FALSE; - } - } - } - - ZeroMemory (Memory.BlockIsRAM, MEMMAP_NUM_BLOCKS); - ZeroMemory (Memory.BlockIsROM, MEMMAP_NUM_BLOCKS); - - Memory.SRAM = Memory.SRAM; - memset (Memory.ROMId, 0, 5); - memset (Memory.CompanyId, 0, 3); - - ParseSNESHeader(RomHeader); - - // Try to auto-detect the DSP1 chip - if (!Settings.ForceNoDSP1 && + Settings.MultiPlayer5Master = Settings.MultiPlayer5; + Settings.MouseMaster = Settings.Mouse; + Settings.SuperScopeMaster = Settings.SuperScope; + Settings.DSP1Master = Settings.ForceDSP1; + Settings.SuperFX = FALSE; + Settings.SA1 = FALSE; + Settings.C4 = FALSE; + Settings.SDD1 = FALSE; + Settings.SRTC = FALSE; + Settings.SPC7110 = FALSE; + Settings.SPC7110RTC = FALSE; + Settings.BS = FALSE; + Settings.OBC1 = FALSE; + Settings.SETA = FALSE; + s7r.DataRomSize = 0; + Memory.CalculatedChecksum = 0; + uint8* RomHeader; + + RomHeader = Memory.ROM + 0x7FB0; + + if (Memory.ExtendedFormat == BIGFIRST) + RomHeader += 0x400000; + + if (Memory.HiROM) + RomHeader += 0x8000; + + if (!Settings.BS) + { + Settings.BS = (-1 != is_bsx(Memory.ROM + 0x7FC0)); + + if (Settings.BS) + { + Memory.LoROM = TRUE; + Memory.HiROM = FALSE; + } + + else + { + Settings.BS = (-1 != is_bsx(Memory.ROM + 0xFFC0)); + if (Settings.BS) + { + Memory.HiROM = TRUE; + Memory.LoROM = FALSE; + } + } + } + + ZeroMemory(Memory.BlockIsRAM, MEMMAP_NUM_BLOCKS); + ZeroMemory(Memory.BlockIsROM, MEMMAP_NUM_BLOCKS); + + Memory.SRAM = Memory.SRAM; + memset(Memory.ROMId, 0, 5); + memset(Memory.CompanyId, 0, 3); + + ParseSNESHeader(RomHeader); + + // Try to auto-detect the DSP1 chip + if (!Settings.ForceNoDSP1 && (Memory.ROMType & 0xf) >= 3 && (Memory.ROMType & 0xf0) == 0) - Settings.DSP1Master = TRUE; - - if (Memory.HiROM) - { - // Enable S-RTC (Real Time Clock) emulation for Dai Kaijyu Monogatari 2 - Settings.SRTC = ((Memory.ROMType & 0xf0) >> 4) == 5; - - if(((Memory.ROMSpeed&0x0F)==0x0A)&&((Memory.ROMType&0xF0)==0xF0)) - { - Settings.SPC7110=true; - if((Memory.ROMType&0x0F)==0x09) - Settings.SPC7110RTC=true; - } - - if (Settings.BS) - BSHiROMMap (); - else if(Settings.SPC7110) - { - SPC7110HiROMMap(); - } + Settings.DSP1Master = TRUE; + + if (Memory.HiROM) + { + // Enable S-RTC (Real Time Clock) emulation for Dai Kaijyu Monogatari 2 + Settings.SRTC = ((Memory.ROMType & 0xf0) >> 4) == 5; + + if (((Memory.ROMSpeed & 0x0F) == 0x0A) && ((Memory.ROMType & 0xF0) == 0xF0)) + { + Settings.SPC7110 = true; + if ((Memory.ROMType & 0x0F) == 0x09) + Settings.SPC7110RTC = true; + } + + if (Settings.BS) + BSHiROMMap(); + else if (Settings.SPC7110) + SPC7110HiROMMap(); else if ((Memory.ROMSpeed & ~0x10) == 0x25) - { - TalesROMMap (Interleaved); - } - else HiROMMap (); - } - else - { - Settings.SuperFX = Settings.ForceSuperFX; - - if(Memory.ROMType==0x25) - { - Settings.OBC1=TRUE; - } - - //BS-X BIOS - if(Memory.ROMType==0xE5) - { - Settings.BS=TRUE; - } + TalesROMMap(Interleaved); + else HiROMMap(); + } + else + { + Settings.SuperFX = Settings.ForceSuperFX; + + if (Memory.ROMType == 0x25) + Settings.OBC1 = TRUE; + + //BS-X BIOS + if (Memory.ROMType == 0xE5) + Settings.BS = TRUE; if ((Memory.ROMType & 0xf0) == 0x10) - Settings.SuperFX = !Settings.ForceNoSuperFX; - - Settings.SDD1 = Settings.ForceSDD1; + Settings.SuperFX = !Settings.ForceNoSuperFX; + + Settings.SDD1 = Settings.ForceSDD1; if ((Memory.ROMType & 0xf0) == 0x40) - Settings.SDD1 = !Settings.ForceNoSDD1; - - if (Settings.SDD1) - S9xLoadSDD1Data (); - - if(((Memory.ROMType &0xF0) == 0xF0)&((Memory.ROMSpeed&0x0F)!=5)) - { - Memory.SRAMSize=2; - SNESGameFixes.SRAMInitialValue = 0x00; - if((Memory.ROMType &0x0F)==6) - { - if(Memory.ROM[0x7FD7]==0x09) - { - Settings.SETA=ST_011; - SetSETA=&S9xSetST011; - GetSETA=&S9xGetST011; - } - else - { - Settings.SETA=ST_010; - SetSETA=&S9xSetST010; - GetSETA=&S9xGetST010; - } - } - else - { - Settings.SETA=ST_018; - Memory.SRAMSize=2; - } - } - Settings.C4 = Settings.ForceC4; + Settings.SDD1 = !Settings.ForceNoSDD1; + + if (Settings.SDD1) + S9xLoadSDD1Data(); + + if (((Memory.ROMType & 0xF0) == 0xF0) & ((Memory.ROMSpeed & 0x0F) != 5)) + { + Memory.SRAMSize = 2; + SNESGameFixes.SRAMInitialValue = 0x00; + if ((Memory.ROMType & 0x0F) == 6) + { + if (Memory.ROM[0x7FD7] == 0x09) + { + Settings.SETA = ST_011; + SetSETA = &S9xSetST011; + GetSETA = &S9xGetST011; + } + else + { + Settings.SETA = ST_010; + SetSETA = &S9xSetST010; + GetSETA = &S9xGetST010; + } + } + else + { + Settings.SETA = ST_018; + Memory.SRAMSize = 2; + } + } + Settings.C4 = Settings.ForceC4; if ((Memory.ROMType & 0xf0) == 0xf0 && - (strncmp (Memory.ROMName, "MEGAMAN X", 9) == 0 || - strncmp (Memory.ROMName, "ROCKMAN X", 9) == 0)) - { - Settings.C4 = !Settings.ForceNoC4; - } - - if(Settings.SETA&&Settings.SETA!=ST_018) - { - SetaDSPMap(); - } - else if (Settings.SuperFX) - { - //::SRAM = ROM + 1024 * 1024 * 4; - SuperFXROMMap (); - Settings.MultiPlayer5Master = FALSE; - //Settings.MouseMaster = FALSE; - //Settings.SuperScopeMaster = FALSE; - Settings.DSP1Master = FALSE; - Settings.SA1 = FALSE; - Settings.C4 = FALSE; - Settings.SDD1 = FALSE; - } - else if (Settings.ForceSA1 || - (!Settings.ForceNoSA1 && (Memory.ROMSpeed & ~0x10) == 0x23 && - (Memory.ROMType & 0xf) > 3 && (Memory.ROMType & 0xf0) == 0x30)) - { - Settings.SA1 = TRUE; -// Settings.MultiPlayer5Master = FALSE; - //Settings.MouseMaster = FALSE; - //Settings.SuperScopeMaster = FALSE; - Settings.DSP1Master = FALSE; - Settings.C4 = FALSE; - Settings.SDD1 = FALSE; - SA1ROMMap (); - } + (strncmp(Memory.ROMName, "MEGAMAN X", 9) == 0 || + strncmp(Memory.ROMName, "ROCKMAN X", 9) == 0)) + Settings.C4 = !Settings.ForceNoC4; + + if (Settings.SETA && Settings.SETA != ST_018) + SetaDSPMap(); + else if (Settings.SuperFX) + { + //::SRAM = ROM + 1024 * 1024 * 4; + SuperFXROMMap(); + Settings.MultiPlayer5Master = FALSE; + //Settings.MouseMaster = FALSE; + //Settings.SuperScopeMaster = FALSE; + Settings.DSP1Master = FALSE; + Settings.SA1 = FALSE; + Settings.C4 = FALSE; + Settings.SDD1 = FALSE; + } + else if (Settings.ForceSA1 || + (!Settings.ForceNoSA1 && (Memory.ROMSpeed & ~0x10) == 0x23 && + (Memory.ROMType & 0xf) > 3 && (Memory.ROMType & 0xf0) == 0x30)) + { + Settings.SA1 = TRUE; + // Settings.MultiPlayer5Master = FALSE; + //Settings.MouseMaster = FALSE; + //Settings.SuperScopeMaster = FALSE; + Settings.DSP1Master = FALSE; + Settings.C4 = FALSE; + Settings.SDD1 = FALSE; + SA1ROMMap(); + } else if ((Memory.ROMSpeed & ~0x10) == 0x25) - TalesROMMap (Interleaved); - else if(Memory.ExtendedFormat!=NOPE) - JumboLoROMMap(Interleaved); - else if (strncmp ((char *) &Memory.ROM [0x7fc0], "SOUND NOVEL-TCOOL", 17) == 0 || - strncmp ((char *) &Memory.ROM [0x7fc0], "DERBY STALLION 96", 17) == 0) - { - LoROM24MBSMap (); - Settings.DSP1Master = FALSE; - } - - else if (strncmp ((char *) &Memory.ROM [0x7fc0], "THOROUGHBRED BREEDER3", 21) == 0 || - strncmp ((char *) &Memory.ROM [0x7fc0], "RPG-TCOOL 2", 11) == 0) - { - SRAM512KLoROMMap (); - Settings.DSP1Master = FALSE; - } - else if (strncmp ((char *) &Memory.ROM [0x7fc0], "ADD-ON BASE CASSETE", 19) == 0) - { - Settings.MultiPlayer5Master = FALSE; - Settings.MouseMaster = FALSE; - Settings.SuperScopeMaster = FALSE; - Settings.DSP1Master = FALSE; - SufamiTurboLoROMMap(); - Memory.SRAMSize = 3; - } + TalesROMMap(Interleaved); + else if (Memory.ExtendedFormat != NOPE) + JumboLoROMMap(Interleaved); + else if (strncmp((char*) &Memory.ROM [0x7fc0], "SOUND NOVEL-TCOOL", 17) == 0 || + strncmp((char*) &Memory.ROM [0x7fc0], "DERBY STALLION 96", 17) == 0) + { + LoROM24MBSMap(); + Settings.DSP1Master = FALSE; + } + + else if (strncmp((char*) &Memory.ROM [0x7fc0], "THOROUGHBRED BREEDER3", + 21) == 0 || + strncmp((char*) &Memory.ROM [0x7fc0], "RPG-TCOOL 2", 11) == 0) + { + SRAM512KLoROMMap(); + Settings.DSP1Master = FALSE; + } + else if (strncmp((char*) &Memory.ROM [0x7fc0], "ADD-ON BASE CASSETE", 19) == 0) + { + Settings.MultiPlayer5Master = FALSE; + Settings.MouseMaster = FALSE; + Settings.SuperScopeMaster = FALSE; + Settings.DSP1Master = FALSE; + SufamiTurboLoROMMap(); + Memory.SRAMSize = 3; + } else if ((Memory.ROMSpeed & ~0x10) == 0x22 && - strncmp (Memory.ROMName, "Super Street Fighter", 20) != 0) - { - AlphaROMMap (); - } - else if (Settings.BS) - BSLoROMMap(); - else LoROMMap (); - } - - if(Settings.BS) - { - Memory.ROMRegion=0; - } - - uint32 sum1 = 0; - uint32 sum2 = 0; - if(0==Memory.CalculatedChecksum) - { - int power2 = 0; + strncmp(Memory.ROMName, "Super Street Fighter", 20) != 0) + AlphaROMMap(); + else if (Settings.BS) + BSLoROMMap(); + else LoROMMap(); + } + + if (Settings.BS) + Memory.ROMRegion = 0; + + uint32 sum1 = 0; + uint32 sum2 = 0; + if (0 == Memory.CalculatedChecksum) + { + int power2 = 0; int size = Memory.CalculatedSize; - - while (size >>= 1) - power2++; - - size = 1 << power2; + + while (size >>= 1) + power2++; + + size = 1 << power2; uint32 remainder = Memory.CalculatedSize - size; - - - int i; - - for (i = 0; i < size; i++) + + + int i; + + for (i = 0; i < size; i++) sum1 += Memory.ROM [i]; - - for (i = 0; i < (int) remainder; i++) + + for (i = 0; i < (int) remainder; i++) sum2 += Memory.ROM [size + i]; - - int sub = 0; - if (Settings.BS&& Memory.ROMType!=0xE5) - { - if (Memory.HiROM) - { - for (i = 0; i < 48; i++) + + int sub = 0; + if (Settings.BS && Memory.ROMType != 0xE5) + { + if (Memory.HiROM) + { + for (i = 0; i < 48; i++) sub += Memory.ROM[0xffb0 + i]; - } - else if (Memory.LoROM) - { - for (i = 0; i < 48; i++) + } + else if (Memory.LoROM) + { + for (i = 0; i < 48; i++) sub += Memory.ROM[0x7fb0 + i]; - } - sum1 -= sub; - } - - - if (remainder) - { - sum1 += sum2 * (size / remainder); - } - - - sum1 &= 0xffff; - Memory.CalculatedChecksum=sum1; - } - //now take a CRC32 - Memory.ROMCRC32 = caCRC32(Memory.ROM, Memory.CalculatedSize, 0xFFFFFFFF); - - if (Settings.ForceNTSC) - Settings.PAL = FALSE; - else if (Settings.ForcePAL) - Settings.PAL = TRUE; - else - { - //Korea refers to South Korea, which uses NTSC - switch(Memory.ROMRegion) - { - case 13: - case 1: - case 0: - Settings.PAL=FALSE; - break; - default: Settings.PAL=TRUE; - break; - } - } - if (Settings.PAL) - { - Settings.FrameTime = Settings.FrameTimePAL; - Memory.ROMFramesPerSecond = 50; - } - else - { - Settings.FrameTime = Settings.FrameTimeNTSC; - Memory.ROMFramesPerSecond = 60; - } - + } + sum1 -= sub; + } + + + if (remainder) + sum1 += sum2 * (size / remainder); + + + sum1 &= 0xffff; + Memory.CalculatedChecksum = sum1; + } + //now take a CRC32 + Memory.ROMCRC32 = caCRC32(Memory.ROM, Memory.CalculatedSize, 0xFFFFFFFF); + + if (Settings.ForceNTSC) + Settings.PAL = FALSE; + else if (Settings.ForcePAL) + Settings.PAL = TRUE; + else + { + //Korea refers to South Korea, which uses NTSC + switch (Memory.ROMRegion) + { + case 13: + case 1: + case 0: + Settings.PAL = FALSE; + break; + default: + Settings.PAL = TRUE; + break; + } + } + if (Settings.PAL) + { + Settings.FrameTime = Settings.FrameTimePAL; + Memory.ROMFramesPerSecond = 50; + } + else + { + Settings.FrameTime = Settings.FrameTimeNTSC; + Memory.ROMFramesPerSecond = 60; + } + Memory.ROMName[ROM_NAME_LEN - 1] = 0; - if (strlen (Memory.ROMName)) - { - char *p = Memory.ROMName + strlen (Memory.ROMName) - 1; - + if (strlen(Memory.ROMName)) + { + char* p = Memory.ROMName + strlen(Memory.ROMName) - 1; + while (p > Memory.ROMName && *(p - 1) == ' ') - p--; - *p = 0; - } - - { + p--; + *p = 0; + } + + { Memory.SRAMMask = Memory.SRAMSize ? - ((1 << (Memory.SRAMSize + 3)) * 128) - 1 : 0; - } - if((Memory.ROMChecksum + Memory.ROMComplementChecksum != 0xffff) || Memory.ROMChecksum != Memory.CalculatedChecksum || ((uint32)Memory.CalculatedSize > (uint32)(((1<<(Memory.ROMSize-7))*128)*1024))) - { - if(Settings.DisplayColor==0xffff || Settings.DisplayColor!=BUILD_PIXEL(31,0,0)) - { - Settings.DisplayColor=BUILD_PIXEL(31,31,0); - SET_UI_COLOR(255,255,0); - } - } - - IAPU.OneCycle = ONE_APU_CYCLE; - Settings.Shutdown = Settings.ShutdownMaster; - - SetDSP=&DSP1SetByte; - GetDSP=&DSP1GetByte; - - ResetSpeedMap(); - ApplyROMFixes (); - sprintf (Memory.ROMName, "%s", Safe (Memory.ROMName)); - sprintf (Memory.ROMId, "%s", Safe (Memory.ROMId)); - sprintf (Memory.CompanyId, "%s", Safe (Memory.CompanyId)); - - sprintf (String, "\"%s\" [%s] %s, %s, Type: %s, Mode: %s, TV: %s, S-RAM: %s, ROMId: %s Company: %2.2s CRC32: %08X", - Memory.ROMName, - (Memory.ROMChecksum + Memory.ROMComplementChecksum != 0xffff || - Memory.ROMChecksum != Memory.CalculatedChecksum) ? "bad checksum" : "checksum ok", - MapType (), - Size (), - KartContents (), - MapMode (), - TVStandard (), - StaticRAMSize (), - Memory.ROMId, - Memory.CompanyId, - Memory.ROMCRC32); - - S9xMessage (S9X_INFO, S9X_ROM_INFO, String); + ((1 << (Memory.SRAMSize + 3)) * 128) - 1 : 0; + } + if ((Memory.ROMChecksum + Memory.ROMComplementChecksum != 0xffff) + || Memory.ROMChecksum != Memory.CalculatedChecksum + || ((uint32)Memory.CalculatedSize > (uint32)(((1 << (Memory.ROMSize - 7)) * 128) + * 1024))) + { + if (Settings.DisplayColor == 0xffff + || Settings.DisplayColor != BUILD_PIXEL(31, 0, 0)) + { + Settings.DisplayColor = BUILD_PIXEL(31, 31, 0); + SET_UI_COLOR(255, 255, 0); + } + } + + IAPU.OneCycle = ONE_APU_CYCLE; + Settings.Shutdown = Settings.ShutdownMaster; + + SetDSP = &DSP1SetByte; + GetDSP = &DSP1GetByte; + + ResetSpeedMap(); + ApplyROMFixes(); + sprintf(Memory.ROMName, "%s", Safe(Memory.ROMName)); + sprintf(Memory.ROMId, "%s", Safe(Memory.ROMId)); + sprintf(Memory.CompanyId, "%s", Safe(Memory.CompanyId)); + + sprintf(String, + "\"%s\" [%s] %s, %s, Type: %s, Mode: %s, TV: %s, S-RAM: %s, ROMId: %s Company: %2.2s CRC32: %08X", + Memory.ROMName, + (Memory.ROMChecksum + Memory.ROMComplementChecksum != 0xffff || + Memory.ROMChecksum != Memory.CalculatedChecksum) ? "bad checksum" : + "checksum ok", + MapType(), + Size(), + KartContents(), + MapMode(), + TVStandard(), + StaticRAMSize(), + Memory.ROMId, + Memory.CompanyId, + Memory.ROMCRC32); + + S9xMessage(S9X_INFO, S9X_ROM_INFO, String); #ifdef __WIN32__ - #ifndef _XBOX - EnableMenuItem(GUI.hMenu, IDM_ROM_INFO, MF_ENABLED); - #endif - #ifdef RTC_DEBUGGER - if(Settings.SPC7110RTC) - EnableMenuItem(GUI.hMenu, IDM_7110_RTC, MF_ENABLED); - else EnableMenuItem(GUI.hMenu, IDM_7110_RTC, MF_GRAYED); - #endif +#ifndef _XBOX + EnableMenuItem(GUI.hMenu, IDM_ROM_INFO, MF_ENABLED); #endif - Settings.ForceHeader = Settings.ForceHiROM = Settings.ForceLoROM = - Settings.ForceInterleaved = Settings.ForceNoHeader = Settings.ForceNotInterleaved = - Settings.ForceInterleaved2=false; +#ifdef RTC_DEBUGGER + if (Settings.SPC7110RTC) + EnableMenuItem(GUI.hMenu, IDM_7110_RTC, MF_ENABLED); + else EnableMenuItem(GUI.hMenu, IDM_7110_RTC, MF_GRAYED); +#endif +#endif + Settings.ForceHeader = Settings.ForceHiROM = Settings.ForceLoROM = + Settings.ForceInterleaved = Settings.ForceNoHeader = + Settings.ForceNotInterleaved = + Settings.ForceInterleaved2 = false; } -bool8 LoadSRAM (const char *filename) +bool8 LoadSRAM(const char* filename) { - int size = Memory.SRAMSize ? - (1 << (Memory.SRAMSize + 3)) * 128 : 0; - - memset (Memory.SRAM, SNESGameFixes.SRAMInitialValue, 0x20000); - - if (size > 0x20000) - size = 0x20000; - - if (size) - { - FILE *file; - if ((file = fopen (filename, "rb"))) - { - int len = fread ((unsigned char*) Memory.SRAM, 1, 0x20000, file); - fclose (file); - if (len - size == 512) - { - // S-RAM file has a header - remove it - // memmove required: Overlapping addresses [Neb] - memmove (Memory.SRAM, Memory.SRAM + 512, size); - } - if (len == size + SRTC_SRAM_PAD) - { - S9xSRTCPostLoadState (); - S9xResetSRTC (); - rtc.index = -1; - rtc.mode = MODE_READ; - } - else - S9xHardResetSRTC (); - - if(Settings.SPC7110RTC) - { - S9xLoadSPC7110RTC (&rtc_f9); - } - - return (TRUE); - } - S9xHardResetSRTC (); - return (FALSE); - } - if (Settings.SDD1) - S9xSDD1LoadLoggedData (); - - return (TRUE); + int size = Memory.SRAMSize ? + (1 << (Memory.SRAMSize + 3)) * 128 : 0; + + memset(Memory.SRAM, SNESGameFixes.SRAMInitialValue, 0x20000); + + if (size > 0x20000) + size = 0x20000; + + if (size) + { + FILE* file; + if ((file = fopen(filename, "rb"))) + { + int len = fread((unsigned char*) Memory.SRAM, 1, 0x20000, file); + fclose(file); + if (len - size == 512) + { + // S-RAM file has a header - remove it + // memmove required: Overlapping addresses [Neb] + memmove(Memory.SRAM, Memory.SRAM + 512, size); + } + if (len == size + SRTC_SRAM_PAD) + { + S9xSRTCPostLoadState(); + S9xResetSRTC(); + rtc.index = -1; + rtc.mode = MODE_READ; + } + else + S9xHardResetSRTC(); + + if (Settings.SPC7110RTC) + S9xLoadSPC7110RTC(&rtc_f9); + + return (TRUE); + } + S9xHardResetSRTC(); + return (FALSE); + } + if (Settings.SDD1) + S9xSDD1LoadLoggedData(); + + return (TRUE); } -bool8 SaveSRAM (const char *filename) +bool8 SaveSRAM(const char* filename) { - if(Settings.SuperFX && Memory.ROMType < 0x15) - return TRUE; - if(Settings.SA1 && Memory.ROMType == 0x34) - return TRUE; - - int size = Memory.SRAMSize ? - (1 << (Memory.SRAMSize + 3)) * 128 : 0; - if (Settings.SRTC) - { - size += SRTC_SRAM_PAD; - S9xSRTCPreSaveState (); - } - - if (Settings.SDD1) - S9xSDD1SaveLoggedData (); - - if (size > 0x20000) - size = 0x20000; - - if (size && *Memory.ROMFilename) - { - - FILE *file= fopen(filename, "w"); - if (file) - { - fwrite((unsigned char *) Memory.SRAM, size, 1, file); - fclose(file); - if(Settings.SPC7110RTC) - { - S9xSaveSPC7110RTC (&rtc_f9); - } - - return (TRUE); - } - } - return (FALSE); + if (Settings.SuperFX && Memory.ROMType < 0x15) + return TRUE; + if (Settings.SA1 && Memory.ROMType == 0x34) + return TRUE; + + int size = Memory.SRAMSize ? + (1 << (Memory.SRAMSize + 3)) * 128 : 0; + if (Settings.SRTC) + { + size += SRTC_SRAM_PAD; + S9xSRTCPreSaveState(); + } + + if (Settings.SDD1) + S9xSDD1SaveLoggedData(); + + if (size > 0x20000) + size = 0x20000; + + if (size && *Memory.ROMFilename) + { + + FILE* file = fopen(filename, "w"); + if (file) + { + fwrite((unsigned char*) Memory.SRAM, size, 1, file); + fclose(file); + if (Settings.SPC7110RTC) + S9xSaveSPC7110RTC(&rtc_f9); + + return (TRUE); + } + } + return (FALSE); } -void FixROMSpeed () +void FixROMSpeed() { - int c; + int c; + + if (CPU.FastROMSpeed == 0) + CPU.FastROMSpeed = SLOW_ONE_CYCLE; - if(CPU.FastROMSpeed==0) - CPU.FastROMSpeed=SLOW_ONE_CYCLE; - - for (c = 0x800; c < 0x1000; c++) - { - if (c&0x8 || c&0x400) + for (c = 0x800; c < 0x1000; c++) + { + if (c & 0x8 || c & 0x400) Memory.MemorySpeed [c] = (uint8) CPU.FastROMSpeed; - } + } } void ResetSpeedMap() { - int i; + int i; memset(Memory.MemorySpeed, SLOW_ONE_CYCLE, 0x1000); - for(i=0;i<0x400;i+=0x10) - { - Memory.MemorySpeed[i+2]=Memory.MemorySpeed[0x800+i+2]= ONE_CYCLE; - Memory.MemorySpeed[i+3]=Memory.MemorySpeed[0x800+i+3]= ONE_CYCLE; - Memory.MemorySpeed[i+4]=Memory.MemorySpeed[0x800+i+4]= ONE_CYCLE; - Memory.MemorySpeed[i+5]=Memory.MemorySpeed[0x800+i+5]= ONE_CYCLE; - } - FixROMSpeed (); + for (i = 0; i < 0x400; i += 0x10) + { + Memory.MemorySpeed[i + 2] = Memory.MemorySpeed[0x800 + i + 2] = ONE_CYCLE; + Memory.MemorySpeed[i + 3] = Memory.MemorySpeed[0x800 + i + 3] = ONE_CYCLE; + Memory.MemorySpeed[i + 4] = Memory.MemorySpeed[0x800 + i + 4] = ONE_CYCLE; + Memory.MemorySpeed[i + 5] = Memory.MemorySpeed[0x800 + i + 5] = ONE_CYCLE; + } + FixROMSpeed(); } -void WriteProtectROM () +void WriteProtectROM() { - // memmove converted: Different mallocs [Neb] - memcpy ((void *) Memory.WriteMap, (void *) Memory.Map, sizeof (Memory.Map)); - int c; - for (c = 0; c < 0x1000; c++) - { + // memmove converted: Different mallocs [Neb] + memcpy((void*) Memory.WriteMap, (void*) Memory.Map, sizeof(Memory.Map)); + int c; + for (c = 0; c < 0x1000; c++) + { if (Memory.BlockIsROM [c]) - Memory.WriteMap [c] = (uint8 *) MAP_NONE; - } + Memory.WriteMap [c] = (uint8*) MAP_NONE; + } } -void MapRAM () +void MapRAM() { - int c; + int c; - if(Memory.LoROM&&!Settings.SDD1) - { - // Banks 70->77, S-RAM - for (c = 0; c < 0x0f; c++) - { + if (Memory.LoROM && !Settings.SDD1) + { + // Banks 70->77, S-RAM + for (c = 0; c < 0x0f; c++) + { int i; - for(i=0;i<8;i++) - { - Memory.Map [(c<<4) + 0xF00+i]=Memory.Map [(c<<4) + 0x700+i] = (uint8 *) MAP_LOROM_SRAM; - Memory.BlockIsRAM [(c<<4) + 0xF00+i] =Memory.BlockIsRAM [(c<<4) + 0x700+i] = TRUE; - Memory.BlockIsROM [(c<<4) + 0xF00+i] =Memory.BlockIsROM [(c<<4) + 0x700+i] = FALSE; - } - } - } - else if(Memory.LoROM&&Settings.SDD1) - { - // Banks 70->77, S-RAM - for (c = 0; c < 0x0f; c++) - { + for (i = 0; i < 8; i++) + { + Memory.Map [(c << 4) + 0xF00 + i] = Memory.Map [(c << 4) + 0x700 + i] = + (uint8*) MAP_LOROM_SRAM; + Memory.BlockIsRAM [(c << 4) + 0xF00 + i] = Memory.BlockIsRAM [(c << 4) + 0x700 + + i] = TRUE; + Memory.BlockIsROM [(c << 4) + 0xF00 + i] = Memory.BlockIsROM [(c << 4) + 0x700 + + i] = FALSE; + } + } + } + else if (Memory.LoROM && Settings.SDD1) + { + // Banks 70->77, S-RAM + for (c = 0; c < 0x0f; c++) + { int i; - for(i=0;i<8;i++) - { - Memory.Map [(c<<4) + 0x700+i] = (uint8 *) MAP_LOROM_SRAM; - Memory.BlockIsRAM [(c<<4) + 0x700+i] = TRUE; - Memory.BlockIsROM [(c<<4) + 0x700+i] = FALSE; - } - } - } - // Banks 7e->7f, RAM - for (c = 0; c < 16; c++) - { + for (i = 0; i < 8; i++) + { + Memory.Map [(c << 4) + 0x700 + i] = (uint8*) MAP_LOROM_SRAM; + Memory.BlockIsRAM [(c << 4) + 0x700 + i] = TRUE; + Memory.BlockIsROM [(c << 4) + 0x700 + i] = FALSE; + } + } + } + // Banks 7e->7f, RAM + for (c = 0; c < 16; c++) + { Memory.Map [c + 0x7e0] = Memory.RAM; Memory.Map [c + 0x7f0] = Memory.RAM + 0x10000; Memory.BlockIsRAM [c + 0x7e0] = TRUE; Memory.BlockIsRAM [c + 0x7f0] = TRUE; Memory.BlockIsROM [c + 0x7e0] = FALSE; Memory.BlockIsROM [c + 0x7f0] = FALSE; - } - WriteProtectROM (); + } + WriteProtectROM(); } -void MapExtraRAM () +void MapExtraRAM() { - int c; - - // Banks 7e->7f, RAM - for (c = 0; c < 16; c++) - { + int c; + + // Banks 7e->7f, RAM + for (c = 0; c < 16; c++) + { Memory.Map [c + 0x7e0] = Memory.RAM; Memory.Map [c + 0x7f0] = Memory.RAM + 0x10000; Memory.BlockIsRAM [c + 0x7e0] = TRUE; Memory.BlockIsRAM [c + 0x7f0] = TRUE; Memory.BlockIsROM [c + 0x7e0] = FALSE; Memory.BlockIsROM [c + 0x7f0] = FALSE; - } - - // Banks 70->73, S-RAM - for (c = 0; c < 16; c++) - { + } + + // Banks 70->73, S-RAM + for (c = 0; c < 16; c++) + { Memory.Map [c + 0x700] = Memory.SRAM; Memory.Map [c + 0x710] = Memory.SRAM + 0x8000; Memory.Map [c + 0x720] = Memory.SRAM + 0x10000; Memory.Map [c + 0x730] = Memory.SRAM + 0x18000; - + Memory.BlockIsRAM [c + 0x700] = TRUE; Memory.BlockIsROM [c + 0x700] = FALSE; Memory.BlockIsRAM [c + 0x710] = TRUE; @@ -1823,2631 +1829,2636 @@ void MapExtraRAM () Memory.BlockIsROM [c + 0x720] = FALSE; Memory.BlockIsRAM [c + 0x730] = TRUE; Memory.BlockIsROM [c + 0x730] = FALSE; - } + } } -void LoROMMap () +void LoROMMap() { - int c; - int i; - int j; - int mask[4]; - for (j=0; j<4; j++) - mask[j]=0x00ff; - - mask[0]=(Memory.CalculatedSize/0x8000)-1; - - int x; - bool foundZeros; - bool pastZeros; - - for(j=0;j<3;j++) - { - x=1; - foundZeros=false; - pastZeros=false; - - mask[j+1]=mask[j]; - - while (x>0x100&&!pastZeros) - { - if(mask[j]&x) - { - x<<=1; - if(foundZeros) - pastZeros=true; - } - else - { - foundZeros=true; - pastZeros=false; - mask[j+1]|=x; - x<<=1; - } - } - } - - - // Banks 00->3f and 80->bf - for (c = 0; c < 0x400; c += 16) - { + int c; + int i; + int j; + int mask[4]; + for (j = 0; j < 4; j++) + mask[j] = 0x00ff; + + mask[0] = (Memory.CalculatedSize / 0x8000) - 1; + + int x; + bool foundZeros; + bool pastZeros; + + for (j = 0; j < 3; j++) + { + x = 1; + foundZeros = false; + pastZeros = false; + + mask[j + 1] = mask[j]; + + while (x > 0x100 && !pastZeros) + { + if (mask[j]&x) + { + x <<= 1; + if (foundZeros) + pastZeros = true; + } + else + { + foundZeros = true; + pastZeros = false; + mask[j + 1] |= x; + x <<= 1; + } + } + } + + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { Memory.Map [c + 0] = Memory.Map [c + 0x800] = Memory.RAM; Memory.Map [c + 1] = Memory.Map [c + 0x801] = Memory.RAM; Memory.BlockIsRAM [c + 0] = Memory.BlockIsRAM [c + 0x800] = TRUE; Memory.BlockIsRAM [c + 1] = Memory.BlockIsRAM [c + 0x801] = TRUE; - - Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8 *) MAP_PPU; - if(Settings.SETA==ST_018) - Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8 *) MAP_SETA_RISC; - else Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8 *) MAP_PPU; - Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8 *) MAP_CPU; - Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) MAP_CPU; - if (Settings.DSP1Master) - { - Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *) MAP_DSP; - Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *) MAP_DSP; - } - else if (Settings.C4) - { - Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *) MAP_C4; - Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *) MAP_C4; - } - else if(Settings.OBC1) - { - Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *) MAP_OBC_RAM; - Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *) MAP_OBC_RAM; - } - else - { - Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *) bytes0x2000 - 0x6000; - Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *) bytes0x2000 - 0x6000; - } - - for (i = c + 8; i < c + 16; i++) - { - int e=3; - int d=c>>4; - while(d>mask[0]) - { - d&=mask[e]; - e--; - } - Memory.Map [i] = Memory.Map [i + 0x800] = Memory.ROM + (((d)-1)*0x8000); + + Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8*) MAP_PPU; + if (Settings.SETA == ST_018) + Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8*) MAP_SETA_RISC; + else Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8*) MAP_PPU; + Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8*) MAP_CPU; + Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8*) MAP_CPU; + if (Settings.DSP1Master) + { + Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8*) MAP_DSP; + Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8*) MAP_DSP; + } + else if (Settings.C4) + { + Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8*) MAP_C4; + Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8*) MAP_C4; + } + else if (Settings.OBC1) + { + Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8*) MAP_OBC_RAM; + Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8*) MAP_OBC_RAM; + } + else + { + Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8*) bytes0x2000 - 0x6000; + Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8*) bytes0x2000 - 0x6000; + } + + for (i = c + 8; i < c + 16; i++) + { + int e = 3; + int d = c >> 4; + while (d > mask[0]) + { + d &= mask[e]; + e--; + } + Memory.Map [i] = Memory.Map [i + 0x800] = Memory.ROM + (((d) - 1) * 0x8000); Memory.BlockIsROM [i] = Memory.BlockIsROM [i + 0x800] = TRUE; - } - } - - if (Settings.DSP1Master) - { - // Banks 30->3f and b0->bf - for (c = 0x300; c < 0x400; c += 16) - { - for (i = c + 8; i < c + 16; i++) - { - Memory.Map [i] = Memory.Map [i + 0x800] = (uint8 *) MAP_DSP; + } + } + + if (Settings.DSP1Master) + { + // Banks 30->3f and b0->bf + for (c = 0x300; c < 0x400; c += 16) + { + for (i = c + 8; i < c + 16; i++) + { + Memory.Map [i] = Memory.Map [i + 0x800] = (uint8*) MAP_DSP; Memory.BlockIsROM [i] = Memory.BlockIsROM [i + 0x800] = FALSE; - } - } - } - - // Banks 40->7f and c0->ff - for (c = 0; c < 0x400; c += 16) - { - for (i = c; i < c + 8; i++) - Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = &Memory.ROM [(c << 11) % Memory.CalculatedSize]; - - for (i = c + 8; i < c + 16; i++) - { - int e=3; - int d=(c+0x400)>>4; - while(d>mask[0]) - { - d&=mask[e]; - e--; - } - - Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = Memory.ROM + (((d)-1)*0x8000); - } - - for (i = c; i < c + 16; i++) - { + } + } + } + + // Banks 40->7f and c0->ff + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 8; i++) + Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = &Memory.ROM [(c << 11) % + Memory.CalculatedSize]; + + for (i = c + 8; i < c + 16; i++) + { + int e = 3; + int d = (c + 0x400) >> 4; + while (d > mask[0]) + { + d &= mask[e]; + e--; + } + + Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = Memory.ROM + ((( + d) - 1) * 0x8000); + } + + for (i = c; i < c + 16; i++) Memory.BlockIsROM [i + 0x400] = Memory.BlockIsROM [i + 0xc00] = TRUE; - } - } - - if (Settings.DSP1Master) - { - for (c = 0; c < 0x100; c++) - { - Memory.Map [c + 0xe00] = (uint8 *) MAP_DSP; + } + + if (Settings.DSP1Master) + { + for (c = 0; c < 0x100; c++) + { + Memory.Map [c + 0xe00] = (uint8*) MAP_DSP; Memory.BlockIsROM [c + 0xe00] = FALSE; - } - } - - int sum=0, k,l, bankcount; - bankcount=1<<(Memory.ROMSize-7);//Mbits - - //safety for corrupt headers - if(bankcount > 128) - bankcount = (Memory.CalculatedSize/0x8000)/4; - bankcount*=4;//to banks - bankcount<<=4;//Map banks - bankcount+=0x800;//normalize - for(k=0x800;k<(bankcount);k+=16) - { - uint8* bank=0x8000+Memory.Map[k+8]; - for(l=0;l<0x8000;l++) - sum+=bank[l]; - } - Memory.CalculatedChecksum=sum&0xFFFF; - - MapRAM (); - WriteProtectROM (); + } + } + + int sum = 0, k, l, bankcount; + bankcount = 1 << (Memory.ROMSize - 7); //Mbits + + //safety for corrupt headers + if (bankcount > 128) + bankcount = (Memory.CalculatedSize / 0x8000) / 4; + bankcount *= 4; //to banks + bankcount <<= 4; //Map banks + bankcount += 0x800; //normalize + for (k = 0x800; k < (bankcount); k += 16) + { + uint8* bank = 0x8000 + Memory.Map[k + 8]; + for (l = 0; l < 0x8000; l++) + sum += bank[l]; + } + Memory.CalculatedChecksum = sum & 0xFFFF; + + MapRAM(); + WriteProtectROM(); } -void SetaDSPMap () +void SetaDSPMap() { - int c; - int i; - int j; - int mask[4]; - for (j=0; j<4; j++) - mask[j]=0x00ff; - - mask[0]=(Memory.CalculatedSize/0x8000)-1; - - int x; - bool foundZeros; - bool pastZeros; - - for(j=0;j<3;j++) - { - x=1; - foundZeros=false; - pastZeros=false; - - mask[j+1]=mask[j]; - - while (x>0x100&&!pastZeros) - { - if(mask[j]&x) - { - x<<=1; - if(foundZeros) - pastZeros=true; - } - else - { - foundZeros=true; - pastZeros=false; - mask[j+1]|=x; - x<<=1; - } - } - } - - - // Banks 00->3f and 80->bf - for (c = 0; c < 0x400; c += 16) - { + int c; + int i; + int j; + int mask[4]; + for (j = 0; j < 4; j++) + mask[j] = 0x00ff; + + mask[0] = (Memory.CalculatedSize / 0x8000) - 1; + + int x; + bool foundZeros; + bool pastZeros; + + for (j = 0; j < 3; j++) + { + x = 1; + foundZeros = false; + pastZeros = false; + + mask[j + 1] = mask[j]; + + while (x > 0x100 && !pastZeros) + { + if (mask[j]&x) + { + x <<= 1; + if (foundZeros) + pastZeros = true; + } + else + { + foundZeros = true; + pastZeros = false; + mask[j + 1] |= x; + x <<= 1; + } + } + } + + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { Memory.Map [c + 0] = Memory.Map [c + 0x800] = Memory.RAM; Memory.Map [c + 1] = Memory.Map [c + 0x801] = Memory.RAM; Memory.BlockIsRAM [c + 0] = Memory.BlockIsRAM [c + 0x800] = TRUE; Memory.BlockIsRAM [c + 1] = Memory.BlockIsRAM [c + 0x801] = TRUE; - - Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8 *) MAP_PPU; - Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8 *) MAP_PPU; - Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8 *) MAP_CPU; - Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) MAP_CPU; - Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *) bytes0x2000 - 0x6000; - Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *) bytes0x2000 - 0x6000; - - for (i = c + 8; i < c + 16; i++) - { - int e=3; - int d=c>>4; - while(d>mask[0]) - { - d&=mask[e]; - e--; - } - Memory.Map [i] = Memory.Map [i + 0x800] = Memory.ROM + (((d)-1)*0x8000); + + Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8*) MAP_PPU; + Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8*) MAP_PPU; + Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8*) MAP_CPU; + Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8*) MAP_CPU; + Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8*) bytes0x2000 - 0x6000; + Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8*) bytes0x2000 - 0x6000; + + for (i = c + 8; i < c + 16; i++) + { + int e = 3; + int d = c >> 4; + while (d > mask[0]) + { + d &= mask[e]; + e--; + } + Memory.Map [i] = Memory.Map [i + 0x800] = Memory.ROM + (((d) - 1) * 0x8000); Memory.BlockIsROM [i] = Memory.BlockIsROM [i + 0x800] = TRUE; - } - } - - // Banks 40->7f and c0->ff - for (c = 0; c < 0x400; c += 16) - { - for (i = c + 8; i < c + 16; i++) - { - int e=3; - int d=(c+0x400)>>4; - while(d>mask[0]) - { - d&=mask[e]; - e--; - } - - Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = Memory.ROM + (((d)-1)*0x8000); - } - - //only upper half is ROM - for (i = c+8; i < c + 16; i++) - { + } + } + + // Banks 40->7f and c0->ff + for (c = 0; c < 0x400; c += 16) + { + for (i = c + 8; i < c + 16; i++) + { + int e = 3; + int d = (c + 0x400) >> 4; + while (d > mask[0]) + { + d &= mask[e]; + e--; + } + + Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = Memory.ROM + ((( + d) - 1) * 0x8000); + } + + //only upper half is ROM + for (i = c + 8; i < c + 16; i++) Memory.BlockIsROM [i + 0x400] = Memory.BlockIsROM [i + 0xc00] = TRUE; - } - } - + } + memset(Memory.SRAM, 0, 0x1000); - for (c=0x600;c<0x680;c+=0x10) - { - for(i=0;i<0x08;i++) - { - //where does the SETA chip access, anyway? - //please confirm this? - Memory.Map[c+0x80+i]=(uint8*)MAP_SETA_DSP; - Memory.BlockIsROM [c+0x80+i] = FALSE; - Memory.BlockIsRAM [c+0x80+i] = TRUE; - } - - for(i=0;i<0x04;i++) - { - //and this! - Memory.Map[c+i]=(uint8*)MAP_SETA_DSP; - Memory.BlockIsROM [c+i] = FALSE; - } - } - - int sum=0, k,l, bankcount; - bankcount=1<<(Memory.ROMSize-7);//Mbits - //safety for corrupt headers - if(bankcount > 128) - bankcount = (Memory.CalculatedSize/0x8000)/4; - bankcount*=4;//to banks - bankcount<<=4;//Map banks - bankcount+=0x800;//normalize - for(k=0x800;k<(bankcount);k+=16) - { - uint8* bank=0x8000+Memory.Map[k+8]; - for(l=0;l<0x8000;l++) - sum+=bank[l]; - } - Memory.CalculatedChecksum=sum&0xFFFF; - - MapRAM (); - WriteProtectROM (); + for (c = 0x600; c < 0x680; c += 0x10) + { + for (i = 0; i < 0x08; i++) + { + //where does the SETA chip access, anyway? + //please confirm this? + Memory.Map[c + 0x80 + i] = (uint8*)MAP_SETA_DSP; + Memory.BlockIsROM [c + 0x80 + i] = FALSE; + Memory.BlockIsRAM [c + 0x80 + i] = TRUE; + } + + for (i = 0; i < 0x04; i++) + { + //and this! + Memory.Map[c + i] = (uint8*)MAP_SETA_DSP; + Memory.BlockIsROM [c + i] = FALSE; + } + } + + int sum = 0, k, l, bankcount; + bankcount = 1 << (Memory.ROMSize - 7); //Mbits + //safety for corrupt headers + if (bankcount > 128) + bankcount = (Memory.CalculatedSize / 0x8000) / 4; + bankcount *= 4; //to banks + bankcount <<= 4; //Map banks + bankcount += 0x800; //normalize + for (k = 0x800; k < (bankcount); k += 16) + { + uint8* bank = 0x8000 + Memory.Map[k + 8]; + for (l = 0; l < 0x8000; l++) + sum += bank[l]; + } + Memory.CalculatedChecksum = sum & 0xFFFF; + + MapRAM(); + WriteProtectROM(); } -void BSLoROMMap () +void BSLoROMMap() { - int c; - int i; - - if(Settings.BS) - Memory.SRAMSize=5; - - // Banks 00->3f and 80->bf - for (c = 0; c < 0x400; c += 16) - { + int c; + int i; + + if (Settings.BS) + Memory.SRAMSize = 5; + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { Memory.Map [c + 0] = Memory.Map [c + 0x800] = Memory.RAM; Memory.Map [c + 1] = Memory.Map [c + 0x801] = Memory.RAM; Memory.BlockIsRAM [c + 0] = Memory.BlockIsRAM [c + 0x800] = TRUE; Memory.BlockIsRAM [c + 1] = Memory.BlockIsRAM [c + 0x801] = TRUE; - - Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8 *) MAP_PPU; - Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8 *) MAP_PPU; - Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8 *) MAP_CPU; - Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) Memory.RAM; -// Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) Memory.SRAM; + + Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8*) MAP_PPU; + Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8*) MAP_PPU; + Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8*) MAP_CPU; + Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8*) Memory.RAM; + // Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) Memory.SRAM; Memory.BlockIsRAM [c + 5] = Memory.BlockIsRAM [c + 0x805] = TRUE; - -// Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *)MAP_NONE; -// Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *)MAP_NONE; - Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *) Memory.RAM; -// Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) SRAM; + + // Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *)MAP_NONE; + // Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *)MAP_NONE; + Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8*) Memory.RAM; + // Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) SRAM; Memory.BlockIsRAM [c + 6] = Memory.BlockIsRAM [c + 0x806] = TRUE; - Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *) Memory.RAM; -// Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) Memory.SRAM; + Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8*) Memory.RAM; + // Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) Memory.SRAM; Memory.BlockIsRAM [c + 7] = Memory.BlockIsRAM [c + 0x807] = TRUE; - for (i = c + 8; i < c + 16; i++) - { - Memory.Map [i] = Memory.Map [i + 0x800] = &Memory.ROM [(c << 11) % Memory.CalculatedSize] - 0x8000; + for (i = c + 8; i < c + 16; i++) + { + Memory.Map [i] = Memory.Map [i + 0x800] = &Memory.ROM [(c << 11) % + Memory.CalculatedSize] - 0x8000; Memory.BlockIsROM [i] = Memory.BlockIsROM [i + 0x800] = TRUE; - } - } - - for(c=0;c<8;c++) - { - Memory.Map[(c<<4)+0x105]=(uint8*)MAP_LOROM_SRAM; - Memory.BlockIsROM [(c<<4)+0x105] = FALSE; - Memory.BlockIsRAM [(c<<4)+0x105] = TRUE; - } - - - /* // Banks 40->7f and c0->ff - for (c = 0; c < 0x400; c += 16) - { - for (i = c; i < c + 8; i++) - Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 11) % CalculatedSize]; - - for (i = c + 8; i < c + 16; i++) - Map [i + 0x400] = Map [i + 0xc00] = &ROM [((c << 11) + 0x200000) % CalculatedSize - 0x8000]; - - for (i = c; i < c + 16; i++) - { - BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE; - } - } - */ - for(c=1;c<=4;c++) - { - for(i=0;i<16; i++) - { - Memory.Map[0x400+i+(c<<4)]=(uint8*)MAP_LOROM_SRAM; - Memory.BlockIsRAM[0x400+i+(c<<4)]=TRUE; - Memory.BlockIsROM[0x400+i+(c<<4)]=FALSE; - } - } - - for(i=0;i<0x80;i++) - { - Memory.Map[0x700+i]=&Memory.BSRAM[0x10000*(i/16)]; - Memory.BlockIsRAM[0x700+i]=TRUE; - Memory.BlockIsROM[0x700+i]=FALSE; - } - for (i=0; i<8;i++) - { - Memory.Map[0x205+(i<<4)]=Memory.Map[0x285+(i<<4)]=Memory.Map[0x305+(i<<4)]=Memory.Map[0x385+(i<<4)]=Memory.Map[0x705+(i<<4)]; - Memory.BlockIsRAM[0x205+(i<<4)]=Memory.BlockIsRAM[0x285+(i<<4)]=Memory.BlockIsRAM[0x305+(i<<4)]=Memory.BlockIsRAM[0x385+(i<<4)]=TRUE; - Memory.BlockIsROM[0x205+(i<<4)]=Memory.BlockIsROM[0x285+(i<<4)]=Memory.BlockIsROM[0x305+(i<<4)]=Memory.BlockIsROM[0x385+(i<<4)]=FALSE; - } - for(c=0;c<8;c++) - { - Memory.Map[(c<<4)+0x005]=Memory.BSRAM-0x5000; - Memory.BlockIsROM [(c<<4)+0x005] = FALSE; - Memory.BlockIsRAM [(c<<4)+0x005] = TRUE; - } - MapRAM (); - WriteProtectROM (); + } + } + + for (c = 0; c < 8; c++) + { + Memory.Map[(c << 4) + 0x105] = (uint8*)MAP_LOROM_SRAM; + Memory.BlockIsROM [(c << 4) + 0x105] = FALSE; + Memory.BlockIsRAM [(c << 4) + 0x105] = TRUE; + } + + + /* // Banks 40->7f and c0->ff + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 8; i++) + Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 11) % CalculatedSize]; + + for (i = c + 8; i < c + 16; i++) + Map [i + 0x400] = Map [i + 0xc00] = &ROM [((c << 11) + 0x200000) % CalculatedSize - 0x8000]; + + for (i = c; i < c + 16; i++) + { + BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE; + } + } + */ + for (c = 1; c <= 4; c++) + { + for (i = 0; i < 16; i++) + { + Memory.Map[0x400 + i + (c << 4)] = (uint8*)MAP_LOROM_SRAM; + Memory.BlockIsRAM[0x400 + i + (c << 4)] = TRUE; + Memory.BlockIsROM[0x400 + i + (c << 4)] = FALSE; + } + } + + for (i = 0; i < 0x80; i++) + { + Memory.Map[0x700 + i] = &Memory.BSRAM[0x10000 * (i / 16)]; + Memory.BlockIsRAM[0x700 + i] = TRUE; + Memory.BlockIsROM[0x700 + i] = FALSE; + } + for (i = 0; i < 8; i++) + { + Memory.Map[0x205 + (i << 4)] = Memory.Map[0x285 + (i << 4)] = Memory.Map[0x305 + + (i << 4)] = Memory.Map[0x385 + (i << 4)] = Memory.Map[0x705 + (i << 4)]; + Memory.BlockIsRAM[0x205 + (i << 4)] = Memory.BlockIsRAM[0x285 + + (i << 4)] = Memory.BlockIsRAM[0x305 + (i << 4)] = Memory.BlockIsRAM[0x385 + + (i << 4)] = TRUE; + Memory.BlockIsROM[0x205 + (i << 4)] = Memory.BlockIsROM[0x285 + + (i << 4)] = Memory.BlockIsROM[0x305 + (i << 4)] = Memory.BlockIsROM[0x385 + + (i << 4)] = FALSE; + } + for (c = 0; c < 8; c++) + { + Memory.Map[(c << 4) + 0x005] = Memory.BSRAM - 0x5000; + Memory.BlockIsROM [(c << 4) + 0x005] = FALSE; + Memory.BlockIsRAM [(c << 4) + 0x005] = TRUE; + } + MapRAM(); + WriteProtectROM(); } -void HiROMMap () +void HiROMMap() { - int i; - int c; - int j; + int i; + int c; + int j; - int mask[4]; - for (j=0; j<4; j++) - mask[j]=0x00ff; + int mask[4]; + for (j = 0; j < 4; j++) + mask[j] = 0x00ff; - mask[0]=(Memory.CalculatedSize/0x10000)-1; + mask[0] = (Memory.CalculatedSize / 0x10000) - 1; - if (Settings.ForceSA1 || + if (Settings.ForceSA1 || (!Settings.ForceNoSA1 && (Memory.ROMSpeed & ~0x10) == 0x23 && - (Memory.ROMType & 0xf) > 3 && (Memory.ROMType & 0xf0) == 0x30)) - { - Settings.DisplayColor=BUILD_PIXEL(31,0,0); - SET_UI_COLOR(255,0,0); - } - - - int x; - bool foundZeros; - bool pastZeros; - - for(j=0;j<3;j++) - { - x=1; - foundZeros=false; - pastZeros=false; - - mask[j+1]=mask[j]; - - while (x>0x100&&!pastZeros) - { - if(mask[j]&x) - { - x<<=1; - if(foundZeros) - pastZeros=true; - } - else - { - foundZeros=true; - pastZeros=false; - mask[j+1]|=x; - x<<=1; - } - } - } - - // Banks 00->3f and 80->bf - for (c = 0; c < 0x400; c += 16) - { + (Memory.ROMType & 0xf) > 3 && (Memory.ROMType & 0xf0) == 0x30)) + { + Settings.DisplayColor = BUILD_PIXEL(31, 0, 0); + SET_UI_COLOR(255, 0, 0); + } + + + int x; + bool foundZeros; + bool pastZeros; + + for (j = 0; j < 3; j++) + { + x = 1; + foundZeros = false; + pastZeros = false; + + mask[j + 1] = mask[j]; + + while (x > 0x100 && !pastZeros) + { + if (mask[j]&x) + { + x <<= 1; + if (foundZeros) + pastZeros = true; + } + else + { + foundZeros = true; + pastZeros = false; + mask[j + 1] |= x; + x <<= 1; + } + } + } + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { Memory.Map [c + 0] = Memory.Map [c + 0x800] = Memory.RAM; Memory.BlockIsRAM [c + 0] = Memory.BlockIsRAM [c + 0x800] = TRUE; Memory.Map [c + 1] = Memory.Map [c + 0x801] = Memory.RAM; Memory.BlockIsRAM [c + 1] = Memory.BlockIsRAM [c + 0x801] = TRUE; - - Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8 *) MAP_PPU; - Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8 *) MAP_PPU; - Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8 *) MAP_CPU; - Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) MAP_CPU; - - if (Settings.DSP1Master) - { - Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *) MAP_DSP; - Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *) MAP_DSP; - } - else - { - Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *) MAP_NONE; - Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *) MAP_NONE; - } - - for (i = c + 8; i < c + 16; i++) - { - int e=3; - int d=c>>4; - while(d>mask[0]) - { - d&=mask[e]; - e--; - } - Memory.Map [i] = Memory.Map [i + 0x800] = Memory.ROM + (d*0x10000); + + Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8*) MAP_PPU; + Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8*) MAP_PPU; + Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8*) MAP_CPU; + Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8*) MAP_CPU; + + if (Settings.DSP1Master) + { + Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8*) MAP_DSP; + Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8*) MAP_DSP; + } + else + { + Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8*) MAP_NONE; + Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8*) MAP_NONE; + } + + for (i = c + 8; i < c + 16; i++) + { + int e = 3; + int d = c >> 4; + while (d > mask[0]) + { + d &= mask[e]; + e--; + } + Memory.Map [i] = Memory.Map [i + 0x800] = Memory.ROM + (d * 0x10000); Memory.BlockIsROM [i] = Memory.BlockIsROM [i + 0x800] = TRUE; - } - } - - // Banks 30->3f and b0->bf, address ranges 6000->7fff is S-RAM. - for (c = 0; c < 16; c++) - { - Memory.Map [0x306 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM; - Memory.Map [0x307 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM; - Memory.Map [0xb06 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM; - Memory.Map [0xb07 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM; + } + } + + // Banks 30->3f and b0->bf, address ranges 6000->7fff is S-RAM. + for (c = 0; c < 16; c++) + { + Memory.Map [0x306 + (c << 4)] = (uint8*) MAP_HIROM_SRAM; + Memory.Map [0x307 + (c << 4)] = (uint8*) MAP_HIROM_SRAM; + Memory.Map [0xb06 + (c << 4)] = (uint8*) MAP_HIROM_SRAM; + Memory.Map [0xb07 + (c << 4)] = (uint8*) MAP_HIROM_SRAM; Memory.BlockIsRAM [0x306 + (c << 4)] = TRUE; Memory.BlockIsRAM [0x307 + (c << 4)] = TRUE; Memory.BlockIsRAM [0xb06 + (c << 4)] = TRUE; Memory.BlockIsRAM [0xb07 + (c << 4)] = TRUE; - } - - // Banks 40->7f and c0->ff - for (c = 0; c < 0x400; c += 16) - { - for (i = c; i < c + 16; i++) - { - int e=3; - int d=(c)>>4; - while(d>mask[0]) - { - d&=mask[e]; - e--; - } - Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = Memory.ROM + (d*0x10000); + } + + // Banks 40->7f and c0->ff + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 16; i++) + { + int e = 3; + int d = (c) >> 4; + while (d > mask[0]) + { + d &= mask[e]; + e--; + } + Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = Memory.ROM + (d * 0x10000); Memory.BlockIsROM [i + 0x400] = Memory.BlockIsROM [i + 0xc00] = TRUE; - } - } - - int bankmax=0x40+ (1<<(Memory.ROMSize-6)); - //safety for corrupt headers - if(bankmax > 128) - bankmax = 0x80; - int sum=0; - for(i=0x40;i 128) + bankmax = 0x80; + int sum = 0; + for (i = 0x40; i < bankmax; i++) + { + uint8* bank_low = (uint8*)Memory.Map[i << 4]; + for (c = 0; c < 0x10000; c++) + sum += bank_low[c]; + } + Memory.CalculatedChecksum = sum & 0xFFFF; + + MapRAM(); + WriteProtectROM(); } -void TalesROMMap (bool8 Interleaved) +void TalesROMMap(bool8 Interleaved) { - int c; - int i; - - if(Interleaved) - { - if(Settings.DisplayColor==0xffff) - { - Settings.DisplayColor=BUILD_PIXEL(0,31,0); - SET_UI_COLOR(0,255,0); - } - } - uint32 OFFSET0 = 0x400000; - uint32 OFFSET1 = 0x400000; - uint32 OFFSET2 = 0x000000; - - if (Interleaved) - { - OFFSET0 = 0x000000; - OFFSET1 = 0x000000; - OFFSET2 = Memory.CalculatedSize-0x400000; //changed to work with interleaved DKJM2. - } - - // Banks 00->3f and 80->bf - for (c = 0; c < 0x400; c += 16) - { + int c; + int i; + + if (Interleaved) + { + if (Settings.DisplayColor == 0xffff) + { + Settings.DisplayColor = BUILD_PIXEL(0, 31, 0); + SET_UI_COLOR(0, 255, 0); + } + } + uint32 OFFSET0 = 0x400000; + uint32 OFFSET1 = 0x400000; + uint32 OFFSET2 = 0x000000; + + if (Interleaved) + { + OFFSET0 = 0x000000; + OFFSET1 = 0x000000; + OFFSET2 = Memory.CalculatedSize - + 0x400000; //changed to work with interleaved DKJM2. + } + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { Memory.Map [c + 0] = Memory.Map [c + 0x800] = Memory.RAM; Memory.Map [c + 1] = Memory.Map [c + 0x801] = Memory.RAM; Memory.BlockIsRAM [c + 0] = Memory.BlockIsRAM [c + 0x800] = TRUE; Memory.BlockIsRAM [c + 1] = Memory.BlockIsRAM [c + 0x801] = TRUE; - - Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8 *) MAP_PPU; - Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8 *) MAP_PPU; - Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8 *) MAP_CPU; - Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) MAP_CPU; - - //makes more sense to map the range here. - //ToP seems to use sram to skip intro??? - if(c>=0x300) - { - Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *) MAP_HIROM_SRAM; - Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *) MAP_HIROM_SRAM; + + Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8*) MAP_PPU; + Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8*) MAP_PPU; + Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8*) MAP_CPU; + Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8*) MAP_CPU; + + //makes more sense to map the range here. + //ToP seems to use sram to skip intro??? + if (c >= 0x300) + { + Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8*) MAP_HIROM_SRAM; + Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8*) MAP_HIROM_SRAM; Memory.BlockIsRAM [6 + c] = Memory.BlockIsRAM [7 + c] = - Memory.BlockIsRAM [0x806 + c]= Memory.BlockIsRAM [0x807 + c] = TRUE; - } - else - { - Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *) MAP_NONE; - Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *) MAP_NONE; - - } - for (i = c + 8; i < c + 16; i++) - { - Memory.Map [i] = &Memory.ROM [((c << 12) % (Memory.CalculatedSize-0x400000)) + OFFSET0]; + Memory.BlockIsRAM [0x806 + c] = Memory.BlockIsRAM [0x807 + c] = TRUE; + } + else + { + Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8*) MAP_NONE; + Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8*) MAP_NONE; + + } + for (i = c + 8; i < c + 16; i++) + { + Memory.Map [i] = &Memory.ROM [((c << 12) % (Memory.CalculatedSize - 0x400000)) + + OFFSET0]; Memory.Map [i + 0x800] = &Memory.ROM [((c << 12) % 0x400000) + OFFSET2]; Memory.BlockIsROM [i] = TRUE; Memory.BlockIsROM [i + 0x800] = TRUE; - } - } - - // Banks 40->7f and c0->ff - for (c = 0; c < 0x400; c += 16) - { - for (i = c; i < c + 8; i++) - { - Memory.Map [i + 0x400] = &Memory.ROM [((c << 12) % (Memory.CalculatedSize-0x400000)) + OFFSET1]; - Memory.Map [i + 0x408] = &Memory.ROM [((c << 12) % (Memory.CalculatedSize-0x400000)) + OFFSET1]; - Memory.Map [i + 0xc00] = &Memory.ROM [((c << 12) %0x400000)+ OFFSET2]; + } + } + + // Banks 40->7f and c0->ff + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 8; i++) + { + Memory.Map [i + 0x400] = &Memory.ROM [((c << 12) % (Memory.CalculatedSize - + 0x400000)) + OFFSET1]; + Memory.Map [i + 0x408] = &Memory.ROM [((c << 12) % (Memory.CalculatedSize - + 0x400000)) + OFFSET1]; + Memory.Map [i + 0xc00] = &Memory.ROM [((c << 12) % 0x400000) + OFFSET2]; Memory.Map [i + 0xc08] = &Memory.ROM [((c << 12) % 0x400000) + OFFSET2]; Memory.BlockIsROM [i + 0x400] = TRUE; Memory.BlockIsROM [i + 0x408] = TRUE; Memory.BlockIsROM [i + 0xc00] = TRUE; Memory.BlockIsROM [i + 0xc08] = TRUE; - } - } - - if((strncmp("TALES",(char*)Memory.Map[8]+0xFFC0, 5)==0)) - { - if(((*(Memory.Map[8]+0xFFDE))==(*(Memory.Map[0x808]+0xFFDE)))) - { - Settings.DisplayColor=BUILD_PIXEL(31,0,0); - SET_UI_COLOR(255,0,0); - } - } - - Memory.ROMChecksum = *(Memory.Map[8]+0xFFDE) + (*(Memory.Map[8]+0xFFDF) << 8); - Memory.ROMComplementChecksum = *(Memory.Map[8]+0xFFDC) + (*(Memory.Map[8]+0xFFDD) << 8); - -int sum=0; -for(i=0x40;i<0x80; i++) -{ - uint8 * bank_low=(uint8*)Memory.Map[i<<4]; - uint8 * bank_high=(uint8*)Memory.Map[(i<<4)+0x800]; - for (c=0;c<0x10000; c++) - { - sum+=bank_low[c]; - sum+=bank_high[c]; - } -} + } + } + + if ((strncmp("TALES", (char*)Memory.Map[8] + 0xFFC0, 5) == 0)) + { + if (((*(Memory.Map[8] + 0xFFDE)) == (*(Memory.Map[0x808] + 0xFFDE)))) + { + Settings.DisplayColor = BUILD_PIXEL(31, 0, 0); + SET_UI_COLOR(255, 0, 0); + } + } + + Memory.ROMChecksum = *(Memory.Map[8] + 0xFFDE) + (*(Memory.Map[8] + 0xFFDF) << + 8); + Memory.ROMComplementChecksum = *(Memory.Map[8] + 0xFFDC) + (* + (Memory.Map[8] + 0xFFDD) << 8); + + int sum = 0; + for (i = 0x40; i < 0x80; i++) + { + uint8* bank_low = (uint8*)Memory.Map[i << 4]; + uint8* bank_high = (uint8*)Memory.Map[(i << 4) + 0x800]; + for (c = 0; c < 0x10000; c++) + { + sum += bank_low[c]; + sum += bank_high[c]; + } + } -Memory.CalculatedChecksum=sum&0xFFFF; + Memory.CalculatedChecksum = sum & 0xFFFF; - MapRAM (); - WriteProtectROM (); + MapRAM(); + WriteProtectROM(); } -void AlphaROMMap () +void AlphaROMMap() { - int c; - int i; - - // Banks 00->3f and 80->bf - for (c = 0; c < 0x400; c += 16) - { + int c; + int i; + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { Memory.Map [c + 0] = Memory.Map [c + 0x800] = Memory.RAM; Memory.Map [c + 1] = Memory.Map [c + 0x801] = Memory.RAM; Memory.BlockIsRAM [c + 0] = Memory.BlockIsRAM [c + 0x800] = TRUE; Memory.BlockIsRAM [c + 1] = Memory.BlockIsRAM [c + 0x801] = TRUE; - - Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8 *) MAP_PPU; - Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8 *) MAP_PPU; - Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8 *) MAP_CPU; - Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) MAP_CPU; - Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *) MAP_NONE; - Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *) MAP_NONE; - - for (i = c + 8; i < c + 16; i++) - { + + Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8*) MAP_PPU; + Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8*) MAP_PPU; + Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8*) MAP_CPU; + Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8*) MAP_CPU; + Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8*) MAP_NONE; + Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8*) MAP_NONE; + + for (i = c + 8; i < c + 16; i++) + { Memory.Map [i] = Memory.Map [i + 0x800] = &Memory.ROM [c << 11] - 0x8000; Memory.BlockIsROM [i] = TRUE; - } - } - - // Banks 40->7f and c0->ff - - for (c = 0; c < 0x400; c += 16) - { - for (i = c; i < c + 16; i++) - { + } + } + + // Banks 40->7f and c0->ff + + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 16; i++) + { Memory.Map [i + 0x400] = &Memory.ROM [(c << 12) % Memory.CalculatedSize]; Memory.Map [i + 0xc00] = &Memory.ROM [(c << 12) % Memory.CalculatedSize]; Memory.BlockIsROM [i + 0x400] = Memory.BlockIsROM [i + 0xc00] = TRUE; - } - } - - MapRAM (); - WriteProtectROM (); + } + } + + MapRAM(); + WriteProtectROM(); } void DetectSuperFxRamSize() { - if(Memory.ROM[0x7FDA]==0x33) - { - Memory.SRAMSize=Memory.ROM[0x7FBD]; - } - else - { - if(strncmp(Memory.ROMName, "STAR FOX 2", 10)==0) - { - Memory.SRAMSize=6; - } - else Memory.SRAMSize=5; - } + if (Memory.ROM[0x7FDA] == 0x33) + Memory.SRAMSize = Memory.ROM[0x7FBD]; + else + { + if (strncmp(Memory.ROMName, "STAR FOX 2", 10) == 0) + Memory.SRAMSize = 6; + else Memory.SRAMSize = 5; + } } -void SuperFXROMMap () +void SuperFXROMMap() { - int c; - int i; - - DetectSuperFxRamSize(); - - // Banks 00->3f and 80->bf - for (c = 0; c < 0x400; c += 16) - { + int c; + int i; + + DetectSuperFxRamSize(); + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { Memory.Map [c + 0] = Memory.Map [c + 0x800] = Memory.RAM; Memory.Map [c + 1] = Memory.Map [c + 0x801] = Memory.RAM; Memory.BlockIsRAM [c + 0] = Memory.BlockIsRAM [c + 0x800] = TRUE; Memory.BlockIsRAM [c + 1] = Memory.BlockIsRAM [c + 0x801] = TRUE; - - Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8 *) MAP_PPU; - Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8 *) MAP_PPU; - Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8 *) MAP_CPU; - Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) MAP_CPU; - Memory.Map [0x006 + c] = Memory.Map [0x806 + c] = (uint8 *) Memory.SRAM - 0x6000; - Memory.Map [0x007 + c] = Memory.Map [0x807 + c] = (uint8 *) Memory.SRAM - 0x6000; - Memory.BlockIsRAM [0x006 + c] = Memory.BlockIsRAM [0x007 + c] = Memory.BlockIsRAM [0x806 + c] = Memory.BlockIsRAM [0x807 + c] = TRUE; - - for (i = c + 8; i < c + 16; i++) - { + + Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8*) MAP_PPU; + Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8*) MAP_PPU; + Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8*) MAP_CPU; + Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8*) MAP_CPU; + Memory.Map [0x006 + c] = Memory.Map [0x806 + c] = (uint8*) Memory.SRAM - 0x6000; + Memory.Map [0x007 + c] = Memory.Map [0x807 + c] = (uint8*) Memory.SRAM - 0x6000; + Memory.BlockIsRAM [0x006 + c] = Memory.BlockIsRAM [0x007 + c] = + Memory.BlockIsRAM [0x806 + c] = Memory.BlockIsRAM [0x807 + c] = TRUE; + + for (i = c + 8; i < c + 16; i++) + { Memory.Map [i] = Memory.Map [i + 0x800] = &Memory.ROM [c << 11] - 0x8000; Memory.BlockIsROM [i] = Memory.BlockIsROM [i + 0x800] = TRUE; - } - } - - // Banks 40->7f and c0->ff - for (c = 0; c < 0x400; c += 16) - { - for (i = c; i < c + 16; i++) - { - Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = &Memory.ROM [(c << 12) % Memory.CalculatedSize]; + } + } + + // Banks 40->7f and c0->ff + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 16; i++) + { + Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = &Memory.ROM [(c << 12) % + Memory.CalculatedSize]; Memory.BlockIsROM [i + 0x400] = Memory.BlockIsROM [i + 0xc00] = TRUE; - } - } - - // Banks 7e->7f, RAM - for (c = 0; c < 16; c++) - { + } + } + + // Banks 7e->7f, RAM + for (c = 0; c < 16; c++) + { Memory.Map [c + 0x7e0] = Memory.RAM; Memory.Map [c + 0x7f0] = Memory.RAM + 0x10000; Memory.BlockIsRAM [c + 0x7e0] = TRUE; Memory.BlockIsRAM [c + 0x7f0] = TRUE; Memory.BlockIsROM [c + 0x7e0] = FALSE; Memory.BlockIsROM [c + 0x7f0] = FALSE; - } - - // Banks 70->71, S-RAM - for (c = 0; c < 32; c++) - { + } + + // Banks 70->71, S-RAM + for (c = 0; c < 32; c++) + { Memory.Map [c + 0x700] = Memory.SRAM + (((c >> 4) & 1) << 16); Memory.BlockIsRAM [c + 0x700] = TRUE; Memory.BlockIsROM [c + 0x700] = FALSE; - } - - // Replicate the first 2Mb of the ROM at ROM + 2MB such that each 32K - // block is repeated twice in each 64K block. + } + + // Replicate the first 2Mb of the ROM at ROM + 2MB such that each 32K + // block is repeated twice in each 64K block. #ifdef DS2_DMA - __dcache_writeback_all(); + __dcache_writeback_all(); #endif - for (c = 0; c < 64; c++) - { + for (c = 0; c < 64; c++) + { #ifdef DS2_DMA - ds2_DMAcopy_32Byte(2 /* channel: emu internal */, &ROM [0x200000 + c * 0x10000], &ROM [c * 0x8000], 0x8000); - ds2_DMAcopy_32Byte(3 /* channel: emu internal 2 */, &ROM [0x208000 + c * 0x10000], &ROM [c * 0x8000], 0x8000); - ds2_DMA_wait(2); - ds2_DMA_wait(3); - ds2_DMA_stop(2); - ds2_DMA_stop(3); + ds2_DMAcopy_32Byte(2 /* channel: emu internal */, &ROM [0x200000 + c * 0x10000], + &ROM [c * 0x8000], 0x8000); + ds2_DMAcopy_32Byte(3 /* channel: emu internal 2 */, + &ROM [0x208000 + c * 0x10000], &ROM [c * 0x8000], 0x8000); + ds2_DMA_wait(2); + ds2_DMA_wait(3); + ds2_DMA_stop(2); + ds2_DMA_stop(3); #else - // memmove converted: Different addresses [Neb] - memcpy (&Memory.ROM [0x200000 + c * 0x10000], &Memory.ROM [c * 0x8000], 0x8000); - // memmove converted: Different addresses [Neb] - memcpy (&Memory.ROM [0x208000 + c * 0x10000], &Memory.ROM [c * 0x8000], 0x8000); + // memmove converted: Different addresses [Neb] + memcpy(&Memory.ROM [0x200000 + c * 0x10000], &Memory.ROM [c * 0x8000], 0x8000); + // memmove converted: Different addresses [Neb] + memcpy(&Memory.ROM [0x208000 + c * 0x10000], &Memory.ROM [c * 0x8000], 0x8000); #endif - } - - WriteProtectROM (); + } + + WriteProtectROM(); } -void SA1ROMMap () +void SA1ROMMap() { - int c; - int i; - - // Banks 00->3f and 80->bf - for (c = 0; c < 0x400; c += 16) - { + int c; + int i; + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { Memory.Map [c + 0] = Memory.Map [c + 0x800] = Memory.RAM; Memory.Map [c + 1] = Memory.Map [c + 0x801] = Memory.RAM; Memory.BlockIsRAM [c + 0] = Memory.BlockIsRAM [c + 0x800] = TRUE; Memory.BlockIsRAM [c + 1] = Memory.BlockIsRAM [c + 0x801] = TRUE; - - Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8 *) MAP_PPU; - Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8 *) &Memory.FillRAM [0x3000] - 0x3000; - Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8 *) MAP_CPU; - Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) MAP_CPU; - Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *) MAP_BWRAM; - Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *) MAP_BWRAM; - for (i = c + 8; i < c + 16; i++) - { + + Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8*) MAP_PPU; + Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8*) &Memory.FillRAM [0x3000] + - 0x3000; + Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8*) MAP_CPU; + Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8*) MAP_CPU; + Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8*) MAP_BWRAM; + Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8*) MAP_BWRAM; + for (i = c + 8; i < c + 16; i++) + { Memory.Map [i] = Memory.Map [i + 0x800] = &Memory.ROM [c << 11] - 0x8000; Memory.BlockIsROM [i] = Memory.BlockIsROM [i + 0x800] = TRUE; - } - } - - // Banks 40->7f - for (c = 0; c < 0x400; c += 16) - { - for (i = c; i < c + 16; i++) - Memory.Map [i + 0x400] = (uint8 *) &Memory.SRAM [(c << 12) & 0x1ffff]; - - for (i = c; i < c + 16; i++) - { + } + } + + // Banks 40->7f + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 16; i++) + Memory.Map [i + 0x400] = (uint8*) &Memory.SRAM [(c << 12) & 0x1ffff]; + + for (i = c; i < c + 16; i++) Memory.BlockIsROM [i + 0x400] = FALSE; - } - } - - // c0->ff - for (c = 0; c < 0x400; c += 16) - { - for (i = c; i < c + 16; i++) - { + } + + // c0->ff + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 16; i++) + { Memory.Map [i + 0xc00] = &Memory.ROM [(c << 12) % Memory.CalculatedSize]; Memory.BlockIsROM [i + 0xc00] = TRUE; - } - } - - for (c = 0; c < 16; c++) - { + } + } + + for (c = 0; c < 16; c++) + { Memory.Map [c + 0x7e0] = Memory.RAM; Memory.Map [c + 0x7f0] = Memory.RAM + 0x10000; Memory.BlockIsRAM [c + 0x7e0] = TRUE; Memory.BlockIsRAM [c + 0x7f0] = TRUE; Memory.BlockIsROM [c + 0x7e0] = FALSE; Memory.BlockIsROM [c + 0x7f0] = FALSE; - } - WriteProtectROM (); - - // Now copy the map and correct it for the SA1 CPU. - // memmove converted: Different mallocs [Neb] - memcpy ((void *) SA1.WriteMap, (void *) Memory.WriteMap, sizeof (Memory.WriteMap)); - // memmove converted: Different mallocs [Neb] - memcpy ((void *) SA1.Map, (void *) Memory.Map, sizeof (Memory.Map)); - - // Banks 00->3f and 80->bf - for (c = 0; c < 0x400; c += 16) - { - SA1.Map [c + 0] = SA1.Map [c + 0x800] = &Memory.FillRAM [0x3000]; - SA1.Map [c + 1] = SA1.Map [c + 0x801] = (uint8 *) MAP_NONE; - SA1.WriteMap [c + 0] = SA1.WriteMap [c + 0x800] = &Memory.FillRAM [0x3000]; - SA1.WriteMap [c + 1] = SA1.WriteMap [c + 0x801] = (uint8 *) MAP_NONE; - } - - // Banks 60->6f - for (c = 0; c < 0x100; c++) - SA1.Map [c + 0x600] = SA1.WriteMap [c + 0x600] = (uint8 *) MAP_BWRAM_BITMAP; - - Memory.BWRAM = Memory.SRAM; + } + WriteProtectROM(); + + // Now copy the map and correct it for the SA1 CPU. + // memmove converted: Different mallocs [Neb] + memcpy((void*) SA1.WriteMap, (void*) Memory.WriteMap, sizeof(Memory.WriteMap)); + // memmove converted: Different mallocs [Neb] + memcpy((void*) SA1.Map, (void*) Memory.Map, sizeof(Memory.Map)); + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { + SA1.Map [c + 0] = SA1.Map [c + 0x800] = &Memory.FillRAM [0x3000]; + SA1.Map [c + 1] = SA1.Map [c + 0x801] = (uint8*) MAP_NONE; + SA1.WriteMap [c + 0] = SA1.WriteMap [c + 0x800] = &Memory.FillRAM [0x3000]; + SA1.WriteMap [c + 1] = SA1.WriteMap [c + 0x801] = (uint8*) MAP_NONE; + } + + // Banks 60->6f + for (c = 0; c < 0x100; c++) + SA1.Map [c + 0x600] = SA1.WriteMap [c + 0x600] = (uint8*) MAP_BWRAM_BITMAP; + + Memory.BWRAM = Memory.SRAM; } -void LoROM24MBSMap () +void LoROM24MBSMap() { - int c; - int i; - - // Banks 00->3f and 80->bf - for (c = 0; c < 0x400; c += 16) - { + int c; + int i; + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { Memory.Map [c + 0] = Memory.Map [c + 0x800] = Memory.RAM; Memory.Map [c + 1] = Memory.Map [c + 0x801] = Memory.RAM; Memory.BlockIsRAM [c + 0] = Memory.BlockIsRAM [c + 0x800] = TRUE; Memory.BlockIsRAM [c + 1] = Memory.BlockIsRAM [c + 0x801] = TRUE; - - Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8 *) MAP_PPU; - Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8 *) MAP_PPU; - Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8 *) MAP_CPU; - Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) MAP_CPU; - Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *) MAP_NONE; - Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *) MAP_NONE; - - for (i = c + 8; i < c + 16; i++) - { + + Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8*) MAP_PPU; + Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8*) MAP_PPU; + Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8*) MAP_CPU; + Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8*) MAP_CPU; + Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8*) MAP_NONE; + Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8*) MAP_NONE; + + for (i = c + 8; i < c + 16; i++) + { Memory.Map [i] = Memory.Map [i + 0x800] = &Memory.ROM [c << 11] - 0x8000; Memory.BlockIsROM [i] = Memory.BlockIsROM [i + 0x800] = TRUE; - } - } - - // Banks 00->3f and 80->bf - for (c = 0; c < 0x200; c += 16) - { + } + } + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x200; c += 16) + { Memory.Map [c + 0x800] = Memory.RAM; Memory.Map [c + 0x801] = Memory.RAM; Memory.BlockIsRAM [c + 0x800] = TRUE; Memory.BlockIsRAM [c + 0x801] = TRUE; - - Memory.Map [c + 0x802] = (uint8 *) MAP_PPU; - Memory.Map [c + 0x803] = (uint8 *) MAP_PPU; - Memory.Map [c + 0x804] = (uint8 *) MAP_CPU; - Memory.Map [c + 0x805] = (uint8 *) MAP_CPU; - Memory.Map [c + 0x806] = (uint8 *) MAP_NONE; - Memory.Map [c + 0x807] = (uint8 *) MAP_NONE; - - for (i = c + 8; i < c + 16; i++) - { + + Memory.Map [c + 0x802] = (uint8*) MAP_PPU; + Memory.Map [c + 0x803] = (uint8*) MAP_PPU; + Memory.Map [c + 0x804] = (uint8*) MAP_CPU; + Memory.Map [c + 0x805] = (uint8*) MAP_CPU; + Memory.Map [c + 0x806] = (uint8*) MAP_NONE; + Memory.Map [c + 0x807] = (uint8*) MAP_NONE; + + for (i = c + 8; i < c + 16; i++) + { Memory.Map [i + 0x800] = &Memory.ROM [c << 11] - 0x8000 + 0x200000; Memory.BlockIsROM [i + 0x800] = TRUE; - } - } - - // Banks 40->7f and c0->ff - for (c = 0; c < 0x400; c += 16) - { - for (i = c; i < c + 8; i++) - Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = &Memory.ROM [(c << 11) + 0x200000]; - - for (i = c + 8; i < c + 16; i++) - Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = &Memory.ROM [(c << 11) + 0x200000 - 0x8000]; - - for (i = c; i < c + 16; i++) - { + } + } + + // Banks 40->7f and c0->ff + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 8; i++) + Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = &Memory.ROM [(c << 11) + + 0x200000]; + + for (i = c + 8; i < c + 16; i++) + Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = &Memory.ROM [(c << 11) + + 0x200000 - 0x8000]; + + for (i = c; i < c + 16; i++) Memory.BlockIsROM [i + 0x400] = Memory.BlockIsROM [i + 0xc00] = TRUE; - } - } - - MapExtraRAM (); - WriteProtectROM (); + } + + MapExtraRAM(); + WriteProtectROM(); } -void SufamiTurboLoROMMap () +void SufamiTurboLoROMMap() { - int c; - int i; - - // Banks 00->3f and 80->bf - for (c = 0; c < 0x400; c += 16) - { + int c; + int i; + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { Memory.Map [c + 0] = Memory.Map [c + 0x800] = Memory.RAM; Memory.Map [c + 1] = Memory.Map [c + 0x801] = Memory.RAM; Memory.BlockIsRAM [c + 0] = Memory.BlockIsRAM [c + 0x800] = TRUE; Memory.BlockIsRAM [c + 1] = Memory.BlockIsRAM [c + 0x801] = TRUE; - - Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8 *) MAP_PPU; - Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8 *) MAP_PPU; - Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8 *) MAP_CPU; - Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) MAP_CPU; - Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *) MAP_NONE; - Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *) MAP_NONE; - for (i = c + 8; i < c + 16; i++) - { + + Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8*) MAP_PPU; + Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8*) MAP_PPU; + Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8*) MAP_CPU; + Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8*) MAP_CPU; + Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8*) MAP_NONE; + Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8*) MAP_NONE; + for (i = c + 8; i < c + 16; i++) + { Memory.Map [i] = Memory.Map [i + 0x800] = &Memory.ROM [c << 11] - 0x8000; Memory.BlockIsROM [i] = Memory.BlockIsROM [i + 0x800] = TRUE; - } - } - - // Banks 40->7f and c0->ff - for (c = 0; c < 0x400; c += 16) - { - for (i = c; i < c + 8; i++) - Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = &Memory.ROM [(c << 11) + 0x200000]; - - for (i = c + 8; i < c + 16; i++) - Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = &Memory.ROM [(c << 11) + 0x200000 - 0x8000]; - - for (i = c; i < c + 16; i++) - { + } + } + + // Banks 40->7f and c0->ff + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 8; i++) + Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = &Memory.ROM [(c << 11) + + 0x200000]; + + for (i = c + 8; i < c + 16; i++) + Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = &Memory.ROM [(c << 11) + + 0x200000 - 0x8000]; + + for (i = c; i < c + 16; i++) Memory.BlockIsROM [i + 0x400] = Memory.BlockIsROM [i + 0xc00] = TRUE; - } - } - - if (Settings.DSP1Master) - { - for (c = 0; c < 0x100; c++) - { - Memory.Map [c + 0xe00] = (uint8 *) MAP_DSP; + } + + if (Settings.DSP1Master) + { + for (c = 0; c < 0x100; c++) + { + Memory.Map [c + 0xe00] = (uint8*) MAP_DSP; Memory.BlockIsROM [c + 0xe00] = FALSE; - } - } - - // Banks 7e->7f, RAM - for (c = 0; c < 16; c++) - { + } + } + + // Banks 7e->7f, RAM + for (c = 0; c < 16; c++) + { Memory.Map [c + 0x7e0] = Memory.RAM; Memory.Map [c + 0x7f0] = Memory.RAM + 0x10000; Memory.BlockIsRAM [c + 0x7e0] = TRUE; Memory.BlockIsRAM [c + 0x7f0] = TRUE; Memory.BlockIsROM [c + 0x7e0] = FALSE; Memory.BlockIsROM [c + 0x7f0] = FALSE; - } - - // Banks 60->67, S-RAM - for (c = 0; c < 0x80; c++) - { - Memory.Map [c + 0x600] = (uint8 *) MAP_LOROM_SRAM; + } + + // Banks 60->67, S-RAM + for (c = 0; c < 0x80; c++) + { + Memory.Map [c + 0x600] = (uint8*) MAP_LOROM_SRAM; Memory.BlockIsRAM [c + 0x600] = TRUE; Memory.BlockIsROM [c + 0x600] = FALSE; - } - - WriteProtectROM (); + } + + WriteProtectROM(); } #if 0 //untested!! -void SameGameMap () +void SameGameMap() { - int i; - int c; - int j; - - int mask[4]; - int mask2[4]; - for (j=0; j<4; j++) - mask[j]=mask2[j]=0x00ff; - - mask[0]=(CalculatedSize/0x10000)-1; - mask2[0]=(Slot1Size/0x10000)-1; - - int x; - bool foundZeros; - bool pastZeros; - - for(j=0;j<3;j++) - { - x=1; - foundZeros=false; - pastZeros=false; - - mask[j+1]=mask[j]; - - while (x>0x100&&!pastZeros) - { - if(mask[j]&x) - { - x<<=1; - if(foundZeros) - pastZeros=true; - } - else - { - foundZeros=true; - pastZeros=false; - mask[j+1]|=x; - x<<=1; - } - } - } - - for(j=0;j<3;j++) - { - x=1; - foundZeros=false; - pastZeros=false; - - mask2[j+1]=mask2[j]; - - while (x>0x100&&!pastZeros) - { - if(mask2[j]&x) - { - x<<=1; - if(foundZeros) - pastZeros=true; - } - else - { - foundZeros=true; - pastZeros=false; - mask2[j+1]|=x; - x<<=1; - } - } - } - - - // Banks 00->3f and 80->bf - for (c = 0; c < 0x400; c += 16) - { + int i; + int c; + int j; + + int mask[4]; + int mask2[4]; + for (j = 0; j < 4; j++) + mask[j] = mask2[j] = 0x00ff; + + mask[0] = (CalculatedSize / 0x10000) - 1; + mask2[0] = (Slot1Size / 0x10000) - 1; + + int x; + bool foundZeros; + bool pastZeros; + + for (j = 0; j < 3; j++) + { + x = 1; + foundZeros = false; + pastZeros = false; + + mask[j + 1] = mask[j]; + + while (x > 0x100 && !pastZeros) + { + if (mask[j]&x) + { + x <<= 1; + if (foundZeros) + pastZeros = true; + } + else + { + foundZeros = true; + pastZeros = false; + mask[j + 1] |= x; + x <<= 1; + } + } + } + + for (j = 0; j < 3; j++) + { + x = 1; + foundZeros = false; + pastZeros = false; + + mask2[j + 1] = mask2[j]; + + while (x > 0x100 && !pastZeros) + { + if (mask2[j]&x) + { + x <<= 1; + if (foundZeros) + pastZeros = true; + } + else + { + foundZeros = true; + pastZeros = false; + mask2[j + 1] |= x; + x <<= 1; + } + } + } + + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { Memory.Map [c + 0] = Memory.Map [c + 0x800] = RAM; Memory.BlockIsRAM [c + 0] = Memory.BlockIsRAM [c + 0x800] = TRUE; Memory.Map [c + 1] = Memory.Map [c + 0x801] = RAM; Memory.BlockIsRAM [c + 1] = Memory.BlockIsRAM [c + 0x801] = TRUE; - - Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8 *) MAP_PPU; - Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8 *) MAP_PPU; - Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8 *) MAP_CPU; - Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) MAP_CPU; - - Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *) MAP_NONE; - Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *) MAP_NONE; - } - - // Banks 30->3f and b0->bf, address ranges 6000->7fff is S-RAM. - for (c = 0; c < 16; c++) - { - Memory.Map [0x306 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM; - Memory.Map [0x307 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM; - Memory.Map [0xb06 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM; - Memory.Map [0xb07 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM; + + Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8*) MAP_PPU; + Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8*) MAP_PPU; + Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8*) MAP_CPU; + Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8*) MAP_CPU; + + Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8*) MAP_NONE; + Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8*) MAP_NONE; + } + + // Banks 30->3f and b0->bf, address ranges 6000->7fff is S-RAM. + for (c = 0; c < 16; c++) + { + Memory.Map [0x306 + (c << 4)] = (uint8*) MAP_HIROM_SRAM; + Memory.Map [0x307 + (c << 4)] = (uint8*) MAP_HIROM_SRAM; + Memory.Map [0xb06 + (c << 4)] = (uint8*) MAP_HIROM_SRAM; + Memory.Map [0xb07 + (c << 4)] = (uint8*) MAP_HIROM_SRAM; Memory.BlockIsRAM [0x306 + (c << 4)] = TRUE; Memory.BlockIsRAM [0x307 + (c << 4)] = TRUE; Memory.BlockIsRAM [0xb06 + (c << 4)] = TRUE; Memory.BlockIsRAM [0xb07 + (c << 4)] = TRUE; - } - - for c=0; c<0x200; c+=16) - { - for(i=0;i<8;i++) - { - int e=3; - int d=c>>4; - while(d>mask[0]) - { - d&=mask[e]; - e--; - } - - int f=3; - int g=c>>4; - while(g>mask2[0]) - { - g&=mask2[f]; - f--; - } - - //stuff in HiROM areas - Memory.Map[c+0x400+i]=&ROM[d*0x10000]; - Memory.Map[c+0xC00+i]=&ROM[d*0x10000]; - //MINI - Memory.Map[c+0x600+i]=&ROMOffset1[g*0x10000]; - Memory.Map[c+0xE00+i]=&ROMOffset1[g*0x10000]; - - } - for(i=8;i<16;i++) - { - int e=3; - int d=c>>4; - while(d>mask[0]) - { - d&=mask[e]; - e--; - } - - int f=3; - int g=c>>4; - while(g>mask2[0]) - { - g&=mask2[f]; - f--; - } - - - //all stuff - //BASE - Memory.Map[c+i]=&ROM[d*0x10000]; - Memory.Map[c+0x800+i]=&ROM[d*0x10000]; - Memory.Map[c+0x400+i]=&ROM[d*0x10000]; - Memory.Map[c+0xC00+i]=&ROM[d*0x10000]; - //MINI - Memory.Map[c+0x200+i]=&ROMOffset1[g*0x10000]; - Memory.Map[c+0xA00+i]=&ROMOffset1[g*0x10000]; - Memory.Map[c+0x600+i]=&ROMOffset1[g*0x10000]; - Memory.Map[c+0xE00+i]=&ROMOffset1[g*0x10000]; - } - - } - - int bankmax=0x40+ (1<<(ROMSize-6)); - //safety for corrupt headers - if(bankmax > 128) - bankmax = 0x80; - int sum=0; - for(i=0x40;i> 4; + while (d > mask[0]) + { + d &= mask[e]; + e--; + } + + int f = 3; + int g = c >> 4; + while (g > mask2[0]) + { + g &= mask2[f]; + f--; + } + + //stuff in HiROM areas + Memory.Map[c + 0x400 + i] = &ROM[d * 0x10000]; + Memory.Map[c + 0xC00 + i] = &ROM[d * 0x10000]; + //MINI + Memory.Map[c + 0x600 + i] = &ROMOffset1[g * 0x10000]; + Memory.Map[c + 0xE00 + i] = &ROMOffset1[g * 0x10000]; + + } + for (i = 8; i < 16; i++) + { + int e = 3; + int d = c >> 4; + while (d > mask[0]) + { + d &= mask[e]; + e--; + } + + int f = 3; + int g = c >> 4; + while (g > mask2[0]) + { + g &= mask2[f]; + f--; + } + + + //all stuff + //BASE + Memory.Map[c + i] = &ROM[d * 0x10000]; + Memory.Map[c + 0x800 + i] = &ROM[d * 0x10000]; + Memory.Map[c + 0x400 + i] = &ROM[d * 0x10000]; + Memory.Map[c + 0xC00 + i] = &ROM[d * 0x10000]; + //MINI + Memory.Map[c + 0x200 + i] = &ROMOffset1[g * 0x10000]; + Memory.Map[c + 0xA00 + i] = &ROMOffset1[g * 0x10000]; + Memory.Map[c + 0x600 + i] = &ROMOffset1[g * 0x10000]; + Memory.Map[c + 0xE00 + i] = &ROMOffset1[g * 0x10000]; + } + + } + + int bankmax = 0x40 + (1 << (ROMSize - 6)); + //safety for corrupt headers + if (bankmax > 128) + bankmax = 0x80; + int sum = 0; + for (i = 0x40; i < bankmax; i++) +{ + uint8* bank_low = (uint8*)Memory.Map[i << 4]; + for (c = 0; c < 0x10000; c++) + sum += bank_low[c]; + } + CalculatedChecksum = sum & 0xFFFF; + + MapRAM(); + WriteProtectROM(); } //Untested!! -void GNextROMMap () +void GNextROMMap() { - int c; - int i; - - // Banks 00->3f and 80->bf - for (c = 0; c < 0x400; c += 16) - { + int c; + int i; + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { Memory.Map [c + 0] = Memory.Map [c + 0x800] = RAM; Memory.Map [c + 1] = Memory.Map [c + 0x801] = RAM; Memory.BlockIsRAM [c + 0] = Memory.BlockIsRAM [c + 0x800] = TRUE; Memory.BlockIsRAM [c + 1] = Memory.BlockIsRAM [c + 0x801] = TRUE; - - Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8 *) MAP_PPU; - Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8 *) &Memory.FillRAM [0x3000] - 0x3000; - Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8 *) MAP_CPU; - Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) MAP_CPU; - Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *) MAP_BWRAM; - Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *) MAP_BWRAM; - for (i = c + 8; i < c + 16; i++) - { + + Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8*) MAP_PPU; + Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8*) &Memory.FillRAM [0x3000] + - 0x3000; + Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8*) MAP_CPU; + Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8*) MAP_CPU; + Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8*) MAP_BWRAM; + Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8*) MAP_BWRAM; + for (i = c + 8; i < c + 16; i++) + { Memory.Map [i] = Memory.Map [i + 0x800] = &ROM [c << 11] - 0x8000; - BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE; - } - } - - - // Banks 40->4f (was 7f, but SNES docs and GNext overdumping shows nothing here.) - for (c = 0; c < 0x100; c += 16) - { - for (i = c; i < c + 16; i++) - Memory.Map [i + 0x400] = (uint8 *) &SRAM [(c << 12) & 0x1ffff]; - - for (i = c; i < c + 16; i++) - { - BlockIsROM [i + 0x400] = FALSE; - } - } - - for (c = 0; c < 0x100; c += 16) - { - for (i = c; i < c + 16; i++) - Memory.Map [i + 0x700] = (uint8 *) &ROMOffset1 [(c << 12) & (Slot1Size-1)]; - } - - // c0->ff - for (c = 0; c < 0x400; c += 16) - { - for (i = c; i < c + 16; i++) - { + BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE; + } + } + + + // Banks 40->4f (was 7f, but SNES docs and GNext overdumping shows nothing here.) + for (c = 0; c < 0x100; c += 16) + { + for (i = c; i < c + 16; i++) + Memory.Map [i + 0x400] = (uint8*) &SRAM [(c << 12) & 0x1ffff]; + + for (i = c; i < c + 16; i++) + BlockIsROM [i + 0x400] = FALSE; + } + + for (c = 0; c < 0x100; c += 16) + { + for (i = c; i < c + 16; i++) + Memory.Map [i + 0x700] = (uint8*) &ROMOffset1 [(c << 12) & (Slot1Size - 1)]; + } + + // c0->ff + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 16; i++) + { Memory.Map [i + 0xc00] = &ROM [(c << 12) % CalculatedSize]; - BlockIsROM [i + 0xc00] = TRUE; - } - } - - for (c = 0; c < 16; c++) - { + BlockIsROM [i + 0xc00] = TRUE; + } + } + + for (c = 0; c < 16; c++) + { Memory.Map [c + 0x7e0] = RAM; Memory.Map [c + 0x7f0] = RAM + 0x10000; Memory.BlockIsRAM [c + 0x7e0] = TRUE; Memory.BlockIsRAM [c + 0x7f0] = TRUE; - BlockIsROM [c + 0x7e0] = FALSE; - BlockIsROM [c + 0x7f0] = FALSE; - } - WriteProtectROM (); - - // Now copy the map and correct it for the SA1 CPU. - // memmove converted: Different mallocs [Neb] - memcpy ((void *) SA1.WriteMap, (void *) WriteMap, sizeof (WriteMap)); - // memmove converted: Different mallocs [Neb] - memcpy ((void *) SA1.Map, (void *) Memory.Map, sizeof (Memory.Map)); - - // Banks 00->3f and 80->bf - for (c = 0; c < 0x400; c += 16) - { - SA1.Map [c + 0] = SA1.Map [c + 0x800] = &Memory.FillRAM [0x3000]; - SA1.Map [c + 1] = SA1.Map [c + 0x801] = (uint8 *) MAP_NONE; - SA1.WriteMap [c + 0] = SA1.WriteMap [c + 0x800] = &Memory.FillRAM [0x3000]; - SA1.WriteMap [c + 1] = SA1.WriteMap [c + 0x801] = (uint8 *) MAP_NONE; - } - - // Banks 60->6f - for (c = 0; c < 0x100; c++) - SA1.Map [c + 0x600] = SA1.WriteMap [c + 0x600] = (uint8 *) MAP_BWRAM_BITMAP; - - BWRAM = SRAM; + BlockIsROM [c + 0x7e0] = FALSE; + BlockIsROM [c + 0x7f0] = FALSE; + } + WriteProtectROM(); + + // Now copy the map and correct it for the SA1 CPU. + // memmove converted: Different mallocs [Neb] + memcpy((void*) SA1.WriteMap, (void*) WriteMap, sizeof(WriteMap)); + // memmove converted: Different mallocs [Neb] + memcpy((void*) SA1.Map, (void*) Memory.Map, sizeof(Memory.Map)); + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { + SA1.Map [c + 0] = SA1.Map [c + 0x800] = &Memory.FillRAM [0x3000]; + SA1.Map [c + 1] = SA1.Map [c + 0x801] = (uint8*) MAP_NONE; + SA1.WriteMap [c + 0] = SA1.WriteMap [c + 0x800] = &Memory.FillRAM [0x3000]; + SA1.WriteMap [c + 1] = SA1.WriteMap [c + 0x801] = (uint8*) MAP_NONE; + } + + // Banks 60->6f + for (c = 0; c < 0x100; c++) + SA1.Map [c + 0x600] = SA1.WriteMap [c + 0x600] = (uint8*) MAP_BWRAM_BITMAP; + + BWRAM = SRAM; } -void SufamiTurboAltROMMap () +void SufamiTurboAltROMMap() { - int c; - int i; - - if(Slot1Size!=0) - Slot1SRAMSize=(1<<((uint8)ROMOffset1[0x32]))*1024; - else Slot1Size=0x8000; - if(Slot2Size!=0) - Slot2SRAMSize=(1<<((uint8)ROMOffset2[0x32]))*1024; -else Slot2Size=0x8000; - - // Banks 00->3f and 80->bf - for (c = 0; c < 0x400; c += 16) - { + int c; + int i; + + if (Slot1Size != 0) + Slot1SRAMSize = (1 << ((uint8)ROMOffset1[0x32])) * 1024; + else Slot1Size = 0x8000; + if (Slot2Size != 0) + Slot2SRAMSize = (1 << ((uint8)ROMOffset2[0x32])) * 1024; + else Slot2Size = 0x8000; + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { Memory.Map [c + 0] = Memory.Map [c + 0x800] = RAM; Memory.Map [c + 1] = Memory.Map [c + 0x801] = RAM; Memory.BlockIsRAM [c + 0] = Memory.BlockIsRAM [c + 0x800] = TRUE; Memory.BlockIsRAM [c + 1] = Memory.BlockIsRAM [c + 0x801] = TRUE; - - Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8 *) MAP_PPU; - Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8 *) MAP_PPU; - Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8 *) MAP_CPU; - Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) MAP_CPU; - Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *) MAP_NONE; - Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *) MAP_NONE; - -// for (i = c + 8; i < c + 16; i++) -// { -// Memory.Map [i] = Memory.Map [i + 0x800] = &ROM [c << 11] - 0x8000; -// BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE; -// } - - } - - //Map Bios - - for (c=0; c<0x200; c+=16) - { - for (i = c + 8; i < c + 16; i++) - { - Memory.Map [i] = Memory.Map [i + 0x800] = &ROM [((c>>4)*0x8000)%CalculatedSize] - 0x8000; - BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE; - } - - } - - - for (c=0x200; c<0x400; c+=16) - { - for (i = c + 8; i < c + 16; i++) - { - if(Slot1Size!=0) - { - Memory.Map [i] = Memory.Map [i + 0x800] = &ROMOffset1 [(((c>>4)*0x8000)%Slot1Size)] - 0x8000; - BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE; - } - else Memory.Map [i] = Memory.Map [i + 0x800] = (uint8*)MAP_NONE; - } - - } - - for (c=0x400; c<0x600; c+=16) - { - for (i = c; i < c + 8; i++) - { - if(Slot2Size!=0) - { - Memory.Map [i] = Memory.Map [i + 0x800] = &ROMOffset2[(((c>>4)*0x8000)%Slot2Size)]; - BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE; - } + + Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8*) MAP_PPU; + Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8*) MAP_PPU; + Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8*) MAP_CPU; + Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8*) MAP_CPU; + Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8*) MAP_NONE; + Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8*) MAP_NONE; + + // for (i = c + 8; i < c + 16; i++) + // { + // Memory.Map [i] = Memory.Map [i + 0x800] = &ROM [c << 11] - 0x8000; + // BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE; + // } + + } + + //Map Bios + + for (c = 0; c < 0x200; c += 16) + { + for (i = c + 8; i < c + 16; i++) + { + Memory.Map [i] = Memory.Map [i + 0x800] = &ROM [((c >> 4) * 0x8000) % + CalculatedSize] - 0x8000; + BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE; + } + + } + + + for (c = 0x200; c < 0x400; c += 16) + { + for (i = c + 8; i < c + 16; i++) + { + if (Slot1Size != 0) + { + Memory.Map [i] = Memory.Map [i + 0x800] = &ROMOffset1 [((( + c >> 4) * 0x8000) % Slot1Size)] - 0x8000; + BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE; + } + else Memory.Map [i] = Memory.Map [i + 0x800] = (uint8*)MAP_NONE; + } + + } + + for (c = 0x400; c < 0x600; c += 16) + { + for (i = c; i < c + 8; i++) + { + if (Slot2Size != 0) + { + Memory.Map [i] = Memory.Map [i + 0x800] = &ROMOffset2[((( + c >> 4) * 0x8000) % Slot2Size)]; + BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE; + } else Memory.Map [i] = Memory.Map [i + 0x800] = (uint8*)MAP_NONE; - } - for (i = c + 8; i < c + 16; i++) - { - if(Slot2Size!=0) - { - Memory.Map [i] = Memory.Map [i + 0x800] = &ROMOffset2[(((c>>4)*0x8000)%Slot2Size)] - 0x8000; - BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE; - } + } + for (i = c + 8; i < c + 16; i++) + { + if (Slot2Size != 0) + { + Memory.Map [i] = Memory.Map [i + 0x800] = &ROMOffset2[((( + c >> 4) * 0x8000) % Slot2Size)] - 0x8000; + BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE; + } else Memory.Map [i] = Memory.Map [i + 0x800] = (uint8*)MAP_NONE; - } + } } - // Banks 60->67 (7F?), S-RAM - if(Slot1SRAMSize!=0) - { - for (c = 0; c < 0x100; c++) - { - Memory.Map [c + 0xE00] = Memory.Map [c + 0x600] = (uint8 *) MAP_LOROM_SRAM; + // Banks 60->67 (7F?), S-RAM + if (Slot1SRAMSize != 0) + { + for (c = 0; c < 0x100; c++) + { + Memory.Map [c + 0xE00] = Memory.Map [c + 0x600] = (uint8*) MAP_LOROM_SRAM; Memory.BlockIsRAM [c + 0xE00] = Memory.BlockIsRAM [c + 0x600] = TRUE; - BlockIsROM [c + 0xE00] = BlockIsROM [c + 0x600] = FALSE; - } - } - if(Slot2SRAMSize!=0) - { - for (c = 0; c < 0x100; c++) - { - Memory.Map [c + 0xF00] = Memory.Map [c + 0x700] = (uint8 *) MAP_LOROM_SRAM; + BlockIsROM [c + 0xE00] = BlockIsROM [c + 0x600] = FALSE; + } + } + if (Slot2SRAMSize != 0) + { + for (c = 0; c < 0x100; c++) + { + Memory.Map [c + 0xF00] = Memory.Map [c + 0x700] = (uint8*) MAP_LOROM_SRAM; Memory.BlockIsRAM [c + 0xF00] = Memory.BlockIsRAM [c + 0x700] = TRUE; - BlockIsROM [c + 0xF00] = BlockIsROM [c + 0x700] = FALSE; - } - } - - // Banks 7e->7f, RAM - for (c = 0; c < 16; c++) - { + BlockIsROM [c + 0xF00] = BlockIsROM [c + 0x700] = FALSE; + } + } + + // Banks 7e->7f, RAM + for (c = 0; c < 16; c++) + { Memory.Map [c + 0x7e0] = RAM; Memory.Map [c + 0x7f0] = RAM + 0x10000; Memory.BlockIsRAM [c + 0x7e0] = TRUE; Memory.BlockIsRAM [c + 0x7f0] = TRUE; - BlockIsROM [c + 0x7e0] = FALSE; - BlockIsROM [c + 0x7f0] = FALSE; - } - - WriteProtectROM (); + BlockIsROM [c + 0x7e0] = FALSE; + BlockIsROM [c + 0x7f0] = FALSE; + } + + WriteProtectROM(); } #endif -void SRAM512KLoROMMap () +void SRAM512KLoROMMap() { - int c; - int i; - - // Banks 00->3f and 80->bf - for (c = 0; c < 0x400; c += 16) - { + int c; + int i; + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { Memory.Map [c + 0] = Memory.Map [c + 0x800] = Memory.RAM; Memory.Map [c + 1] = Memory.Map [c + 0x801] = Memory.RAM; Memory.BlockIsRAM [c + 0] = Memory.BlockIsRAM [c + 0x800] = TRUE; Memory.BlockIsRAM [c + 1] = Memory.BlockIsRAM [c + 0x801] = TRUE; - - Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8 *) MAP_PPU; - Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8 *) MAP_PPU; - Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8 *) MAP_CPU; - Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) MAP_CPU; - Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *) MAP_NONE; - Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *) MAP_NONE; - - for (i = c + 8; i < c + 16; i++) - { + + Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8*) MAP_PPU; + Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8*) MAP_PPU; + Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8*) MAP_CPU; + Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8*) MAP_CPU; + Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8*) MAP_NONE; + Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8*) MAP_NONE; + + for (i = c + 8; i < c + 16; i++) + { Memory.Map [i] = Memory.Map [i + 0x800] = &Memory.ROM [c << 11] - 0x8000; Memory.BlockIsROM [i] = Memory.BlockIsROM [i + 0x800] = TRUE; - } - } - - // Banks 40->7f and c0->ff - for (c = 0; c < 0x400; c += 16) - { - for (i = c; i < c + 8; i++) - Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = &Memory.ROM [(c << 11) + 0x200000]; - - for (i = c + 8; i < c + 16; i++) - Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = &Memory.ROM [(c << 11) + 0x200000 - 0x8000]; - - for (i = c; i < c + 16; i++) - { + } + } + + // Banks 40->7f and c0->ff + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 8; i++) + Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = &Memory.ROM [(c << 11) + + 0x200000]; + + for (i = c + 8; i < c + 16; i++) + Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = &Memory.ROM [(c << 11) + + 0x200000 - 0x8000]; + + for (i = c; i < c + 16; i++) Memory.BlockIsROM [i + 0x400] = Memory.BlockIsROM [i + 0xc00] = TRUE; - } - } - - MapExtraRAM (); - WriteProtectROM (); + } + + MapExtraRAM(); + WriteProtectROM(); } -void BSHiROMMap () +void BSHiROMMap() { - int c; - int i; - - Memory.SRAMSize=5; - - // Banks 00->3f and 80->bf - for (c = 0; c < 0x400; c += 16) - { + int c; + int i; + + Memory.SRAMSize = 5; + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { Memory.Map [c + 0] = Memory.Map [c + 0x800] = Memory.RAM; Memory.BlockIsRAM [c + 0] = Memory.BlockIsRAM [c + 0x800] = TRUE; Memory.Map [c + 1] = Memory.Map [c + 0x801] = Memory.RAM; Memory.BlockIsRAM [c + 1] = Memory.BlockIsRAM [c + 0x801] = TRUE; - - Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8 *) MAP_PPU; - Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8 *) MAP_PPU; - Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8 *) MAP_CPU; - // XXX: How large is SRAM?? - Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) Memory.RAM; -// Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) SRAM; + + Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8*) MAP_PPU; + Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8*) MAP_PPU; + Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8*) MAP_CPU; + // XXX: How large is SRAM?? + Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8*) Memory.RAM; + // Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) SRAM; Memory.BlockIsRAM [c + 5] = Memory.BlockIsRAM [c + 0x805] = TRUE; -// Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *) MAP_NONE; -// Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *) MAP_NONE; - - Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *) Memory.RAM; -// Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) SRAM; + // Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *) MAP_NONE; + // Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *) MAP_NONE; + + Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8*) Memory.RAM; + // Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) SRAM; Memory.BlockIsRAM [c + 6] = Memory.BlockIsRAM [c + 0x806] = TRUE; - Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *) Memory.RAM; -// Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) Memory.SRAM; + Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8*) Memory.RAM; + // Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) Memory.SRAM; Memory.BlockIsRAM [c + 7] = Memory.BlockIsRAM [c + 0x807] = TRUE; - for (i = c + 8; i < c + 16; i++) - { - Memory.Map [i] = Memory.Map [i + 0x800] = &Memory.ROM [(c << 12) % Memory.CalculatedSize]; + for (i = c + 8; i < c + 16; i++) + { + Memory.Map [i] = Memory.Map [i + 0x800] = &Memory.ROM [(c << 12) % + Memory.CalculatedSize]; Memory.BlockIsROM [i] = Memory.BlockIsROM [i + 0x800] = TRUE; - } - } - - // Banks 60->7d offset 0000->7fff & 60->7f offset 8000->ffff PSRAM - // XXX: How large is PSRAM? - - //not adjusted, but The Dumper says "4 Mbits" - for (c = 0x600; c < 0x7e0; c += 16) - { - for (i = c; i < c + 8; i++) - { + } + } + + // Banks 60->7d offset 0000->7fff & 60->7f offset 8000->ffff PSRAM + // XXX: How large is PSRAM? + + //not adjusted, but The Dumper says "4 Mbits" + for (c = 0x600; c < 0x7e0; c += 16) + { + for (i = c; i < c + 8; i++) + { Memory.Map [i] = &Memory.ROM [0x400000 + (c << 11)]; Memory.BlockIsRAM [i] = TRUE; - } - for (i = c + 8; i < c + 16; i++) - { + } + for (i = c + 8; i < c + 16; i++) + { Memory.Map [i] = &Memory.ROM [0x400000 + (c << 11) - 0x8000]; Memory.BlockIsRAM [i] = TRUE; - } - } - - // Banks 40->7f and c0->ff - for (c = 0; c < 0x400; c += 16) - { - for (i = c; i < c + 16; i++) - { - Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = &Memory.ROM [(c << 12) % Memory.CalculatedSize]; + } + } + + // Banks 40->7f and c0->ff + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 16; i++) + { + Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = &Memory.ROM [(c << 12) % + Memory.CalculatedSize]; Memory.BlockIsROM [i + 0x400] = Memory.BlockIsROM [i + 0xc00] = TRUE; - } - } - for(i=0;i<0x80;i++) - { - Memory.Map[0x700+i]=&Memory.BSRAM[0x10000*(i/16)]; - Memory.BlockIsRAM[0x700+i]=TRUE; - Memory.BlockIsROM[0x700+i]=FALSE; - } - for (i=0; i<8;i++) - { - Memory.Map[0x205+(i<<4)]=Memory.Map[0x285+(i<<4)]=Memory.Map[0x305+(i<<4)]=Memory.Map[0x385+(i<<4)]=Memory.Map[0x705+(i<<4)]; - Memory.BlockIsRAM[0x205+(i<<4)]=Memory.BlockIsRAM[0x285+(i<<4)]=Memory.BlockIsRAM[0x305+(i<<4)]=Memory.BlockIsRAM[0x385+(i<<4)]=TRUE; - Memory.BlockIsROM[0x205+(i<<4)]=Memory.BlockIsROM[0x285+(i<<4)]=Memory.BlockIsROM[0x305+(i<<4)]=Memory.BlockIsROM[0x385+(i<<4)]=FALSE; - } - - MapRAM (); - WriteProtectROM (); + } + } + for (i = 0; i < 0x80; i++) + { + Memory.Map[0x700 + i] = &Memory.BSRAM[0x10000 * (i / 16)]; + Memory.BlockIsRAM[0x700 + i] = TRUE; + Memory.BlockIsROM[0x700 + i] = FALSE; + } + for (i = 0; i < 8; i++) + { + Memory.Map[0x205 + (i << 4)] = Memory.Map[0x285 + (i << 4)] = Memory.Map[0x305 + + (i << 4)] = Memory.Map[0x385 + (i << 4)] = Memory.Map[0x705 + (i << 4)]; + Memory.BlockIsRAM[0x205 + (i << 4)] = Memory.BlockIsRAM[0x285 + + (i << 4)] = Memory.BlockIsRAM[0x305 + (i << 4)] = Memory.BlockIsRAM[0x385 + + (i << 4)] = TRUE; + Memory.BlockIsROM[0x205 + (i << 4)] = Memory.BlockIsROM[0x285 + + (i << 4)] = Memory.BlockIsROM[0x305 + (i << 4)] = Memory.BlockIsROM[0x385 + + (i << 4)] = FALSE; + } + + MapRAM(); + WriteProtectROM(); } -void JumboLoROMMap (bool8 Interleaved) +void JumboLoROMMap(bool8 Interleaved) { - int c; - int i; - - uint32 OFFSET0 = 0x400000; - uint32 OFFSET1 = 0x400000; - uint32 OFFSET2 = 0x000000; - - if (Interleaved) - { - OFFSET0 = 0x000000; - OFFSET1 = 0x000000; - OFFSET2 = Memory.CalculatedSize-0x400000; //changed to work with interleaved DKJM2. - } - // Banks 00->3f and 80->bf - for (c = 0; c < 0x400; c += 16) - { + int c; + int i; + + uint32 OFFSET0 = 0x400000; + uint32 OFFSET1 = 0x400000; + uint32 OFFSET2 = 0x000000; + + if (Interleaved) + { + OFFSET0 = 0x000000; + OFFSET1 = 0x000000; + OFFSET2 = Memory.CalculatedSize - + 0x400000; //changed to work with interleaved DKJM2. + } + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { Memory.Map [c + 0] = Memory.Map [c + 0x800] = Memory.RAM; Memory.Map [c + 1] = Memory.Map [c + 0x801] = Memory.RAM; Memory.BlockIsRAM [c + 0] = Memory.BlockIsRAM [c + 0x800] = TRUE; Memory.BlockIsRAM [c + 1] = Memory.BlockIsRAM [c + 0x801] = TRUE; - - Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8 *) MAP_PPU; - Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8 *) MAP_PPU; - Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8 *) MAP_CPU; - Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) MAP_CPU; - if (Settings.DSP1Master) - { - Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *) MAP_DSP; - Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *) MAP_DSP; - } - else if (Settings.C4) - { - Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *) MAP_C4; - Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *) MAP_C4; - } - else - { - Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8 *) bytes0x2000 - 0x6000; - Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8 *) bytes0x2000 - 0x6000; - } - - for (i = c + 8; i < c + 16; i++) - { - Memory.Map [i]= &Memory.ROM [((c << 11) % (Memory.CalculatedSize - 0x400000)) + OFFSET0] - 0x8000; - Memory.Map [i + 0x800] = &Memory.ROM [((c << 11) % (0x400000)) + OFFSET2] - 0x8000; + + Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8*) MAP_PPU; + Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8*) MAP_PPU; + Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8*) MAP_CPU; + Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8*) MAP_CPU; + if (Settings.DSP1Master) + { + Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8*) MAP_DSP; + Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8*) MAP_DSP; + } + else if (Settings.C4) + { + Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8*) MAP_C4; + Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8*) MAP_C4; + } + else + { + Memory.Map [c + 6] = Memory.Map [c + 0x806] = (uint8*) bytes0x2000 - 0x6000; + Memory.Map [c + 7] = Memory.Map [c + 0x807] = (uint8*) bytes0x2000 - 0x6000; + } + + for (i = c + 8; i < c + 16; i++) + { + Memory.Map [i] = &Memory.ROM [((c << 11) % (Memory.CalculatedSize - 0x400000)) + + OFFSET0] - 0x8000; + Memory.Map [i + 0x800] = &Memory.ROM [((c << 11) % (0x400000)) + OFFSET2] - + 0x8000; Memory.BlockIsROM [i + 0x800] = Memory.BlockIsROM [i] = TRUE; - } - } - - if (Settings.DSP1Master) - { - // Banks 30->3f and b0->bf - for (c = 0x300; c < 0x400; c += 16) - { - for (i = c + 8; i < c + 16; i++) - { - Memory.Map [i + 0x800] = (uint8 *) MAP_DSP; + } + } + + if (Settings.DSP1Master) + { + // Banks 30->3f and b0->bf + for (c = 0x300; c < 0x400; c += 16) + { + for (i = c + 8; i < c + 16; i++) + { + Memory.Map [i + 0x800] = (uint8*) MAP_DSP; Memory.BlockIsROM [i] = Memory.BlockIsROM [i + 0x800] = FALSE; - } - } - } - - // Banks 40->7f and c0->ff - for (c = 0x400; c < 0x800; c += 16) - { - //updated mappings to correct A15 mirroring - for (i = c; i < c + 8; i++) - { - Memory.Map [i]= &Memory.ROM [((c << 11) % (Memory.CalculatedSize - 0x400000)) + OFFSET0]; - Memory.Map [i + 0x800] = &Memory.ROM [((c << 11) % 0x400000) +OFFSET2]; - } - - for (i = c + 8; i < c + 16; i++) - { - Memory.Map [i]= &Memory.ROM [((c << 11) % (Memory.CalculatedSize - 0x400000)) + OFFSET0] - 0x8000; - Memory.Map [i + 0x800] = &Memory.ROM [((c << 11) % 0x400000) + OFFSET2 ] - 0x8000; - } - - for (i = c; i < c + 16; i++) - { + } + } + } + + // Banks 40->7f and c0->ff + for (c = 0x400; c < 0x800; c += 16) + { + //updated mappings to correct A15 mirroring + for (i = c; i < c + 8; i++) + { + Memory.Map [i] = &Memory.ROM [((c << 11) % (Memory.CalculatedSize - 0x400000)) + + OFFSET0]; + Memory.Map [i + 0x800] = &Memory.ROM [((c << 11) % 0x400000) + OFFSET2]; + } + + for (i = c + 8; i < c + 16; i++) + { + Memory.Map [i] = &Memory.ROM [((c << 11) % (Memory.CalculatedSize - 0x400000)) + + OFFSET0] - 0x8000; + Memory.Map [i + 0x800] = &Memory.ROM [((c << 11) % 0x400000) + OFFSET2 ] - + 0x8000; + } + + for (i = c; i < c + 16; i++) Memory.BlockIsROM [i] = Memory.BlockIsROM [i + 0x800] = TRUE; - } - } - - //ROM type has to be 64 Mbit header! - int sum=0, k,l; - for(k=0;k<256;k++) - { - uint8* bank=0x8000+Memory.Map[8+(k<<4)];//use upper half of the banks, and adjust for LoROM. - for(l=0;l<0x8000;l++) - sum+=bank[l]; - } - Memory.CalculatedChecksum=sum&0xFFFF; - - MapRAM (); - WriteProtectROM (); + } + + //ROM type has to be 64 Mbit header! + int sum = 0, k, l; + for (k = 0; k < 256; k++) + { + uint8* bank = 0x8000 + Memory.Map[8 + (k << + 4)]; //use upper half of the banks, and adjust for LoROM. + for (l = 0; l < 0x8000; l++) + sum += bank[l]; + } + Memory.CalculatedChecksum = sum & 0xFFFF; + + MapRAM(); + WriteProtectROM(); } -void SPC7110HiROMMap () +void SPC7110HiROMMap() { - int c; - int i; - - // Banks 00->3f and 80->bf - for (c = 0; c < 0x400; c += 16) - { + int c; + int i; + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { Memory.Map [c + 0] = Memory.Map [c + 0x800] = Memory.RAM; Memory.BlockIsRAM [c + 0] = Memory.BlockIsRAM [c + 0x800] = TRUE; Memory.Map [c + 1] = Memory.Map [c + 0x801] = Memory.RAM; Memory.BlockIsRAM [c + 1] = Memory.BlockIsRAM [c + 0x801] = TRUE; - - Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8 *) MAP_PPU; - Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8 *) MAP_PPU; - Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8 *) MAP_CPU; - Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8 *) MAP_CPU; - - Memory.Map [c + 6] /*= Memory.Map [c + 0x806]*/ = (uint8 *) MAP_HIROM_SRAM; - Memory.Map [c + 7] /*= Memory.Map [c + 0x807]*/ = (uint8 *) MAP_HIROM_SRAM; - Memory.Map [c + 0x806]=Memory.Map [c + 0x807]= (uint8 *) MAP_NONE; - - for (i = c + 8; i < c + 16; i++) - { - Memory.Map [i] = Memory.Map [i + 0x800] = &Memory.ROM [(c << 12) % Memory.CalculatedSize]; + + Memory.Map [c + 2] = Memory.Map [c + 0x802] = (uint8*) MAP_PPU; + Memory.Map [c + 3] = Memory.Map [c + 0x803] = (uint8*) MAP_PPU; + Memory.Map [c + 4] = Memory.Map [c + 0x804] = (uint8*) MAP_CPU; + Memory.Map [c + 5] = Memory.Map [c + 0x805] = (uint8*) MAP_CPU; + + Memory.Map [c + 6] /*= Memory.Map [c + 0x806]*/ = (uint8*) MAP_HIROM_SRAM; + Memory.Map [c + 7] /*= Memory.Map [c + 0x807]*/ = (uint8*) MAP_HIROM_SRAM; + Memory.Map [c + 0x806] = Memory.Map [c + 0x807] = (uint8*) MAP_NONE; + + for (i = c + 8; i < c + 16; i++) + { + Memory.Map [i] = Memory.Map [i + 0x800] = &Memory.ROM [(c << 12) % + Memory.CalculatedSize]; Memory.BlockIsROM [i] = Memory.BlockIsROM [i + 0x800] = TRUE; - } - } - - // Banks 30->3f and b0->bf, address ranges 6000->7fff is S-RAM. - for (c = 0; c < 16; c++) - { - Memory.Map [0x306 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM; - Memory.Map [0x307 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM; - Memory.Map [0xb06 + (c << 4)] = (uint8 *) MAP_NONE; - Memory.Map [0xb07 + (c << 4)] = (uint8 *) MAP_NONE; + } + } + + // Banks 30->3f and b0->bf, address ranges 6000->7fff is S-RAM. + for (c = 0; c < 16; c++) + { + Memory.Map [0x306 + (c << 4)] = (uint8*) MAP_HIROM_SRAM; + Memory.Map [0x307 + (c << 4)] = (uint8*) MAP_HIROM_SRAM; + Memory.Map [0xb06 + (c << 4)] = (uint8*) MAP_NONE; + Memory.Map [0xb07 + (c << 4)] = (uint8*) MAP_NONE; Memory.BlockIsRAM [0x306 + (c << 4)] = TRUE; Memory.BlockIsRAM [0x307 + (c << 4)] = TRUE; - // Memory.BlockIsRAM [0xb06 + (c << 4)] = TRUE; - // Memory.BlockIsRAM [0xb07 + (c << 4)] = TRUE; - } - - // Banks 40->7f and c0->ff - for (c = 0; c < 0x400; c += 16) - { - for (i = c; i < c + 16; i++) - { - Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = &Memory.ROM [(c << 12) % Memory.CalculatedSize]; + // Memory.BlockIsRAM [0xb06 + (c << 4)] = TRUE; + // Memory.BlockIsRAM [0xb07 + (c << 4)] = TRUE; + } + + // Banks 40->7f and c0->ff + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 16; i++) + { + Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = &Memory.ROM [(c << 12) % + Memory.CalculatedSize]; Memory.BlockIsROM [i + 0x400] = Memory.BlockIsROM [i + 0xc00] = TRUE; - } - } - - for (c=0;c<0x10;c++) - { - Memory.Map [0x500+c]=(uint8 *)MAP_SPC7110_DRAM; - Memory.BlockIsROM [0x500+c]=TRUE; - } - - for (c=0;c<0x100;c++) - { - Memory.Map [0xD00+c] = (uint8 *) MAP_SPC7110_ROM; - Memory.Map [0xE00+c] = (uint8 *) MAP_SPC7110_ROM; - Memory.Map [0xF00+c] = (uint8 *) MAP_SPC7110_ROM; - Memory.BlockIsROM [0xD00+c] = Memory.BlockIsROM [0xE00+c] = Memory.BlockIsROM [0xF00+c] = TRUE; - - } - S9xSpc7110Init(); - -int sum=0; -for(i=0;i<(int)Memory.CalculatedSize; i++) -{ - sum+=Memory.ROM[i]; -} + } + } + + for (c = 0; c < 0x10; c++) + { + Memory.Map [0x500 + c] = (uint8*)MAP_SPC7110_DRAM; + Memory.BlockIsROM [0x500 + c] = TRUE; + } -if(Memory.CalculatedSize==0x300000) - sum<<=1; -Memory.CalculatedChecksum=sum&0xFFFF; + for (c = 0; c < 0x100; c++) + { + Memory.Map [0xD00 + c] = (uint8*) MAP_SPC7110_ROM; + Memory.Map [0xE00 + c] = (uint8*) MAP_SPC7110_ROM; + Memory.Map [0xF00 + c] = (uint8*) MAP_SPC7110_ROM; + Memory.BlockIsROM [0xD00 + c] = Memory.BlockIsROM [0xE00 + c] = + Memory.BlockIsROM [0xF00 + c] = TRUE; + + } + S9xSpc7110Init(); + + int sum = 0; + for (i = 0; i < (int)Memory.CalculatedSize; i++) + sum += Memory.ROM[i]; - MapRAM (); - WriteProtectROM (); + if (Memory.CalculatedSize == 0x300000) + sum <<= 1; + Memory.CalculatedChecksum = sum & 0xFFFF; + + MapRAM(); + WriteProtectROM(); } void SPC7110Sram(uint8 newstate) { - if(newstate&0x80) - { - Memory.Map[6]=(uint8 *)MAP_HIROM_SRAM; - Memory.Map[7]=(uint8 *)MAP_HIROM_SRAM; - Memory.Map[0x306]=(uint8 *)MAP_HIROM_SRAM; - Memory.Map[0x307]=(uint8 *)MAP_HIROM_SRAM; - - - } - else - { - Memory.Map[6]=(uint8 *)MAP_RONLY_SRAM; - Memory.Map[7]=(uint8 *)MAP_RONLY_SRAM; - Memory.Map[0x306]=(uint8 *)MAP_RONLY_SRAM; - Memory.Map[0x307]=(uint8 *)MAP_RONLY_SRAM; - } + if (newstate & 0x80) + { + Memory.Map[6] = (uint8*)MAP_HIROM_SRAM; + Memory.Map[7] = (uint8*)MAP_HIROM_SRAM; + Memory.Map[0x306] = (uint8*)MAP_HIROM_SRAM; + Memory.Map[0x307] = (uint8*)MAP_HIROM_SRAM; + + + } + else + { + Memory.Map[6] = (uint8*)MAP_RONLY_SRAM; + Memory.Map[7] = (uint8*)MAP_RONLY_SRAM; + Memory.Map[0x306] = (uint8*)MAP_RONLY_SRAM; + Memory.Map[0x307] = (uint8*)MAP_RONLY_SRAM; + } } -const char *TVStandard () +const char* TVStandard() { - return (Settings.PAL ? "PAL" : "NTSC"); + return (Settings.PAL ? "PAL" : "NTSC"); } -const char *Speed () +const char* Speed() { - return (Memory.ROMSpeed & 0x10 ? "120ns" : "200ns"); + return (Memory.ROMSpeed & 0x10 ? "120ns" : "200ns"); } -const char *MapType () +const char* MapType() { - return (Memory.HiROM ? "HiROM" : "LoROM"); + return (Memory.HiROM ? "HiROM" : "LoROM"); } -const char *StaticRAMSize () +const char* StaticRAMSize() { - static char tmp [20]; - - if (Memory.SRAMSize > 16) - return ("Corrupt"); - sprintf (tmp, "%dKB", (Memory.SRAMMask + 1) / 1024); - return (tmp); + static char tmp [20]; + + if (Memory.SRAMSize > 16) + return ("Corrupt"); + sprintf(tmp, "%dKB", (Memory.SRAMMask + 1) / 1024); + return (tmp); } -const char *Size () +const char* Size() { - static char tmp [20]; - - if (Memory.ROMSize < 7 || Memory.ROMSize - 7 > 23) - return ("Corrupt"); - sprintf (tmp, "%dMbits", 1 << (Memory.ROMSize - 7)); - return (tmp); + static char tmp [20]; + + if (Memory.ROMSize < 7 || Memory.ROMSize - 7 > 23) + return ("Corrupt"); + sprintf(tmp, "%dMbits", 1 << (Memory.ROMSize - 7)); + return (tmp); } -const char *KartContents () +const char* KartContents() { - static char tmp [30]; - static const char *CoPro [16] = { - "DSP1", "SuperFX", "OBC1", "SA-1", "S-DD1", "S-RTC", "CoPro#6", - "CoPro#7", "CoPro#8", "CoPro#9", "CoPro#10", "CoPro#11", "CoPro#12", - "CoPro#13", "CoPro#14", "CoPro-Custom" - }; - static const char *Contents [3] = { - "ROM", "ROM+RAM", "ROM+RAM+BAT" - }; - if (Memory.ROMType == 0&&!Settings.BS) - return ("ROM only"); - - sprintf (tmp, "%s", Contents [(Memory.ROMType & 0xf) % 3]); - - - if(Settings.BS) - sprintf (tmp, "%s+%s", tmp, "BSX"); - else if(Settings.SPC7110&&Settings.SPC7110RTC) - sprintf (tmp, "%s+%s", tmp, "SPC7110+RTC"); - else if(Settings.SPC7110) - sprintf (tmp, "%s+%s", tmp, "SPC7110"); - else if(Settings.SETA!=0) - { - switch(Settings.SETA) - { - case ST_010: - sprintf (tmp, "%s+%s", tmp, "ST-010"); - break; - case ST_011: - sprintf (tmp, "%s+%s", tmp, "ST-011"); - break; - - case ST_018: - sprintf (tmp, "%s+%s", tmp, "ST-018"); - break; - - } - } - else if ((Memory.ROMType & 0xf) >= 3) - sprintf (tmp, "%s+%s", tmp, CoPro [(Memory.ROMType & 0xf0) >> 4]); - - return (tmp); + static char tmp [30]; + static const char* CoPro [16] = + { + "DSP1", "SuperFX", "OBC1", "SA-1", "S-DD1", "S-RTC", "CoPro#6", + "CoPro#7", "CoPro#8", "CoPro#9", "CoPro#10", "CoPro#11", "CoPro#12", + "CoPro#13", "CoPro#14", "CoPro-Custom" + }; + static const char* Contents [3] = + { + "ROM", "ROM+RAM", "ROM+RAM+BAT" + }; + if (Memory.ROMType == 0 && !Settings.BS) + return ("ROM only"); + + sprintf(tmp, "%s", Contents [(Memory.ROMType & 0xf) % 3]); + + + if (Settings.BS) + sprintf(tmp, "%s+%s", tmp, "BSX"); + else if (Settings.SPC7110 && Settings.SPC7110RTC) + sprintf(tmp, "%s+%s", tmp, "SPC7110+RTC"); + else if (Settings.SPC7110) + sprintf(tmp, "%s+%s", tmp, "SPC7110"); + else if (Settings.SETA != 0) + { + switch (Settings.SETA) + { + case ST_010: + sprintf(tmp, "%s+%s", tmp, "ST-010"); + break; + case ST_011: + sprintf(tmp, "%s+%s", tmp, "ST-011"); + break; + + case ST_018: + sprintf(tmp, "%s+%s", tmp, "ST-018"); + break; + + } + } + else if ((Memory.ROMType & 0xf) >= 3) + sprintf(tmp, "%s+%s", tmp, CoPro [(Memory.ROMType & 0xf0) >> 4]); + + return (tmp); } -const char *MapMode () +const char* MapMode() { - static char tmp [4]; - sprintf (tmp, "%02x", Memory.ROMSpeed & ~0x10); - return (tmp); + static char tmp [4]; + sprintf(tmp, "%02x", Memory.ROMSpeed & ~0x10); + return (tmp); } -const char *ROMID () +const char* ROMID() { - return (Memory.ROMId); + return (Memory.ROMId); } -void ApplyROMFixes () +void ApplyROMFixes() { #ifdef __W32_HEAP - if(_HEAPOK!=_heapchk()) + if (_HEAPOK != _heapchk()) MessageBox(GUI.hWnd, "ApplyROMFixes", "Heap Corrupt", MB_OK); #endif - //don't steal my work! -MK - if(Memory.ROMCRC32 == 0x1B4A5616 && strncmp(Memory.ROMName, "RUDORA NO HIHOU", 15)==0) - { + //don't steal my work! -MK + if (Memory.ROMCRC32 == 0x1B4A5616 + && strncmp(Memory.ROMName, "RUDORA NO HIHOU", 15) == 0) + { strncpy(Memory.ROMName, "THIS SCRIPT WAS STOLEN", 22); - Settings.DisplayColor=BUILD_PIXEL(31,0,0); - SET_UI_COLOR(255,0,0); - } - - /* - HACKS NSRT can fix that we hadn't detected before. -[14:25:13] <@Nach> case 0x0c572ef0: //So called Hook (US)(2648) -[14:25:13] <@Nach> case 0x6810aa95: //Bazooka Blitzkreig swapped sizes hack -handled -[14:25:17] <@Nach> case 0x61E29C06: //The Tick region hack -[14:25:19] <@Nach> case 0x1EF90F74: //Jikkyou Keiba Simulation Stable Star PAL hack -[14:25:23] <@Nach> case 0x4ab225b5: //So called Krusty's Super Fun House (E) -[14:25:25] <@Nach> case 0x77fd806a: //Donkey Kong Country 2 (E) v1.1 bad dump -handled -[14:25:27] <@Nach> case 0x340f23e5: //Donkey Kong Country 3 (U) copier hack - handled - */ - - if(Memory.ROMCRC32==0x6810aa95 || Memory.ROMCRC32==0x340f23e5 || Memory.ROMCRC32==0x77fd806a || - strncmp (Memory.ROMName, "HIGHWAY BATTLE 2", 16)==0 || - (strcmp (Memory.ROMName, "FX SKIING NINTENDO 96") == 0 && Memory.ROM[0x7FDA]==0)) - { - Settings.DisplayColor=BUILD_PIXEL(31,0,0); - SET_UI_COLOR(255,0,0); - } - - //Ambiguous chip function pointer assignments - - //DSP switching: - if(strncmp(Memory.ROMName, "DUNGEON MASTER", 14)==0) - { - //Set DSP-2 - SetDSP=&DSP2SetByte; - GetDSP=&DSP2GetByte; - } + Settings.DisplayColor = BUILD_PIXEL(31, 0, 0); + SET_UI_COLOR(255, 0, 0); + } + + /* + HACKS NSRT can fix that we hadn't detected before. + [14:25:13] <@Nach> case 0x0c572ef0: //So called Hook (US)(2648) + [14:25:13] <@Nach> case 0x6810aa95: //Bazooka Blitzkreig swapped sizes hack -handled + [14:25:17] <@Nach> case 0x61E29C06: //The Tick region hack + [14:25:19] <@Nach> case 0x1EF90F74: //Jikkyou Keiba Simulation Stable Star PAL hack + [14:25:23] <@Nach> case 0x4ab225b5: //So called Krusty's Super Fun House (E) + [14:25:25] <@Nach> case 0x77fd806a: //Donkey Kong Country 2 (E) v1.1 bad dump -handled + [14:25:27] <@Nach> case 0x340f23e5: //Donkey Kong Country 3 (U) copier hack - handled + */ + + if (Memory.ROMCRC32 == 0x6810aa95 || Memory.ROMCRC32 == 0x340f23e5 + || Memory.ROMCRC32 == 0x77fd806a || + strncmp(Memory.ROMName, "HIGHWAY BATTLE 2", 16) == 0 || + (strcmp(Memory.ROMName, "FX SKIING NINTENDO 96") == 0 + && Memory.ROM[0x7FDA] == 0)) + { + Settings.DisplayColor = BUILD_PIXEL(31, 0, 0); + SET_UI_COLOR(255, 0, 0); + } + + //Ambiguous chip function pointer assignments + + //DSP switching: + if (strncmp(Memory.ROMName, "DUNGEON MASTER", 14) == 0) + { + //Set DSP-2 + SetDSP = &DSP2SetByte; + GetDSP = &DSP2GetByte; + } #ifdef DSP_DUMMY_LOOPS - if(strncmp(ROMName, "SD\x0b6\x0de\x0dd\x0c0\x0de\x0d1GX", 10)==0) - { - //Set DSP-3 - SetDSP=&DSP3SetByte; - GetDSP=&DSP3GetByte; - } + if (strncmp(ROMName, "SD\x0b6\x0de\x0dd\x0c0\x0de\x0d1GX", 10) == 0) + { + //Set DSP-3 + SetDSP = &DSP3SetByte; + GetDSP = &DSP3GetByte; + } #endif - if(strncmp(Memory.ROMName, "TOP GEAR 3000", 13)==0 - ||strncmp(Memory.ROMName, "PLANETS CHAMP TG3000", 20)==0) - { - //Set DSP-4 - SetDSP=&DSP4SetByte; - GetDSP=&DSP4GetByte; - } - - //memory map corrections - if(strncmp(Memory.ROMName, "XBAND",5)==0) - { + if (strncmp(Memory.ROMName, "TOP GEAR 3000", 13) == 0 + || strncmp(Memory.ROMName, "PLANETS CHAMP TG3000", 20) == 0) + { + //Set DSP-4 + SetDSP = &DSP4SetByte; + GetDSP = &DSP4GetByte; + } + + //memory map corrections + if (strncmp(Memory.ROMName, "XBAND", 5) == 0) + { int c; - for (c=0xE00;c<0xE10;c++) - { - Memory.Map [c] = (uint8 *) MAP_LOROM_SRAM; + for (c = 0xE00; c < 0xE10; c++) + { + Memory.Map [c] = (uint8*) MAP_LOROM_SRAM; Memory.BlockIsRAM [c] = TRUE; Memory.BlockIsROM [c] = FALSE; - } - WriteProtectROM (); - } + } + WriteProtectROM(); + } - //not MAD-1 compliant - if(strcmp (Memory.ROMName, "WANDERERS FROM YS") == 0) - { + //not MAD-1 compliant + if (strcmp(Memory.ROMName, "WANDERERS FROM YS") == 0) + { int c; - for(c=0;c<0xE0;c++) - { - Memory.Map[c+0x700]=(uint8*)MAP_LOROM_SRAM; - Memory.BlockIsROM[c+0x700]=FALSE; - Memory.BlockIsRAM[c+0x700]=TRUE; - } - WriteProtectROM(); - } - - if (strcmp (Memory.ROMName, "GOGO ACKMAN3") == 0 || - strcmp (Memory.ROMName, "HOME ALONE") == 0) - { - // Banks 00->3f and 80->bf + for (c = 0; c < 0xE0; c++) + { + Memory.Map[c + 0x700] = (uint8*)MAP_LOROM_SRAM; + Memory.BlockIsROM[c + 0x700] = FALSE; + Memory.BlockIsRAM[c + 0x700] = TRUE; + } + WriteProtectROM(); + } + + if (strcmp(Memory.ROMName, "GOGO ACKMAN3") == 0 || + strcmp(Memory.ROMName, "HOME ALONE") == 0) + { + // Banks 00->3f and 80->bf int c; for (c = 0; c < 0x400; c += 16) - { + { Memory.Map [c + 6] = Memory.Map [c + 0x806] = Memory.SRAM; Memory.Map [c + 7] = Memory.Map [c + 0x807] = Memory.SRAM; Memory.BlockIsROM [c + 6] = Memory.BlockIsROM [c + 0x806] = FALSE; Memory.BlockIsROM [c + 7] = Memory.BlockIsROM [c + 0x807] = FALSE; Memory.BlockIsRAM [c + 6] = Memory.BlockIsRAM [c + 0x806] = TRUE; Memory.BlockIsRAM [c + 7] = Memory.BlockIsRAM [c + 0x807] = TRUE; - } - WriteProtectROM (); - } - - if (strcmp (Memory.ROMName, "RADICAL DREAMERS") == 0 || - strcmp (Memory.ROMName, "TREASURE CONFLIX") == 0) - { - int c; - - for (c = 0; c < 0x80; c++) - { + } + WriteProtectROM(); + } + + if (strcmp(Memory.ROMName, "RADICAL DREAMERS") == 0 || + strcmp(Memory.ROMName, "TREASURE CONFLIX") == 0) + { + int c; + + for (c = 0; c < 0x80; c++) + { Memory.Map [c + 0x700] = Memory.ROM + 0x200000 + 0x1000 * (c & 0xf0); Memory.BlockIsRAM [c + 0x700] = TRUE; Memory.BlockIsROM [c + 0x700] = FALSE; - } - for (c = 0; c < 0x400; c += 16) - { + } + for (c = 0; c < 0x400; c += 16) + { Memory.Map [c + 5] = Memory.Map [c + 0x805] = Memory.ROM + 0x300000; Memory.BlockIsRAM [c + 5] = Memory.BlockIsRAM [c + 0x805] = TRUE; - } - WriteProtectROM (); - } + } + WriteProtectROM(); + } - if(strncmp(Memory.ROMName, "WAR 2410", 8)==0) - { - Memory.Map [0x005] = (uint8 *) Memory.RAM; + if (strncmp(Memory.ROMName, "WAR 2410", 8) == 0) + { + Memory.Map [0x005] = (uint8*) Memory.RAM; Memory.BlockIsRAM [0x005] = TRUE; Memory.BlockIsROM [0x005] = FALSE; - } - - if (strcmp (Memory.ROMName, "BATMAN--REVENGE JOKER") == 0) - { - Memory.HiROM = FALSE; - Memory.LoROM = TRUE; - LoROMMap (); - } - - - //NMI hacks - CPU.NMITriggerPoint = 4; - if (strcmp (Memory.ROMName, "CACOMA KNIGHT") == 0) - CPU.NMITriggerPoint = 25; - - //Disabling a speed-up - // Games which spool sound samples between the SNES and sound CPU using - // H-DMA as the sample is playing. - if (strcmp (Memory.ROMName, "EARTHWORM JIM 2") == 0 || - strcmp (Memory.ROMName, "PRIMAL RAGE") == 0 || - strcmp (Memory.ROMName, "CLAY FIGHTER") == 0 || - strcmp (Memory.ROMName, "ClayFighter 2") == 0 || - strncasecmp (Memory.ROMName, "MADDEN", 6) == 0 || - strncmp (Memory.ROMName, "NHL", 3) == 0 || - strcmp (Memory.ROMName, "WeaponLord") == 0|| - strncmp(Memory.ROMName, "WAR 2410", 8)==0) - { - Settings.Shutdown = FALSE; - } - - - //APU timing hacks - - // Stunt Racer FX - if (strcmp (Memory.ROMId, "CQ ") == 0 || - // Illusion of Gaia - strncmp (Memory.ROMId, "JG", 2) == 0 || - strcmp (Memory.ROMName, "GAIA GENSOUKI 1 JPN") == 0) - { - IAPU.OneCycle = 13; - } - - // RENDERING RANGER R2 - if (strcmp (Memory.ROMId, "AVCJ") == 0 || - //Mark Davis - strncmp(Memory.ROMName, "THE FISHING MASTER", 18)==0 || //needs >= actual APU timing. (21 is .002 Mhz slower) - // Star Ocean - strncmp (Memory.ROMId, "ARF", 3) == 0 || - // Tales of Phantasia - strncmp (Memory.ROMId, "ATV", 3) == 0 || - // Act Raiser 1 & 2 - strncasecmp (Memory.ROMName, "ActRaiser", 9) == 0 || - // Soulblazer - strcmp (Memory.ROMName, "SOULBLAZER - 1 USA") == 0 || - strcmp (Memory.ROMName, "SOULBLADER - 1") == 0 || - - // Terranigma - strncmp (Memory.ROMId, "AQT", 3) == 0 || - // Robotrek - strncmp (Memory.ROMId, "E9 ", 3) == 0 || - strcmp (Memory.ROMName, "SLAP STICK 1 JPN") == 0 || - // ZENNIHON PURORESU2 - strncmp (Memory.ROMId, "APR", 3) == 0 || - // Bomberman 4 - strncmp (Memory.ROMId, "A4B", 3) == 0 || - // UFO KAMEN YAKISOBAN - strncmp (Memory.ROMId, "Y7 ", 3) == 0 || - strncmp (Memory.ROMId, "Y9 ", 3) == 0 || - // Panic Bomber World - strncmp (Memory.ROMId, "APB", 3) == 0 || - ((strncmp (Memory.ROMName, "Parlor", 6) == 0 || - strcmp (Memory.ROMName, "HEIWA Parlor!Mini8") == 0 || - strncmp (Memory.ROMName, "SANKYO Fever! ̨°ÊÞ°!", 21) == 0) && - strcmp (Memory.CompanyId, "A0") == 0) || - strcmp (Memory.ROMName, "DARK KINGDOM") == 0 || - strcmp (Memory.ROMName, "ZAN3 SFC") == 0 || - strcmp (Memory.ROMName, "HIOUDEN") == 0 || - strcmp (Memory.ROMName, "ÃݼɳÀ") == 0 || //Tenshi no Uta - strcmp (Memory.ROMName, "FORTUNE QUEST") == 0 || - strcmp (Memory.ROMName, "FISHING TO BASSING") == 0 || - strncmp (Memory.ROMName, "TokyoDome '95Battle 7", 21) == 0 || - strcmp (Memory.ROMName, "OHMONO BLACKBASS") == 0 || - strncmp (Memory.ROMName, "SWORD WORLD SFC", 15) == 0 || - strcmp (Memory.ROMName, "MASTERS") ==0 || //Augusta 2 J - strcmp (Memory.ROMName, "SFC ¶ÒÝײÀÞ°") == 0 || //Kamen Rider - strncmp (Memory.ROMName, "LETs PACHINKO(", 14) == 0) //A set of BS games - { - IAPU.OneCycle = 15; - } - - - //Specific game fixes - - Settings.StarfoxHack = strcmp (Memory.ROMName, "STAR FOX") == 0 || - strcmp (Memory.ROMName, "STAR WING") == 0; - Settings.WinterGold = strcmp (Memory.ROMName, "FX SKIING NINTENDO 96") == 0 || - strcmp (Memory.ROMName, "DIRT RACER") == 0 || - Settings.StarfoxHack; - - - if((strcmp(Memory.ROMName, "LEGEND")==0&&!Settings.PAL)|| - strcmp(Memory.ROMName, "King Arthurs World")==0) - { - SNESGameFixes.EchoOnlyOutput=TRUE; - } - - - Settings.DaffyDuck = (strcmp (Memory.ROMName, "DAFFY DUCK: MARV MISS") == 0) || - (strcmp (Memory.ROMName, "ROBOCOP VS THE TERMIN") == 0) || - (strcmp (Memory.ROMName, "ROBOCOP VS TERMINATOR") == 0); //ROBOCOP VS THE TERMIN - Settings.HBlankStart = (256 * Settings.H_Max) / SNES_HCOUNTER_MAX; - - //OAM hacks because we don't fully understand the - //behavior of the SNES. - - //Totally wacky display... - //seems to need a disproven behavior, so - //we're definitely overlooking some other bug? - if(strncmp(Memory.ROMName, "UNIRACERS", 9)==0) - SNESGameFixes.Uniracers=true; - - - //is this even useful now? - if (strcmp (Memory.ROMName, "ALIENS vs. PREDATOR") == 0) - SNESGameFixes.alienVSpredetorFix = TRUE; - - if (strcmp (Memory.ROMName, "½°Ȩ̂߰нÀ") == 0 || //Super Famista - strcmp (Memory.ROMName, "½°Ȩ̂߰нÀ 2") == 0 || //Super Famista 2 - strcmp (Memory.ROMName, "ZENKI TENCHIMEIDOU") == 0 || - strcmp (Memory.ROMName, "GANBA LEAGUE") == 0) - { - SNESGameFixes.APU_OutPorts_ReturnValueFix = TRUE; - } - - if (strcmp (Memory.ROMName, "FURAI NO SIREN") == 0) - SNESGameFixes.SoundEnvelopeHeightReading2 = TRUE; - - //CPU timing hacks - Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * - Settings.CyclesPercentage) / 100; - - //no need to ifdef for right now... -//#ifdef HDMA_HACKS - - // A Couple of HDMA related hacks - Lantus - if ((strcmp(Memory.ROMName, "SFX SUPERBUTOUDEN2")==0) || - (strcmp(Memory.ROMName, "ALIEN vs. PREDATOR")==0) || - (strcmp(Memory.ROMName, "STONE PROTECTORS")==0) || - (strcmp(Memory.ROMName, "SUPER BATTLETANK 2")==0)) - Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 130) / 100; - - if(strcmp(Memory.ROMName, "HOME IMPROVEMENT")==0) - Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 200) / 100; - - // End HDMA hacks -//#endif - - - if (strcmp (Memory.ROMId, "ASRJ") == 0 && Settings.CyclesPercentage == 100) - // Street Racer - Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 95) / 100; - - // Power Rangers Fight - if (strncmp (Memory.ROMId, "A3R", 3) == 0 || - // Clock Tower - strncmp (Memory.ROMId, "AJE", 3) == 0) - Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 103) / 100; - - - if (strncmp (Memory.ROMId, "A3M", 3) == 0 && Settings.CyclesPercentage == 100) - // Mortal Kombat 3. Fixes cut off speech sample - Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 110) / 100; - - //Darkness Beyond Twilight - //Crimson beyond blood that flows - //buried in the stream of time - //is where your power grows - //I pledge myself to conquer - //all the foes who stand - //before the might gift betsowed - //in my unworthy hand - if (strcmp (Memory.ROMName, "\x0bd\x0da\x0b2\x0d4\x0b0\x0bd\x0de") == 0 && - Settings.CyclesPercentage == 100) - Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 101) / 100; + } + + if (strcmp(Memory.ROMName, "BATMAN--REVENGE JOKER") == 0) + { + Memory.HiROM = FALSE; + Memory.LoROM = TRUE; + LoROMMap(); + } + + + //NMI hacks + CPU.NMITriggerPoint = 4; + if (strcmp(Memory.ROMName, "CACOMA KNIGHT") == 0) + CPU.NMITriggerPoint = 25; + + //Disabling a speed-up + // Games which spool sound samples between the SNES and sound CPU using + // H-DMA as the sample is playing. + if (strcmp(Memory.ROMName, "EARTHWORM JIM 2") == 0 || + strcmp(Memory.ROMName, "PRIMAL RAGE") == 0 || + strcmp(Memory.ROMName, "CLAY FIGHTER") == 0 || + strcmp(Memory.ROMName, "ClayFighter 2") == 0 || + strncasecmp(Memory.ROMName, "MADDEN", 6) == 0 || + strncmp(Memory.ROMName, "NHL", 3) == 0 || + strcmp(Memory.ROMName, "WeaponLord") == 0 || + strncmp(Memory.ROMName, "WAR 2410", 8) == 0) + Settings.Shutdown = FALSE; + + + //APU timing hacks + + // Stunt Racer FX + if (strcmp(Memory.ROMId, "CQ ") == 0 || + // Illusion of Gaia + strncmp(Memory.ROMId, "JG", 2) == 0 || + strcmp(Memory.ROMName, "GAIA GENSOUKI 1 JPN") == 0) + IAPU.OneCycle = 13; + + // RENDERING RANGER R2 + if (strcmp(Memory.ROMId, "AVCJ") == 0 || + //Mark Davis + strncmp(Memory.ROMName, "THE FISHING MASTER", 18) == 0 + || //needs >= actual APU timing. (21 is .002 Mhz slower) + // Star Ocean + strncmp(Memory.ROMId, "ARF", 3) == 0 || + // Tales of Phantasia + strncmp(Memory.ROMId, "ATV", 3) == 0 || + // Act Raiser 1 & 2 + strncasecmp(Memory.ROMName, "ActRaiser", 9) == 0 || + // Soulblazer + strcmp(Memory.ROMName, "SOULBLAZER - 1 USA") == 0 || + strcmp(Memory.ROMName, "SOULBLADER - 1") == 0 || + + // Terranigma + strncmp(Memory.ROMId, "AQT", 3) == 0 || + // Robotrek + strncmp(Memory.ROMId, "E9 ", 3) == 0 || + strcmp(Memory.ROMName, "SLAP STICK 1 JPN") == 0 || + // ZENNIHON PURORESU2 + strncmp(Memory.ROMId, "APR", 3) == 0 || + // Bomberman 4 + strncmp(Memory.ROMId, "A4B", 3) == 0 || + // UFO KAMEN YAKISOBAN + strncmp(Memory.ROMId, "Y7 ", 3) == 0 || + strncmp(Memory.ROMId, "Y9 ", 3) == 0 || + // Panic Bomber World + strncmp(Memory.ROMId, "APB", 3) == 0 || + ((strncmp(Memory.ROMName, "Parlor", 6) == 0 || + strcmp(Memory.ROMName, "HEIWA Parlor!Mini8") == 0 || + strncmp(Memory.ROMName, "SANKYO Fever! ̨��ް!", 21) == 0) && + strcmp(Memory.CompanyId, "A0") == 0) || + strcmp(Memory.ROMName, "DARK KINGDOM") == 0 || + strcmp(Memory.ROMName, "ZAN3 SFC") == 0 || + strcmp(Memory.ROMName, "HIOUDEN") == 0 || + strcmp(Memory.ROMName, "�ݼɳ�") == 0 || //Tenshi no Uta + strcmp(Memory.ROMName, "FORTUNE QUEST") == 0 || + strcmp(Memory.ROMName, "FISHING TO BASSING") == 0 || + strncmp(Memory.ROMName, "TokyoDome '95Battle 7", 21) == 0 || + strcmp(Memory.ROMName, "OHMONO BLACKBASS") == 0 || + strncmp(Memory.ROMName, "SWORD WORLD SFC", 15) == 0 || + strcmp(Memory.ROMName, "MASTERS") == 0 || //Augusta 2 J + strcmp(Memory.ROMName, "SFC ���ײ�ް") == 0 + || //Kamen Rider + strncmp(Memory.ROMName, "LETs PACHINKO(", 14) == 0) //A set of BS games + IAPU.OneCycle = 15; + + + //Specific game fixes + + Settings.StarfoxHack = strcmp(Memory.ROMName, "STAR FOX") == 0 || + strcmp(Memory.ROMName, "STAR WING") == 0; + Settings.WinterGold = strcmp(Memory.ROMName, "FX SKIING NINTENDO 96") == 0 || + strcmp(Memory.ROMName, "DIRT RACER") == 0 || + Settings.StarfoxHack; + + + if ((strcmp(Memory.ROMName, "LEGEND") == 0 && !Settings.PAL) || + strcmp(Memory.ROMName, "King Arthurs World") == 0) + SNESGameFixes.EchoOnlyOutput = TRUE; + + + Settings.DaffyDuck = (strcmp(Memory.ROMName, "DAFFY DUCK: MARV MISS") == 0) || + (strcmp(Memory.ROMName, "ROBOCOP VS THE TERMIN") == 0) || + (strcmp(Memory.ROMName, "ROBOCOP VS TERMINATOR") == 0); //ROBOCOP VS THE TERMIN + Settings.HBlankStart = (256 * Settings.H_Max) / SNES_HCOUNTER_MAX; + + //OAM hacks because we don't fully understand the + //behavior of the SNES. + + //Totally wacky display... + //seems to need a disproven behavior, so + //we're definitely overlooking some other bug? + if (strncmp(Memory.ROMName, "UNIRACERS", 9) == 0) + SNESGameFixes.Uniracers = true; + + + //is this even useful now? + if (strcmp(Memory.ROMName, "ALIENS vs. PREDATOR") == 0) + SNESGameFixes.alienVSpredetorFix = TRUE; + + if (strcmp(Memory.ROMName, "���̧߰н�") == 0 + || //Super Famista + strcmp(Memory.ROMName, "���̧߰н� 2") == 0 + || //Super Famista 2 + strcmp(Memory.ROMName, "ZENKI TENCHIMEIDOU") == 0 || + strcmp(Memory.ROMName, "GANBA LEAGUE") == 0) + SNESGameFixes.APU_OutPorts_ReturnValueFix = TRUE; + + if (strcmp(Memory.ROMName, "FURAI NO SIREN") == 0) + SNESGameFixes.SoundEnvelopeHeightReading2 = TRUE; + + //CPU timing hacks + Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * + Settings.CyclesPercentage) / 100; + + //no need to ifdef for right now... + //#ifdef HDMA_HACKS + + // A Couple of HDMA related hacks - Lantus + if ((strcmp(Memory.ROMName, "SFX SUPERBUTOUDEN2") == 0) || + (strcmp(Memory.ROMName, "ALIEN vs. PREDATOR") == 0) || + (strcmp(Memory.ROMName, "STONE PROTECTORS") == 0) || + (strcmp(Memory.ROMName, "SUPER BATTLETANK 2") == 0)) + Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 130) / 100; + + if (strcmp(Memory.ROMName, "HOME IMPROVEMENT") == 0) + Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 200) / 100; + + // End HDMA hacks + //#endif + + + if (strcmp(Memory.ROMId, "ASRJ") == 0 && Settings.CyclesPercentage == 100) + // Street Racer + Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 95) / 100; + + // Power Rangers Fight + if (strncmp(Memory.ROMId, "A3R", 3) == 0 || + // Clock Tower + strncmp(Memory.ROMId, "AJE", 3) == 0) + Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 103) / 100; + + + if (strncmp(Memory.ROMId, "A3M", 3) == 0 && Settings.CyclesPercentage == 100) + // Mortal Kombat 3. Fixes cut off speech sample + Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 110) / 100; + + //Darkness Beyond Twilight + //Crimson beyond blood that flows + //buried in the stream of time + //is where your power grows + //I pledge myself to conquer + //all the foes who stand + //before the might gift betsowed + //in my unworthy hand + if (strcmp(Memory.ROMName, "\x0bd\x0da\x0b2\x0d4\x0b0\x0bd\x0de") == 0 && + Settings.CyclesPercentage == 100) + Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 101) / 100; #ifdef DETECT_NASTY_FX_INTERLEAVE -//XXX: Test without these. Win32 port indicates they aren't needed? -//Apparently are needed! - if (strcmp (Memory.ROMName, "WILD TRAX") == 0 || - strcmp (Memory.ROMName, "STAR FOX 2") == 0 || - strcmp (Memory.ROMName, "YOSSY'S ISLAND") == 0 || - strcmp (Memory.ROMName, "YOSHI'S ISLAND") == 0) - CPU.TriedInterleavedMode2 = TRUE; + //XXX: Test without these. Win32 port indicates they aren't needed? + //Apparently are needed! + if (strcmp(Memory.ROMName, "WILD TRAX") == 0 || + strcmp(Memory.ROMName, "STAR FOX 2") == 0 || + strcmp(Memory.ROMName, "YOSSY'S ISLAND") == 0 || + strcmp(Memory.ROMName, "YOSHI'S ISLAND") == 0) + CPU.TriedInterleavedMode2 = TRUE; #endif - // Start Trek: Deep Sleep 9 - if (strncmp (Memory.ROMId, "A9D", 3) == 0 && Settings.CyclesPercentage == 100) - Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 110) / 100; + // Start Trek: Deep Sleep 9 + if (strncmp(Memory.ROMId, "A9D", 3) == 0 && Settings.CyclesPercentage == 100) + Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 110) / 100; + + //SA-1 Speedup settings + SA1.WaitAddress = NULL; + SA1.WaitByteAddress1 = NULL; + SA1.WaitByteAddress2 = NULL; - //SA-1 Speedup settings - SA1.WaitAddress = NULL; - SA1.WaitByteAddress1 = NULL; - SA1.WaitByteAddress2 = NULL; - - /* Bass Fishing */ - if (strcmp (Memory.ROMId, "ZBPJ") == 0) - { - SA1.WaitAddress = SA1.Map [0x0093f1 >> MEMMAP_SHIFT] + 0x93f1; + /* Bass Fishing */ + if (strcmp(Memory.ROMId, "ZBPJ") == 0) + { + SA1.WaitAddress = SA1.Map [0x0093f1 >> MEMMAP_SHIFT] + 0x93f1; SA1.WaitByteAddress1 = Memory.FillRAM + 0x304a; - } - /* DAISENRYAKU EXPERTWW2 */ - if (strcmp (Memory.ROMId, "AEVJ") == 0) - { - SA1.WaitAddress = SA1.Map [0x0ed18d >> MEMMAP_SHIFT] + 0xd18d; + } + /* DAISENRYAKU EXPERTWW2 */ + if (strcmp(Memory.ROMId, "AEVJ") == 0) + { + SA1.WaitAddress = SA1.Map [0x0ed18d >> MEMMAP_SHIFT] + 0xd18d; SA1.WaitByteAddress1 = Memory.FillRAM + 0x3000; - } - /* debjk2 */ - if (strcmp (Memory.ROMId, "A2DJ") == 0) - { - SA1.WaitAddress = SA1.Map [0x008b62 >> MEMMAP_SHIFT] + 0x8b62; - } - /* Dragon Ballz HD */ - if (strcmp (Memory.ROMId, "AZIJ") == 0) - { - SA1.WaitAddress = SA1.Map [0x008083 >> MEMMAP_SHIFT] + 0x8083; + } + /* debjk2 */ + if (strcmp(Memory.ROMId, "A2DJ") == 0) + SA1.WaitAddress = SA1.Map [0x008b62 >> MEMMAP_SHIFT] + 0x8b62; + /* Dragon Ballz HD */ + if (strcmp(Memory.ROMId, "AZIJ") == 0) + { + SA1.WaitAddress = SA1.Map [0x008083 >> MEMMAP_SHIFT] + 0x8083; SA1.WaitByteAddress1 = Memory.FillRAM + 0x3020; - } - /* SFC SDGUNDAMGNEXT */ - if (strcmp (Memory.ROMId, "ZX3J") == 0) - { - SA1.WaitAddress = SA1.Map [0x0087f2 >> MEMMAP_SHIFT] + 0x87f2; + } + /* SFC SDGUNDAMGNEXT */ + if (strcmp(Memory.ROMId, "ZX3J") == 0) + { + SA1.WaitAddress = SA1.Map [0x0087f2 >> MEMMAP_SHIFT] + 0x87f2; SA1.WaitByteAddress1 = Memory.FillRAM + 0x30c4; - } - /* ShougiNoHanamichi */ - if (strcmp (Memory.ROMId, "AARJ") == 0) - { - SA1.WaitAddress = SA1.Map [0xc1f85a >> MEMMAP_SHIFT] + 0xf85a; + } + /* ShougiNoHanamichi */ + if (strcmp(Memory.ROMId, "AARJ") == 0) + { + SA1.WaitAddress = SA1.Map [0xc1f85a >> MEMMAP_SHIFT] + 0xf85a; SA1.WaitByteAddress1 = Memory.SRAM + 0x0c64; SA1.WaitByteAddress2 = Memory.SRAM + 0x0c66; - } - /* KATO HIFUMI9DAN SYOGI */ - if (strcmp (Memory.ROMId, "A23J") == 0) - { - SA1.WaitAddress = SA1.Map [0xc25037 >> MEMMAP_SHIFT] + 0x5037; + } + /* KATO HIFUMI9DAN SYOGI */ + if (strcmp(Memory.ROMId, "A23J") == 0) + { + SA1.WaitAddress = SA1.Map [0xc25037 >> MEMMAP_SHIFT] + 0x5037; SA1.WaitByteAddress1 = Memory.SRAM + 0x0c06; SA1.WaitByteAddress2 = Memory.SRAM + 0x0c08; - } - /* idaten */ - if (strcmp (Memory.ROMId, "AIIJ") == 0) - { - SA1.WaitAddress = SA1.Map [0xc100be >> MEMMAP_SHIFT] + 0x00be; + } + /* idaten */ + if (strcmp(Memory.ROMId, "AIIJ") == 0) + { + SA1.WaitAddress = SA1.Map [0xc100be >> MEMMAP_SHIFT] + 0x00be; SA1.WaitByteAddress1 = Memory.SRAM + 0x1002; SA1.WaitByteAddress2 = Memory.SRAM + 0x1004; - } - /* igotais */ - if (strcmp (Memory.ROMId, "AITJ") == 0) - { - SA1.WaitAddress = SA1.Map [0x0080b7 >> MEMMAP_SHIFT] + 0x80b7; - } - /* J96 DREAM STADIUM */ - if (strcmp (Memory.ROMId, "AJ6J") == 0) - { - SA1.WaitAddress = SA1.Map [0xc0f74a >> MEMMAP_SHIFT] + 0xf74a; - } - /* JumpinDerby */ - if (strcmp (Memory.ROMId, "AJUJ") == 0) - { - SA1.WaitAddress = SA1.Map [0x00d926 >> MEMMAP_SHIFT] + 0xd926; - } - /* JKAKINOKI SHOUGI */ - if (strcmp (Memory.ROMId, "AKAJ") == 0) - { - SA1.WaitAddress = SA1.Map [0x00f070 >> MEMMAP_SHIFT] + 0xf070; - } - /* HOSHI NO KIRBY 3 & KIRBY'S DREAM LAND 3 JAP & US */ - if (strcmp (Memory.ROMId, "AFJJ") == 0 || strcmp (Memory.ROMId, "AFJE") == 0) - { - SA1.WaitAddress = SA1.Map [0x0082d4 >> MEMMAP_SHIFT] + 0x82d4; + } + /* igotais */ + if (strcmp(Memory.ROMId, "AITJ") == 0) + SA1.WaitAddress = SA1.Map [0x0080b7 >> MEMMAP_SHIFT] + 0x80b7; + /* J96 DREAM STADIUM */ + if (strcmp(Memory.ROMId, "AJ6J") == 0) + SA1.WaitAddress = SA1.Map [0xc0f74a >> MEMMAP_SHIFT] + 0xf74a; + /* JumpinDerby */ + if (strcmp(Memory.ROMId, "AJUJ") == 0) + SA1.WaitAddress = SA1.Map [0x00d926 >> MEMMAP_SHIFT] + 0xd926; + /* JKAKINOKI SHOUGI */ + if (strcmp(Memory.ROMId, "AKAJ") == 0) + SA1.WaitAddress = SA1.Map [0x00f070 >> MEMMAP_SHIFT] + 0xf070; + /* HOSHI NO KIRBY 3 & KIRBY'S DREAM LAND 3 JAP & US */ + if (strcmp(Memory.ROMId, "AFJJ") == 0 || strcmp(Memory.ROMId, "AFJE") == 0) + { + SA1.WaitAddress = SA1.Map [0x0082d4 >> MEMMAP_SHIFT] + 0x82d4; SA1.WaitByteAddress1 = Memory.SRAM + 0x72a4; - } - /* KIRBY SUPER DELUXE JAP */ - if (strcmp (Memory.ROMId, "AKFJ") == 0) - { - SA1.WaitAddress = SA1.Map [0x008c93 >> MEMMAP_SHIFT] + 0x8c93; + } + /* KIRBY SUPER DELUXE JAP */ + if (strcmp(Memory.ROMId, "AKFJ") == 0) + { + SA1.WaitAddress = SA1.Map [0x008c93 >> MEMMAP_SHIFT] + 0x8c93; SA1.WaitByteAddress1 = Memory.FillRAM + 0x300a; SA1.WaitByteAddress2 = Memory.FillRAM + 0x300e; - } - /* KIRBY SUPER DELUXE US */ - if (strcmp (Memory.ROMId, "AKFE") == 0) - { - SA1.WaitAddress = SA1.Map [0x008cb8 >> MEMMAP_SHIFT] + 0x8cb8; + } + /* KIRBY SUPER DELUXE US */ + if (strcmp(Memory.ROMId, "AKFE") == 0) + { + SA1.WaitAddress = SA1.Map [0x008cb8 >> MEMMAP_SHIFT] + 0x8cb8; SA1.WaitByteAddress1 = Memory.FillRAM + 0x300a; SA1.WaitByteAddress2 = Memory.FillRAM + 0x300e; - } - /* SUPER MARIO RPG JAP & US */ - if (strcmp (Memory.ROMId, "ARWJ") == 0 || strcmp (Memory.ROMId, "ARWE") == 0) - { - SA1.WaitAddress = SA1.Map [0xc0816f >> MEMMAP_SHIFT] + 0x816f; + } + /* SUPER MARIO RPG JAP & US */ + if (strcmp(Memory.ROMId, "ARWJ") == 0 || strcmp(Memory.ROMId, "ARWE") == 0) + { + SA1.WaitAddress = SA1.Map [0xc0816f >> MEMMAP_SHIFT] + 0x816f; SA1.WaitByteAddress1 = Memory.FillRAM + 0x3000; - } - /* marvelous.zip */ - if (strcmp (Memory.ROMId, "AVRJ") == 0) - { - SA1.WaitAddress = SA1.Map [0x0085f2 >> MEMMAP_SHIFT] + 0x85f2; + } + /* marvelous.zip */ + if (strcmp(Memory.ROMId, "AVRJ") == 0) + { + SA1.WaitAddress = SA1.Map [0x0085f2 >> MEMMAP_SHIFT] + 0x85f2; SA1.WaitByteAddress1 = Memory.FillRAM + 0x3024; - } - /* AUGUSTA3 MASTERS NEW */ - if (strcmp (Memory.ROMId, "AO3J") == 0) - { - SA1.WaitAddress = SA1.Map [0x00dddb >> MEMMAP_SHIFT] + 0xdddb; + } + /* AUGUSTA3 MASTERS NEW */ + if (strcmp(Memory.ROMId, "AO3J") == 0) + { + SA1.WaitAddress = SA1.Map [0x00dddb >> MEMMAP_SHIFT] + 0xdddb; SA1.WaitByteAddress1 = Memory.FillRAM + 0x37b4; - } - /* OSHABERI PARODIUS */ - if (strcmp (Memory.ROMId, "AJOJ") == 0) - { - SA1.WaitAddress = SA1.Map [0x8084e5 >> MEMMAP_SHIFT] + 0x84e5; - } - /* PANIC BOMBER WORLD */ - if (strcmp (Memory.ROMId, "APBJ") == 0) - { - SA1.WaitAddress = SA1.Map [0x00857a >> MEMMAP_SHIFT] + 0x857a; - } - /* PEBBLE BEACH NEW */ - if (strcmp (Memory.ROMId, "AONJ") == 0) - { - SA1.WaitAddress = SA1.Map [0x00df33 >> MEMMAP_SHIFT] + 0xdf33; + } + /* OSHABERI PARODIUS */ + if (strcmp(Memory.ROMId, "AJOJ") == 0) + SA1.WaitAddress = SA1.Map [0x8084e5 >> MEMMAP_SHIFT] + 0x84e5; + /* PANIC BOMBER WORLD */ + if (strcmp(Memory.ROMId, "APBJ") == 0) + SA1.WaitAddress = SA1.Map [0x00857a >> MEMMAP_SHIFT] + 0x857a; + /* PEBBLE BEACH NEW */ + if (strcmp(Memory.ROMId, "AONJ") == 0) + { + SA1.WaitAddress = SA1.Map [0x00df33 >> MEMMAP_SHIFT] + 0xdf33; SA1.WaitByteAddress1 = Memory.FillRAM + 0x37b4; - } - /* PGA EUROPEAN TOUR */ - if (strcmp (Memory.ROMId, "AEPE") == 0) - { - SA1.WaitAddress = SA1.Map [0x003700 >> MEMMAP_SHIFT] + 0x3700; + } + /* PGA EUROPEAN TOUR */ + if (strcmp(Memory.ROMId, "AEPE") == 0) + { + SA1.WaitAddress = SA1.Map [0x003700 >> MEMMAP_SHIFT] + 0x3700; SA1.WaitByteAddress1 = Memory.FillRAM + 0x3102; - } - /* PGA TOUR 96 */ - if (strcmp (Memory.ROMId, "A3GE") == 0) - { - SA1.WaitAddress = SA1.Map [0x003700 >> MEMMAP_SHIFT] + 0x3700; + } + /* PGA TOUR 96 */ + if (strcmp(Memory.ROMId, "A3GE") == 0) + { + SA1.WaitAddress = SA1.Map [0x003700 >> MEMMAP_SHIFT] + 0x3700; SA1.WaitByteAddress1 = Memory.FillRAM + 0x3102; - } - /* POWER RANGERS 4 */ - if (strcmp (Memory.ROMId, "A4RE") == 0) - { - SA1.WaitAddress = SA1.Map [0x009899 >> MEMMAP_SHIFT] + 0x9899; + } + /* POWER RANGERS 4 */ + if (strcmp(Memory.ROMId, "A4RE") == 0) + { + SA1.WaitAddress = SA1.Map [0x009899 >> MEMMAP_SHIFT] + 0x9899; SA1.WaitByteAddress1 = Memory.FillRAM + 0x3000; - } - /* PACHISURO PALUSUPE */ - if (strcmp (Memory.ROMId, "AGFJ") == 0) - { - // Never seems to turn on the SA-1! - } - /* SD F1 GRAND PRIX */ - if (strcmp (Memory.ROMId, "AGFJ") == 0) - { - SA1.WaitAddress = SA1.Map [0x0181bc >> MEMMAP_SHIFT] + 0x81bc; - } - /* SHOUGI MARJONG */ - if (strcmp (Memory.ROMId, "ASYJ") == 0) - { - SA1.WaitAddress = SA1.Map [0x00f2cc >> MEMMAP_SHIFT] + 0xf2cc; + } + /* PACHISURO PALUSUPE */ + if (strcmp(Memory.ROMId, "AGFJ") == 0) + { + // Never seems to turn on the SA-1! + } + /* SD F1 GRAND PRIX */ + if (strcmp(Memory.ROMId, "AGFJ") == 0) + SA1.WaitAddress = SA1.Map [0x0181bc >> MEMMAP_SHIFT] + 0x81bc; + /* SHOUGI MARJONG */ + if (strcmp(Memory.ROMId, "ASYJ") == 0) + { + SA1.WaitAddress = SA1.Map [0x00f2cc >> MEMMAP_SHIFT] + 0xf2cc; SA1.WaitByteAddress1 = Memory.SRAM + 0x7ffe; SA1.WaitByteAddress2 = Memory.SRAM + 0x7ffc; - } - /* shogisai2 */ - if (strcmp (Memory.ROMId, "AX2J") == 0) - { - SA1.WaitAddress = SA1.Map [0x00d675 >> MEMMAP_SHIFT] + 0xd675; - } - - /* SHINING SCORPION */ - if (strcmp (Memory.ROMId, "A4WJ") == 0) - { - SA1.WaitAddress = SA1.Map [0xc048be >> MEMMAP_SHIFT] + 0x48be; - } - /* SHIN SHOUGI CLUB */ - if (strcmp (Memory.ROMId, "AHJJ") == 0) - { - SA1.WaitAddress = SA1.Map [0xc1002a >> MEMMAP_SHIFT] + 0x002a; + } + /* shogisai2 */ + if (strcmp(Memory.ROMId, "AX2J") == 0) + SA1.WaitAddress = SA1.Map [0x00d675 >> MEMMAP_SHIFT] + 0xd675; + + /* SHINING SCORPION */ + if (strcmp(Memory.ROMId, "A4WJ") == 0) + SA1.WaitAddress = SA1.Map [0xc048be >> MEMMAP_SHIFT] + 0x48be; + /* SHIN SHOUGI CLUB */ + if (strcmp(Memory.ROMId, "AHJJ") == 0) + { + SA1.WaitAddress = SA1.Map [0xc1002a >> MEMMAP_SHIFT] + 0x002a; SA1.WaitByteAddress1 = Memory.SRAM + 0x0806; SA1.WaitByteAddress2 = Memory.SRAM + 0x0808; - } - - - //Other - - // Additional game fixes by sanmaiwashi ... - if (strcmp (Memory.ROMName, "SFX ŲĶÞÝÀÞÑÓɶÞÀØ 1") == 0) //Gundam Knight Story - { - bytes0x2000 [0xb18] = 0x4c; - bytes0x2000 [0xb19] = 0x4b; - bytes0x2000 [0xb1a] = 0xea; - SNESGameFixes.SRAMInitialValue = 0x6b; - } - - - // HITOMI3 - if (strcmp (Memory.ROMName, "HITOMI3") == 0) - { - Memory.SRAMSize = 1; + } + + + //Other + + // Additional game fixes by sanmaiwashi ... + if (strcmp(Memory.ROMName, + "SFX ŲĶ������ɶ��� 1") == + 0) //Gundam Knight Story + { + bytes0x2000 [0xb18] = 0x4c; + bytes0x2000 [0xb19] = 0x4b; + bytes0x2000 [0xb1a] = 0xea; + SNESGameFixes.SRAMInitialValue = 0x6b; + } + + + // HITOMI3 + if (strcmp(Memory.ROMName, "HITOMI3") == 0) + { + Memory.SRAMSize = 1; Memory.SRAMMask = Memory.SRAMSize ? - ((1 << (Memory.SRAMSize + 3)) * 128) - 1 : 0; - } + ((1 << (Memory.SRAMSize + 3)) * 128) - 1 : 0; + } - //sram value fixes - if (strcmp (Memory.ROMName, "SUPER DRIFT OUT") == 0 || - strcmp(Memory.ROMName, "SATAN IS OUR FATHER!") == 0 || - strcmp (Memory.ROMName, "goemon 4") == 0) - SNESGameFixes.SRAMInitialValue = 0x00; + //sram value fixes + if (strcmp(Memory.ROMName, "SUPER DRIFT OUT") == 0 || + strcmp(Memory.ROMName, "SATAN IS OUR FATHER!") == 0 || + strcmp(Memory.ROMName, "goemon 4") == 0) + SNESGameFixes.SRAMInitialValue = 0x00; #if 0 - if(strcmp (Memory.ROMName, "XBAND JAPANESE MODEM") == 0) - { - for (c = 0x200; c < 0x400; c += 16) - { - for (int i = c; i < c + 16; i++) - { + if (strcmp(Memory.ROMName, "XBAND JAPANESE MODEM") == 0) + { + for (c = 0x200; c < 0x400; c += 16) + { + for (int i = c; i < c + 16; i++) + { Memory.Map [i + 0x400] = Memory.Map [i + 0xc00] = &ROM[c * 0x1000]; Memory.BlockIsRAM [i + 0x400] = Memory.BlockIsRAM [i + 0xc00] = TRUE; - BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = FALSE; - } - } - WriteProtectROM (); - } + BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = FALSE; + } + } + WriteProtectROM(); + } #endif - + #define RomPatch(adr,ov,nv) \ if (Memory.ROM [adr] == ov) \ Memory.ROM [adr] = nv - - - // Love Quest - if (strcmp (Memory.ROMName, "LOVE QUEST") == 0) - { - RomPatch (0x1385ec, 0xd0, 0xea); - RomPatch (0x1385ed, 0xb2, 0xea); - } - //BNE D0 into nops - - //seems like the next instruction is a BRA - //otherwise, this one's too complex for MKendora - // Nangoku Syonen Papuwa Kun - if (strcmp (Memory.ROMName, "NANGOKUSYONEN PAPUWA") == 0) - RomPatch (0x1f0d1, 0xa0, 0x6b); - //turns an LDY into an RTL? - - //this is a cmp on $00:2140 - // Super Batter Up - if (strcmp (Memory.ROMName, "Super Batter Up") == 0) - { - RomPatch (0x27ae0, 0xd0, 0xea); - RomPatch (0x27ae1, 0xfa, 0xea); - } - //BNE + + + // Love Quest + if (strcmp(Memory.ROMName, "LOVE QUEST") == 0) + { + RomPatch(0x1385ec, 0xd0, 0xea); + RomPatch(0x1385ed, 0xb2, 0xea); + } + //BNE D0 into nops + + //seems like the next instruction is a BRA + //otherwise, this one's too complex for MKendora + // Nangoku Syonen Papuwa Kun + if (strcmp(Memory.ROMName, "NANGOKUSYONEN PAPUWA") == 0) + RomPatch(0x1f0d1, 0xa0, 0x6b); + //turns an LDY into an RTL? + + //this is a cmp on $00:2140 + // Super Batter Up + if (strcmp(Memory.ROMName, "Super Batter Up") == 0) + { + RomPatch(0x27ae0, 0xd0, 0xea); + RomPatch(0x27ae1, 0xfa, 0xea); + } + //BNE } // Read variable size MSB int from a file -static long ReadInt (FILE *f, unsigned nbytes) +static long ReadInt(FILE* f, unsigned nbytes) { - long v = 0; - while (nbytes--) - { - int c = fgetc(f); - if (c == EOF) - return -1; - v = (v << 8) | (c & 0xFF); - } - return (v); + long v = 0; + while (nbytes--) + { + int c = fgetc(f); + if (c == EOF) + return -1; + v = (v << 8) | (c & 0xFF); + } + return (v); } #define IPS_EOF 0x00454F46l -void CheckForIPSPatch (const char *rom_filename, bool8 header, - int32* rom_size) +void CheckForIPSPatch(const char* rom_filename, bool8 header, + int32* rom_size) { - char dir [_MAX_DIR + 1]; - char drive [_MAX_DRIVE + 1]; - char name [_MAX_FNAME + 1]; - char ext [_MAX_EXT + 1]; - char fname [_MAX_PATH + 1]; - FILE *patch_file = NULL; - long offset = header ? 512 : 0; - - _splitpath (rom_filename, drive, dir, name, ext); - _makepath (fname, drive, dir, name, "ips"); - - if (!(patch_file = fopen (fname, "rb"))) - { - if (!(patch_file = fopen (S9xGetFilename (".ips"), "rb"))) - return; - } - - if (fread ((unsigned char*)fname, 1, 5, patch_file) != 5 || - strncmp (fname, "PATCH", 5) != 0) - { - fclose (patch_file); - return; - } - - int32 ofs; - - for (;;) - { - long len; - long rlen; - int rchar; - - ofs = ReadInt (patch_file, 3); - if (ofs == -1) - goto err_eof; - - if (ofs == IPS_EOF) - break; - - ofs -= offset; - - len = ReadInt (patch_file, 2); - if (len == -1) - goto err_eof; - - /* Apply patch block */ - if (len) - { - if (ofs + len > MAX_ROM_SIZE) - goto err_eof; - - while (len--) - { - rchar = fgetc (patch_file); - if (rchar == EOF) - goto err_eof; + char dir [_MAX_DIR + 1]; + char drive [_MAX_DRIVE + 1]; + char name [_MAX_FNAME + 1]; + char ext [_MAX_EXT + 1]; + char fname [_MAX_PATH + 1]; + FILE* patch_file = NULL; + long offset = header ? 512 : 0; + + _splitpath(rom_filename, drive, dir, name, ext); + _makepath(fname, drive, dir, name, "ips"); + + if (!(patch_file = fopen(fname, "rb"))) + { + if (!(patch_file = fopen(S9xGetFilename(".ips"), "rb"))) + return; + } + + if (fread((unsigned char*)fname, 1, 5, patch_file) != 5 || + strncmp(fname, "PATCH", 5) != 0) + { + fclose(patch_file); + return; + } + + int32 ofs; + + for (;;) + { + long len; + long rlen; + int rchar; + + ofs = ReadInt(patch_file, 3); + if (ofs == -1) + goto err_eof; + + if (ofs == IPS_EOF) + break; + + ofs -= offset; + + len = ReadInt(patch_file, 2); + if (len == -1) + goto err_eof; + + /* Apply patch block */ + if (len) + { + if (ofs + len > MAX_ROM_SIZE) + goto err_eof; + + while (len--) + { + rchar = fgetc(patch_file); + if (rchar == EOF) + goto err_eof; Memory.ROM [ofs++] = (uint8) rchar; - } + } if (ofs > *rom_size) *rom_size = ofs; - } - else - { - rlen = ReadInt (patch_file, 2); - if (rlen == -1) - goto err_eof; - - rchar = fgetc (patch_file); - if (rchar == EOF) - goto err_eof; - - if (ofs + rlen > MAX_ROM_SIZE) - goto err_eof; - - while (rlen--) + } + else + { + rlen = ReadInt(patch_file, 2); + if (rlen == -1) + goto err_eof; + + rchar = fgetc(patch_file); + if (rchar == EOF) + goto err_eof; + + if (ofs + rlen > MAX_ROM_SIZE) + goto err_eof; + + while (rlen--) Memory.ROM [ofs++] = (uint8) rchar; - + if (ofs > *rom_size) *rom_size = ofs; - } - } - - // Check if ROM image needs to be truncated - ofs = ReadInt (patch_file, 3); - if (ofs != -1 && ofs - offset < *rom_size) - { - // Need to truncate ROM image + } + } + + // Check if ROM image needs to be truncated + ofs = ReadInt(patch_file, 3); + if (ofs != -1 && ofs - offset < *rom_size) + { + // Need to truncate ROM image *rom_size = ofs - offset; - } - fclose (patch_file); - return; - + } + fclose(patch_file); + return; + err_eof: - if (patch_file) - fclose (patch_file); + if (patch_file) + fclose(patch_file); } -int is_bsx(unsigned char *p) +int is_bsx(unsigned char* p) { - unsigned c; - - if ( p[0x19] & 0x4f ) - goto notbsx; - c = p[0x1a]; - if ( (c != 0x33) && (c != 0xff) ) // 0x33 = Manufacturer: Nintendo - goto notbsx; - c = (p[0x17] << 8) | p[0x16]; - if ( (c != 0x0000) && (c != 0xffff) ) - { - if ( (c & 0x040f) != 0 ) - goto notbsx; - if ( (c & 0xff) > 0xc0 ) - goto notbsx; - } - c = p[0x18]; - if ( (c & 0xce) || ((c & 0x30)==0) ) - goto notbsx; - if ( (p[0x15] & 0x03) != 0 ) - goto notbsx; - c = p[0x13]; - if ( (c != 0x00) && (c != 0xff) ) - goto notbsx; - if ( p[0x14] != 0x00 ) - goto notbsx; - if ( bs_name(p) != 0 ) - goto notbsx; - return 0; // It's a Satellaview ROM! + unsigned c; + + if (p[0x19] & 0x4f) + goto notbsx; + c = p[0x1a]; + if ((c != 0x33) && (c != 0xff)) // 0x33 = Manufacturer: Nintendo + goto notbsx; + c = (p[0x17] << 8) | p[0x16]; + if ((c != 0x0000) && (c != 0xffff)) + { + if ((c & 0x040f) != 0) + goto notbsx; + if ((c & 0xff) > 0xc0) + goto notbsx; + } + c = p[0x18]; + if ((c & 0xce) || ((c & 0x30) == 0)) + goto notbsx; + if ((p[0x15] & 0x03) != 0) + goto notbsx; + c = p[0x13]; + if ((c != 0x00) && (c != 0xff)) + goto notbsx; + if (p[0x14] != 0x00) + goto notbsx; + if (bs_name(p) != 0) + goto notbsx; + return 0; // It's a Satellaview ROM! notbsx: - return -1; + return -1; } -int bs_name(unsigned char *p) +int bs_name(unsigned char* p) { - unsigned c; - int lcount; - int numv; // number of valid name characters seen so far - numv = 0; - for ( lcount = 16; lcount > 0; lcount-- ) - { - if ( check_char( c = *p++ ) != 0 ) - { - c = *p++; - if ( c < 0x20 ) - { - if ( (numv != 0x0b) || (c != 0) ) // Dr. Mario Hack - goto notBsName; - } - - numv++; - lcount--; - continue; - } - else - { - if ( c == 0 ) - { - if ( numv == 0 ) - goto notBsName; - continue; - } - - if ( c < 0x20 ) - goto notBsName; - if ( c >= 0x80 ) - { - if ( (c < 0xa0) || ( c >= 0xf0 ) ) - goto notBsName; - } - numv++; - } - } - if ( numv > 0 ) - return 0; + unsigned c; + int lcount; + int numv; // number of valid name characters seen so far + numv = 0; + for (lcount = 16; lcount > 0; lcount--) + { + if (check_char(c = *p++) != 0) + { + c = *p++; + if (c < 0x20) + { + if ((numv != 0x0b) || (c != 0)) // Dr. Mario Hack + goto notBsName; + } + + numv++; + lcount--; + continue; + } + else + { + if (c == 0) + { + if (numv == 0) + goto notBsName; + continue; + } + + if (c < 0x20) + goto notBsName; + if (c >= 0x80) + { + if ((c < 0xa0) || (c >= 0xf0)) + goto notBsName; + } + numv++; + } + } + if (numv > 0) + return 0; notBsName: - return -1; + return -1; } int check_char(unsigned c) { - if ( ( c & 0x80 ) == 0 ) - return 0; - if ( ( c - 0x20 ) & 0x40 ) - return 1; - else - return 0; + if ((c & 0x80) == 0) + return 0; + if ((c - 0x20) & 0x40) + return 1; + else + return 0; } void ParseSNESHeader(uint8* RomHeader) { - Memory.SRAMSize = RomHeader [0x28]; - strncpy (Memory.ROMName, (char *) &RomHeader[0x10], ROM_NAME_LEN - 1); - Memory.ROMSpeed = RomHeader [0x25]; - Memory.ROMType = RomHeader [0x26]; - Memory.ROMSize = RomHeader [0x27]; - Memory.ROMChecksum = RomHeader [0x2e] + (RomHeader [0x2f] << 8); - Memory.ROMComplementChecksum = RomHeader [0x2c] + (RomHeader [0x2d] << 8); - Memory.ROMRegion= RomHeader[0x29]; - // memmove converted: Different mallocs [Neb] - memcpy (Memory.ROMId, &RomHeader [0x2], 4); - if(RomHeader[0x2A]==0x33) - // memmove converted: Different mallocs [Neb] - memcpy (Memory.CompanyId, &RomHeader [0], 2); - else sprintf(Memory.CompanyId, "%02X", RomHeader[0x2A]); + Memory.SRAMSize = RomHeader [0x28]; + strncpy(Memory.ROMName, (char*) &RomHeader[0x10], ROM_NAME_LEN - 1); + Memory.ROMSpeed = RomHeader [0x25]; + Memory.ROMType = RomHeader [0x26]; + Memory.ROMSize = RomHeader [0x27]; + Memory.ROMChecksum = RomHeader [0x2e] + (RomHeader [0x2f] << 8); + Memory.ROMComplementChecksum = RomHeader [0x2c] + (RomHeader [0x2d] << 8); + Memory.ROMRegion = RomHeader[0x29]; + // memmove converted: Different mallocs [Neb] + memcpy(Memory.ROMId, &RomHeader [0x2], 4); + if (RomHeader[0x2A] == 0x33) + // memmove converted: Different mallocs [Neb] + memcpy(Memory.CompanyId, &RomHeader [0], 2); + else sprintf(Memory.CompanyId, "%02X", RomHeader[0x2A]); } #undef INLINE diff --git a/source/memmap.h b/source/memmap.h index 2d83852..3304095 100644 --- a/source/memmap.h +++ b/source/memmap.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -105,11 +105,11 @@ #else #define READ_WORD(s) ( *(uint8 *) (s) |\ - (*((uint8 *) (s) + 1) << 8)) + (*((uint8 *) (s) + 1) << 8)) #define READ_DWORD(s) ( *(uint8 *) (s) |\ - (*((uint8 *) (s) + 1) << 8) |\ - (*((uint8 *) (s) + 2) << 16) |\ - (*((uint8 *) (s) + 3) << 24)) + (*((uint8 *) (s) + 1) << 8) |\ + (*((uint8 *) (s) + 2) << 16) |\ + (*((uint8 *) (s) + 3) << 24)) #define WRITE_WORD(s, d) *(uint8 *) (s) = (d), \ *((uint8 *) (s) + 1) = (d) >> 8 #define WRITE_DWORD(s, d) *(uint8 *) (s) = (uint8) (d), \ @@ -137,132 +137,133 @@ #define BIGFIRST 2 #define SMALLFIRST 3 -bool8 LoadROM (const char *); -uint32 FileLoader (uint8* buffer, const char* filename, int32 maxsize); -void InitROM (bool8); -bool8 LoadSRAM (const char *); -bool8 SaveSRAM (const char *); -bool8 Init (); -void Deinit (); -void FreeSDD1Data (); - -void WriteProtectROM (); -void FixROMSpeed (); -void MapRAM (); -void MapExtraRAM (); -char *Safe (const char *); +bool8 LoadROM(const char*); +uint32 FileLoader(uint8* buffer, const char* filename, int32 maxsize); +void InitROM(bool8); +bool8 LoadSRAM(const char*); +bool8 SaveSRAM(const char*); +bool8 Init(); +void Deinit(); +void FreeSDD1Data(); + +void WriteProtectROM(); +void FixROMSpeed(); +void MapRAM(); +void MapExtraRAM(); +char* Safe(const char*); void BSLoROMMap(); -void JumboLoROMMap (bool8); -void LoROMMap (); -void LoROM24MBSMap (); -void SRAM512KLoROMMap (); +void JumboLoROMMap(bool8); +void LoROMMap(); +void LoROM24MBSMap(); +void SRAM512KLoROMMap(); // void SRAM1024KLoROMMap (); -void SufamiTurboLoROMMap (); -void HiROMMap (); -void SuperFXROMMap (); -void TalesROMMap (bool8); -void AlphaROMMap (); -void SA1ROMMap (); -void BSHiROMMap (); +void SufamiTurboLoROMMap(); +void HiROMMap(); +void SuperFXROMMap(); +void TalesROMMap(bool8); +void AlphaROMMap(); +void SA1ROMMap(); +void BSHiROMMap(); void SPC7110HiROMMap(); void SPC7110Sram(uint8); void SetaDSPMap(); -bool8 AllASCII (uint8 *b, int size); -int ScoreHiROM (bool8 skip_header, int32 offset); -int ScoreLoROM (bool8 skip_header, int32 offset); +bool8 AllASCII(uint8* b, int size); +int ScoreHiROM(bool8 skip_header, int32 offset); +int ScoreLoROM(bool8 skip_header, int32 offset); #if 0 void SufamiTurboAltROMMap(); #endif -void ApplyROMFixes (); -void CheckForIPSPatch (const char *rom_filename, bool8 header, - int32* rom_size); - -const char *TVStandard (); -const char *Speed (); -const char *StaticRAMSize (); -const char *MapType (); -const char *MapMode (); -const char *KartContents (); -const char *Size (); -const char *Headers (); -const char *ROMID (); -const char *CompanyID (); +void ApplyROMFixes(); +void CheckForIPSPatch(const char* rom_filename, bool8 header, + int32* rom_size); + +const char* TVStandard(); +const char* Speed(); +const char* StaticRAMSize(); +const char* MapType(); +const char* MapMode(); +const char* KartContents(); +const char* Size(); +const char* Headers(); +const char* ROMID(); +const char* CompanyID(); void ParseSNESHeader(uint8*); -enum { -MAP_PPU, MAP_CPU, MAP_DSP, MAP_LOROM_SRAM, MAP_HIROM_SRAM, -MAP_NONE, MAP_DEBUG, MAP_C4, MAP_BWRAM, MAP_BWRAM_BITMAP, -MAP_BWRAM_BITMAP2, MAP_SA1RAM, MAP_SPC7110_ROM, MAP_SPC7110_DRAM, -MAP_RONLY_SRAM, MAP_OBC_RAM, MAP_SETA_DSP, MAP_SETA_RISC, MAP_LAST +enum +{ + MAP_PPU, MAP_CPU, MAP_DSP, MAP_LOROM_SRAM, MAP_HIROM_SRAM, + MAP_NONE, MAP_DEBUG, MAP_C4, MAP_BWRAM, MAP_BWRAM_BITMAP, + MAP_BWRAM_BITMAP2, MAP_SA1RAM, MAP_SPC7110_ROM, MAP_SPC7110_DRAM, + MAP_RONLY_SRAM, MAP_OBC_RAM, MAP_SETA_DSP, MAP_SETA_RISC, MAP_LAST }; enum { MAX_ROM_SIZE = 0x800000 }; typedef struct { - uint8 *RAM; - uint8 *ROM; - uint8 *VRAM; - uint8 *SRAM; - uint8 *BWRAM; - uint8 *FillRAM; - uint8 *C4RAM; - bool8 HiROM; - bool8 LoROM; - uint32 SRAMMask; - uint8 SRAMSize; - uint8 *Map [MEMMAP_NUM_BLOCKS]; - uint8 *WriteMap [MEMMAP_NUM_BLOCKS]; - uint8 MemorySpeed [MEMMAP_NUM_BLOCKS]; - uint8 BlockIsRAM [MEMMAP_NUM_BLOCKS]; - uint8 BlockIsROM [MEMMAP_NUM_BLOCKS]; - char ROMName [ROM_NAME_LEN]; - char ROMId [5]; - char CompanyId [3]; - uint8 ROMSpeed; - uint8 ROMType; - uint8 ROMSize; - int32 ROMFramesPerSecond; - int32 HeaderCount; - uint32 CalculatedSize; - uint32 CalculatedChecksum; - uint32 ROMChecksum; - uint32 ROMComplementChecksum; - uint8 *SDD1Index; - uint8 *SDD1Data; - uint32 SDD1Entries; - uint32 SDD1LoggedDataCountPrev; - uint32 SDD1LoggedDataCount; - uint8 SDD1LoggedData [MEMMAP_MAX_SDD1_LOGGED_ENTRIES]; - char ROMFilename [_MAX_PATH]; - uint8 ROMRegion; - uint32 ROMCRC32; - uint8 ExtendedFormat; - uint8 *BSRAM; + uint8* RAM; + uint8* ROM; + uint8* VRAM; + uint8* SRAM; + uint8* BWRAM; + uint8* FillRAM; + uint8* C4RAM; + bool8 HiROM; + bool8 LoROM; + uint32 SRAMMask; + uint8 SRAMSize; + uint8* Map [MEMMAP_NUM_BLOCKS]; + uint8* WriteMap [MEMMAP_NUM_BLOCKS]; + uint8 MemorySpeed [MEMMAP_NUM_BLOCKS]; + uint8 BlockIsRAM [MEMMAP_NUM_BLOCKS]; + uint8 BlockIsROM [MEMMAP_NUM_BLOCKS]; + char ROMName [ROM_NAME_LEN]; + char ROMId [5]; + char CompanyId [3]; + uint8 ROMSpeed; + uint8 ROMType; + uint8 ROMSize; + int32 ROMFramesPerSecond; + int32 HeaderCount; + uint32 CalculatedSize; + uint32 CalculatedChecksum; + uint32 ROMChecksum; + uint32 ROMComplementChecksum; + uint8* SDD1Index; + uint8* SDD1Data; + uint32 SDD1Entries; + uint32 SDD1LoggedDataCountPrev; + uint32 SDD1LoggedDataCount; + uint8 SDD1LoggedData [MEMMAP_MAX_SDD1_LOGGED_ENTRIES]; + char ROMFilename [_MAX_PATH]; + uint8 ROMRegion; + uint32 ROMCRC32; + uint8 ExtendedFormat; + uint8* BSRAM; #if 0 - bool8 LoadMulti (const char *,const char *,const char *); + bool8 LoadMulti(const char*, const char*, const char*); #endif -}CMemory; +} CMemory; void ResetSpeedMap(); extern CMemory Memory; -void S9xDeinterleaveMode2 (); +void S9xDeinterleaveMode2(); bool8 LoadZip(const char* zipname, - int32 *TotalFileSize, - int32 *headers, - uint8 *buffer); + int32* TotalFileSize, + int32* headers, + uint8* buffer); -void S9xAutoSaveSRAM (); +void S9xAutoSaveSRAM(); #ifdef NO_INLINE_SET_GET -uint8 S9xGetByte (uint32 Address); -uint16 S9xGetWord (uint32 Address); -void S9xSetByte (uint8 Byte, uint32 Address); -void S9xSetWord (uint16 Byte, uint32 Address); -void S9xSetPCBase (uint32 Address); -uint8 *S9xGetMemPointer (uint32 Address); -uint8 *GetBasePointer (uint32 Address); +uint8 S9xGetByte(uint32 Address); +uint16 S9xGetWord(uint32 Address); +void S9xSetByte(uint8 Byte, uint32 Address); +void S9xSetWord(uint16 Byte, uint32 Address); +void S9xSetPCBase(uint32 Address); +uint8* S9xGetMemPointer(uint32 Address); +uint8* GetBasePointer(uint32 Address); extern uint8 OpenBus; diff --git a/source/messages.h b/source/messages.h index 1f85576..39b9ff5 100644 --- a/source/messages.h +++ b/source/messages.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -91,46 +91,48 @@ #define _messages_h_ /* Types of message sent to S9xMessage routine */ -enum { - S9X_TRACE, - S9X_DEBUG, - S9X_WARNING, - S9X_INFO, - S9X_ERROR, - S9X_FATAL_ERROR +enum +{ + S9X_TRACE, + S9X_DEBUG, + S9X_WARNING, + S9X_INFO, + S9X_ERROR, + S9X_FATAL_ERROR }; /* Individual message numbers */ -enum { - S9X_ROM_INFO, - S9X_HEADERS_INFO, - S9X_ROM_CONFUSING_FORMAT_INFO, - S9X_ROM_INTERLEAVED_INFO, - S9X_SOUND_DEVICE_OPEN_FAILED, - S9X_APU_STOPPED, - S9X_USAGE, - S9X_GAME_GENIE_CODE_ERROR, - S9X_ACTION_REPLY_CODE_ERROR, - S9X_GOLD_FINGER_CODE_ERROR, - S9X_DEBUG_OUTPUT, - S9X_DMA_TRACE, - S9X_HDMA_TRACE, - S9X_WRONG_FORMAT, - S9X_WRONG_VERSION, - S9X_ROM_NOT_FOUND, - S9X_FREEZE_FILE_NOT_FOUND, - S9X_PPU_TRACE, - S9X_TRACE_DSP1, - S9X_FREEZE_ROM_NAME, - S9X_HEADER_WARNING, - S9X_NETPLAY_NOT_SERVER, - S9X_FREEZE_FILE_INFO, - S9X_TURBO_MODE, - S9X_SOUND_NOT_BUILT, - S9X_MOVIE_INFO, - S9X_WRONG_MOVIE_SNAPSHOT, - S9X_NOT_A_MOVIE_SNAPSHOT, - S9X_AVI_INFO +enum +{ + S9X_ROM_INFO, + S9X_HEADERS_INFO, + S9X_ROM_CONFUSING_FORMAT_INFO, + S9X_ROM_INTERLEAVED_INFO, + S9X_SOUND_DEVICE_OPEN_FAILED, + S9X_APU_STOPPED, + S9X_USAGE, + S9X_GAME_GENIE_CODE_ERROR, + S9X_ACTION_REPLY_CODE_ERROR, + S9X_GOLD_FINGER_CODE_ERROR, + S9X_DEBUG_OUTPUT, + S9X_DMA_TRACE, + S9X_HDMA_TRACE, + S9X_WRONG_FORMAT, + S9X_WRONG_VERSION, + S9X_ROM_NOT_FOUND, + S9X_FREEZE_FILE_NOT_FOUND, + S9X_PPU_TRACE, + S9X_TRACE_DSP1, + S9X_FREEZE_ROM_NAME, + S9X_HEADER_WARNING, + S9X_NETPLAY_NOT_SERVER, + S9X_FREEZE_FILE_INFO, + S9X_TURBO_MODE, + S9X_SOUND_NOT_BUILT, + S9X_MOVIE_INFO, + S9X_WRONG_MOVIE_SNAPSHOT, + S9X_NOT_A_MOVIE_SNAPSHOT, + S9X_AVI_INFO }; #endif diff --git a/source/missing.h b/source/missing.h index f3858b3..7762194 100644 --- a/source/missing.h +++ b/source/missing.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -92,71 +92,71 @@ struct HDMA { - uint8 used; - uint8 bbus_address; - uint8 abus_bank; - uint16 abus_address; - uint8 indirect_address; - uint8 force_table_address_write; - uint8 force_table_address_read; - uint8 line_count_write; - uint8 line_count_read; + uint8 used; + uint8 bbus_address; + uint8 abus_bank; + uint16 abus_address; + uint8 indirect_address; + uint8 force_table_address_write; + uint8 force_table_address_read; + uint8 line_count_write; + uint8 line_count_read; }; struct Missing { - uint8 emulate6502; - uint8 decimal_mode; - uint8 mv_8bit_index; - uint8 mv_8bit_acc; - uint8 interlace; - uint8 lines_239; - uint8 pseudo_512; - struct HDMA hdma [8]; - uint8 modes [8]; - uint8 mode7_fx; - uint8 mode7_flip; - uint8 mode7_bgmode; - uint8 direct; - uint8 matrix_multiply; - uint8 oam_read; - uint8 vram_read; - uint8 cgram_read; - uint8 wram_read; - uint8 dma_read; - uint8 vram_inc; - uint8 vram_full_graphic_inc; - uint8 virq; - uint8 hirq; - uint16 virq_pos; - uint16 hirq_pos; - uint8 h_v_latch; - uint8 h_counter_read; - uint8 v_counter_read; - uint8 fast_rom; - uint8 window1 [6]; - uint8 window2 [6]; - uint8 sprite_priority_rotation; - uint8 subscreen; - uint8 subscreen_add; - uint8 subscreen_sub; - uint8 fixed_colour_add; - uint8 fixed_colour_sub; - uint8 mosaic; - uint8 sprite_double_height; - uint8 dma_channels; - uint8 dma_this_frame; - uint8 oam_address_read; - uint8 bg_offset_read; - uint8 matrix_read; - uint8 hdma_channels; - uint8 hdma_this_frame; - uint16 unknownppu_read; - uint16 unknownppu_write; - uint16 unknowncpu_read; - uint16 unknowncpu_write; - uint16 unknowndsp_read; - uint16 unknowndsp_write; + uint8 emulate6502; + uint8 decimal_mode; + uint8 mv_8bit_index; + uint8 mv_8bit_acc; + uint8 interlace; + uint8 lines_239; + uint8 pseudo_512; + struct HDMA hdma [8]; + uint8 modes [8]; + uint8 mode7_fx; + uint8 mode7_flip; + uint8 mode7_bgmode; + uint8 direct; + uint8 matrix_multiply; + uint8 oam_read; + uint8 vram_read; + uint8 cgram_read; + uint8 wram_read; + uint8 dma_read; + uint8 vram_inc; + uint8 vram_full_graphic_inc; + uint8 virq; + uint8 hirq; + uint16 virq_pos; + uint16 hirq_pos; + uint8 h_v_latch; + uint8 h_counter_read; + uint8 v_counter_read; + uint8 fast_rom; + uint8 window1 [6]; + uint8 window2 [6]; + uint8 sprite_priority_rotation; + uint8 subscreen; + uint8 subscreen_add; + uint8 subscreen_sub; + uint8 fixed_colour_add; + uint8 fixed_colour_sub; + uint8 mosaic; + uint8 sprite_double_height; + uint8 dma_channels; + uint8 dma_this_frame; + uint8 oam_address_read; + uint8 bg_offset_read; + uint8 matrix_read; + uint8 hdma_channels; + uint8 hdma_this_frame; + uint16 unknownppu_read; + uint16 unknownppu_write; + uint16 unknowncpu_read; + uint16 unknowncpu_write; + uint16 unknowndsp_read; + uint16 unknowndsp_write; }; struct Missing missing; diff --git a/source/obc1.c b/source/obc1.c index 2761f77..1bc8db8 100644 --- a/source/obc1.c +++ b/source/obc1.c @@ -1,6 +1,6 @@ /**************************************************** Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -90,111 +90,113 @@ #include "memmap.h" #include "obc1.h" -static uint8 *OBC1_RAM = NULL; +static uint8* OBC1_RAM = NULL; int OBC1_Address; int OBC1_BasePtr; int OBC1_Shift; -uint8 GetOBC1 (uint16 Address) +uint8 GetOBC1(uint16 Address) { - switch(Address) { - case 0x7ff0: - return OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2)]; - - case 0x7ff1: - return OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2) + 1]; - - case 0x7ff2: - return OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2) + 2]; - - case 0x7ff3: - return OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2) + 3]; - - case 0x7ff4: - return OBC1_RAM[OBC1_BasePtr + (OBC1_Address >> 2) + 0x200]; - } - - return OBC1_RAM[Address & 0x1fff]; + switch (Address) + { + case 0x7ff0: + return OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2)]; + + case 0x7ff1: + return OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2) + 1]; + + case 0x7ff2: + return OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2) + 2]; + + case 0x7ff3: + return OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2) + 3]; + + case 0x7ff4: + return OBC1_RAM[OBC1_BasePtr + (OBC1_Address >> 2) + 0x200]; + } + + return OBC1_RAM[Address & 0x1fff]; } -void SetOBC1 (uint8 Byte, uint16 Address) +void SetOBC1(uint8 Byte, uint16 Address) { - switch(Address) { - case 0x7ff0: - { - OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2)] = Byte; - break; - } - - case 0x7ff1: - { - OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2) + 1] = Byte; - break; - } - - case 0x7ff2: - { - OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2) + 2] = Byte; - break; - } - - case 0x7ff3: - { - OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2) + 3] = Byte; - break; - } - - case 0x7ff4: - { - unsigned char Temp; - - Temp = OBC1_RAM[OBC1_BasePtr + (OBC1_Address >> 2) + 0x200]; - Temp = (Temp & ~(3 << OBC1_Shift)) | ((Byte & 3) << OBC1_Shift); - OBC1_RAM[OBC1_BasePtr + (OBC1_Address >> 2) + 0x200] = Temp; - break; - } - - case 0x7ff5: - { - if (Byte & 1) - OBC1_BasePtr = 0x1800; - else - OBC1_BasePtr = 0x1c00; - - OBC1_RAM[0x1ff5] = Byte; - break; - } - - case 0x7ff6: - { - OBC1_Address = Byte & 0x7f; - OBC1_Shift = (Byte & 3) << 1; - break; - } - - default: - OBC1_RAM[Address & 0x1fff] = Byte; - break; - } + switch (Address) + { + case 0x7ff0: + { + OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2)] = Byte; + break; + } + + case 0x7ff1: + { + OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2) + 1] = Byte; + break; + } + + case 0x7ff2: + { + OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2) + 2] = Byte; + break; + } + + case 0x7ff3: + { + OBC1_RAM[OBC1_BasePtr + (OBC1_Address << 2) + 3] = Byte; + break; + } + + case 0x7ff4: + { + unsigned char Temp; + + Temp = OBC1_RAM[OBC1_BasePtr + (OBC1_Address >> 2) + 0x200]; + Temp = (Temp & ~(3 << OBC1_Shift)) | ((Byte & 3) << OBC1_Shift); + OBC1_RAM[OBC1_BasePtr + (OBC1_Address >> 2) + 0x200] = Temp; + break; + } + + case 0x7ff5: + { + if (Byte & 1) + OBC1_BasePtr = 0x1800; + else + OBC1_BasePtr = 0x1c00; + + OBC1_RAM[0x1ff5] = Byte; + break; + } + + case 0x7ff6: + { + OBC1_Address = Byte & 0x7f; + OBC1_Shift = (Byte & 3) << 1; + break; + } + + default: + OBC1_RAM[Address & 0x1fff] = Byte; + break; + } } -uint8 *GetBasePointerOBC1(uint32 Address) +uint8* GetBasePointerOBC1(uint32 Address) { - return Memory.FillRAM; + return Memory.FillRAM; } -uint8 *GetMemPointerOBC1(uint32 Address) +uint8* GetMemPointerOBC1(uint32 Address) { - return (Memory.FillRAM + (Address & 0xffff)); + return (Memory.FillRAM + (Address & 0xffff)); } void ResetOBC1() { - OBC1_Address = 0; - OBC1_BasePtr = 0x1c00; - OBC1_Shift = 0; - OBC1_RAM = &Memory.FillRAM[0x6000]; + OBC1_Address = 0; + OBC1_BasePtr = 0x1c00; + OBC1_Shift = 0; + OBC1_RAM = &Memory.FillRAM[0x6000]; - memset(OBC1_RAM, 0x00, 0x2000); + memset(OBC1_RAM, 0x00, 0x2000); } diff --git a/source/obc1.h b/source/obc1.h index 706fa9e..b2ef338 100644 --- a/source/obc1.h +++ b/source/obc1.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -90,10 +90,10 @@ #ifndef _OBC1_H_ #define _OBC1_H_ -uint8 GetOBC1 (uint16 Address); -void SetOBC1 (uint8 Byte, uint16 Address); -uint8 *GetBasePointerOBC1(uint32 Address); -uint8 *GetMemPointerOBC1(uint32 Address); +uint8 GetOBC1(uint16 Address); +void SetOBC1(uint8 Byte, uint16 Address); +uint8* GetBasePointerOBC1(uint32 Address); +uint8* GetMemPointerOBC1(uint32 Address); void ResetOBC1();//bool8 full); #endif diff --git a/source/pixform.h b/source/pixform.h index b8f9faf..c58f89c 100644 --- a/source/pixform.h +++ b/source/pixform.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -96,9 +96,9 @@ #define DECOMPOSE_PIXEL_RGB565(PIX,R,G,B) {(R) = (PIX) >> 11; (G) = ((PIX) >> 6) & 0x1f; (B) = (PIX) & 0x1f; } #define SPARE_RGB_BIT_MASK_RGB565 (1 << 5) -#define MAX_RED_RGB565 31 -#define MAX_GREEN_RGB565 63 -#define MAX_BLUE_RGB565 31 +#define MAX_RED_RGB565 31 +#define MAX_GREEN_RGB565 63 +#define MAX_BLUE_RGB565 31 #define RED_LOW_BIT_MASK_RGB565 0x0800 #define GREEN_LOW_BIT_MASK_RGB565 0x0020 #define BLUE_LOW_BIT_MASK_RGB565 0x0001 @@ -108,7 +108,7 @@ #define FIRST_COLOR_MASK_RGB565 0xF800 #define SECOND_COLOR_MASK_RGB565 0x07E0 #define THIRD_COLOR_MASK_RGB565 0x001F -#define ALPHA_BITS_MASK_RGB565 0x0000 +#define ALPHA_BITS_MASK_RGB565 0x0000 /* RGB555 format */ #define BUILD_PIXEL_RGB555(R,G,B) (((int) (R) << 10) | ((int) (G) << 5) | (int) (B)) @@ -116,9 +116,9 @@ #define DECOMPOSE_PIXEL_RGB555(PIX,R,G,B) {(R) = (PIX) >> 10; (G) = ((PIX) >> 5) & 0x1f; (B) = (PIX) & 0x1f; } #define SPARE_RGB_BIT_MASK_RGB555 (1 << 15) -#define MAX_RED_RGB555 31 -#define MAX_GREEN_RGB555 31 -#define MAX_BLUE_RGB555 31 +#define MAX_RED_RGB555 31 +#define MAX_GREEN_RGB555 31 +#define MAX_BLUE_RGB555 31 #define RED_LOW_BIT_MASK_RGB555 0x0400 #define GREEN_LOW_BIT_MASK_RGB555 0x0020 #define BLUE_LOW_BIT_MASK_RGB555 0x0001 @@ -136,9 +136,9 @@ #define DECOMPOSE_PIXEL_BGR565(PIX,R,G,B) {(B) = (PIX) >> 11; (G) = ((PIX) >> 6) & 0x1f; (R) = (PIX) & 0x1f; } #define SPARE_RGB_BIT_MASK_BGR565 (1 << 5) -#define MAX_RED_BGR565 31 -#define MAX_GREEN_BGR565 63 -#define MAX_BLUE_BGR565 31 +#define MAX_RED_BGR565 31 +#define MAX_GREEN_BGR565 63 +#define MAX_BLUE_BGR565 31 #define RED_LOW_BIT_MASK_BGR565 0x0001 #define GREEN_LOW_BIT_MASK_BGR565 0x0040 #define BLUE_LOW_BIT_MASK_BGR565 0x0800 @@ -156,9 +156,9 @@ #define DECOMPOSE_PIXEL_BGR555(PIX,R,G,B) {(B) = (PIX) >> 10; (G) = ((PIX) >> 5) & 0x1f; (R) = (PIX) & 0x1f; } #define SPARE_RGB_BIT_MASK_BGR555 (1 << 15) -#define MAX_RED_BGR555 31 -#define MAX_GREEN_BGR555 31 -#define MAX_BLUE_BGR555 31 +#define MAX_RED_BGR555 31 +#define MAX_GREEN_BGR555 31 +#define MAX_BLUE_BGR555 31 #define RED_LOW_BIT_MASK_BGR555 0x0001 #define GREEN_LOW_BIT_MASK_BGR555 0x0020 #define BLUE_LOW_BIT_MASK_BGR555 0x0400 @@ -216,9 +216,9 @@ #define DECOMPOSE_PIXEL_RGB5551(PIX,R,G,B) {(R) = (PIX) >> 11; (G) = ((PIX) >> 6) & 0x1f; (B) = ((PIX) >> 1) & 0x1f; } #define SPARE_RGB_BIT_MASK_RGB5551 (1) -#define MAX_RED_RGB5551 31 -#define MAX_GREEN_RGB5551 31 -#define MAX_BLUE_RGB5551 31 +#define MAX_RED_RGB5551 31 +#define MAX_GREEN_RGB5551 31 +#define MAX_BLUE_RGB5551 31 #define RED_LOW_BIT_MASK_RGB5551 0x0800 #define GREEN_LOW_BIT_MASK_RGB5551 0x0040 #define BLUE_LOW_BIT_MASK_RGB5551 0x0002 @@ -243,27 +243,27 @@ #define BUILD_PIXEL2(R,G,B) BUILD_PIXEL2_D(PIXEL_FORMAT,R,G,B) #define DECOMPOSE_PIXEL(PIX,R,G,B) DECOMPOSE_PIXEL_D(PIXEL_FORMAT,PIX,R,G,B) -#define MAX_RED_D(F) CONCAT(MAX_RED_,F) -#define MAX_BLUE_D(F) CONCAT(MAX_BLUE_,F) -#define MAX_GREEN_D(F) CONCAT(MAX_GREEN_,F) -#define RED_LOW_BIT_MASK_D(F) CONCAT(RED_LOW_BIT_MASK_,F) -#define BLUE_LOW_BIT_MASK_D(F) CONCAT(BLUE_LOW_BIT_MASK_,F) -#define GREEN_LOW_BIT_MASK_D(F) CONCAT(GREEN_LOW_BIT_MASK_,F) -#define RED_HI_BIT_MASK_D(F) CONCAT(RED_HI_BIT_MASK_,F) -#define BLUE_HI_BIT_MASK_D(F) CONCAT(BLUE_HI_BIT_MASK_,F) -#define GREEN_HI_BIT_MASK_D(F) CONCAT(GREEN_HI_BIT_MASK_,F) +#define MAX_RED_D(F) CONCAT(MAX_RED_,F) +#define MAX_BLUE_D(F) CONCAT(MAX_BLUE_,F) +#define MAX_GREEN_D(F) CONCAT(MAX_GREEN_,F) +#define RED_LOW_BIT_MASK_D(F) CONCAT(RED_LOW_BIT_MASK_,F) +#define BLUE_LOW_BIT_MASK_D(F) CONCAT(BLUE_LOW_BIT_MASK_,F) +#define GREEN_LOW_BIT_MASK_D(F) CONCAT(GREEN_LOW_BIT_MASK_,F) +#define RED_HI_BIT_MASK_D(F) CONCAT(RED_HI_BIT_MASK_,F) +#define BLUE_HI_BIT_MASK_D(F) CONCAT(BLUE_HI_BIT_MASK_,F) +#define GREEN_HI_BIT_MASK_D(F) CONCAT(GREEN_HI_BIT_MASK_,F) #define FIRST_COLOR_MASK_D(F) CONCAT(FIRST_COLOR_MASK_,F) #define SECOND_COLOR_MASK_D(F) CONCAT(SECOND_COLOR_MASK_,F) #define THIRD_COLOR_MASK_D(F) CONCAT(THIRD_COLOR_MASK_,F) #define ALPHA_BITS_MASK_D(F) CONCAT(ALPHA_BITS_MASK_,F) -#define MAX_RED MAX_RED_D(PIXEL_FORMAT) -#define MAX_BLUE MAX_BLUE_D(PIXEL_FORMAT) -#define MAX_GREEN MAX_GREEN_D(PIXEL_FORMAT) -#define RED_LOW_BIT_MASK RED_LOW_BIT_MASK_D(PIXEL_FORMAT) +#define MAX_RED MAX_RED_D(PIXEL_FORMAT) +#define MAX_BLUE MAX_BLUE_D(PIXEL_FORMAT) +#define MAX_GREEN MAX_GREEN_D(PIXEL_FORMAT) +#define RED_LOW_BIT_MASK RED_LOW_BIT_MASK_D(PIXEL_FORMAT) #define BLUE_LOW_BIT_MASK BLUE_LOW_BIT_MASK_D(PIXEL_FORMAT) #define GREEN_LOW_BIT_MASK GREEN_LOW_BIT_MASK_D(PIXEL_FORMAT) -#define RED_HI_BIT_MASK RED_HI_BIT_MASK_D(PIXEL_FORMAT) +#define RED_HI_BIT_MASK RED_HI_BIT_MASK_D(PIXEL_FORMAT) #define BLUE_HI_BIT_MASK BLUE_HI_BIT_MASK_D(PIXEL_FORMAT) #define GREEN_HI_BIT_MASK GREEN_HI_BIT_MASK_D(PIXEL_FORMAT) #define FIRST_COLOR_MASK FIRST_COLOR_MASK_D(PIXEL_FORMAT) @@ -271,13 +271,13 @@ #define THIRD_COLOR_MASK THIRD_COLOR_MASK_D(PIXEL_FORMAT) #define ALPHA_BITS_MASK ALPHA_BITS_MASK_D(PIXEL_FORMAT) -#define GREEN_HI_BIT ((MAX_GREEN + 1) >> 1) +#define GREEN_HI_BIT ((MAX_GREEN + 1) >> 1) #define RGB_LOW_BITS_MASK (RED_LOW_BIT_MASK | GREEN_LOW_BIT_MASK | \ - BLUE_LOW_BIT_MASK) + BLUE_LOW_BIT_MASK) #define RGB_HI_BITS_MASK (RED_HI_BIT_MASK | GREEN_HI_BIT_MASK | \ - BLUE_HI_BIT_MASK) + BLUE_HI_BIT_MASK) #define RGB_HI_BITS_MASKx2 ((RED_HI_BIT_MASK | GREEN_HI_BIT_MASK | \ - BLUE_HI_BIT_MASK) << 1) + BLUE_HI_BIT_MASK) << 1) #define RGB_REMOVE_LOW_BITS_MASK (~RGB_LOW_BITS_MASK) #define FIRST_THIRD_COLOR_MASK (FIRST_COLOR_MASK | THIRD_COLOR_MASK) #define TWO_LOW_BITS_MASK (RGB_LOW_BITS_MASK | (RGB_LOW_BITS_MASK << 1)) diff --git a/source/port.h b/source/port.h index 2ddab20..2d33513 100644 --- a/source/port.h +++ b/source/port.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -135,8 +135,8 @@ #undef DEBUGGER /* Apple Universal Headers sometimes #define DEBUGGER */ -int strncasecmp(const char *s1, const char *s2, unsigned n); -int strcasecmp(const char *s1, const char *s2 ); +int strncasecmp(const char* s1, const char* s2, unsigned n); +int strcasecmp(const char* s1, const char* s2); #endif /* TARGET_OS_MAC */ @@ -214,16 +214,16 @@ typedef __int64 int64; #define ZeroMemory(a,b) memset((a),0,(b)) -void _makepath (char *path, const char *drive, const char *dir, - const char *fname, const char *ext); -void _splitpath (const char *path, char *drive, char *dir, char *fname, - char *ext); +void _makepath(char* path, const char* drive, const char* dir, + const char* fname, const char* ext); +void _splitpath(const char* path, char* drive, char* dir, char* fname, + char* ext); #else /* __WIN32__ */ #define strcasecmp stricmp #define strncasecmp strnicmp #endif -void S9xGenerateSound (); +void S9xGenerateSound(); #ifdef STORM int soundsignal; diff --git a/source/ppu.c b/source/ppu.c index 631039b..a7d58a2 100644 --- a/source/ppu.c +++ b/source/ppu.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -106,103 +106,102 @@ #include "fxinst.h" extern struct FxInit_s SuperFX; #else -void S9xSuperFXWriteReg (uint8, uint32); -uint8 S9xSuperFXReadReg (uint32); +void S9xSuperFXWriteReg(uint8, uint32); +uint8 S9xSuperFXReadReg(uint32); #endif -uint32 justifiers=0xFFFF00AA; -uint8 in_bit=0; +uint32 justifiers = 0xFFFF00AA; +uint8 in_bit = 0; -extern uint8 *HDMAMemPointers [8]; +extern uint8* HDMAMemPointers [8]; -void S9xLatchCounters (bool force) +void S9xLatchCounters(bool force) { - if(!force && !(Memory.FillRAM[0x4213] & 0x80)) return; + if (!force && !(Memory.FillRAM[0x4213] & 0x80)) return; #if 0 # ifdef CPU_SHUTDOWN - CPU.WaitAddress = CPU.PCAtOpcodeStart; + CPU.WaitAddress = CPU.PCAtOpcodeStart; # endif #endif - PPU.HVBeamCounterLatched = 1; - PPU.VBeamPosLatched = (uint16) CPU.V_Counter; - PPU.HBeamPosLatched = (uint16) ((CPU.Cycles * SNES_HCOUNTER_MAX) / Settings.H_Max); + PPU.HVBeamCounterLatched = 1; + PPU.VBeamPosLatched = (uint16) CPU.V_Counter; + PPU.HBeamPosLatched = (uint16)((CPU.Cycles * SNES_HCOUNTER_MAX) / + Settings.H_Max); - // Causes screen flicker for Yoshi's Island if uncommented - //CLEAR_IRQ_SOURCE (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE); + // Causes screen flicker for Yoshi's Island if uncommented + //CLEAR_IRQ_SOURCE (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE); - Memory.FillRAM [0x213F] |= 0x40; + Memory.FillRAM [0x213F] |= 0x40; } void S9xUpdateJustifiers(); -void S9xUpdateHTimer () +void S9xUpdateHTimer() { - if (PPU.HTimerEnabled) - { - PPU.HTimerPosition = PPU.IRQHBeamPos * Settings.H_Max / SNES_HCOUNTER_MAX; - if (PPU.HTimerPosition == Settings.H_Max || - PPU.HTimerPosition == Settings.HBlankStart) - { - PPU.HTimerPosition--; - } - - if (!PPU.VTimerEnabled || CPU.V_Counter == PPU.IRQVBeamPos) - { - if (PPU.HTimerPosition < CPU.Cycles) - { - // Missed the IRQ on this line already - if (CPU.WhichEvent == HBLANK_END_EVENT || - CPU.WhichEvent == HTIMER_AFTER_EVENT) - { - CPU.WhichEvent = HBLANK_END_EVENT; - CPU.NextEvent = Settings.H_Max; - } - else - { - CPU.WhichEvent = HBLANK_START_EVENT; - CPU.NextEvent = Settings.HBlankStart; - } - } - else - { - if (CPU.WhichEvent == HTIMER_BEFORE_EVENT || - CPU.WhichEvent == HBLANK_START_EVENT) - { - if (PPU.HTimerPosition > Settings.HBlankStart) - { - // HTimer was to trigger before h-blank start, - // now triggers after start of h-blank - CPU.NextEvent = Settings.HBlankStart; - CPU.WhichEvent = HBLANK_START_EVENT; - } - else - { - CPU.NextEvent = PPU.HTimerPosition; - CPU.WhichEvent = HTIMER_BEFORE_EVENT; - } - } - else - { - CPU.WhichEvent = HTIMER_AFTER_EVENT; - CPU.NextEvent = PPU.HTimerPosition; - } - } - } - } + if (PPU.HTimerEnabled) + { + PPU.HTimerPosition = PPU.IRQHBeamPos * Settings.H_Max / SNES_HCOUNTER_MAX; + if (PPU.HTimerPosition == Settings.H_Max || + PPU.HTimerPosition == Settings.HBlankStart) + PPU.HTimerPosition--; + + if (!PPU.VTimerEnabled || CPU.V_Counter == PPU.IRQVBeamPos) + { + if (PPU.HTimerPosition < CPU.Cycles) + { + // Missed the IRQ on this line already + if (CPU.WhichEvent == HBLANK_END_EVENT || + CPU.WhichEvent == HTIMER_AFTER_EVENT) + { + CPU.WhichEvent = HBLANK_END_EVENT; + CPU.NextEvent = Settings.H_Max; + } + else + { + CPU.WhichEvent = HBLANK_START_EVENT; + CPU.NextEvent = Settings.HBlankStart; + } + } + else + { + if (CPU.WhichEvent == HTIMER_BEFORE_EVENT || + CPU.WhichEvent == HBLANK_START_EVENT) + { + if (PPU.HTimerPosition > Settings.HBlankStart) + { + // HTimer was to trigger before h-blank start, + // now triggers after start of h-blank + CPU.NextEvent = Settings.HBlankStart; + CPU.WhichEvent = HBLANK_START_EVENT; + } + else + { + CPU.NextEvent = PPU.HTimerPosition; + CPU.WhichEvent = HTIMER_BEFORE_EVENT; + } + } + else + { + CPU.WhichEvent = HTIMER_AFTER_EVENT; + CPU.NextEvent = PPU.HTimerPosition; + } + } + } + } } -void S9xFixColourBrightness () +void S9xFixColourBrightness() { - IPPU.XB = mul_brightness [PPU.Brightness]; - int i; + IPPU.XB = mul_brightness [PPU.Brightness]; + int i; for (i = 0; i < 256; i++) { IPPU.Red [i] = IPPU.XB [PPU.CGDATA [i] & 0x1f]; IPPU.Green [i] = IPPU.XB [(PPU.CGDATA [i] >> 5) & 0x1f]; IPPU.Blue [i] = IPPU.XB [(PPU.CGDATA [i] >> 10) & 0x1f]; - IPPU.ScreenColors [i] = BUILD_PIXEL (IPPU.Red [i], IPPU.Green [i], - IPPU.Blue [i]); + IPPU.ScreenColors [i] = BUILD_PIXEL(IPPU.Red [i], IPPU.Green [i], + IPPU.Blue [i]); } } @@ -210,695 +209,744 @@ void S9xFixColourBrightness () /* S9xSetPPU() */ /* This function sets a PPU Register to a specific byte */ /******************************************************************************/ -void S9xSetPPU (uint8 Byte, uint16 Address) +void S9xSetPPU(uint8 Byte, uint16 Address) { -// fprintf(stderr, "%03d: %02x to %04x\n", CPU.V_Counter, Byte, Address); - if (Address <= 0x2183) - { - switch (Address) - { - case 0x2100: - // Brightness and screen blank bit - if (Byte != Memory.FillRAM [0x2100]) - { - FLUSH_REDRAW (); - if (PPU.Brightness != (Byte & 0xF)) - { - IPPU.ColorsChanged = TRUE; - IPPU.DirectColourMapsNeedRebuild = TRUE; - PPU.Brightness = Byte & 0xF; - S9xFixColourBrightness (); - if (PPU.Brightness > IPPU.MaxBrightness) - IPPU.MaxBrightness = PPU.Brightness; - } - if ((Memory.FillRAM[0x2100] & 0x80) != (Byte & 0x80)) - { - IPPU.ColorsChanged = TRUE; - PPU.ForcedBlanking = (Byte >> 7) & 1; - } - } - break; - - case 0x2101: - // Sprite (OBJ) tile address - if (Byte != Memory.FillRAM [0x2101]) - { - FLUSH_REDRAW (); - PPU.OBJNameBase = (Byte & 3) << 14; - PPU.OBJNameSelect = ((Byte >> 3) & 3) << 13; - PPU.OBJSizeSelect = (Byte >> 5) & 7; - IPPU.OBJChanged = TRUE; - } - break; - - case 0x2102: - // Sprite write address (low) - PPU.OAMAddr = ((Memory.FillRAM[0x2103]&1)<<8) | Byte; - PPU.OAMFlip = 2; - PPU.OAMReadFlip = 0; - PPU.SavedOAMAddr = PPU.OAMAddr; - if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1)) - { - PPU.FirstSprite = (PPU.OAMAddr&0xFE) >> 1; - IPPU.OBJChanged = TRUE; - } - break; - - case 0x2103: - // Sprite register write address (high), sprite priority rotation - // bit. - PPU.OAMAddr = ((Byte&1)<<8) | Memory.FillRAM[0x2102]; - - PPU.OAMPriorityRotation=(Byte & 0x80)? 1 : 0; - if (PPU.OAMPriorityRotation) - { - if (PPU.FirstSprite != (PPU.OAMAddr >> 1)) - { - PPU.FirstSprite = (PPU.OAMAddr&0xFE) >> 1; - IPPU.OBJChanged = TRUE; - } - } else { - if (PPU.FirstSprite != 0) - { - PPU.FirstSprite = 0; - IPPU.OBJChanged = TRUE; - } - } - PPU.OAMFlip = 0; - PPU.OAMReadFlip = 0; - PPU.SavedOAMAddr = PPU.OAMAddr; - break; - - case 0x2104: - // Sprite register write - REGISTER_2104(Byte); - break; - - case 0x2105: - // Screen mode (0 - 7), background tile sizes and background 3 - // priority - if (Byte != Memory.FillRAM [0x2105]) - { - FLUSH_REDRAW (); - PPU.BG[0].BGSize = (Byte >> 4) & 1; - PPU.BG[1].BGSize = (Byte >> 5) & 1; - PPU.BG[2].BGSize = (Byte >> 6) & 1; - PPU.BG[3].BGSize = (Byte >> 7) & 1; - PPU.BGMode = Byte & 7; - // BJ: BG3Priority only takes effect if BGMode==1 and the bit is set - PPU.BG3Priority = ((Byte & 0x0f) == 0x09); - if(PPU.BGMode==5||PPU.BGMode==6) - IPPU.Interlace = Memory.FillRAM[0x2133]&1; - } - break; - - case 0x2106: - // Mosaic pixel size and enable - if (Byte != Memory.FillRAM [0x2106]) - { - FLUSH_REDRAW (); - PPU.Mosaic = (Byte >> 4) + 1; - PPU.BGMosaic [0] = (Byte & 1) && PPU.Mosaic > 1; - PPU.BGMosaic [1] = (Byte & 2) && PPU.Mosaic > 1; - PPU.BGMosaic [2] = (Byte & 4) && PPU.Mosaic > 1; - PPU.BGMosaic [3] = (Byte & 8) && PPU.Mosaic > 1; - } - break; - case 0x2107: // [BG0SC] - case 0x2108: // [BG1SC] - case 0x2109: // [BG2SC] - case 0x210A: // [BG3SC] - if (Byte != Memory.FillRAM [Address]) - { - FLUSH_REDRAW (); - PPU.BG[Address - 0x2107].SCSize = Byte & 3; - PPU.BG[Address - 0x2107].SCBase = (Byte & 0x7c) << 8; - } - break; - - case 0x210B: // [BG01NBA] - if (Byte != Memory.FillRAM [0x210b]) - { - FLUSH_REDRAW (); - PPU.BG[0].NameBase = (Byte & 7) << 12; - PPU.BG[1].NameBase = ((Byte >> 4) & 7) << 12; - } - break; - - case 0x210C: // [BG23NBA] - if (Byte != Memory.FillRAM [0x210c]) - { - FLUSH_REDRAW (); - PPU.BG[2].NameBase = (Byte & 7) << 12; - PPU.BG[3].NameBase = ((Byte >> 4) & 7) << 12; - } - break; - - - //This is the Theme Park fix - it appears all these registers - //share a previous byte value for setting them. - - case 0x210D: - //TEST9 if(last_written != 0x210d) PPU.BGnxOFSbyte = 0; - PPU.BG[0].HOffset = (Byte<<8) | PPU.BGnxOFSbyte; - PPU.BGnxOFSbyte = Byte; - // fprintf(stderr, "%02x to %04x (PPU.BG[0].HOffset = %04x %d)\n", Byte, Address, PPU.BG[0].HOffset, CPU.V_Counter); - break; - - case 0x210E: - PPU.BG[0].VOffset = (Byte<<8) | PPU.BGnxOFSbyte; - PPU.BGnxOFSbyte = Byte; - // fprintf(stderr, "%02x to %04x (PPU.BG[0].VOffset = %04x %d)\n", Byte, Address, PPU.BG[0].VOffset, CPU.V_Counter); - break; - - case 0x210F: - PPU.BG[1].HOffset = (Byte<<8) | PPU.BGnxOFSbyte; - PPU.BGnxOFSbyte = Byte; - // fprintf(stderr, "%02x to %04x (PPU.BG[1].HOffset = %04x %d)\n", Byte, Address, PPU.BG[1].HOffset, CPU.V_Counter); - break; - - case 0x2110: - PPU.BG[1].VOffset = (Byte<<8) | PPU.BGnxOFSbyte; - PPU.BGnxOFSbyte = Byte; - // fprintf(stderr, "%02x to %04x (PPU.BG[1].VOffset = %04x %d)\n", Byte, Address, PPU.BG[1].VOffset, CPU.V_Counter); - break; - - case 0x2111: - PPU.BG[2].HOffset = (Byte<<8) | PPU.BGnxOFSbyte; - PPU.BGnxOFSbyte = Byte; - // fprintf(stderr, "%02x to %04x (PPU.BG[2].HOffset = %04x %d)\n", Byte, Address, PPU.BG[2].HOffset, CPU.V_Counter); - break; - - case 0x2112: - PPU.BG[2].VOffset = (Byte<<8) | PPU.BGnxOFSbyte; - PPU.BGnxOFSbyte = Byte; - // fprintf(stderr, "%02x to %04x (PPU.BG[2].VOffset = %04x %d)\n", Byte, Address, PPU.BG[2].VOffset, CPU.V_Counter); - break; - - case 0x2113: - PPU.BG[3].HOffset = (Byte<<8) | PPU.BGnxOFSbyte; - PPU.BGnxOFSbyte = Byte; - // fprintf(stderr, "%02x to %04x (PPU.BG[3].HOffset = %04x %d)\n", Byte, Address, PPU.BG[3].HOffset, CPU.V_Counter); - break; - - case 0x2114: - PPU.BG[3].VOffset = (Byte<<8) | PPU.BGnxOFSbyte; - PPU.BGnxOFSbyte = Byte; - // fprintf(stderr, "%02x to %04x (PPU.BG[3].VOffset = %04x %d)\n", Byte, Address, PPU.BG[3].VOffset, CPU.V_Counter); - break; - - //end Theme Park - - case 0x2115: - // VRAM byte/word access flag and increment - PPU.VMA.High = (Byte & 0x80) == 0 ? FALSE : TRUE; - switch (Byte & 3) - { - case 0: - PPU.VMA.Increment = 1; - break; - case 1: - PPU.VMA.Increment = 32; - break; - case 2: - case 3: - PPU.VMA.Increment = 128; - break; - } - if (Byte & 0x0c) - { - static uint16 IncCount [4] = { 0, 32, 64, 128 }; - static uint16 Shift [4] = { 0, 5, 6, 7 }; -// PPU.VMA.Increment = 1; - uint8 i = (Byte & 0x0c) >> 2; - PPU.VMA.FullGraphicCount = IncCount [i]; - PPU.VMA.Mask1 = IncCount [i] * 8 - 1; - PPU.VMA.Shift = Shift [i]; - } - else - PPU.VMA.FullGraphicCount = 0; - break; - - case 0x2116: - // VRAM read/write address (low) - PPU.VMA.Address &= 0xFF00; - PPU.VMA.Address |= Byte; + // fprintf(stderr, "%03d: %02x to %04x\n", CPU.V_Counter, Byte, Address); + if (Address <= 0x2183) + { + switch (Address) + { + case 0x2100: + // Brightness and screen blank bit + if (Byte != Memory.FillRAM [0x2100]) + { + FLUSH_REDRAW(); + if (PPU.Brightness != (Byte & 0xF)) + { + IPPU.ColorsChanged = TRUE; + IPPU.DirectColourMapsNeedRebuild = TRUE; + PPU.Brightness = Byte & 0xF; + S9xFixColourBrightness(); + if (PPU.Brightness > IPPU.MaxBrightness) + IPPU.MaxBrightness = PPU.Brightness; + } + if ((Memory.FillRAM[0x2100] & 0x80) != (Byte & 0x80)) + { + IPPU.ColorsChanged = TRUE; + PPU.ForcedBlanking = (Byte >> 7) & 1; + } + } + break; + + case 0x2101: + // Sprite (OBJ) tile address + if (Byte != Memory.FillRAM [0x2101]) + { + FLUSH_REDRAW(); + PPU.OBJNameBase = (Byte & 3) << 14; + PPU.OBJNameSelect = ((Byte >> 3) & 3) << 13; + PPU.OBJSizeSelect = (Byte >> 5) & 7; + IPPU.OBJChanged = TRUE; + } + break; + + case 0x2102: + // Sprite write address (low) + PPU.OAMAddr = ((Memory.FillRAM[0x2103] & 1) << 8) | Byte; + PPU.OAMFlip = 2; + PPU.OAMReadFlip = 0; + PPU.SavedOAMAddr = PPU.OAMAddr; + if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1)) + { + PPU.FirstSprite = (PPU.OAMAddr & 0xFE) >> 1; + IPPU.OBJChanged = TRUE; + } + break; + + case 0x2103: + // Sprite register write address (high), sprite priority rotation + // bit. + PPU.OAMAddr = ((Byte & 1) << 8) | Memory.FillRAM[0x2102]; + + PPU.OAMPriorityRotation = (Byte & 0x80) ? 1 : 0; + if (PPU.OAMPriorityRotation) + { + if (PPU.FirstSprite != (PPU.OAMAddr >> 1)) + { + PPU.FirstSprite = (PPU.OAMAddr & 0xFE) >> 1; + IPPU.OBJChanged = TRUE; + } + } + else + { + if (PPU.FirstSprite != 0) + { + PPU.FirstSprite = 0; + IPPU.OBJChanged = TRUE; + } + } + PPU.OAMFlip = 0; + PPU.OAMReadFlip = 0; + PPU.SavedOAMAddr = PPU.OAMAddr; + break; + + case 0x2104: + // Sprite register write + REGISTER_2104(Byte); + break; + + case 0x2105: + // Screen mode (0 - 7), background tile sizes and background 3 + // priority + if (Byte != Memory.FillRAM [0x2105]) + { + FLUSH_REDRAW(); + PPU.BG[0].BGSize = (Byte >> 4) & 1; + PPU.BG[1].BGSize = (Byte >> 5) & 1; + PPU.BG[2].BGSize = (Byte >> 6) & 1; + PPU.BG[3].BGSize = (Byte >> 7) & 1; + PPU.BGMode = Byte & 7; + // BJ: BG3Priority only takes effect if BGMode==1 and the bit is set + PPU.BG3Priority = ((Byte & 0x0f) == 0x09); + if (PPU.BGMode == 5 || PPU.BGMode == 6) + IPPU.Interlace = Memory.FillRAM[0x2133] & 1; + } + break; + + case 0x2106: + // Mosaic pixel size and enable + if (Byte != Memory.FillRAM [0x2106]) + { + FLUSH_REDRAW(); + PPU.Mosaic = (Byte >> 4) + 1; + PPU.BGMosaic [0] = (Byte & 1) && PPU.Mosaic > 1; + PPU.BGMosaic [1] = (Byte & 2) && PPU.Mosaic > 1; + PPU.BGMosaic [2] = (Byte & 4) && PPU.Mosaic > 1; + PPU.BGMosaic [3] = (Byte & 8) && PPU.Mosaic > 1; + } + break; + case 0x2107: // [BG0SC] + case 0x2108: // [BG1SC] + case 0x2109: // [BG2SC] + case 0x210A: // [BG3SC] + if (Byte != Memory.FillRAM [Address]) + { + FLUSH_REDRAW(); + PPU.BG[Address - 0x2107].SCSize = Byte & 3; + PPU.BG[Address - 0x2107].SCBase = (Byte & 0x7c) << 8; + } + break; + + case 0x210B: // [BG01NBA] + if (Byte != Memory.FillRAM [0x210b]) + { + FLUSH_REDRAW(); + PPU.BG[0].NameBase = (Byte & 7) << 12; + PPU.BG[1].NameBase = ((Byte >> 4) & 7) << 12; + } + break; + + case 0x210C: // [BG23NBA] + if (Byte != Memory.FillRAM [0x210c]) + { + FLUSH_REDRAW(); + PPU.BG[2].NameBase = (Byte & 7) << 12; + PPU.BG[3].NameBase = ((Byte >> 4) & 7) << 12; + } + break; + + + //This is the Theme Park fix - it appears all these registers + //share a previous byte value for setting them. + + case 0x210D: + //TEST9 if(last_written != 0x210d) PPU.BGnxOFSbyte = 0; + PPU.BG[0].HOffset = (Byte << 8) | PPU.BGnxOFSbyte; + PPU.BGnxOFSbyte = Byte; + // fprintf(stderr, "%02x to %04x (PPU.BG[0].HOffset = %04x %d)\n", Byte, Address, PPU.BG[0].HOffset, CPU.V_Counter); + break; + + case 0x210E: + PPU.BG[0].VOffset = (Byte << 8) | PPU.BGnxOFSbyte; + PPU.BGnxOFSbyte = Byte; + // fprintf(stderr, "%02x to %04x (PPU.BG[0].VOffset = %04x %d)\n", Byte, Address, PPU.BG[0].VOffset, CPU.V_Counter); + break; + + case 0x210F: + PPU.BG[1].HOffset = (Byte << 8) | PPU.BGnxOFSbyte; + PPU.BGnxOFSbyte = Byte; + // fprintf(stderr, "%02x to %04x (PPU.BG[1].HOffset = %04x %d)\n", Byte, Address, PPU.BG[1].HOffset, CPU.V_Counter); + break; + + case 0x2110: + PPU.BG[1].VOffset = (Byte << 8) | PPU.BGnxOFSbyte; + PPU.BGnxOFSbyte = Byte; + // fprintf(stderr, "%02x to %04x (PPU.BG[1].VOffset = %04x %d)\n", Byte, Address, PPU.BG[1].VOffset, CPU.V_Counter); + break; + + case 0x2111: + PPU.BG[2].HOffset = (Byte << 8) | PPU.BGnxOFSbyte; + PPU.BGnxOFSbyte = Byte; + // fprintf(stderr, "%02x to %04x (PPU.BG[2].HOffset = %04x %d)\n", Byte, Address, PPU.BG[2].HOffset, CPU.V_Counter); + break; + + case 0x2112: + PPU.BG[2].VOffset = (Byte << 8) | PPU.BGnxOFSbyte; + PPU.BGnxOFSbyte = Byte; + // fprintf(stderr, "%02x to %04x (PPU.BG[2].VOffset = %04x %d)\n", Byte, Address, PPU.BG[2].VOffset, CPU.V_Counter); + break; + + case 0x2113: + PPU.BG[3].HOffset = (Byte << 8) | PPU.BGnxOFSbyte; + PPU.BGnxOFSbyte = Byte; + // fprintf(stderr, "%02x to %04x (PPU.BG[3].HOffset = %04x %d)\n", Byte, Address, PPU.BG[3].HOffset, CPU.V_Counter); + break; + + case 0x2114: + PPU.BG[3].VOffset = (Byte << 8) | PPU.BGnxOFSbyte; + PPU.BGnxOFSbyte = Byte; + // fprintf(stderr, "%02x to %04x (PPU.BG[3].VOffset = %04x %d)\n", Byte, Address, PPU.BG[3].VOffset, CPU.V_Counter); + break; + + //end Theme Park + + case 0x2115: + // VRAM byte/word access flag and increment + PPU.VMA.High = (Byte & 0x80) == 0 ? FALSE : TRUE; + switch (Byte & 3) + { + case 0: + PPU.VMA.Increment = 1; + break; + case 1: + PPU.VMA.Increment = 32; + break; + case 2: + case 3: + PPU.VMA.Increment = 128; + break; + } + if (Byte & 0x0c) + { + static uint16 IncCount [4] = { 0, 32, 64, 128 }; + static uint16 Shift [4] = { 0, 5, 6, 7 }; + // PPU.VMA.Increment = 1; + uint8 i = (Byte & 0x0c) >> 2; + PPU.VMA.FullGraphicCount = IncCount [i]; + PPU.VMA.Mask1 = IncCount [i] * 8 - 1; + PPU.VMA.Shift = Shift [i]; + } + else + PPU.VMA.FullGraphicCount = 0; + break; + + case 0x2116: + // VRAM read/write address (low) + PPU.VMA.Address &= 0xFF00; + PPU.VMA.Address |= Byte; #ifdef CORRECT_VRAM_READS - if (PPU.VMA.FullGraphicCount) - { - uint32 addr = PPU.VMA.Address; - uint32 rem = addr & PPU.VMA.Mask1; - uint32 address = (addr & ~PPU.VMA.Mask1) + - (rem >> PPU.VMA.Shift) + - ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3); - IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM+((address << 1) & 0xFFFF)); - } else - IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM+((PPU.VMA.Address << 1) & 0xffff)); + if (PPU.VMA.FullGraphicCount) + { + uint32 addr = PPU.VMA.Address; + uint32 rem = addr & PPU.VMA.Mask1; + uint32 address = (addr & ~PPU.VMA.Mask1) + + (rem >> PPU.VMA.Shift) + + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3); + IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((address << 1) & 0xFFFF)); + } + else + IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((PPU.VMA.Address << 1) & + 0xffff)); #else - IPPU.FirstVRAMRead = TRUE; + IPPU.FirstVRAMRead = TRUE; #endif - break; + break; - case 0x2117: - // VRAM read/write address (high) - PPU.VMA.Address &= 0x00FF; - PPU.VMA.Address |= Byte << 8; + case 0x2117: + // VRAM read/write address (high) + PPU.VMA.Address &= 0x00FF; + PPU.VMA.Address |= Byte << 8; #ifdef CORRECT_VRAM_READS - if (PPU.VMA.FullGraphicCount) - { - uint32 addr = PPU.VMA.Address; - uint32 rem = addr & PPU.VMA.Mask1; - uint32 address = (addr & ~PPU.VMA.Mask1) + - (rem >> PPU.VMA.Shift) + - ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3); - IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM+((address << 1) & 0xFFFF)); - } else - IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM+((PPU.VMA.Address << 1) & 0xffff)); + if (PPU.VMA.FullGraphicCount) + { + uint32 addr = PPU.VMA.Address; + uint32 rem = addr & PPU.VMA.Mask1; + uint32 address = (addr & ~PPU.VMA.Mask1) + + (rem >> PPU.VMA.Shift) + + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3); + IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((address << 1) & 0xFFFF)); + } + else + IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((PPU.VMA.Address << 1) & + 0xffff)); #else - IPPU.FirstVRAMRead = TRUE; + IPPU.FirstVRAMRead = TRUE; #endif - break; + break; - case 0x2118: - // VRAM write data (low) + case 0x2118: + // VRAM write data (low) #ifndef CORRECT_VRAM_READS - IPPU.FirstVRAMRead = TRUE; + IPPU.FirstVRAMRead = TRUE; #endif - REGISTER_2118(Byte); - break; + REGISTER_2118(Byte); + break; - case 0x2119: - // VRAM write data (high) + case 0x2119: + // VRAM write data (high) #ifndef CORRECT_VRAM_READS - IPPU.FirstVRAMRead = TRUE; + IPPU.FirstVRAMRead = TRUE; #endif - REGISTER_2119(Byte); - break; - - case 0x211a: - // Mode 7 outside rotation area display mode and flipping - if (Byte != Memory.FillRAM [0x211a]) - { - FLUSH_REDRAW (); - PPU.Mode7Repeat = Byte >> 6; - if (PPU.Mode7Repeat == 1) - PPU.Mode7Repeat = 0; - PPU.Mode7VFlip = (Byte & 2) >> 1; - PPU.Mode7HFlip = Byte & 1; - } - break; - case 0x211b: - // Mode 7 matrix A (low & high) - PPU.MatrixA = ((PPU.MatrixA >> 8) & 0xff) | (Byte << 8); - PPU.Need16x8Mulitply = TRUE; - break; - case 0x211c: - // Mode 7 matrix B (low & high) - PPU.MatrixB = ((PPU.MatrixB >> 8) & 0xff) | (Byte << 8); - PPU.Need16x8Mulitply = TRUE; - break; - case 0x211d: - // Mode 7 matrix C (low & high) - PPU.MatrixC = ((PPU.MatrixC >> 8) & 0xff) | (Byte << 8); - break; - case 0x211e: - // Mode 7 matrix D (low & high) - PPU.MatrixD = ((PPU.MatrixD >> 8) & 0xff) | (Byte << 8); - break; - case 0x211f: - // Mode 7 centre of rotation X (low & high) - PPU.CentreX = ((PPU.CentreX >> 8) & 0xff) | (Byte << 8); - break; - case 0x2120: - // Mode 7 centre of rotation Y (low & high) - PPU.CentreY = ((PPU.CentreY >> 8) & 0xff) | (Byte << 8); - break; - - case 0x2121: - // CG-RAM address - PPU.CGFLIP = 0; - PPU.CGFLIPRead = 0; - PPU.CGADD = Byte; - break; - - case 0x2122: - REGISTER_2122(Byte); - break; - - case 0x2123: - // Window 1 and 2 enable for backgrounds 1 and 2 - if (Byte != Memory.FillRAM [0x2123]) - { - FLUSH_REDRAW (); - PPU.ClipWindow1Enable [0] = !!(Byte & 0x02); - PPU.ClipWindow1Enable [1] = !!(Byte & 0x20); - PPU.ClipWindow2Enable [0] = !!(Byte & 0x08); - PPU.ClipWindow2Enable [1] = !!(Byte & 0x80); - PPU.ClipWindow1Inside [0] = !(Byte & 0x01); - PPU.ClipWindow1Inside [1] = !(Byte & 0x10); - PPU.ClipWindow2Inside [0] = !(Byte & 0x04); - PPU.ClipWindow2Inside [1] = !(Byte & 0x40); - PPU.RecomputeClipWindows = TRUE; - } - break; - case 0x2124: - // Window 1 and 2 enable for backgrounds 3 and 4 - if (Byte != Memory.FillRAM [0x2124]) - { - FLUSH_REDRAW (); - PPU.ClipWindow1Enable [2] = !!(Byte & 0x02); - PPU.ClipWindow1Enable [3] = !!(Byte & 0x20); - PPU.ClipWindow2Enable [2] = !!(Byte & 0x08); - PPU.ClipWindow2Enable [3] = !!(Byte & 0x80); - PPU.ClipWindow1Inside [2] = !(Byte & 0x01); - PPU.ClipWindow1Inside [3] = !(Byte & 0x10); - PPU.ClipWindow2Inside [2] = !(Byte & 0x04); - PPU.ClipWindow2Inside [3] = !(Byte & 0x40); - PPU.RecomputeClipWindows = TRUE; - } - break; - case 0x2125: - // Window 1 and 2 enable for objects and colour window - if (Byte != Memory.FillRAM [0x2125]) - { - FLUSH_REDRAW (); - PPU.ClipWindow1Enable [4] = !!(Byte & 0x02); - PPU.ClipWindow1Enable [5] = !!(Byte & 0x20); - PPU.ClipWindow2Enable [4] = !!(Byte & 0x08); - PPU.ClipWindow2Enable [5] = !!(Byte & 0x80); - PPU.ClipWindow1Inside [4] = !(Byte & 0x01); - PPU.ClipWindow1Inside [5] = !(Byte & 0x10); - PPU.ClipWindow2Inside [4] = !(Byte & 0x04); - PPU.ClipWindow2Inside [5] = !(Byte & 0x40); - PPU.RecomputeClipWindows = TRUE; - } - break; - case 0x2126: - // Window 1 left position - if (Byte != Memory.FillRAM [0x2126]) - { - FLUSH_REDRAW (); - PPU.Window1Left = Byte; - PPU.RecomputeClipWindows = TRUE; - } - break; - case 0x2127: - // Window 1 right position - if (Byte != Memory.FillRAM [0x2127]) - { - FLUSH_REDRAW (); - PPU.Window1Right = Byte; - PPU.RecomputeClipWindows = TRUE; - } - break; - case 0x2128: - // Window 2 left position - if (Byte != Memory.FillRAM [0x2128]) - { - FLUSH_REDRAW (); - PPU.Window2Left = Byte; - PPU.RecomputeClipWindows = TRUE; - } - break; - case 0x2129: - // Window 2 right position - if (Byte != Memory.FillRAM [0x2129]) - { - FLUSH_REDRAW (); - PPU.Window2Right = Byte; - PPU.RecomputeClipWindows = TRUE; - } - break; - case 0x212a: - // Windows 1 & 2 overlap logic for backgrounds 1 - 4 - if (Byte != Memory.FillRAM [0x212a]) - { - FLUSH_REDRAW (); - PPU.ClipWindowOverlapLogic [0] = (Byte & 0x03); - PPU.ClipWindowOverlapLogic [1] = (Byte & 0x0c) >> 2; - PPU.ClipWindowOverlapLogic [2] = (Byte & 0x30) >> 4; - PPU.ClipWindowOverlapLogic [3] = (Byte & 0xc0) >> 6; - PPU.RecomputeClipWindows = TRUE; - } - break; - case 0x212b: - // Windows 1 & 2 overlap logic for objects and colour window - if (Byte != Memory.FillRAM [0x212b]) - { - FLUSH_REDRAW (); - PPU.ClipWindowOverlapLogic [4] = Byte & 0x03; - PPU.ClipWindowOverlapLogic [5] = (Byte & 0x0c) >> 2; - PPU.RecomputeClipWindows = TRUE; - } - break; - case 0x212c: - // Main screen designation (backgrounds 1 - 4 and objects) - if (Byte != Memory.FillRAM [0x212c]) - { - FLUSH_REDRAW (); - PPU.RecomputeClipWindows = TRUE; - Memory.FillRAM [Address] = Byte; - return; - } - break; - case 0x212d: - // Sub-screen designation (backgrounds 1 - 4 and objects) - if (Byte != Memory.FillRAM [0x212d]) - { - FLUSH_REDRAW (); - PPU.RecomputeClipWindows = TRUE; - Memory.FillRAM [Address] = Byte; - return; - } - break; - case 0x212e: - // Window mask designation for main screen ? - case 0x212f: - // Window mask designation for sub-screen ? - if (Byte != Memory.FillRAM [Address]) - { - FLUSH_REDRAW (); - PPU.RecomputeClipWindows = TRUE; - } - break; - case 0x2130: - // Fixed colour addition or screen addition - if (Byte != Memory.FillRAM [0x2130]) - { - FLUSH_REDRAW (); - PPU.RecomputeClipWindows = TRUE; - } - break; - case 0x2131: - // Colour addition or subtraction select - if (Byte != Memory.FillRAM[0x2131]) - { - FLUSH_REDRAW (); - // Backgrounds 1 - 4, objects and backdrop colour add/sub enable - Memory.FillRAM[0x2131] = Byte; - } - break; - case 0x2132: - if (Byte != Memory.FillRAM [0x2132]) - { - FLUSH_REDRAW (); - // Colour data for fixed colour addition/subtraction - if (Byte & 0x80) - PPU.FixedColourBlue = Byte & 0x1f; - if (Byte & 0x40) - PPU.FixedColourGreen = Byte & 0x1f; - if (Byte & 0x20) - PPU.FixedColourRed = Byte & 0x1f; - } - break; - case 0x2133: - // Screen settings - if (Byte != Memory.FillRAM [0x2133]) - { - if (Byte & 0x04) - { - PPU.ScreenHeight = SNES_HEIGHT_EXTENDED; - if(IPPU.DoubleHeightPixels) - IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1; - else - IPPU.RenderedScreenHeight = PPU.ScreenHeight; - } - else PPU.ScreenHeight = SNES_HEIGHT; - - //if((Byte & 1)&&(PPU.BGMode==5||PPU.BGMode==6)) - //IPPU.Interlace=1; - if((Memory.FillRAM [0x2133] ^ Byte)&3) - { - FLUSH_REDRAW (); - if((Memory.FillRAM [0x2133] ^ Byte)&2) - IPPU.OBJChanged = TRUE; - if(PPU.BGMode==5||PPU.BGMode==6) - IPPU.Interlace = Byte&1; - IPPU.InterlaceSprites=0; - // IPPU.InterlaceSprites = (Byte&2)>>1; - } - - } - break; - case 0x2134: - case 0x2135: - case 0x2136: - // Matrix 16bit x 8bit multiply result (read-only) - /* fall through */ - case 0x2137: - // Software latch for horizontal and vertical timers (read-only) - /* fall through */ - case 0x2138: - // OAM read data (read-only) - /* fall through */ - case 0x2139: - case 0x213a: - // VRAM read data (read-only) - /* fall through */ - case 0x213b: - // CG-RAM read data (read-only) - /* fall through */ - case 0x213c: - case 0x213d: - // Horizontal and vertical (low/high) read counter (read-only) - /* fall through */ - case 0x213e: - // PPU status (time over and range over) - /* fall through */ - case 0x213f: - // NTSC/PAL select and field (read-only) - return; - case 0x2140: case 0x2141: case 0x2142: case 0x2143: - case 0x2144: case 0x2145: case 0x2146: case 0x2147: - case 0x2148: case 0x2149: case 0x214a: case 0x214b: - case 0x214c: case 0x214d: case 0x214e: case 0x214f: - case 0x2150: case 0x2151: case 0x2152: case 0x2153: - case 0x2154: case 0x2155: case 0x2156: case 0x2157: - case 0x2158: case 0x2159: case 0x215a: case 0x215b: - case 0x215c: case 0x215d: case 0x215e: case 0x215f: - case 0x2160: case 0x2161: case 0x2162: case 0x2163: - case 0x2164: case 0x2165: case 0x2166: case 0x2167: - case 0x2168: case 0x2169: case 0x216a: case 0x216b: - case 0x216c: case 0x216d: case 0x216e: case 0x216f: - case 0x2170: case 0x2171: case 0x2172: case 0x2173: - case 0x2174: case 0x2175: case 0x2176: case 0x2177: - case 0x2178: case 0x2179: case 0x217a: case 0x217b: - case 0x217c: case 0x217d: case 0x217e: case 0x217f: + REGISTER_2119(Byte); + break; + + case 0x211a: + // Mode 7 outside rotation area display mode and flipping + if (Byte != Memory.FillRAM [0x211a]) + { + FLUSH_REDRAW(); + PPU.Mode7Repeat = Byte >> 6; + if (PPU.Mode7Repeat == 1) + PPU.Mode7Repeat = 0; + PPU.Mode7VFlip = (Byte & 2) >> 1; + PPU.Mode7HFlip = Byte & 1; + } + break; + case 0x211b: + // Mode 7 matrix A (low & high) + PPU.MatrixA = ((PPU.MatrixA >> 8) & 0xff) | (Byte << 8); + PPU.Need16x8Mulitply = TRUE; + break; + case 0x211c: + // Mode 7 matrix B (low & high) + PPU.MatrixB = ((PPU.MatrixB >> 8) & 0xff) | (Byte << 8); + PPU.Need16x8Mulitply = TRUE; + break; + case 0x211d: + // Mode 7 matrix C (low & high) + PPU.MatrixC = ((PPU.MatrixC >> 8) & 0xff) | (Byte << 8); + break; + case 0x211e: + // Mode 7 matrix D (low & high) + PPU.MatrixD = ((PPU.MatrixD >> 8) & 0xff) | (Byte << 8); + break; + case 0x211f: + // Mode 7 centre of rotation X (low & high) + PPU.CentreX = ((PPU.CentreX >> 8) & 0xff) | (Byte << 8); + break; + case 0x2120: + // Mode 7 centre of rotation Y (low & high) + PPU.CentreY = ((PPU.CentreY >> 8) & 0xff) | (Byte << 8); + break; + + case 0x2121: + // CG-RAM address + PPU.CGFLIP = 0; + PPU.CGFLIPRead = 0; + PPU.CGADD = Byte; + break; + + case 0x2122: + REGISTER_2122(Byte); + break; + + case 0x2123: + // Window 1 and 2 enable for backgrounds 1 and 2 + if (Byte != Memory.FillRAM [0x2123]) + { + FLUSH_REDRAW(); + PPU.ClipWindow1Enable [0] = !!(Byte & 0x02); + PPU.ClipWindow1Enable [1] = !!(Byte & 0x20); + PPU.ClipWindow2Enable [0] = !!(Byte & 0x08); + PPU.ClipWindow2Enable [1] = !!(Byte & 0x80); + PPU.ClipWindow1Inside [0] = !(Byte & 0x01); + PPU.ClipWindow1Inside [1] = !(Byte & 0x10); + PPU.ClipWindow2Inside [0] = !(Byte & 0x04); + PPU.ClipWindow2Inside [1] = !(Byte & 0x40); + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x2124: + // Window 1 and 2 enable for backgrounds 3 and 4 + if (Byte != Memory.FillRAM [0x2124]) + { + FLUSH_REDRAW(); + PPU.ClipWindow1Enable [2] = !!(Byte & 0x02); + PPU.ClipWindow1Enable [3] = !!(Byte & 0x20); + PPU.ClipWindow2Enable [2] = !!(Byte & 0x08); + PPU.ClipWindow2Enable [3] = !!(Byte & 0x80); + PPU.ClipWindow1Inside [2] = !(Byte & 0x01); + PPU.ClipWindow1Inside [3] = !(Byte & 0x10); + PPU.ClipWindow2Inside [2] = !(Byte & 0x04); + PPU.ClipWindow2Inside [3] = !(Byte & 0x40); + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x2125: + // Window 1 and 2 enable for objects and colour window + if (Byte != Memory.FillRAM [0x2125]) + { + FLUSH_REDRAW(); + PPU.ClipWindow1Enable [4] = !!(Byte & 0x02); + PPU.ClipWindow1Enable [5] = !!(Byte & 0x20); + PPU.ClipWindow2Enable [4] = !!(Byte & 0x08); + PPU.ClipWindow2Enable [5] = !!(Byte & 0x80); + PPU.ClipWindow1Inside [4] = !(Byte & 0x01); + PPU.ClipWindow1Inside [5] = !(Byte & 0x10); + PPU.ClipWindow2Inside [4] = !(Byte & 0x04); + PPU.ClipWindow2Inside [5] = !(Byte & 0x40); + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x2126: + // Window 1 left position + if (Byte != Memory.FillRAM [0x2126]) + { + FLUSH_REDRAW(); + PPU.Window1Left = Byte; + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x2127: + // Window 1 right position + if (Byte != Memory.FillRAM [0x2127]) + { + FLUSH_REDRAW(); + PPU.Window1Right = Byte; + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x2128: + // Window 2 left position + if (Byte != Memory.FillRAM [0x2128]) + { + FLUSH_REDRAW(); + PPU.Window2Left = Byte; + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x2129: + // Window 2 right position + if (Byte != Memory.FillRAM [0x2129]) + { + FLUSH_REDRAW(); + PPU.Window2Right = Byte; + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x212a: + // Windows 1 & 2 overlap logic for backgrounds 1 - 4 + if (Byte != Memory.FillRAM [0x212a]) + { + FLUSH_REDRAW(); + PPU.ClipWindowOverlapLogic [0] = (Byte & 0x03); + PPU.ClipWindowOverlapLogic [1] = (Byte & 0x0c) >> 2; + PPU.ClipWindowOverlapLogic [2] = (Byte & 0x30) >> 4; + PPU.ClipWindowOverlapLogic [3] = (Byte & 0xc0) >> 6; + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x212b: + // Windows 1 & 2 overlap logic for objects and colour window + if (Byte != Memory.FillRAM [0x212b]) + { + FLUSH_REDRAW(); + PPU.ClipWindowOverlapLogic [4] = Byte & 0x03; + PPU.ClipWindowOverlapLogic [5] = (Byte & 0x0c) >> 2; + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x212c: + // Main screen designation (backgrounds 1 - 4 and objects) + if (Byte != Memory.FillRAM [0x212c]) + { + FLUSH_REDRAW(); + PPU.RecomputeClipWindows = TRUE; + Memory.FillRAM [Address] = Byte; + return; + } + break; + case 0x212d: + // Sub-screen designation (backgrounds 1 - 4 and objects) + if (Byte != Memory.FillRAM [0x212d]) + { + FLUSH_REDRAW(); + PPU.RecomputeClipWindows = TRUE; + Memory.FillRAM [Address] = Byte; + return; + } + break; + case 0x212e: + // Window mask designation for main screen ? + case 0x212f: + // Window mask designation for sub-screen ? + if (Byte != Memory.FillRAM [Address]) + { + FLUSH_REDRAW(); + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x2130: + // Fixed colour addition or screen addition + if (Byte != Memory.FillRAM [0x2130]) + { + FLUSH_REDRAW(); + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x2131: + // Colour addition or subtraction select + if (Byte != Memory.FillRAM[0x2131]) + { + FLUSH_REDRAW(); + // Backgrounds 1 - 4, objects and backdrop colour add/sub enable + Memory.FillRAM[0x2131] = Byte; + } + break; + case 0x2132: + if (Byte != Memory.FillRAM [0x2132]) + { + FLUSH_REDRAW(); + // Colour data for fixed colour addition/subtraction + if (Byte & 0x80) + PPU.FixedColourBlue = Byte & 0x1f; + if (Byte & 0x40) + PPU.FixedColourGreen = Byte & 0x1f; + if (Byte & 0x20) + PPU.FixedColourRed = Byte & 0x1f; + } + break; + case 0x2133: + // Screen settings + if (Byte != Memory.FillRAM [0x2133]) + { + if (Byte & 0x04) + { + PPU.ScreenHeight = SNES_HEIGHT_EXTENDED; + if (IPPU.DoubleHeightPixels) + IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1; + else + IPPU.RenderedScreenHeight = PPU.ScreenHeight; + } + else PPU.ScreenHeight = SNES_HEIGHT; + + //if((Byte & 1)&&(PPU.BGMode==5||PPU.BGMode==6)) + //IPPU.Interlace=1; + if ((Memory.FillRAM [0x2133] ^ Byte) & 3) + { + FLUSH_REDRAW(); + if ((Memory.FillRAM [0x2133] ^ Byte) & 2) + IPPU.OBJChanged = TRUE; + if (PPU.BGMode == 5 || PPU.BGMode == 6) + IPPU.Interlace = Byte & 1; + IPPU.InterlaceSprites = 0; + // IPPU.InterlaceSprites = (Byte&2)>>1; + } + + } + break; + case 0x2134: + case 0x2135: + case 0x2136: + // Matrix 16bit x 8bit multiply result (read-only) + /* fall through */ + case 0x2137: + // Software latch for horizontal and vertical timers (read-only) + /* fall through */ + case 0x2138: + // OAM read data (read-only) + /* fall through */ + case 0x2139: + case 0x213a: + // VRAM read data (read-only) + /* fall through */ + case 0x213b: + // CG-RAM read data (read-only) + /* fall through */ + case 0x213c: + case 0x213d: + // Horizontal and vertical (low/high) read counter (read-only) + /* fall through */ + case 0x213e: + // PPU status (time over and range over) + /* fall through */ + case 0x213f: + // NTSC/PAL select and field (read-only) + return; + case 0x2140: + case 0x2141: + case 0x2142: + case 0x2143: + case 0x2144: + case 0x2145: + case 0x2146: + case 0x2147: + case 0x2148: + case 0x2149: + case 0x214a: + case 0x214b: + case 0x214c: + case 0x214d: + case 0x214e: + case 0x214f: + case 0x2150: + case 0x2151: + case 0x2152: + case 0x2153: + case 0x2154: + case 0x2155: + case 0x2156: + case 0x2157: + case 0x2158: + case 0x2159: + case 0x215a: + case 0x215b: + case 0x215c: + case 0x215d: + case 0x215e: + case 0x215f: + case 0x2160: + case 0x2161: + case 0x2162: + case 0x2163: + case 0x2164: + case 0x2165: + case 0x2166: + case 0x2167: + case 0x2168: + case 0x2169: + case 0x216a: + case 0x216b: + case 0x216c: + case 0x216d: + case 0x216e: + case 0x216f: + case 0x2170: + case 0x2171: + case 0x2172: + case 0x2173: + case 0x2174: + case 0x2175: + case 0x2176: + case 0x2177: + case 0x2178: + case 0x2179: + case 0x217a: + case 0x217b: + case 0x217c: + case 0x217d: + case 0x217e: + case 0x217f: #ifdef SPCTOOL - _SPCInPB (Address & 3, Byte); -#else - // CPU.Flags |= DEBUG_MODE_FLAG; - Memory.FillRAM [Address] = Byte; - IAPU.RAM [(Address & 3) + 0xf4] = Byte; + _SPCInPB(Address & 3, Byte); +#else + // CPU.Flags |= DEBUG_MODE_FLAG; + Memory.FillRAM [Address] = Byte; + IAPU.RAM [(Address & 3) + 0xf4] = Byte; #ifdef SPC700_SHUTDOWN - IAPU.APUExecuting = Settings.APUEnabled; - IAPU.WaitCounter++; + IAPU.APUExecuting = Settings.APUEnabled; + IAPU.WaitCounter++; #endif #endif // SPCTOOL - break; - case 0x2180: - REGISTER_2180(Byte); - break; - case 0x2181: - PPU.WRAM &= 0x1FF00; - PPU.WRAM |= Byte; - break; - case 0x2182: - PPU.WRAM &= 0x100FF; - PPU.WRAM |= Byte << 8; - break; - case 0x2183: - PPU.WRAM &= 0x0FFFF; - PPU.WRAM |= Byte << 16; - PPU.WRAM &= 0x1FFFF; - break; - } - } - else - { - if (Settings.SA1) - { - if (Address >= 0x2200 && Address <0x23ff) - S9xSetSA1 (Byte, Address); - else - Memory.FillRAM [Address] = Byte; - - return; - } - else - // Dai Kaijyu Monogatari II - if (Address == 0x2801 && Settings.SRTC) - S9xSetSRTC (Byte, Address); - else - if (Address >= 0x3000 && Address < 0x3300) - { - if (!Settings.SuperFX) - { - return; - } + break; + case 0x2180: + REGISTER_2180(Byte); + break; + case 0x2181: + PPU.WRAM &= 0x1FF00; + PPU.WRAM |= Byte; + break; + case 0x2182: + PPU.WRAM &= 0x100FF; + PPU.WRAM |= Byte << 8; + break; + case 0x2183: + PPU.WRAM &= 0x0FFFF; + PPU.WRAM |= Byte << 16; + PPU.WRAM &= 0x1FFFF; + break; + } + } + else + { + if (Settings.SA1) + { + if (Address >= 0x2200 && Address < 0x23ff) + S9xSetSA1(Byte, Address); + else + Memory.FillRAM [Address] = Byte; + + return; + } + else + // Dai Kaijyu Monogatari II + if (Address == 0x2801 && Settings.SRTC) + S9xSetSRTC(Byte, Address); + else if (Address >= 0x3000 && Address < 0x3300) + { + if (!Settings.SuperFX) + return; #ifdef ZSNES_FX - Memory.FillRAM [Address] = Byte; - if (Address < 0x3040) - S9xSuperFXWriteReg (Byte, Address); + Memory.FillRAM [Address] = Byte; + if (Address < 0x3040) + S9xSuperFXWriteReg(Byte, Address); #else - switch (Address) - { - case 0x3030: - if ((Memory.FillRAM [0x3030] ^ Byte) & FLG_G) - { - Memory.FillRAM [Address] = Byte; - // Go flag has been changed - if (Byte & FLG_G) - S9xSuperFXExec (); - else - FxFlushCache (); - } - else - Memory.FillRAM [Address] = Byte; - break; - - case 0x3031: - case 0x3033: - case 0x3037: - case 0x3039: - case 0x303a: - case 0x303f: - Memory.FillRAM [Address] = Byte; - break; - case 0x3034: - case 0x3036: - Memory.FillRAM [Address] = Byte & 0x7f; - break; - case 0x3038: - Memory.FillRAM [Address] = Byte; - fx_dirtySCBR(); - break; - case 0x303b: - break; - case 0x303c: - Memory.FillRAM [Address] = Byte; - fx_updateRamBank(Byte); - break; - case 0x301f: - Memory.FillRAM [Address] = Byte; - Memory.FillRAM [0x3000 + GSU_SFR] |= FLG_G; - S9xSuperFXExec (); - return; - - default: - Memory.FillRAM[Address] = Byte; - if (Address >= 0x3100) - { - FxCacheWriteAccess (Address); - } - break; - } + switch (Address) + { + case 0x3030: + if ((Memory.FillRAM [0x3030] ^ Byte) & FLG_G) + { + Memory.FillRAM [Address] = Byte; + // Go flag has been changed + if (Byte & FLG_G) + S9xSuperFXExec(); + else + FxFlushCache(); + } + else + Memory.FillRAM [Address] = Byte; + break; + + case 0x3031: + case 0x3033: + case 0x3037: + case 0x3039: + case 0x303a: + case 0x303f: + Memory.FillRAM [Address] = Byte; + break; + case 0x3034: + case 0x3036: + Memory.FillRAM [Address] = Byte & 0x7f; + break; + case 0x3038: + Memory.FillRAM [Address] = Byte; + fx_dirtySCBR(); + break; + case 0x303b: + break; + case 0x303c: + Memory.FillRAM [Address] = Byte; + fx_updateRamBank(Byte); + break; + case 0x301f: + Memory.FillRAM [Address] = Byte; + Memory.FillRAM [0x3000 + GSU_SFR] |= FLG_G; + S9xSuperFXExec(); + return; + + default: + Memory.FillRAM[Address] = Byte; + if (Address >= 0x3100) + FxCacheWriteAccess(Address); + break; + } #endif - return; - } - } - Memory.FillRAM[Address] = Byte; + return; + } + } + Memory.FillRAM[Address] = Byte; } @@ -906,1972 +954,2021 @@ void S9xSetPPU (uint8 Byte, uint16 Address) /* S9xGetPPU() */ /* This function retrieves a PPU Register */ /******************************************************************************/ -uint8 S9xGetPPU (uint16 Address) +uint8 S9xGetPPU(uint16 Address) { - uint8 byte = OpenBus; - if(Address<0x2100)//not a real PPU reg - return OpenBus; //treat as unmapped memory returning last byte on the bus - if (Address <= 0x2190) - { - switch (Address) - { - case 0x2100: - case 0x2101: - case 0x2102: - case 0x2103: - return OpenBus; - - case 0x2104: - case 0x2105: - case 0x2106: - case 0x2108: - case 0x2109: - case 0x210a: - case 0x2115: - case 0x2116: - case 0x2118: - case 0x2119: - case 0x211a: - case 0x2124: - case 0x2125: - case 0x2126: - case 0x2128: - case 0x2129: - case 0x212a: - return PPU.OpenBus1; - - case 0x2107: - case 0x2117: - case 0x2121: - case 0x2122: - case 0x2123: - case 0x2127: - case 0x212b: - case 0x212c: - case 0x212d: - case 0x212e: - case 0x212f: - case 0x2130: - case 0x2131: - case 0x2132: - case 0x2133: - return OpenBus; - - case 0x210b: - case 0x210c: - case 0x210d: - case 0x210e: - case 0x210f: - case 0x2110: - case 0x2111: - case 0x2112: - case 0x2113: - return OpenBus; - - case 0x2114: - case 0x211b: - case 0x211c: - case 0x211d: - case 0x211e: - case 0x211f: - case 0x2120: - return OpenBus; - - - case 0x2134: - case 0x2135: - case 0x2136: - // 16bit x 8bit multiply read result. - if (PPU.Need16x8Mulitply) - { - int32 r = (int32) PPU.MatrixA * (int32) (PPU.MatrixB >> 8); - - Memory.FillRAM[0x2134] = (uint8) r; - Memory.FillRAM[0x2135] = (uint8)(r >> 8); - Memory.FillRAM[0x2136] = (uint8)(r >> 16); - PPU.Need16x8Mulitply = FALSE; - } - return (PPU.OpenBus1 = Memory.FillRAM[Address]); - case 0x2137: - S9xLatchCounters(0); - return OpenBus; - - case 0x2138: - // Read OAM (sprite) control data - if(PPU.OAMAddr&0x100){ - if (!(PPU.OAMFlip&1)) - { - byte = PPU.OAMData [(PPU.OAMAddr&0x10f) << 1]; - } - else - { - byte = PPU.OAMData [((PPU.OAMAddr&0x10f) << 1) + 1]; - PPU.OAMAddr=(PPU.OAMAddr+1)&0x1ff; - if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1)) - { - PPU.FirstSprite = (PPU.OAMAddr&0xFE) >> 1; - IPPU.OBJChanged = TRUE; - } - } - } else { - if (!(PPU.OAMFlip&1)) - { - byte = PPU.OAMData [PPU.OAMAddr << 1]; - } - else - { - byte = PPU.OAMData [(PPU.OAMAddr << 1) + 1]; - ++PPU.OAMAddr; - if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1)) - { - PPU.FirstSprite = (PPU.OAMAddr&0xFE) >> 1; - IPPU.OBJChanged = TRUE; - } - } - } - PPU.OAMFlip ^= 1; - return (PPU.OpenBus1 = byte); - - case 0x2139: - // Read vram low byte + uint8 byte = OpenBus; + if (Address < 0x2100) //not a real PPU reg + return OpenBus; //treat as unmapped memory returning last byte on the bus + if (Address <= 0x2190) + { + switch (Address) + { + case 0x2100: + case 0x2101: + case 0x2102: + case 0x2103: + return OpenBus; + + case 0x2104: + case 0x2105: + case 0x2106: + case 0x2108: + case 0x2109: + case 0x210a: + case 0x2115: + case 0x2116: + case 0x2118: + case 0x2119: + case 0x211a: + case 0x2124: + case 0x2125: + case 0x2126: + case 0x2128: + case 0x2129: + case 0x212a: + return PPU.OpenBus1; + + case 0x2107: + case 0x2117: + case 0x2121: + case 0x2122: + case 0x2123: + case 0x2127: + case 0x212b: + case 0x212c: + case 0x212d: + case 0x212e: + case 0x212f: + case 0x2130: + case 0x2131: + case 0x2132: + case 0x2133: + return OpenBus; + + case 0x210b: + case 0x210c: + case 0x210d: + case 0x210e: + case 0x210f: + case 0x2110: + case 0x2111: + case 0x2112: + case 0x2113: + return OpenBus; + + case 0x2114: + case 0x211b: + case 0x211c: + case 0x211d: + case 0x211e: + case 0x211f: + case 0x2120: + return OpenBus; + + + case 0x2134: + case 0x2135: + case 0x2136: + // 16bit x 8bit multiply read result. + if (PPU.Need16x8Mulitply) + { + int32 r = (int32) PPU.MatrixA * (int32)(PPU.MatrixB >> 8); + + Memory.FillRAM[0x2134] = (uint8) r; + Memory.FillRAM[0x2135] = (uint8)(r >> 8); + Memory.FillRAM[0x2136] = (uint8)(r >> 16); + PPU.Need16x8Mulitply = FALSE; + } + return (PPU.OpenBus1 = Memory.FillRAM[Address]); + case 0x2137: + S9xLatchCounters(0); + return OpenBus; + + case 0x2138: + // Read OAM (sprite) control data + if (PPU.OAMAddr & 0x100) + { + if (!(PPU.OAMFlip & 1)) + byte = PPU.OAMData [(PPU.OAMAddr & 0x10f) << 1]; + else + { + byte = PPU.OAMData [((PPU.OAMAddr & 0x10f) << 1) + 1]; + PPU.OAMAddr = (PPU.OAMAddr + 1) & 0x1ff; + if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1)) + { + PPU.FirstSprite = (PPU.OAMAddr & 0xFE) >> 1; + IPPU.OBJChanged = TRUE; + } + } + } + else + { + if (!(PPU.OAMFlip & 1)) + byte = PPU.OAMData [PPU.OAMAddr << 1]; + else + { + byte = PPU.OAMData [(PPU.OAMAddr << 1) + 1]; + ++PPU.OAMAddr; + if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1)) + { + PPU.FirstSprite = (PPU.OAMAddr & 0xFE) >> 1; + IPPU.OBJChanged = TRUE; + } + } + } + PPU.OAMFlip ^= 1; + return (PPU.OpenBus1 = byte); + + case 0x2139: + // Read vram low byte #ifdef CORRECT_VRAM_READS - byte = IPPU.VRAMReadBuffer & 0xff; - if (!PPU.VMA.High) - { - if (PPU.VMA.FullGraphicCount) - { - uint32 addr = PPU.VMA.Address; - uint32 rem = addr & PPU.VMA.Mask1; - uint32 address = (addr & ~PPU.VMA.Mask1) + - (rem >> PPU.VMA.Shift) + - ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3); - IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM+((address << 1) & 0xFFFF)); - } else - IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM+((PPU.VMA.Address << 1) & 0xffff)); - PPU.VMA.Address += PPU.VMA.Increment; - } + byte = IPPU.VRAMReadBuffer & 0xff; + if (!PPU.VMA.High) + { + if (PPU.VMA.FullGraphicCount) + { + uint32 addr = PPU.VMA.Address; + uint32 rem = addr & PPU.VMA.Mask1; + uint32 address = (addr & ~PPU.VMA.Mask1) + + (rem >> PPU.VMA.Shift) + + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3); + IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((address << 1) & 0xFFFF)); + } + else + IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((PPU.VMA.Address << 1) & + 0xffff)); + 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; - } + 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 - PPU.OpenBus1 = byte; - break; - case 0x213A: - // Read vram high byte + PPU.OpenBus1 = byte; + break; + case 0x213A: + // Read vram high byte #ifdef CORRECT_VRAM_READS - byte = (IPPU.VRAMReadBuffer>>8) & 0xff; - if (PPU.VMA.High) - { - if (PPU.VMA.FullGraphicCount) - { - uint32 addr = PPU.VMA.Address; - uint32 rem = addr & PPU.VMA.Mask1; - uint32 address = (addr & ~PPU.VMA.Mask1) + - (rem >> PPU.VMA.Shift) + - ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3); - IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM+((address << 1) & 0xFFFF)); - } else - IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM+((PPU.VMA.Address << 1) & 0xffff)); - PPU.VMA.Address += PPU.VMA.Increment; - } + byte = (IPPU.VRAMReadBuffer >> 8) & 0xff; + if (PPU.VMA.High) + { + if (PPU.VMA.FullGraphicCount) + { + uint32 addr = PPU.VMA.Address; + uint32 rem = addr & PPU.VMA.Mask1; + uint32 address = (addr & ~PPU.VMA.Mask1) + + (rem >> PPU.VMA.Shift) + + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3); + IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((address << 1) & 0xFFFF)); + } + else + IPPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((PPU.VMA.Address << 1) & + 0xffff)); + 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; - } + 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 - PPU.OpenBus1 = byte; - break; - - case 0x213B: - // Read palette data - if (PPU.CGFLIPRead) - byte = PPU.CGDATA [PPU.CGADD++] >> 8; - else - byte = PPU.CGDATA [PPU.CGADD] & 0xff; - - PPU.CGFLIPRead ^= 1; - return (PPU.OpenBus2 = byte); - - case 0x213C: - // Horizontal counter value 0-339 - if (PPU.HBeamFlip) - byte = (PPU.OpenBus2 & 0xfe) - | ((PPU.HBeamPosLatched >> 8) & 0x01); - - else - byte = (uint8)PPU.HBeamPosLatched; - PPU.OpenBus2 = byte; - PPU.HBeamFlip ^= 1; - break; - - case 0x213D: - // Vertical counter value 0-262 - if (PPU.VBeamFlip) - byte = (PPU.OpenBus2 & 0xfe) - | ((PPU.VBeamPosLatched >> 8) & 0x01); - else - byte = (uint8)PPU.VBeamPosLatched; - PPU.OpenBus2 = byte; - PPU.VBeamFlip ^= 1; - break; - - case 0x213E: - // PPU time and range over flags - FLUSH_REDRAW (); - - //so far, 5c77 version is always 1. - return (PPU.OpenBus1 = (Model->_5C77 | PPU.RangeTimeOver)); - - case 0x213F: - // NTSC/PAL and which field flags - PPU.VBeamFlip = PPU.HBeamFlip = 0; - //neviksti found a 2 and a 3 here. SNEeSe uses a 3. - //XXX: field flags not emulated - return ((Settings.PAL ? 0x10 : 0) | (Memory.FillRAM[0x213f] & 0xc0)| Model->_5C78) | (~PPU.OpenBus2 & 0x20); - - case 0x2140: case 0x2141: case 0x2142: case 0x2143: - case 0x2144: case 0x2145: case 0x2146: case 0x2147: - case 0x2148: case 0x2149: case 0x214a: case 0x214b: - case 0x214c: case 0x214d: case 0x214e: case 0x214f: - case 0x2150: case 0x2151: case 0x2152: case 0x2153: - case 0x2154: case 0x2155: case 0x2156: case 0x2157: - case 0x2158: case 0x2159: case 0x215a: case 0x215b: - case 0x215c: case 0x215d: case 0x215e: case 0x215f: - case 0x2160: case 0x2161: case 0x2162: case 0x2163: - case 0x2164: case 0x2165: case 0x2166: case 0x2167: - case 0x2168: case 0x2169: case 0x216a: case 0x216b: - case 0x216c: case 0x216d: case 0x216e: case 0x216f: - case 0x2170: case 0x2171: case 0x2172: case 0x2173: - case 0x2174: case 0x2175: case 0x2176: case 0x2177: - case 0x2178: case 0x2179: case 0x217a: case 0x217b: - case 0x217c: case 0x217d: case 0x217e: case 0x217f: + PPU.OpenBus1 = byte; + break; + + case 0x213B: + // Read palette data + if (PPU.CGFLIPRead) + byte = PPU.CGDATA [PPU.CGADD++] >> 8; + else + byte = PPU.CGDATA [PPU.CGADD] & 0xff; + + PPU.CGFLIPRead ^= 1; + return (PPU.OpenBus2 = byte); + + case 0x213C: + // Horizontal counter value 0-339 + if (PPU.HBeamFlip) + byte = (PPU.OpenBus2 & 0xfe) + | ((PPU.HBeamPosLatched >> 8) & 0x01); + + else + byte = (uint8)PPU.HBeamPosLatched; + PPU.OpenBus2 = byte; + PPU.HBeamFlip ^= 1; + break; + + case 0x213D: + // Vertical counter value 0-262 + if (PPU.VBeamFlip) + byte = (PPU.OpenBus2 & 0xfe) + | ((PPU.VBeamPosLatched >> 8) & 0x01); + else + byte = (uint8)PPU.VBeamPosLatched; + PPU.OpenBus2 = byte; + PPU.VBeamFlip ^= 1; + break; + + case 0x213E: + // PPU time and range over flags + FLUSH_REDRAW(); + + //so far, 5c77 version is always 1. + return (PPU.OpenBus1 = (Model->_5C77 | PPU.RangeTimeOver)); + + case 0x213F: + // NTSC/PAL and which field flags + PPU.VBeamFlip = PPU.HBeamFlip = 0; + //neviksti found a 2 and a 3 here. SNEeSe uses a 3. + //XXX: field flags not emulated + return ((Settings.PAL ? 0x10 : 0) | (Memory.FillRAM[0x213f] & 0xc0) | + Model->_5C78) | (~PPU.OpenBus2 & 0x20); + + case 0x2140: + case 0x2141: + case 0x2142: + case 0x2143: + case 0x2144: + case 0x2145: + case 0x2146: + case 0x2147: + case 0x2148: + case 0x2149: + case 0x214a: + case 0x214b: + case 0x214c: + case 0x214d: + case 0x214e: + case 0x214f: + case 0x2150: + case 0x2151: + case 0x2152: + case 0x2153: + case 0x2154: + case 0x2155: + case 0x2156: + case 0x2157: + case 0x2158: + case 0x2159: + case 0x215a: + case 0x215b: + case 0x215c: + case 0x215d: + case 0x215e: + case 0x215f: + case 0x2160: + case 0x2161: + case 0x2162: + case 0x2163: + case 0x2164: + case 0x2165: + case 0x2166: + case 0x2167: + case 0x2168: + case 0x2169: + case 0x216a: + case 0x216b: + case 0x216c: + case 0x216d: + case 0x216e: + case 0x216f: + case 0x2170: + case 0x2171: + case 0x2172: + case 0x2173: + case 0x2174: + case 0x2175: + case 0x2176: + case 0x2177: + case 0x2178: + case 0x2179: + case 0x217a: + case 0x217b: + case 0x217c: + case 0x217d: + case 0x217e: + case 0x217f: #ifdef SPCTOOL - return ((uint8) _SPCOutP [Address & 3]); + return ((uint8) _SPCOutP [Address & 3]); #else - // CPU.Flags |= DEBUG_MODE_FLAG; -#ifdef SPC700_SHUTDOWN - IAPU.APUExecuting = Settings.APUEnabled; - IAPU.WaitCounter++; + // CPU.Flags |= DEBUG_MODE_FLAG; +#ifdef SPC700_SHUTDOWN + IAPU.APUExecuting = Settings.APUEnabled; + IAPU.WaitCounter++; #endif - if (Settings.APUEnabled) - { + if (Settings.APUEnabled) + { #ifdef CPU_SHUTDOWN -// CPU.WaitAddress = CPU.PCAtOpcodeStart; + // CPU.WaitAddress = CPU.PCAtOpcodeStart; #endif - if (SNESGameFixes.APU_OutPorts_ReturnValueFix && - Address >= 0x2140 && Address <= 0x2143 && !CPU.V_Counter) - { - return (uint8)((Address & 1) ? ((rand() & 0xff00) >> 8) : - (rand() & 0xff)); - } - - return (APU.OutPorts [Address & 3]); - } - - switch (Settings.SoundSkipMethod) - { - case 0: - case 1: - case 3: - CPU.BranchSkip = TRUE; - break; - case 2: - break; - } - if ((Address & 3) < 2) - { - int r = rand (); - if (r & 2) - { - if (r & 4) - return ((Address & 3) == 1 ? 0xaa : 0xbb); - else - return ((r >> 3) & 0xff); - } - } - else - { - int r = rand (); - if (r & 2) - return ((r >> 3) & 0xff); - } - return (Memory.FillRAM[Address]); + if (SNESGameFixes.APU_OutPorts_ReturnValueFix && + Address >= 0x2140 && Address <= 0x2143 && !CPU.V_Counter) + { + return (uint8)((Address & 1) ? ((rand() & 0xff00) >> 8) : + (rand() & 0xff)); + } + + return (APU.OutPorts [Address & 3]); + } + + switch (Settings.SoundSkipMethod) + { + case 0: + case 1: + case 3: + CPU.BranchSkip = TRUE; + break; + case 2: + break; + } + if ((Address & 3) < 2) + { + int r = rand(); + if (r & 2) + { + if (r & 4) + return ((Address & 3) == 1 ? 0xaa : 0xbb); + else + return ((r >> 3) & 0xff); + } + } + else + { + int r = rand(); + if (r & 2) + return ((r >> 3) & 0xff); + } + return (Memory.FillRAM[Address]); #endif // SPCTOOL - case 0x2180: - // Read WRAM - byte = Memory.RAM [PPU.WRAM++]; - PPU.WRAM &= 0x1FFFF; - break; - case 0x2181: - case 0x2182: - case 0x2183: - default: - return OpenBus; - } - } - else - { - if (Settings.SA1) - return (S9xGetSA1 (Address)); - - if (Address <= 0x2fff || Address >= 0x3300) - { - switch (Address) - { - case 0x21c2: - if(Model->_5C77 ==2) - return (0x20); - - // fprintf(stderr, "Read from $21c2!\n"); - return OpenBus; - case 0x21c3: - if(Model->_5C77 ==2) - return (0); - // fprintf(stderr, "Read from $21c3!\n"); - return OpenBus; - case 0x2800: - // For Dai Kaijyu Monogatari II - if (Settings.SRTC) - return (S9xGetSRTC (Address)); - /*FALL*/ - - default: - return OpenBus; - } - } - - if (!Settings.SuperFX) - return OpenBus; + case 0x2180: + // Read WRAM + byte = Memory.RAM [PPU.WRAM++]; + PPU.WRAM &= 0x1FFFF; + break; + case 0x2181: + case 0x2182: + case 0x2183: + default: + return OpenBus; + } + } + else + { + if (Settings.SA1) + return (S9xGetSA1(Address)); + + if (Address <= 0x2fff || Address >= 0x3300) + { + switch (Address) + { + case 0x21c2: + if (Model->_5C77 == 2) + return (0x20); + + // fprintf(stderr, "Read from $21c2!\n"); + return OpenBus; + case 0x21c3: + if (Model->_5C77 == 2) + return (0); + // fprintf(stderr, "Read from $21c3!\n"); + return OpenBus; + case 0x2800: + // For Dai Kaijyu Monogatari II + if (Settings.SRTC) + return (S9xGetSRTC(Address)); + /*FALL*/ + + default: + return OpenBus; + } + } + + if (!Settings.SuperFX) + return OpenBus; #ifdef ZSNES_FX - if (Address < 0x3040) - byte = S9xSuperFXReadReg (Address); - else - byte = Memory.FillRAM [Address]; + if (Address < 0x3040) + byte = S9xSuperFXReadReg(Address); + else + byte = Memory.FillRAM [Address]; #ifdef CPU_SHUTDOWN - if (Address == 0x3030) - CPU.WaitAddress = CPU.PCAtOpcodeStart; -#endif - if (Address == 0x3031) - CLEAR_IRQ_SOURCE (GSU_IRQ_SOURCE); + if (Address == 0x3030) + CPU.WaitAddress = CPU.PCAtOpcodeStart; +#endif + if (Address == 0x3031) + CLEAR_IRQ_SOURCE(GSU_IRQ_SOURCE); #else - byte = Memory.FillRAM [Address]; + byte = Memory.FillRAM [Address]; -//if (Address != 0x3030 && Address != 0x3031) -//printf ("%04x\n", Address); + //if (Address != 0x3030 && Address != 0x3031) + //printf ("%04x\n", Address); #ifdef CPU_SHUTDOWN - if (Address == 0x3030) - { - CPU.WaitAddress = CPU.PCAtOpcodeStart; - } - else + if (Address == 0x3030) + CPU.WaitAddress = CPU.PCAtOpcodeStart; + else #endif - if (Address == 0x3031) - { - CLEAR_IRQ_SOURCE (GSU_IRQ_SOURCE); - Memory.FillRAM [0x3031] = byte & 0x7f; - } - return (byte); + if (Address == 0x3031) + { + CLEAR_IRQ_SOURCE(GSU_IRQ_SOURCE); + Memory.FillRAM [0x3031] = byte & 0x7f; + } + return (byte); #endif - } -// fprintf(stderr, "%03d: %02x from %04x\n", CPU.V_Counter, byte, Address); - return (byte); + } + // fprintf(stderr, "%03d: %02x from %04x\n", CPU.V_Counter, byte, Address); + return (byte); } /******************************************************************************/ /* S9xSetCPU() */ /* This function sets a CPU/DMA Register to a specific byte */ /******************************************************************************/ -void S9xSetCPU (uint8 byte, uint16 Address) +void S9xSetCPU(uint8 byte, uint16 Address) { - int d; -// fprintf(stderr, "%03d: %02x to %04x\n", CPU.V_Counter, byte, Address); - - if (Address < 0x4200) - { - CPU.Cycles += ONE_CYCLE; - switch (Address) - { - case 0x4016: - // S9xReset reading of old-style joypads - if ((byte & 1) && !(Memory.FillRAM [Address] & 1)) - { - PPU.Joypad1ButtonReadPos = 0; - PPU.Joypad2ButtonReadPos = 0; - PPU.Joypad3ButtonReadPos = 0; - } - break; - case 0x4017: - break; - default: - break; - } - } - else - switch (Address) - { - case 0x4200: - // NMI, V & H IRQ and joypad reading enable flags - if (byte & 0x20) - { - //if(!SNESGameFixes.umiharakawaseFix && PPU.IRQVBeamPos==262) fprintf(stderr, "PPU.IRQVBeamPos = %d, CPU.V_Counter = %d\n", PPU.IRQVBeamPos, CPU.V_Counter); - if (!PPU.VTimerEnabled) - { - PPU.VTimerEnabled = TRUE; - if (PPU.HTimerEnabled) - S9xUpdateHTimer (); - else - if (PPU.IRQVBeamPos == CPU.V_Counter) - S9xSetIRQ (PPU_V_BEAM_IRQ_SOURCE); - } - } - else - { - PPU.VTimerEnabled = FALSE; -// if (SNESGameFixes.umiharakawaseFix) -// byte &= ~0x20; - } - - if (byte & 0x10) - { - if (!PPU.HTimerEnabled) - { - PPU.HTimerEnabled = TRUE; - S9xUpdateHTimer (); - } - } - else - { - // No need to check for HTimer being disabled as the scanline - // event trigger code won't trigger an H-IRQ unless its enabled. - PPU.HTimerEnabled = FALSE; - PPU.HTimerPosition = Settings.H_Max + 1; - } - if (!Settings.DaffyDuck) - CLEAR_IRQ_SOURCE (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE); - - if ((byte & 0x80) && - !(Memory.FillRAM [0x4200] & 0x80) && - CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE && - CPU.V_Counter <= PPU.ScreenHeight + - (SNESGameFixes.alienVSpredetorFix ? 25 : 15) && //jyam 15->25 alien vs predetor -// Panic Bomberman clears the NMI pending flag @ scanline 230 before enabling -// NMIs again. The NMI routine crashes the CPU if it is called without the NMI -// pending flag being set... - (Memory.FillRAM [0x4210] & 0x80) && - !CPU.NMIActive) - { - CPU.Flags |= NMI_FLAG; - CPU.NMIActive = TRUE; - CPU.NMICycleCount = CPU.NMITriggerPoint; - } - break; - case 0x4201: - if((byte&0x80)==0 && (Memory.FillRAM[0x4213]&0x80)==0x80) - S9xLatchCounters(1); - Memory.FillRAM[0x4201] = Memory.FillRAM[0x4213] = byte; - break; - case 0x4202: - // Multiplier (for multply) - break; - case 0x4203: - { - // Multiplicand - uint32 res = Memory.FillRAM[0x4202] * byte; + int d; + // fprintf(stderr, "%03d: %02x to %04x\n", CPU.V_Counter, byte, Address); + + if (Address < 0x4200) + { + CPU.Cycles += ONE_CYCLE; + switch (Address) + { + case 0x4016: + // S9xReset reading of old-style joypads + if ((byte & 1) && !(Memory.FillRAM [Address] & 1)) + { + PPU.Joypad1ButtonReadPos = 0; + PPU.Joypad2ButtonReadPos = 0; + PPU.Joypad3ButtonReadPos = 0; + } + break; + case 0x4017: + break; + default: + break; + } + } + else + switch (Address) + { + case 0x4200: + // NMI, V & H IRQ and joypad reading enable flags + if (byte & 0x20) + { + //if(!SNESGameFixes.umiharakawaseFix && PPU.IRQVBeamPos==262) fprintf(stderr, "PPU.IRQVBeamPos = %d, CPU.V_Counter = %d\n", PPU.IRQVBeamPos, CPU.V_Counter); + if (!PPU.VTimerEnabled) + { + PPU.VTimerEnabled = TRUE; + if (PPU.HTimerEnabled) + S9xUpdateHTimer(); + else if (PPU.IRQVBeamPos == CPU.V_Counter) + S9xSetIRQ(PPU_V_BEAM_IRQ_SOURCE); + } + } + else + { + PPU.VTimerEnabled = FALSE; + // if (SNESGameFixes.umiharakawaseFix) + // byte &= ~0x20; + } + + if (byte & 0x10) + { + if (!PPU.HTimerEnabled) + { + PPU.HTimerEnabled = TRUE; + S9xUpdateHTimer(); + } + } + else + { + // No need to check for HTimer being disabled as the scanline + // event trigger code won't trigger an H-IRQ unless its enabled. + PPU.HTimerEnabled = FALSE; + PPU.HTimerPosition = Settings.H_Max + 1; + } + if (!Settings.DaffyDuck) + CLEAR_IRQ_SOURCE(PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE); + + if ((byte & 0x80) && + !(Memory.FillRAM [0x4200] & 0x80) && + CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE && + CPU.V_Counter <= PPU.ScreenHeight + + (SNESGameFixes.alienVSpredetorFix ? 25 : 15) + && //jyam 15->25 alien vs predetor + // Panic Bomberman clears the NMI pending flag @ scanline 230 before enabling + // NMIs again. The NMI routine crashes the CPU if it is called without the NMI + // pending flag being set... + (Memory.FillRAM [0x4210] & 0x80) && + !CPU.NMIActive) + { + CPU.Flags |= NMI_FLAG; + CPU.NMIActive = TRUE; + CPU.NMICycleCount = CPU.NMITriggerPoint; + } + break; + case 0x4201: + if ((byte & 0x80) == 0 && (Memory.FillRAM[0x4213] & 0x80) == 0x80) + S9xLatchCounters(1); + Memory.FillRAM[0x4201] = Memory.FillRAM[0x4213] = byte; + break; + case 0x4202: + // Multiplier (for multply) + break; + case 0x4203: + { + // Multiplicand + uint32 res = Memory.FillRAM[0x4202] * byte; #if defined FAST_LSB_WORD_ACCESS || defined FAST_ALIGNED_LSB_WORD_ACCESS - // assume malloc'd memory is 2-byte aligned - * ((uint16 *) &Memory.FillRAM[0x4216]) = res; + // assume malloc'd memory is 2-byte aligned + * ((uint16*) &Memory.FillRAM[0x4216]) = res; #else - Memory.FillRAM[0x4216] = (uint8) res; - Memory.FillRAM[0x4217] = (uint8) (res >> 8); + Memory.FillRAM[0x4216] = (uint8) res; + Memory.FillRAM[0x4217] = (uint8)(res >> 8); #endif - break; - } - case 0x4204: - case 0x4205: - // Low and high muliplier (for divide) - break; - case 0x4206: - { + break; + } + case 0x4204: + case 0x4205: + // Low and high muliplier (for divide) + break; + case 0x4206: + { #if defined FAST_LSB_WORD_ACCESS || defined FAST_ALIGNED_LSB_WORD_ACCESS - // assume malloc'd memory is 2-byte aligned - uint16 a = *((uint16 *) &Memory.FillRAM[0x4204]); + // assume malloc'd memory is 2-byte aligned + uint16 a = *((uint16*) &Memory.FillRAM[0x4204]); #else - uint16 a = Memory.FillRAM[0x4204] + (Memory.FillRAM[0x4205] << 8); + uint16 a = Memory.FillRAM[0x4204] + (Memory.FillRAM[0x4205] << 8); #endif - uint16 div = byte ? a / byte : 0xffff; - uint16 rem = byte ? a % byte : a; + uint16 div = byte ? a / byte : 0xffff; + uint16 rem = byte ? a % byte : a; #if defined FAST_LSB_WORD_ACCESS || defined FAST_ALIGNED_LSB_WORD_ACCESS - // assume malloc'd memory is 2-byte aligned - * ((uint16 *) &Memory.FillRAM[0x4214]) = div; - * ((uint16 *) &Memory.FillRAM[0x4216]) = rem; + // assume malloc'd memory is 2-byte aligned + * ((uint16*) &Memory.FillRAM[0x4214]) = div; + * ((uint16*) &Memory.FillRAM[0x4216]) = rem; #else - Memory.FillRAM[0x4214] = (uint8)div; - Memory.FillRAM[0x4215] = div >> 8; - Memory.FillRAM[0x4216] = (uint8)rem; - Memory.FillRAM[0x4217] = rem >> 8; + Memory.FillRAM[0x4214] = (uint8)div; + Memory.FillRAM[0x4215] = div >> 8; + Memory.FillRAM[0x4216] = (uint8)rem; + Memory.FillRAM[0x4217] = rem >> 8; #endif - break; - } - case 0x4207: - d = PPU.IRQHBeamPos; - PPU.IRQHBeamPos = (PPU.IRQHBeamPos & 0xFF00) | byte; - - if (PPU.HTimerEnabled && PPU.IRQHBeamPos != d) - S9xUpdateHTimer (); - break; - - case 0x4208: - d = PPU.IRQHBeamPos; - PPU.IRQHBeamPos = (PPU.IRQHBeamPos & 0xFF) | ((byte & 1) << 8); - - if (PPU.HTimerEnabled && PPU.IRQHBeamPos != d) - S9xUpdateHTimer (); - - break; - - case 0x4209: - d = PPU.IRQVBeamPos; - PPU.IRQVBeamPos = (PPU.IRQVBeamPos & 0xFF00) | byte; - if (PPU.VTimerEnabled && PPU.IRQVBeamPos != d) - { - if (PPU.HTimerEnabled) - S9xUpdateHTimer (); - else - { - if (PPU.IRQVBeamPos == CPU.V_Counter) - S9xSetIRQ (PPU_V_BEAM_IRQ_SOURCE); - } - } - break; - - case 0x420A: - d = PPU.IRQVBeamPos; - PPU.IRQVBeamPos = (PPU.IRQVBeamPos & 0xFF) | ((byte & 1) << 8); - if (PPU.VTimerEnabled && PPU.IRQVBeamPos != d) - { - if (PPU.HTimerEnabled) - S9xUpdateHTimer (); - else - { - if (PPU.IRQVBeamPos == CPU.V_Counter) - S9xSetIRQ (PPU_V_BEAM_IRQ_SOURCE); - } - } - break; - - case 0x420B: - if ((byte & 0x01) != 0) - S9xDoDMA (0); - if ((byte & 0x02) != 0) - S9xDoDMA (1); - if ((byte & 0x04) != 0) - S9xDoDMA (2); - if ((byte & 0x08) != 0) - S9xDoDMA (3); - if ((byte & 0x10) != 0) - S9xDoDMA (4); - if ((byte & 0x20) != 0) - S9xDoDMA (5); - if ((byte & 0x40) != 0) - S9xDoDMA (6); - if ((byte & 0x80) != 0) - S9xDoDMA (7); - break; - case 0x420C: - if (Settings.DisableHDMA) - byte = 0; - Memory.FillRAM[0x420c] = byte; - IPPU.HDMA = byte; - break; - - case 0x420d: - // Cycle speed 0 - 2.68Mhz, 1 - 3.58Mhz (banks 0x80 +) - if ((byte & 1) != (Memory.FillRAM [0x420d] & 1)) - { - if (byte & 1) - { - CPU.FastROMSpeed = ONE_CYCLE; - } - else CPU.FastROMSpeed = SLOW_ONE_CYCLE; - - FixROMSpeed (); - } - break; - - case 0x420e: - case 0x420f: - // --->>> Unknown - break; - case 0x4210: - // NMI ocurred flag (reset on read or write) - Memory.FillRAM[0x4210] = Model->_5A22; - return; - case 0x4211: - // IRQ ocurred flag (reset on read or write) - CLEAR_IRQ_SOURCE (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE); - break; - case 0x4212: - // v-blank, h-blank and joypad being scanned flags (read-only) - /* fall through */ - case 0x4213: - // I/O Port (read-only) - /* fall through */ - case 0x4214: - case 0x4215: - // Quotent of divide (read-only) - /* fall through */ - case 0x4216: - case 0x4217: - // Multiply product (read-only) - /* fall through */ - case 0x4218: - case 0x4219: - case 0x421a: - case 0x421b: - case 0x421c: - case 0x421d: - case 0x421e: - case 0x421f: - // Joypad values (read-only) - return; - - case 0x4300: - case 0x4310: - case 0x4320: - case 0x4330: - case 0x4340: - case 0x4350: - case 0x4360: - case 0x4370: - d = (Address >> 4) & 0x7; - DMA[d].TransferDirection = (byte & 128) != 0 ? 1 : 0; - DMA[d].HDMAIndirectAddressing = (byte & 64) != 0 ? 1 : 0; - DMA[d].AAddressDecrement = (byte & 16) != 0 ? 1 : 0; - DMA[d].AAddressFixed = (byte & 8) != 0 ? 1 : 0; - DMA[d].TransferMode = (byte & 7); - break; - - case 0x4301: - case 0x4311: - case 0x4321: - case 0x4331: - case 0x4341: - case 0x4351: - case 0x4361: - case 0x4371: - DMA[((Address >> 4) & 0x7)].BAddress = byte; - break; - - case 0x4302: - case 0x4312: - case 0x4322: - case 0x4332: - case 0x4342: - case 0x4352: - case 0x4362: - case 0x4372: - d = (Address >> 4) & 0x7; - DMA[d].AAddress &= 0xFF00; - DMA[d].AAddress |= byte; - break; - - case 0x4303: - case 0x4313: - case 0x4323: - case 0x4333: - case 0x4343: - case 0x4353: - case 0x4363: - case 0x4373: - d = (Address >> 4) & 0x7; - DMA[d].AAddress &= 0xFF; - DMA[d].AAddress |= byte << 8; - break; - - case 0x4304: - case 0x4314: - case 0x4324: - case 0x4334: - case 0x4344: - case 0x4354: - case 0x4364: - case 0x4374: - DMA[((Address >> 4) & 0x7)].ABank = byte; - HDMAMemPointers[((Address >> 4) & 0x7)]=NULL; - - break; - - case 0x4305: - case 0x4315: - case 0x4325: - case 0x4335: - case 0x4345: - case 0x4355: - case 0x4365: - case 0x4375: - d = (Address >> 4) & 0x7; - DMA[d].TransferBytes &= 0xFF00; - DMA[d].TransferBytes |= byte; - DMA[d].IndirectAddress &= 0xff00; - DMA[d].IndirectAddress |= byte; - HDMAMemPointers[d]=NULL; - break; - - case 0x4306: - case 0x4316: - case 0x4326: - case 0x4336: - case 0x4346: - case 0x4356: - case 0x4366: - case 0x4376: - d = (Address >> 4) & 0x7; - DMA[d].TransferBytes &= 0xFF; - DMA[d].TransferBytes |= byte << 8; - DMA[d].IndirectAddress &= 0xff; - DMA[d].IndirectAddress |= byte << 8; - HDMAMemPointers[d]=NULL; - break; - - case 0x4307: - case 0x4317: - case 0x4327: - case 0x4337: - case 0x4347: - case 0x4357: - case 0x4367: - case 0x4377: - DMA[d = ((Address >> 4) & 0x7)].IndirectBank = byte; - HDMAMemPointers[d]=NULL; - break; - - case 0x4308: - case 0x4318: - case 0x4328: - case 0x4338: - case 0x4348: - case 0x4358: - case 0x4368: - case 0x4378: - d = (Address >> 4) & 7; - DMA[d].Address &= 0xff00; - DMA[d].Address |= byte; - HDMAMemPointers[d] = NULL; - break; - - case 0x4309: - case 0x4319: - case 0x4329: - case 0x4339: - case 0x4349: - case 0x4359: - case 0x4369: - case 0x4379: - d = (Address >> 4) & 0x7; - DMA[d].Address &= 0xff; - DMA[d].Address |= byte << 8; - HDMAMemPointers[d] = NULL; - break; - - case 0x430A: - case 0x431A: - case 0x432A: - case 0x433A: - case 0x434A: - case 0x435A: - case 0x436A: - case 0x437A: - d = (Address >> 4) & 0x7; - DMA[d].LineCount = byte & 0x7f; - DMA[d].Repeat = !(byte & 0x80); - break; - - case 0x430F: - case 0x431F: - case 0x432F: - case 0x433F: - case 0x434F: - case 0x435F: - case 0x436F: - case 0x437F: - Address &= ~4; // Convert 43xF to 43xB - /* fall through */ - case 0x430B: - case 0x431B: - case 0x432B: - case 0x433B: - case 0x434B: - case 0x435B: - case 0x436B: - case 0x437B: - - // Unknown, but they seem to be RAM-ish + break; + } + case 0x4207: + d = PPU.IRQHBeamPos; + PPU.IRQHBeamPos = (PPU.IRQHBeamPos & 0xFF00) | byte; + + if (PPU.HTimerEnabled && PPU.IRQHBeamPos != d) + S9xUpdateHTimer(); + break; + + case 0x4208: + d = PPU.IRQHBeamPos; + PPU.IRQHBeamPos = (PPU.IRQHBeamPos & 0xFF) | ((byte & 1) << 8); + + if (PPU.HTimerEnabled && PPU.IRQHBeamPos != d) + S9xUpdateHTimer(); + + break; + + case 0x4209: + d = PPU.IRQVBeamPos; + PPU.IRQVBeamPos = (PPU.IRQVBeamPos & 0xFF00) | byte; + if (PPU.VTimerEnabled && PPU.IRQVBeamPos != d) + { + if (PPU.HTimerEnabled) + S9xUpdateHTimer(); + else + { + if (PPU.IRQVBeamPos == CPU.V_Counter) + S9xSetIRQ(PPU_V_BEAM_IRQ_SOURCE); + } + } + break; + + case 0x420A: + d = PPU.IRQVBeamPos; + PPU.IRQVBeamPos = (PPU.IRQVBeamPos & 0xFF) | ((byte & 1) << 8); + if (PPU.VTimerEnabled && PPU.IRQVBeamPos != d) + { + if (PPU.HTimerEnabled) + S9xUpdateHTimer(); + else + { + if (PPU.IRQVBeamPos == CPU.V_Counter) + S9xSetIRQ(PPU_V_BEAM_IRQ_SOURCE); + } + } + break; + + case 0x420B: + if ((byte & 0x01) != 0) + S9xDoDMA(0); + if ((byte & 0x02) != 0) + S9xDoDMA(1); + if ((byte & 0x04) != 0) + S9xDoDMA(2); + if ((byte & 0x08) != 0) + S9xDoDMA(3); + if ((byte & 0x10) != 0) + S9xDoDMA(4); + if ((byte & 0x20) != 0) + S9xDoDMA(5); + if ((byte & 0x40) != 0) + S9xDoDMA(6); + if ((byte & 0x80) != 0) + S9xDoDMA(7); + break; + case 0x420C: + if (Settings.DisableHDMA) + byte = 0; + Memory.FillRAM[0x420c] = byte; + IPPU.HDMA = byte; + break; + + case 0x420d: + // Cycle speed 0 - 2.68Mhz, 1 - 3.58Mhz (banks 0x80 +) + if ((byte & 1) != (Memory.FillRAM [0x420d] & 1)) + { + if (byte & 1) + CPU.FastROMSpeed = ONE_CYCLE; + else CPU.FastROMSpeed = SLOW_ONE_CYCLE; + + FixROMSpeed(); + } + break; + + case 0x420e: + case 0x420f: + // --->>> Unknown + break; + case 0x4210: + // NMI ocurred flag (reset on read or write) + Memory.FillRAM[0x4210] = Model->_5A22; + return; + case 0x4211: + // IRQ ocurred flag (reset on read or write) + CLEAR_IRQ_SOURCE(PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE); + break; + case 0x4212: + // v-blank, h-blank and joypad being scanned flags (read-only) + /* fall through */ + case 0x4213: + // I/O Port (read-only) + /* fall through */ + case 0x4214: + case 0x4215: + // Quotent of divide (read-only) + /* fall through */ + case 0x4216: + case 0x4217: + // Multiply product (read-only) + /* fall through */ + case 0x4218: + case 0x4219: + case 0x421a: + case 0x421b: + case 0x421c: + case 0x421d: + case 0x421e: + case 0x421f: + // Joypad values (read-only) + return; + + case 0x4300: + case 0x4310: + case 0x4320: + case 0x4330: + case 0x4340: + case 0x4350: + case 0x4360: + case 0x4370: + d = (Address >> 4) & 0x7; + DMA[d].TransferDirection = (byte & 128) != 0 ? 1 : 0; + DMA[d].HDMAIndirectAddressing = (byte & 64) != 0 ? 1 : 0; + DMA[d].AAddressDecrement = (byte & 16) != 0 ? 1 : 0; + DMA[d].AAddressFixed = (byte & 8) != 0 ? 1 : 0; + DMA[d].TransferMode = (byte & 7); + break; + + case 0x4301: + case 0x4311: + case 0x4321: + case 0x4331: + case 0x4341: + case 0x4351: + case 0x4361: + case 0x4371: + DMA[((Address >> 4) & 0x7)].BAddress = byte; + break; + + case 0x4302: + case 0x4312: + case 0x4322: + case 0x4332: + case 0x4342: + case 0x4352: + case 0x4362: + case 0x4372: + d = (Address >> 4) & 0x7; + DMA[d].AAddress &= 0xFF00; + DMA[d].AAddress |= byte; + break; + + case 0x4303: + case 0x4313: + case 0x4323: + case 0x4333: + case 0x4343: + case 0x4353: + case 0x4363: + case 0x4373: + d = (Address >> 4) & 0x7; + DMA[d].AAddress &= 0xFF; + DMA[d].AAddress |= byte << 8; + break; + + case 0x4304: + case 0x4314: + case 0x4324: + case 0x4334: + case 0x4344: + case 0x4354: + case 0x4364: + case 0x4374: + DMA[((Address >> 4) & 0x7)].ABank = byte; + HDMAMemPointers[((Address >> 4) & 0x7)] = NULL; + + break; + + case 0x4305: + case 0x4315: + case 0x4325: + case 0x4335: + case 0x4345: + case 0x4355: + case 0x4365: + case 0x4375: + d = (Address >> 4) & 0x7; + DMA[d].TransferBytes &= 0xFF00; + DMA[d].TransferBytes |= byte; + DMA[d].IndirectAddress &= 0xff00; + DMA[d].IndirectAddress |= byte; + HDMAMemPointers[d] = NULL; + break; + + case 0x4306: + case 0x4316: + case 0x4326: + case 0x4336: + case 0x4346: + case 0x4356: + case 0x4366: + case 0x4376: + d = (Address >> 4) & 0x7; + DMA[d].TransferBytes &= 0xFF; + DMA[d].TransferBytes |= byte << 8; + DMA[d].IndirectAddress &= 0xff; + DMA[d].IndirectAddress |= byte << 8; + HDMAMemPointers[d] = NULL; + break; + + case 0x4307: + case 0x4317: + case 0x4327: + case 0x4337: + case 0x4347: + case 0x4357: + case 0x4367: + case 0x4377: + DMA[d = ((Address >> 4) & 0x7)].IndirectBank = byte; + HDMAMemPointers[d] = NULL; + break; + + case 0x4308: + case 0x4318: + case 0x4328: + case 0x4338: + case 0x4348: + case 0x4358: + case 0x4368: + case 0x4378: + d = (Address >> 4) & 7; + DMA[d].Address &= 0xff00; + DMA[d].Address |= byte; + HDMAMemPointers[d] = NULL; + break; + + case 0x4309: + case 0x4319: + case 0x4329: + case 0x4339: + case 0x4349: + case 0x4359: + case 0x4369: + case 0x4379: + d = (Address >> 4) & 0x7; + DMA[d].Address &= 0xff; + DMA[d].Address |= byte << 8; + HDMAMemPointers[d] = NULL; + break; + + case 0x430A: + case 0x431A: + case 0x432A: + case 0x433A: + case 0x434A: + case 0x435A: + case 0x436A: + case 0x437A: + d = (Address >> 4) & 0x7; + DMA[d].LineCount = byte & 0x7f; + DMA[d].Repeat = !(byte & 0x80); + break; + + case 0x430F: + case 0x431F: + case 0x432F: + case 0x433F: + case 0x434F: + case 0x435F: + case 0x436F: + case 0x437F: + Address &= ~4; // Convert 43xF to 43xB + /* fall through */ + case 0x430B: + case 0x431B: + case 0x432B: + case 0x433B: + case 0x434B: + case 0x435B: + case 0x436B: + case 0x437B: + + // Unknown, but they seem to be RAM-ish #if 0 - fprintf(stderr, "Write %02x to %04x!\n", byte, Address); + fprintf(stderr, "Write %02x to %04x!\n", byte, Address); #endif - break; - - //These registers are used by both the S-DD1 and the SPC7110 - case 0x4800: - case 0x4801: - case 0x4802: - case 0x4803: - if(Settings.SPC7110) - S9xSetSPC7110(byte, Address); - //printf ("%02x->%04x\n", byte, Address); - break; - - case 0x4804: - case 0x4805: - case 0x4806: - case 0x4807: - //printf ("%02x->%04x\n", byte, Address); - if(Settings.SPC7110) - S9xSetSPC7110(byte, Address); - else S9xSetSDD1MemoryMap (Address - 0x4804, byte & 7); - break; - - //these are used by the SPC7110 - case 0x4808: - case 0x4809: - case 0x480A: - case 0x480B: - case 0x480C: - case 0x4810: - case 0x4811: - case 0x4812: - case 0x4813: - case 0x4814: - case 0x4815: - case 0x4816: - case 0x4817: - case 0x4818: - case 0x481A: - case 0x4820: - case 0x4821: - case 0x4822: - case 0x4823: - case 0x4824: - case 0x4825: - case 0x4826: - case 0x4827: - case 0x4828: - case 0x4829: - case 0x482A: - case 0x482B: - case 0x482C: - case 0x482D: - case 0x482E: - case 0x482F: - case 0x4830: - case 0x4831: - case 0x4832: - case 0x4833: - case 0x4834: - case 0x4840: - case 0x4841: - case 0x4842: - if(Settings.SPC7110) - { - S9xSetSPC7110(byte, Address); - break; - } - - default: - break; - } - Memory.FillRAM [Address] = byte; + break; + + //These registers are used by both the S-DD1 and the SPC7110 + case 0x4800: + case 0x4801: + case 0x4802: + case 0x4803: + if (Settings.SPC7110) + S9xSetSPC7110(byte, Address); + //printf ("%02x->%04x\n", byte, Address); + break; + + case 0x4804: + case 0x4805: + case 0x4806: + case 0x4807: + //printf ("%02x->%04x\n", byte, Address); + if (Settings.SPC7110) + S9xSetSPC7110(byte, Address); + else S9xSetSDD1MemoryMap(Address - 0x4804, byte & 7); + break; + + //these are used by the SPC7110 + case 0x4808: + case 0x4809: + case 0x480A: + case 0x480B: + case 0x480C: + case 0x4810: + case 0x4811: + case 0x4812: + case 0x4813: + case 0x4814: + case 0x4815: + case 0x4816: + case 0x4817: + case 0x4818: + case 0x481A: + case 0x4820: + case 0x4821: + case 0x4822: + case 0x4823: + case 0x4824: + case 0x4825: + case 0x4826: + case 0x4827: + case 0x4828: + case 0x4829: + case 0x482A: + case 0x482B: + case 0x482C: + case 0x482D: + case 0x482E: + case 0x482F: + case 0x4830: + case 0x4831: + case 0x4832: + case 0x4833: + case 0x4834: + case 0x4840: + case 0x4841: + case 0x4842: + if (Settings.SPC7110) + { + S9xSetSPC7110(byte, Address); + break; + } + + default: + break; + } + Memory.FillRAM [Address] = byte; } /******************************************************************************/ /* S9xGetCPU() */ /* This function retrieves a CPU/DMA Register */ /******************************************************************************/ -uint8 S9xGetCPU (uint16 Address) +uint8 S9xGetCPU(uint16 Address) { - uint8 byte; -// fprintf(stderr, "read from %04x\n", Address); - - if (Address < 0x4200) - { - CPU.Cycles += ONE_CYCLE; - switch (Address) - { - case 0x4016: - { - if (Memory.FillRAM [0x4016] & 1) - { - if ((!Settings.SwapJoypads && - IPPU.Controller == SNES_MOUSE_SWAPPED) || - (Settings.SwapJoypads && - IPPU.Controller == SNES_MOUSE)) - { - if (++PPU.MouseSpeed [0] > 2) - PPU.MouseSpeed [0] = 0; - } - return (0); - } - - int ind = Settings.SwapJoypads ? 1 : 0; - byte = IPPU.Joypads[ind] >> (PPU.Joypad1ButtonReadPos ^ 15); - PPU.Joypad1ButtonReadPos++; - return (byte & 1); - } - case 0x4017: - { - if (Memory.FillRAM [0x4016] & 1) - { - // MultiPlayer5 adaptor is only allowed to be plugged into port 2 - switch (IPPU.Controller) - { - case SNES_MULTIPLAYER5: - return (2); - case SNES_MOUSE_SWAPPED: - if (Settings.SwapJoypads && ++PPU.MouseSpeed [0] > 2) - PPU.MouseSpeed [0] = 0; - break; - - case SNES_MOUSE: - if (!Settings.SwapJoypads && ++PPU.MouseSpeed [0] > 2) - PPU.MouseSpeed [0] = 0; - break; - } - return (0x00); - } - - int ind = Settings.SwapJoypads ? 0 : 1; - - if (IPPU.Controller == SNES_MULTIPLAYER5) - { - if (Memory.FillRAM [0x4201] & 0x80) - { - byte = ((IPPU.Joypads[ind] >> (PPU.Joypad2ButtonReadPos ^ 15)) & 1) | - (((IPPU.Joypads[2] >> (PPU.Joypad2ButtonReadPos ^ 15)) & 1) << 1); - PPU.Joypad2ButtonReadPos++; - return (byte); - } - else - { - byte = ((IPPU.Joypads[3] >> (PPU.Joypad3ButtonReadPos ^ 15)) & 1) | - (((IPPU.Joypads[4] >> (PPU.Joypad3ButtonReadPos ^ 15)) & 1) << 1); - PPU.Joypad3ButtonReadPos++; - return (byte); - } - } - else if(IPPU.Controller ==SNES_JUSTIFIER || IPPU.Controller ==SNES_JUSTIFIER_2) - { - uint8 rv; - rv=(1&(justifiers>>in_bit)); - in_bit++; - in_bit%=32; - return rv; - } - return ((IPPU.Joypads[ind] >> (PPU.Joypad2ButtonReadPos++ ^ 15)) & 1); - } - default: - return OpenBus; - } -// return (Memory.FillRAM [Address]); - } - else - switch (Address) - { - case 0x4200: - case 0x4201: - case 0x4202: - case 0x4203: - case 0x4204: - case 0x4205: - case 0x4206: - case 0x4207: - case 0x4208: - case 0x4209: - case 0x420a: - case 0x420b: - case 0x420c: - case 0x420d: - case 0x420e: - case 0x420f: - return OpenBus; - - case 0x4210: + uint8 byte; + // fprintf(stderr, "read from %04x\n", Address); + + if (Address < 0x4200) + { + CPU.Cycles += ONE_CYCLE; + switch (Address) + { + case 0x4016: + { + if (Memory.FillRAM [0x4016] & 1) + { + if ((!Settings.SwapJoypads && + IPPU.Controller == SNES_MOUSE_SWAPPED) || + (Settings.SwapJoypads && + IPPU.Controller == SNES_MOUSE)) + { + if (++PPU.MouseSpeed [0] > 2) + PPU.MouseSpeed [0] = 0; + } + return (0); + } + + int ind = Settings.SwapJoypads ? 1 : 0; + byte = IPPU.Joypads[ind] >> (PPU.Joypad1ButtonReadPos ^ 15); + PPU.Joypad1ButtonReadPos++; + return (byte & 1); + } + case 0x4017: + { + if (Memory.FillRAM [0x4016] & 1) + { + // MultiPlayer5 adaptor is only allowed to be plugged into port 2 + switch (IPPU.Controller) + { + case SNES_MULTIPLAYER5: + return (2); + case SNES_MOUSE_SWAPPED: + if (Settings.SwapJoypads && ++PPU.MouseSpeed [0] > 2) + PPU.MouseSpeed [0] = 0; + break; + + case SNES_MOUSE: + if (!Settings.SwapJoypads && ++PPU.MouseSpeed [0] > 2) + PPU.MouseSpeed [0] = 0; + break; + } + return (0x00); + } + + int ind = Settings.SwapJoypads ? 0 : 1; + + if (IPPU.Controller == SNES_MULTIPLAYER5) + { + if (Memory.FillRAM [0x4201] & 0x80) + { + byte = ((IPPU.Joypads[ind] >> (PPU.Joypad2ButtonReadPos ^ 15)) & 1) | + (((IPPU.Joypads[2] >> (PPU.Joypad2ButtonReadPos ^ 15)) & 1) << 1); + PPU.Joypad2ButtonReadPos++; + return (byte); + } + else + { + byte = ((IPPU.Joypads[3] >> (PPU.Joypad3ButtonReadPos ^ 15)) & 1) | + (((IPPU.Joypads[4] >> (PPU.Joypad3ButtonReadPos ^ 15)) & 1) << 1); + PPU.Joypad3ButtonReadPos++; + return (byte); + } + } + else if (IPPU.Controller == SNES_JUSTIFIER + || IPPU.Controller == SNES_JUSTIFIER_2) + { + uint8 rv; + rv = (1 & (justifiers >> in_bit)); + in_bit++; + in_bit %= 32; + return rv; + } + return ((IPPU.Joypads[ind] >> (PPU.Joypad2ButtonReadPos++ ^ 15)) & 1); + } + default: + return OpenBus; + } + // return (Memory.FillRAM [Address]); + } + else + switch (Address) + { + case 0x4200: + case 0x4201: + case 0x4202: + case 0x4203: + case 0x4204: + case 0x4205: + case 0x4206: + case 0x4207: + case 0x4208: + case 0x4209: + case 0x420a: + case 0x420b: + case 0x420c: + case 0x420d: + case 0x420e: + case 0x420f: + return OpenBus; + + case 0x4210: #ifdef CPU_SHUTDOWN - CPU.WaitAddress = CPU.PCAtOpcodeStart; -#endif - byte = Memory.FillRAM[0x4210]; - Memory.FillRAM[0x4210] = Model->_5A22; - //SNEeSe returns 2 for 5A22 version. - return ((byte&0x80) - |(OpenBus&0x70) - |Model->_5A22); - - case 0x4211: - byte = (CPU.IRQActive & (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE)) ? 0x80 : 0; - // Super Robot Wars Ex ROM bug requires this. - byte |= CPU.Cycles >= Settings.HBlankStart ? 0x40 : 0; - CLEAR_IRQ_SOURCE (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE); - - // Maybe? Register Scan indicated open bus... - byte |= OpenBus&0x3f; - - return (byte); - - case 0x4212: - // V-blank, h-blank and joypads being read flags (read-only) + CPU.WaitAddress = CPU.PCAtOpcodeStart; +#endif + byte = Memory.FillRAM[0x4210]; + Memory.FillRAM[0x4210] = Model->_5A22; + //SNEeSe returns 2 for 5A22 version. + return ((byte & 0x80) + | (OpenBus & 0x70) + | Model->_5A22); + + case 0x4211: + byte = (CPU.IRQActive & (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE)) ? + 0x80 : 0; + // Super Robot Wars Ex ROM bug requires this. + byte |= CPU.Cycles >= Settings.HBlankStart ? 0x40 : 0; + CLEAR_IRQ_SOURCE(PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE); + + // Maybe? Register Scan indicated open bus... + byte |= OpenBus & 0x3f; + + return (byte); + + case 0x4212: + // V-blank, h-blank and joypads being read flags (read-only) #ifdef CPU_SHUTDOWN - CPU.WaitAddress = CPU.PCAtOpcodeStart; + CPU.WaitAddress = CPU.PCAtOpcodeStart; #endif - return (REGISTER_4212() - |(OpenBus&0x3E) - ); - - case 0x4213: - // I/O port input - returns 0 wherever $4201 is 0, and 1 elsewhere - // unless something else pulls it down (i.e. a gun) - /* fall through */ - case 0x4214: - case 0x4215: - // Quotient of divide result - case 0x4216: - case 0x4217: - // Multiplcation result (for multiply) or remainder of - // divison. - /* fall through */ - case 0x4218: - case 0x4219: - case 0x421a: - case 0x421b: - case 0x421c: - case 0x421d: - case 0x421e: - case 0x421f: - // Joypads 1-4 button and direction state. - /* fall through */ - case 0x4300: - case 0x4310: - case 0x4320: - case 0x4330: - case 0x4340: - case 0x4350: - case 0x4360: - case 0x4370: - // DMA direction, address type, fixed flag, - /* fall through */ - case 0x4301: - case 0x4311: - case 0x4321: - case 0x4331: - case 0x4341: - case 0x4351: - case 0x4361: - case 0x4371: - /* fall through */ - case 0x4302: - case 0x4312: - case 0x4322: - case 0x4332: - case 0x4342: - case 0x4352: - case 0x4362: - case 0x4372: - /* fall through */ - case 0x4303: - case 0x4313: - case 0x4323: - case 0x4333: - case 0x4343: - case 0x4353: - case 0x4363: - case 0x4373: - /* fall through */ - case 0x4304: - case 0x4314: - case 0x4324: - case 0x4334: - case 0x4344: - case 0x4354: - case 0x4364: - case 0x4374: - /* fall through */ - case 0x4305: - case 0x4315: - case 0x4325: - case 0x4335: - case 0x4345: - case 0x4355: - case 0x4365: - case 0x4375: - /* fall through */ - case 0x4306: - case 0x4316: - case 0x4326: - case 0x4336: - case 0x4346: - case 0x4356: - case 0x4366: - case 0x4376: - /* fall through */ - case 0x4308: - case 0x4318: - case 0x4328: - case 0x4338: - case 0x4348: - case 0x4358: - case 0x4368: - case 0x4378: - /* fall through */ - case 0x4309: - case 0x4319: - case 0x4329: - case 0x4339: - case 0x4349: - case 0x4359: - case 0x4369: - case 0x4379: - return (Memory.FillRAM[Address]); - - case 0x4307: - case 0x4317: - case 0x4327: - case 0x4337: - case 0x4347: - case 0x4357: - case 0x4367: - case 0x4377: - return (DMA[(Address >> 4) & 7].IndirectBank); - - case 0x430A: - case 0x431A: - case 0x432A: - case 0x433A: - case 0x434A: - case 0x435A: - case 0x436A: - case 0x437A: - { - int d = (Address & 0x70) >> 4; - if (IPPU.HDMA & (1 << d)) - { - return (DMA[d].LineCount); - } - return (Memory.FillRAM[Address]); - } - - case 0x430F: - case 0x431F: - case 0x432F: - case 0x433F: - case 0x434F: - case 0x435F: - case 0x436F: - case 0x437F: - Address &= ~4; // Convert 43xF to 43xB - /* fall through */ - case 0x430B: - case 0x431B: - case 0x432B: - case 0x433B: - case 0x434B: - case 0x435B: - case 0x436B: - case 0x437B: - - // Unknown, but they seem to be RAM-ish - return (Memory.FillRAM[Address]); - - default: - if(Address>= 0x4800&&Settings.SPC7110) - return S9xGetSPC7110(Address); - - if(Address>=0x4800&&Address<=0x4807&&Settings.SDD1) - { - return Memory.FillRAM[Address]; - } - - return OpenBus; - } -// return (Memory.FillRAM[Address]); + return (REGISTER_4212() + | (OpenBus & 0x3E) + ); + + case 0x4213: + // I/O port input - returns 0 wherever $4201 is 0, and 1 elsewhere + // unless something else pulls it down (i.e. a gun) + /* fall through */ + case 0x4214: + case 0x4215: + // Quotient of divide result + case 0x4216: + case 0x4217: + // Multiplcation result (for multiply) or remainder of + // divison. + /* fall through */ + case 0x4218: + case 0x4219: + case 0x421a: + case 0x421b: + case 0x421c: + case 0x421d: + case 0x421e: + case 0x421f: + // Joypads 1-4 button and direction state. + /* fall through */ + case 0x4300: + case 0x4310: + case 0x4320: + case 0x4330: + case 0x4340: + case 0x4350: + case 0x4360: + case 0x4370: + // DMA direction, address type, fixed flag, + /* fall through */ + case 0x4301: + case 0x4311: + case 0x4321: + case 0x4331: + case 0x4341: + case 0x4351: + case 0x4361: + case 0x4371: + /* fall through */ + case 0x4302: + case 0x4312: + case 0x4322: + case 0x4332: + case 0x4342: + case 0x4352: + case 0x4362: + case 0x4372: + /* fall through */ + case 0x4303: + case 0x4313: + case 0x4323: + case 0x4333: + case 0x4343: + case 0x4353: + case 0x4363: + case 0x4373: + /* fall through */ + case 0x4304: + case 0x4314: + case 0x4324: + case 0x4334: + case 0x4344: + case 0x4354: + case 0x4364: + case 0x4374: + /* fall through */ + case 0x4305: + case 0x4315: + case 0x4325: + case 0x4335: + case 0x4345: + case 0x4355: + case 0x4365: + case 0x4375: + /* fall through */ + case 0x4306: + case 0x4316: + case 0x4326: + case 0x4336: + case 0x4346: + case 0x4356: + case 0x4366: + case 0x4376: + /* fall through */ + case 0x4308: + case 0x4318: + case 0x4328: + case 0x4338: + case 0x4348: + case 0x4358: + case 0x4368: + case 0x4378: + /* fall through */ + case 0x4309: + case 0x4319: + case 0x4329: + case 0x4339: + case 0x4349: + case 0x4359: + case 0x4369: + case 0x4379: + return (Memory.FillRAM[Address]); + + case 0x4307: + case 0x4317: + case 0x4327: + case 0x4337: + case 0x4347: + case 0x4357: + case 0x4367: + case 0x4377: + return (DMA[(Address >> 4) & 7].IndirectBank); + + case 0x430A: + case 0x431A: + case 0x432A: + case 0x433A: + case 0x434A: + case 0x435A: + case 0x436A: + case 0x437A: + { + int d = (Address & 0x70) >> 4; + if (IPPU.HDMA & (1 << d)) + return (DMA[d].LineCount); + return (Memory.FillRAM[Address]); + } + + case 0x430F: + case 0x431F: + case 0x432F: + case 0x433F: + case 0x434F: + case 0x435F: + case 0x436F: + case 0x437F: + Address &= ~4; // Convert 43xF to 43xB + /* fall through */ + case 0x430B: + case 0x431B: + case 0x432B: + case 0x433B: + case 0x434B: + case 0x435B: + case 0x436B: + case 0x437B: + + // Unknown, but they seem to be RAM-ish + return (Memory.FillRAM[Address]); + + default: + if (Address >= 0x4800 && Settings.SPC7110) + return S9xGetSPC7110(Address); + + if (Address >= 0x4800 && Address <= 0x4807 && Settings.SDD1) + return Memory.FillRAM[Address]; + + return OpenBus; + } + // return (Memory.FillRAM[Address]); } -static void CommonPPUReset () +static void CommonPPUReset() { - PPU.BGMode = 0; - PPU.BG3Priority = 0; - PPU.Brightness = 0; - PPU.VMA.High = 0; - PPU.VMA.Increment = 1; - PPU.VMA.Address = 0; - PPU.VMA.FullGraphicCount = 0; - PPU.VMA.Shift = 0; + PPU.BGMode = 0; + PPU.BG3Priority = 0; + PPU.Brightness = 0; + PPU.VMA.High = 0; + PPU.VMA.Increment = 1; + PPU.VMA.Address = 0; + PPU.VMA.FullGraphicCount = 0; + PPU.VMA.Shift = 0; uint8 B; for (B = 0; B != 4; B++) - { - PPU.BG[B].SCBase = 0; - PPU.BG[B].VOffset = 0; - PPU.BG[B].HOffset = 0; - PPU.BG[B].BGSize = 0; - PPU.BG[B].NameBase = 0; - PPU.BG[B].SCSize = 0; - - PPU.ClipCounts[B] = 0; - PPU.ClipWindowOverlapLogic [B] = CLIP_OR; - PPU.ClipWindow1Enable[B] = FALSE; - PPU.ClipWindow2Enable[B] = FALSE; - PPU.ClipWindow1Inside[B] = TRUE; - PPU.ClipWindow2Inside[B] = TRUE; - } - - PPU.ClipCounts[4] = 0; - PPU.ClipCounts[5] = 0; - PPU.ClipWindowOverlapLogic[4] = PPU.ClipWindowOverlapLogic[5] = CLIP_OR; - PPU.ClipWindow1Enable[4] = PPU.ClipWindow1Enable[5] = FALSE; - PPU.ClipWindow2Enable[4] = PPU.ClipWindow2Enable[5] = FALSE; - PPU.ClipWindow1Inside[4] = PPU.ClipWindow1Inside[5] = TRUE; - PPU.ClipWindow2Inside[4] = PPU.ClipWindow2Inside[5] = TRUE; - - PPU.CGFLIP = 0; - int c; - for (c = 0; c < 256; c++) - { - IPPU.Red [c] = (c & 7) << 2; - IPPU.Green [c] = ((c >> 3) & 7) << 2; - IPPU.Blue [c] = ((c >> 6) & 2) << 3; - PPU.CGDATA [c] = IPPU.Red [c] | (IPPU.Green [c] << 5) | - (IPPU.Blue [c] << 10); - } - - PPU.FirstSprite = 0; - PPU.LastSprite = 127; + { + PPU.BG[B].SCBase = 0; + PPU.BG[B].VOffset = 0; + PPU.BG[B].HOffset = 0; + PPU.BG[B].BGSize = 0; + PPU.BG[B].NameBase = 0; + PPU.BG[B].SCSize = 0; + + PPU.ClipCounts[B] = 0; + PPU.ClipWindowOverlapLogic [B] = CLIP_OR; + PPU.ClipWindow1Enable[B] = FALSE; + PPU.ClipWindow2Enable[B] = FALSE; + PPU.ClipWindow1Inside[B] = TRUE; + PPU.ClipWindow2Inside[B] = TRUE; + } + + PPU.ClipCounts[4] = 0; + PPU.ClipCounts[5] = 0; + PPU.ClipWindowOverlapLogic[4] = PPU.ClipWindowOverlapLogic[5] = CLIP_OR; + PPU.ClipWindow1Enable[4] = PPU.ClipWindow1Enable[5] = FALSE; + PPU.ClipWindow2Enable[4] = PPU.ClipWindow2Enable[5] = FALSE; + PPU.ClipWindow1Inside[4] = PPU.ClipWindow1Inside[5] = TRUE; + PPU.ClipWindow2Inside[4] = PPU.ClipWindow2Inside[5] = TRUE; + + PPU.CGFLIP = 0; + int c; + for (c = 0; c < 256; c++) + { + IPPU.Red [c] = (c & 7) << 2; + IPPU.Green [c] = ((c >> 3) & 7) << 2; + IPPU.Blue [c] = ((c >> 6) & 2) << 3; + PPU.CGDATA [c] = IPPU.Red [c] | (IPPU.Green [c] << 5) | + (IPPU.Blue [c] << 10); + } + + PPU.FirstSprite = 0; + PPU.LastSprite = 127; int Sprite; for (Sprite = 0; Sprite < 128; Sprite++) - { - PPU.OBJ[Sprite].HPos = 0; - PPU.OBJ[Sprite].VPos = 0; - PPU.OBJ[Sprite].VFlip = 0; - PPU.OBJ[Sprite].HFlip = 0; - PPU.OBJ[Sprite].Priority = 0; - PPU.OBJ[Sprite].Palette = 0; - PPU.OBJ[Sprite].Name = 0; - PPU.OBJ[Sprite].Size = 0; - } - PPU.OAMPriorityRotation = 0; - PPU.OAMWriteRegister = 0; - PPU.RangeTimeOver = 0; - PPU.OpenBus1 = 0; - PPU.OpenBus2 = 0; - - PPU.OAMFlip = 0; - PPU.OAMTileAddress = 0; - PPU.OAMAddr = 0; - PPU.IRQVBeamPos = 0; - PPU.IRQHBeamPos = 0; - PPU.VBeamPosLatched = 0; - PPU.HBeamPosLatched = 0; - - PPU.HBeamFlip = 0; - PPU.VBeamFlip = 0; - PPU.HVBeamCounterLatched = 0; - - PPU.MatrixA = PPU.MatrixB = PPU.MatrixC = PPU.MatrixD = 0; - PPU.CentreX = PPU.CentreY = 0; - PPU.CGADD = 0; - PPU.FixedColourRed = PPU.FixedColourGreen = PPU.FixedColourBlue = 0; - PPU.SavedOAMAddr = 0; - PPU.ScreenHeight = SNES_HEIGHT; - PPU.WRAM = 0; - PPU.BG_Forced = 0; - PPU.ForcedBlanking = TRUE; - PPU.OBJThroughMain = FALSE; - PPU.OBJThroughSub = FALSE; - PPU.OBJSizeSelect = 0; - PPU.OBJNameSelect = 0; - PPU.OBJNameBase = 0; - PPU.OBJAddition = FALSE; - PPU.OAMReadFlip = 0; - PPU.BGnxOFSbyte = 0; - ZeroMemory (PPU.OAMData, 512 + 32); - - PPU.VTimerEnabled = FALSE; - PPU.HTimerEnabled = FALSE; - PPU.HTimerPosition = Settings.H_Max + 1; - PPU.Mosaic = 0; - PPU.BGMosaic [0] = PPU.BGMosaic [1] = FALSE; - PPU.BGMosaic [2] = PPU.BGMosaic [3] = FALSE; - PPU.Mode7HFlip = FALSE; - PPU.Mode7VFlip = FALSE; - PPU.Mode7Repeat = 0; - PPU.Window1Left = 1; - PPU.Window1Right = 0; - PPU.Window2Left = 1; - PPU.Window2Right = 0; - PPU.RecomputeClipWindows = TRUE; - PPU.CGFLIPRead = 0; - PPU.Need16x8Mulitply = FALSE; - PPU.MouseSpeed[0] = PPU.MouseSpeed[1] = 0; - - IPPU.ColorsChanged = TRUE; - IPPU.HDMA = 0; - IPPU.HDMAStarted = FALSE; - IPPU.MaxBrightness = 0; - IPPU.LatchedBlanking = 0; - IPPU.OBJChanged = TRUE; - IPPU.RenderThisFrame = TRUE; - IPPU.DirectColourMapsNeedRebuild = TRUE; - IPPU.FrameCount = 0; - IPPU.RenderedFramesCount = 0; - IPPU.DisplayedRenderedFrameCount = 0; - IPPU.SkippedFrames = 0; - IPPU.FrameSkip = 0; - ZeroMemory (IPPU.TileCached [TILE_2BIT], MAX_2BIT_TILES); - ZeroMemory (IPPU.TileCached [TILE_4BIT], MAX_4BIT_TILES); - ZeroMemory (IPPU.TileCached [TILE_8BIT], MAX_8BIT_TILES); + { + PPU.OBJ[Sprite].HPos = 0; + PPU.OBJ[Sprite].VPos = 0; + PPU.OBJ[Sprite].VFlip = 0; + PPU.OBJ[Sprite].HFlip = 0; + PPU.OBJ[Sprite].Priority = 0; + PPU.OBJ[Sprite].Palette = 0; + PPU.OBJ[Sprite].Name = 0; + PPU.OBJ[Sprite].Size = 0; + } + PPU.OAMPriorityRotation = 0; + PPU.OAMWriteRegister = 0; + PPU.RangeTimeOver = 0; + PPU.OpenBus1 = 0; + PPU.OpenBus2 = 0; + + PPU.OAMFlip = 0; + PPU.OAMTileAddress = 0; + PPU.OAMAddr = 0; + PPU.IRQVBeamPos = 0; + PPU.IRQHBeamPos = 0; + PPU.VBeamPosLatched = 0; + PPU.HBeamPosLatched = 0; + + PPU.HBeamFlip = 0; + PPU.VBeamFlip = 0; + PPU.HVBeamCounterLatched = 0; + + PPU.MatrixA = PPU.MatrixB = PPU.MatrixC = PPU.MatrixD = 0; + PPU.CentreX = PPU.CentreY = 0; + PPU.CGADD = 0; + PPU.FixedColourRed = PPU.FixedColourGreen = PPU.FixedColourBlue = 0; + PPU.SavedOAMAddr = 0; + PPU.ScreenHeight = SNES_HEIGHT; + PPU.WRAM = 0; + PPU.BG_Forced = 0; + PPU.ForcedBlanking = TRUE; + PPU.OBJThroughMain = FALSE; + PPU.OBJThroughSub = FALSE; + PPU.OBJSizeSelect = 0; + PPU.OBJNameSelect = 0; + PPU.OBJNameBase = 0; + PPU.OBJAddition = FALSE; + PPU.OAMReadFlip = 0; + PPU.BGnxOFSbyte = 0; + ZeroMemory(PPU.OAMData, 512 + 32); + + PPU.VTimerEnabled = FALSE; + PPU.HTimerEnabled = FALSE; + PPU.HTimerPosition = Settings.H_Max + 1; + PPU.Mosaic = 0; + PPU.BGMosaic [0] = PPU.BGMosaic [1] = FALSE; + PPU.BGMosaic [2] = PPU.BGMosaic [3] = FALSE; + PPU.Mode7HFlip = FALSE; + PPU.Mode7VFlip = FALSE; + PPU.Mode7Repeat = 0; + PPU.Window1Left = 1; + PPU.Window1Right = 0; + PPU.Window2Left = 1; + PPU.Window2Right = 0; + PPU.RecomputeClipWindows = TRUE; + PPU.CGFLIPRead = 0; + PPU.Need16x8Mulitply = FALSE; + PPU.MouseSpeed[0] = PPU.MouseSpeed[1] = 0; + + IPPU.ColorsChanged = TRUE; + IPPU.HDMA = 0; + IPPU.HDMAStarted = FALSE; + IPPU.MaxBrightness = 0; + IPPU.LatchedBlanking = 0; + IPPU.OBJChanged = TRUE; + IPPU.RenderThisFrame = TRUE; + IPPU.DirectColourMapsNeedRebuild = TRUE; + IPPU.FrameCount = 0; + IPPU.RenderedFramesCount = 0; + IPPU.DisplayedRenderedFrameCount = 0; + IPPU.SkippedFrames = 0; + IPPU.FrameSkip = 0; + ZeroMemory(IPPU.TileCached [TILE_2BIT], MAX_2BIT_TILES); + ZeroMemory(IPPU.TileCached [TILE_4BIT], MAX_4BIT_TILES); + ZeroMemory(IPPU.TileCached [TILE_8BIT], MAX_8BIT_TILES); #ifdef CORRECT_VRAM_READS - IPPU.VRAMReadBuffer = 0; // XXX: FIXME: anything better? + IPPU.VRAMReadBuffer = 0; // XXX: FIXME: anything better? #else - IPPU.FirstVRAMRead = FALSE; + IPPU.FirstVRAMRead = FALSE; #endif - IPPU.Interlace = FALSE; - IPPU.InterlaceSprites = FALSE; - IPPU.DoubleWidthPixels = FALSE; - IPPU.HalfWidthPixels = FALSE; - IPPU.DoubleHeightPixels = FALSE; - IPPU.RenderedScreenWidth = SNES_WIDTH; - IPPU.RenderedScreenHeight = SNES_HEIGHT; - IPPU.XB = NULL; - for (c = 0; c < 256; c++) - IPPU.ScreenColors [c] = c; - S9xFixColourBrightness (); - IPPU.PreviousLine = IPPU.CurrentLine = 0; - - if (Settings.ControllerOption == 0) - IPPU.Controller = SNES_MAX_CONTROLLER_OPTIONS - 1; - else - IPPU.Controller = Settings.ControllerOption - 1; - S9xNextController (); - - for (c = 0; c < 2; c++) - memset (&IPPU.Clip [c], 0, sizeof (struct ClipData)); - - if (Settings.MouseMaster) - { - S9xProcessMouse (0); - S9xProcessMouse (1); - } + IPPU.Interlace = FALSE; + IPPU.InterlaceSprites = FALSE; + IPPU.DoubleWidthPixels = FALSE; + IPPU.HalfWidthPixels = FALSE; + IPPU.DoubleHeightPixels = FALSE; + IPPU.RenderedScreenWidth = SNES_WIDTH; + IPPU.RenderedScreenHeight = SNES_HEIGHT; + IPPU.XB = NULL; + for (c = 0; c < 256; c++) + IPPU.ScreenColors [c] = c; + S9xFixColourBrightness(); + IPPU.PreviousLine = IPPU.CurrentLine = 0; + + if (Settings.ControllerOption == 0) + IPPU.Controller = SNES_MAX_CONTROLLER_OPTIONS - 1; + else + IPPU.Controller = Settings.ControllerOption - 1; + S9xNextController(); + + for (c = 0; c < 2; c++) + memset(&IPPU.Clip [c], 0, sizeof(struct ClipData)); + + if (Settings.MouseMaster) + { + S9xProcessMouse(0); + S9xProcessMouse(1); + } } -void S9xResetPPU () +void S9xResetPPU() { - CommonPPUReset (); - PPU.Joypad1ButtonReadPos = 0; - PPU.Joypad2ButtonReadPos = 0; - PPU.Joypad3ButtonReadPos = 0; - - IPPU.Joypads[0] = IPPU.Joypads[1] = IPPU.Joypads[2] = 0; - IPPU.Joypads[3] = IPPU.Joypads[4] = 0; - IPPU.SuperScope = 0; - IPPU.Mouse[0] = IPPU.Mouse[1] = 0; - IPPU.PrevMouseX[0] = IPPU.PrevMouseX[1] = 256 / 2; - IPPU.PrevMouseY[0] = IPPU.PrevMouseY[1] = 224 / 2; + CommonPPUReset(); + PPU.Joypad1ButtonReadPos = 0; + PPU.Joypad2ButtonReadPos = 0; + PPU.Joypad3ButtonReadPos = 0; + + IPPU.Joypads[0] = IPPU.Joypads[1] = IPPU.Joypads[2] = 0; + IPPU.Joypads[3] = IPPU.Joypads[4] = 0; + IPPU.SuperScope = 0; + IPPU.Mouse[0] = IPPU.Mouse[1] = 0; + IPPU.PrevMouseX[0] = IPPU.PrevMouseX[1] = 256 / 2; + IPPU.PrevMouseY[0] = IPPU.PrevMouseY[1] = 224 / 2; int c; for (c = 0; c < 0x8000; c += 0x100) - { - if ( !Settings.SuperFX ) - { - memset (&Memory.FillRAM [c], c >> 8, 0x100); - } - else if ( (unsigned)c < 0x3000 || (unsigned)c >= 0x3300 ) - { - /* Don't overwrite SFX pvRegisters at 0x3000-0x32FF, - * they were set in FxReset. - */ - memset (&Memory.FillRAM [c], c >> 8, 0x100); - } - } - - ZeroMemory (&Memory.FillRAM [0x2100], 0x100); - ZeroMemory (&Memory.FillRAM [0x4200], 0x100); - ZeroMemory (&Memory.FillRAM [0x4000], 0x100); - // For BS Suttehakkun 2... - ZeroMemory (&Memory.FillRAM [0x1000], 0x1000); - - Memory.FillRAM[0x4201]=Memory.FillRAM[0x4213]=0xFF; + { + if (!Settings.SuperFX) + memset(&Memory.FillRAM [c], c >> 8, 0x100); + else if ((unsigned)c < 0x3000 || (unsigned)c >= 0x3300) + { + /* Don't overwrite SFX pvRegisters at 0x3000-0x32FF, + * they were set in FxReset. + */ + memset(&Memory.FillRAM [c], c >> 8, 0x100); + } + } + + ZeroMemory(&Memory.FillRAM [0x2100], 0x100); + ZeroMemory(&Memory.FillRAM [0x4200], 0x100); + ZeroMemory(&Memory.FillRAM [0x4000], 0x100); + // For BS Suttehakkun 2... + ZeroMemory(&Memory.FillRAM [0x1000], 0x1000); + + Memory.FillRAM[0x4201] = Memory.FillRAM[0x4213] = 0xFF; } -void S9xSoftResetPPU () +void S9xSoftResetPPU() { - CommonPPUReset (); -// PPU.Joypad1ButtonReadPos = 0; -// PPU.Joypad2ButtonReadPos = 0; -// PPU.Joypad3ButtonReadPos = 0; - -// IPPU.Joypads[0] = IPPU.Joypads[1] = IPPU.Joypads[2] = 0; -// IPPU.Joypads[3] = IPPU.Joypads[4] = 0; -// IPPU.SuperScope = 0; -// IPPU.Mouse[0] = IPPU.Mouse[1] = 0; -// IPPU.PrevMouseX[0] = IPPU.PrevMouseX[1] = 256 / 2; -// IPPU.PrevMouseY[0] = IPPU.PrevMouseY[1] = 224 / 2; + CommonPPUReset(); + // PPU.Joypad1ButtonReadPos = 0; + // PPU.Joypad2ButtonReadPos = 0; + // PPU.Joypad3ButtonReadPos = 0; + + // IPPU.Joypads[0] = IPPU.Joypads[1] = IPPU.Joypads[2] = 0; + // IPPU.Joypads[3] = IPPU.Joypads[4] = 0; + // IPPU.SuperScope = 0; + // IPPU.Mouse[0] = IPPU.Mouse[1] = 0; + // IPPU.PrevMouseX[0] = IPPU.PrevMouseX[1] = 256 / 2; + // IPPU.PrevMouseY[0] = IPPU.PrevMouseY[1] = 224 / 2; int c; for (c = 0; c < 0x8000; c += 0x100) - memset (&Memory.FillRAM [c], c >> 8, 0x100); + memset(&Memory.FillRAM [c], c >> 8, 0x100); - ZeroMemory (&Memory.FillRAM [0x2100], 0x100); - ZeroMemory (&Memory.FillRAM [0x4200], 0x100); - ZeroMemory (&Memory.FillRAM [0x4000], 0x100); - // For BS Suttehakkun 2... - ZeroMemory (&Memory.FillRAM [0x1000], 0x1000); + ZeroMemory(&Memory.FillRAM [0x2100], 0x100); + ZeroMemory(&Memory.FillRAM [0x4200], 0x100); + ZeroMemory(&Memory.FillRAM [0x4000], 0x100); + // For BS Suttehakkun 2... + ZeroMemory(&Memory.FillRAM [0x1000], 0x1000); - Memory.FillRAM[0x4201]=Memory.FillRAM[0x4213]=0xFF; + Memory.FillRAM[0x4201] = Memory.FillRAM[0x4213] = 0xFF; } -void S9xProcessMouse (int which1) +void S9xProcessMouse(int which1) { - int x, y; - uint32 buttons; - - if ((IPPU.Controller == SNES_MOUSE || IPPU.Controller == SNES_MOUSE_SWAPPED) && S9xReadMousePosition (which1, &x, &y, &buttons)) - { - int delta_x, delta_y; + int x, y; + uint32 buttons; + + if ((IPPU.Controller == SNES_MOUSE || IPPU.Controller == SNES_MOUSE_SWAPPED) + && S9xReadMousePosition(which1, &x, &y, &buttons)) + { + int delta_x, delta_y; #define MOUSE_SIGNATURE 0x1 - IPPU.Mouse [which1] = MOUSE_SIGNATURE | - (PPU.MouseSpeed [which1] << 4) | - ((buttons & 1) << 6) | ((buttons & 2) << 6); - - delta_x = x - IPPU.PrevMouseX[which1]; - delta_y = y - IPPU.PrevMouseY[which1]; - - if (delta_x > 63) - { - delta_x = 63; - IPPU.PrevMouseX[which1] += 63; - } - else - if (delta_x < -63) - { - delta_x = -63; - IPPU.PrevMouseX[which1] -= 63; - } - else - IPPU.PrevMouseX[which1] = x; - - if (delta_y > 63) - { - delta_y = 63; - IPPU.PrevMouseY[which1] += 63; - } - else - if (delta_y < -63) - { - delta_y = -63; - IPPU.PrevMouseY[which1] -= 63; - } - else - IPPU.PrevMouseY[which1] = y; - - if (delta_x < 0) - { - delta_x = -delta_x; - IPPU.Mouse [which1] |= (delta_x | 0x80) << 16; - } - else - IPPU.Mouse [which1] |= delta_x << 16; - - if (delta_y < 0) - { - delta_y = -delta_y; - IPPU.Mouse [which1] |= (delta_y | 0x80) << 24; - } - else - IPPU.Mouse [which1] |= delta_y << 24; - - if (IPPU.Controller == SNES_MOUSE_SWAPPED) - IPPU.Joypads [0] = IPPU.Mouse [which1]; - else - IPPU.Joypads [1] = IPPU.Mouse [which1]; - } + IPPU.Mouse [which1] = MOUSE_SIGNATURE | + (PPU.MouseSpeed [which1] << 4) | + ((buttons & 1) << 6) | ((buttons & 2) << 6); + + delta_x = x - IPPU.PrevMouseX[which1]; + delta_y = y - IPPU.PrevMouseY[which1]; + + if (delta_x > 63) + { + delta_x = 63; + IPPU.PrevMouseX[which1] += 63; + } + else if (delta_x < -63) + { + delta_x = -63; + IPPU.PrevMouseX[which1] -= 63; + } + else + IPPU.PrevMouseX[which1] = x; + + if (delta_y > 63) + { + delta_y = 63; + IPPU.PrevMouseY[which1] += 63; + } + else if (delta_y < -63) + { + delta_y = -63; + IPPU.PrevMouseY[which1] -= 63; + } + else + IPPU.PrevMouseY[which1] = y; + + if (delta_x < 0) + { + delta_x = -delta_x; + IPPU.Mouse [which1] |= (delta_x | 0x80) << 16; + } + else + IPPU.Mouse [which1] |= delta_x << 16; + + if (delta_y < 0) + { + delta_y = -delta_y; + IPPU.Mouse [which1] |= (delta_y | 0x80) << 24; + } + else + IPPU.Mouse [which1] |= delta_y << 24; + + if (IPPU.Controller == SNES_MOUSE_SWAPPED) + IPPU.Joypads [0] = IPPU.Mouse [which1]; + else + IPPU.Joypads [1] = IPPU.Mouse [which1]; + } } -void ProcessSuperScope () +void ProcessSuperScope() { - int x, y; - uint32 buttons; + int x, y; + uint32 buttons; - if (IPPU.Controller == SNES_SUPERSCOPE && - S9xReadSuperScopePosition (&x, &y, &buttons)) - { + if (IPPU.Controller == SNES_SUPERSCOPE && + S9xReadSuperScopePosition(&x, &y, &buttons)) + { #define SUPERSCOPE_SIGNATURE 0x00ff - uint32 scope; - - scope = SUPERSCOPE_SIGNATURE | ((buttons & 1) << (7 + 8)) | - ((buttons & 2) << (5 + 8)) | ((buttons & 4) << (3 + 8)) | - ((buttons & 8) << (1 + 8)); - if(Memory.FillRAM[0x4201]&0x80){ - x+=40; - if (x > 295) - x = 295; - if (x < 40) - x = 40; - if (y > PPU.ScreenHeight - 1) - y = PPU.ScreenHeight - 1; - if (y < 0) - y = 0; - - PPU.VBeamPosLatched = (uint16) (y + 1); - PPU.HBeamPosLatched = (uint16) x; - PPU.HVBeamCounterLatched = TRUE; - Memory.FillRAM [0x213F] |= 0x40 | Model->_5C78; - } - IPPU.Joypads [1] = scope; - } + uint32 scope; + + scope = SUPERSCOPE_SIGNATURE | ((buttons & 1) << (7 + 8)) | + ((buttons & 2) << (5 + 8)) | ((buttons & 4) << (3 + 8)) | + ((buttons & 8) << (1 + 8)); + if (Memory.FillRAM[0x4201] & 0x80) + { + x += 40; + if (x > 295) + x = 295; + if (x < 40) + x = 40; + if (y > PPU.ScreenHeight - 1) + y = PPU.ScreenHeight - 1; + if (y < 0) + y = 0; + + PPU.VBeamPosLatched = (uint16)(y + 1); + PPU.HBeamPosLatched = (uint16) x; + PPU.HVBeamCounterLatched = TRUE; + Memory.FillRAM [0x213F] |= 0x40 | Model->_5C78; + } + IPPU.Joypads [1] = scope; + } } -void S9xNextController () +void S9xNextController() { - switch (IPPU.Controller) - { - case SNES_MULTIPLAYER5: - IPPU.Controller = SNES_JOYPAD; - break; - case SNES_JOYPAD: - if (Settings.MouseMaster) - { - IPPU.Controller = SNES_MOUSE_SWAPPED; - break; - } - case SNES_MOUSE_SWAPPED: - if (Settings.MouseMaster) - { - IPPU.Controller = SNES_MOUSE; - break; - } - case SNES_MOUSE: - if (Settings.SuperScopeMaster) - { - IPPU.Controller = SNES_SUPERSCOPE; - break; - } - case SNES_SUPERSCOPE: - if (Settings.JustifierMaster) - { - IPPU.Controller = SNES_JUSTIFIER; - break; - } - case SNES_JUSTIFIER: - if(Settings.JustifierMaster) - { - IPPU.Controller=SNES_JUSTIFIER_2; - break; - } - case SNES_JUSTIFIER_2: - if(Settings.MultiPlayer5Master) - { - IPPU.Controller=SNES_MULTIPLAYER5; - break; - } - default: - IPPU.Controller = SNES_JOYPAD; - break; - } + switch (IPPU.Controller) + { + case SNES_MULTIPLAYER5: + IPPU.Controller = SNES_JOYPAD; + break; + case SNES_JOYPAD: + if (Settings.MouseMaster) + { + IPPU.Controller = SNES_MOUSE_SWAPPED; + break; + } + case SNES_MOUSE_SWAPPED: + if (Settings.MouseMaster) + { + IPPU.Controller = SNES_MOUSE; + break; + } + case SNES_MOUSE: + if (Settings.SuperScopeMaster) + { + IPPU.Controller = SNES_SUPERSCOPE; + break; + } + case SNES_SUPERSCOPE: + if (Settings.JustifierMaster) + { + IPPU.Controller = SNES_JUSTIFIER; + break; + } + case SNES_JUSTIFIER: + if (Settings.JustifierMaster) + { + IPPU.Controller = SNES_JUSTIFIER_2; + break; + } + case SNES_JUSTIFIER_2: + if (Settings.MultiPlayer5Master) + { + IPPU.Controller = SNES_MULTIPLAYER5; + break; + } + default: + IPPU.Controller = SNES_JOYPAD; + break; + } } void S9xUpdateJustifiers() { - static bool last_p1; - in_bit=0; -// static int p1count; - justifiers=0xFFFF00AA; + static bool last_p1; + in_bit = 0; + // static int p1count; + justifiers = 0xFFFF00AA; - bool offscreen=JustifierOffscreen(); + bool offscreen = JustifierOffscreen(); JustifierButtons(&justifiers); -// if(p1count==32) -// { - last_p1=!last_p1; -// p1count=0; -// } -// p1count++; - - if(!last_p1) - justifiers|=0x1000; - - int x,y; - uint32 buttons; - - if(Memory.FillRAM[0x4201]&0x80) - { - - S9xReadSuperScopePosition(&x,&y,&buttons); - - x+=40; - if (x > 295) - x = 295; - if (x < 40) - x = 40; - if (y > PPU.ScreenHeight - 1) - y = PPU.ScreenHeight - 1; - if (y < 0) - y = 0; - - if(last_p1) - { - - PPU.HVBeamCounterLatched = FALSE; - Memory.FillRAM [0x213F] = Model->_5C78; - - //process latch as Justifier 2 - if(Settings.SecondJustifier) - { - if(IPPU.Controller==SNES_JUSTIFIER_2) - { - if(!offscreen) - { - - PPU.VBeamPosLatched = (uint16) (y + 1); - PPU.HBeamPosLatched = (uint16) x; - PPU.HVBeamCounterLatched = TRUE; - Memory.FillRAM [0x213F] |= 0x40 | Model->_5C78; - } - } - } - } - else - { - - PPU.HVBeamCounterLatched = FALSE; - Memory.FillRAM [0x213F] = Model->_5C78; - - //emulate player 1. - if(IPPU.Controller==SNES_JUSTIFIER) - { - if(!offscreen) - { - PPU.VBeamPosLatched = (uint16) (y + 1); - PPU.HBeamPosLatched = (uint16) x; - PPU.HVBeamCounterLatched = TRUE; - Memory.FillRAM [0x213F] |= 0x40 | Model->_5C78; - } - } - } - - //needs restructure - if(!offscreen) - { - - if((!last_p1&&IPPU.Controller==SNES_JUSTIFIER)||(last_p1&&IPPU.Controller==SNES_JUSTIFIER_2)) - { - PPU.VBeamPosLatched = (uint16) (y + 1); - PPU.HBeamPosLatched = (uint16) x; - PPU.HVBeamCounterLatched = TRUE; - Memory.FillRAM [0x213F] |= 0x40 | Model->_5C78; - } - else - { - PPU.HVBeamCounterLatched = FALSE; - Memory.FillRAM [0x213F] = Model->_5C78; - - } - } - else - { - PPU.HVBeamCounterLatched = FALSE; - Memory.FillRAM [0x213F] = Model->_5C78; - } - } + // if(p1count==32) + // { + last_p1 = !last_p1; + // p1count=0; + // } + // p1count++; + + if (!last_p1) + justifiers |= 0x1000; + + int x, y; + uint32 buttons; + + if (Memory.FillRAM[0x4201] & 0x80) + { + + S9xReadSuperScopePosition(&x, &y, &buttons); + + x += 40; + if (x > 295) + x = 295; + if (x < 40) + x = 40; + if (y > PPU.ScreenHeight - 1) + y = PPU.ScreenHeight - 1; + if (y < 0) + y = 0; + + if (last_p1) + { + + PPU.HVBeamCounterLatched = FALSE; + Memory.FillRAM [0x213F] = Model->_5C78; + + //process latch as Justifier 2 + if (Settings.SecondJustifier) + { + if (IPPU.Controller == SNES_JUSTIFIER_2) + { + if (!offscreen) + { + + PPU.VBeamPosLatched = (uint16)(y + 1); + PPU.HBeamPosLatched = (uint16) x; + PPU.HVBeamCounterLatched = TRUE; + Memory.FillRAM [0x213F] |= 0x40 | Model->_5C78; + } + } + } + } + else + { + + PPU.HVBeamCounterLatched = FALSE; + Memory.FillRAM [0x213F] = Model->_5C78; + + //emulate player 1. + if (IPPU.Controller == SNES_JUSTIFIER) + { + if (!offscreen) + { + PPU.VBeamPosLatched = (uint16)(y + 1); + PPU.HBeamPosLatched = (uint16) x; + PPU.HVBeamCounterLatched = TRUE; + Memory.FillRAM [0x213F] |= 0x40 | Model->_5C78; + } + } + } + + //needs restructure + if (!offscreen) + { + + if ((!last_p1 && IPPU.Controller == SNES_JUSTIFIER) || (last_p1 + && IPPU.Controller == SNES_JUSTIFIER_2)) + { + PPU.VBeamPosLatched = (uint16)(y + 1); + PPU.HBeamPosLatched = (uint16) x; + PPU.HVBeamCounterLatched = TRUE; + Memory.FillRAM [0x213F] |= 0x40 | Model->_5C78; + } + else + { + PPU.HVBeamCounterLatched = FALSE; + Memory.FillRAM [0x213F] = Model->_5C78; + + } + } + else + { + PPU.HVBeamCounterLatched = FALSE; + Memory.FillRAM [0x213F] = Model->_5C78; + } + } } -void S9xUpdateJoypads () +void S9xUpdateJoypads() { - uint32 i; - - for (i = 0; i < 5; i++) - { - IPPU.Joypads [i] = S9xReadJoypad (i); - } - -// S9xMovieUpdate(); - - for (i = 0; i < 5; i++) - { - if ((IPPU.Joypads [i] & (SNES_LEFT_MASK | SNES_RIGHT_MASK)) == (SNES_LEFT_MASK | SNES_RIGHT_MASK)) - IPPU.Joypads [i] &= ~SNES_RIGHT_MASK; - if ((IPPU.Joypads [i] & (SNES_UP_MASK | SNES_DOWN_MASK)) == (SNES_UP_MASK | SNES_DOWN_MASK)) - IPPU.Joypads [i] &= ~SNES_DOWN_MASK; - } - - // BJ: This is correct behavior AFAICT (used to be Touhaiden hack) - if (IPPU.Controller == SNES_JOYPAD || IPPU.Controller == SNES_MULTIPLAYER5) - { - for (i = 0; i < 5; i++) - { - if (IPPU.Joypads [i]) - IPPU.Joypads [i] |= 0xffff0000; - } - } - - // Read mouse position if enabled - if (Settings.MouseMaster) - { - for (i = 0; i < 2; i++) - S9xProcessMouse (i); - } - - // Read SuperScope if enabled - if (Settings.SuperScopeMaster) - ProcessSuperScope (); - - if (Memory.FillRAM [0x4200] & 1) - { - PPU.Joypad1ButtonReadPos = 16; - if (Memory.FillRAM [0x4201] & 0x80) - { - PPU.Joypad2ButtonReadPos = 16; - PPU.Joypad3ButtonReadPos = 0; - } - else - { - PPU.Joypad2ButtonReadPos = 0; - PPU.Joypad3ButtonReadPos = 16; - } - int ind = Settings.SwapJoypads ? 1 : 0; - - Memory.FillRAM [0x4218] = (uint8) IPPU.Joypads [ind]; - Memory.FillRAM [0x4219] = (uint8) (IPPU.Joypads [ind] >> 8); - Memory.FillRAM [0x421a] = (uint8) IPPU.Joypads [ind ^ 1]; - Memory.FillRAM [0x421b] = (uint8) (IPPU.Joypads [ind ^ 1] >> 8); - if (Memory.FillRAM [0x4201] & 0x80) - { - Memory.FillRAM [0x421c] = (uint8) IPPU.Joypads [ind]; - Memory.FillRAM [0x421d] = (uint8) (IPPU.Joypads [ind] >> 8); - Memory.FillRAM [0x421e] = (uint8) IPPU.Joypads [2]; - Memory.FillRAM [0x421f] = (uint8) (IPPU.Joypads [2] >> 8); - } - else - { - Memory.FillRAM [0x421c] = (uint8) IPPU.Joypads [3]; - Memory.FillRAM [0x421d] = (uint8) (IPPU.Joypads [3] >> 8); - Memory.FillRAM [0x421e] = (uint8) IPPU.Joypads [4]; - Memory.FillRAM [0x421f] = (uint8) (IPPU.Joypads [4] >> 8); - } - } - if(Settings.Justifier||Settings.SecondJustifier) - { - Memory.FillRAM [0x421a] = 0x0E; - Memory.FillRAM [0x421b] = 0; - S9xUpdateJustifiers(); - } - + uint32 i; + + for (i = 0; i < 5; i++) + IPPU.Joypads [i] = S9xReadJoypad(i); + + // S9xMovieUpdate(); + + for (i = 0; i < 5; i++) + { + if ((IPPU.Joypads [i] & (SNES_LEFT_MASK | SNES_RIGHT_MASK)) == + (SNES_LEFT_MASK | SNES_RIGHT_MASK)) + IPPU.Joypads [i] &= ~SNES_RIGHT_MASK; + if ((IPPU.Joypads [i] & (SNES_UP_MASK | SNES_DOWN_MASK)) == + (SNES_UP_MASK | SNES_DOWN_MASK)) + IPPU.Joypads [i] &= ~SNES_DOWN_MASK; + } + + // BJ: This is correct behavior AFAICT (used to be Touhaiden hack) + if (IPPU.Controller == SNES_JOYPAD || IPPU.Controller == SNES_MULTIPLAYER5) + { + for (i = 0; i < 5; i++) + { + if (IPPU.Joypads [i]) + IPPU.Joypads [i] |= 0xffff0000; + } + } + + // Read mouse position if enabled + if (Settings.MouseMaster) + { + for (i = 0; i < 2; i++) + S9xProcessMouse(i); + } + + // Read SuperScope if enabled + if (Settings.SuperScopeMaster) + ProcessSuperScope(); + + if (Memory.FillRAM [0x4200] & 1) + { + PPU.Joypad1ButtonReadPos = 16; + if (Memory.FillRAM [0x4201] & 0x80) + { + PPU.Joypad2ButtonReadPos = 16; + PPU.Joypad3ButtonReadPos = 0; + } + else + { + PPU.Joypad2ButtonReadPos = 0; + PPU.Joypad3ButtonReadPos = 16; + } + int ind = Settings.SwapJoypads ? 1 : 0; + + Memory.FillRAM [0x4218] = (uint8) IPPU.Joypads [ind]; + Memory.FillRAM [0x4219] = (uint8)(IPPU.Joypads [ind] >> 8); + Memory.FillRAM [0x421a] = (uint8) IPPU.Joypads [ind ^ 1]; + Memory.FillRAM [0x421b] = (uint8)(IPPU.Joypads [ind ^ 1] >> 8); + if (Memory.FillRAM [0x4201] & 0x80) + { + Memory.FillRAM [0x421c] = (uint8) IPPU.Joypads [ind]; + Memory.FillRAM [0x421d] = (uint8)(IPPU.Joypads [ind] >> 8); + Memory.FillRAM [0x421e] = (uint8) IPPU.Joypads [2]; + Memory.FillRAM [0x421f] = (uint8)(IPPU.Joypads [2] >> 8); + } + else + { + Memory.FillRAM [0x421c] = (uint8) IPPU.Joypads [3]; + Memory.FillRAM [0x421d] = (uint8)(IPPU.Joypads [3] >> 8); + Memory.FillRAM [0x421e] = (uint8) IPPU.Joypads [4]; + Memory.FillRAM [0x421f] = (uint8)(IPPU.Joypads [4] >> 8); + } + } + if (Settings.Justifier || Settings.SecondJustifier) + { + Memory.FillRAM [0x421a] = 0x0E; + Memory.FillRAM [0x421b] = 0; + S9xUpdateJustifiers(); + } + } #ifndef ZSNES_FX -void S9xSuperFXExec () +void S9xSuperFXExec() { #if 1 - if (Settings.SuperFX) - { - if ((Memory.FillRAM [0x3000 + GSU_SFR] & FLG_G) && - (Memory.FillRAM [0x3000 + GSU_SCMR] & 0x18) == 0x18) - { - if (!Settings.WinterGold||Settings.StarfoxHack) - FxEmulate (~0); - else - FxEmulate ((Memory.FillRAM [0x3000 + GSU_CLSR] & 1) ? 700 : 350); - int GSUStatus = Memory.FillRAM [0x3000 + GSU_SFR] | - (Memory.FillRAM [0x3000 + GSU_SFR + 1] << 8); - if ((GSUStatus & (FLG_G | FLG_IRQ)) == FLG_IRQ) - { - // Trigger a GSU IRQ. - S9xSetIRQ (GSU_IRQ_SOURCE); - } - } - } + if (Settings.SuperFX) + { + if ((Memory.FillRAM [0x3000 + GSU_SFR] & FLG_G) && + (Memory.FillRAM [0x3000 + GSU_SCMR] & 0x18) == 0x18) + { + if (!Settings.WinterGold || Settings.StarfoxHack) + FxEmulate(~0); + else + FxEmulate((Memory.FillRAM [0x3000 + GSU_CLSR] & 1) ? 700 : 350); + int GSUStatus = Memory.FillRAM [0x3000 + GSU_SFR] | + (Memory.FillRAM [0x3000 + GSU_SFR + 1] << 8); + if ((GSUStatus & (FLG_G | FLG_IRQ)) == FLG_IRQ) + { + // Trigger a GSU IRQ. + S9xSetIRQ(GSU_IRQ_SOURCE); + } + } + } #else - uint32 tmp = (Memory.FillRAM[0x3034] << 16) + *(uint16 *) &Memory.FillRAM [0x301e]; + uint32 tmp = (Memory.FillRAM[0x3034] << 16) + *(uint16*) + &Memory.FillRAM [0x301e]; #if 0 - if (tmp == 0x018428) - { - *(uint16 *) &SRAM [0x0064] = 0xbc00; - *(uint16 *) &SRAM [0x002c] = 0x8000; - } + if (tmp == 0x018428) + { + *(uint16*) &SRAM [0x0064] = 0xbc00; + *(uint16*) &SRAM [0x002c] = 0x8000; + } #endif - if (tmp == -1)//0x018428) //0x01bfc3) //0x09edaf) //-1) //0x57edaf) - { - while (Memory.FillRAM [0x3030] & 0x20) - { - int i; - int32 vError; - uint8 avReg[0x40]; - char tmp[128]; - uint8 vPipe; - uint8 vColr; - uint8 vPor; - - FxPipeString (tmp); - /* Make the string 32 chars long */ - if(strlen(tmp) < 32) { memset(&tmp[strlen(tmp)],' ',32-strlen(tmp)); tmp[32] = 0; } - - /* Copy registers (so we can see if any changed) */ - vColr = FxGetColorRegister(); - vPor = FxGetPlotOptionRegister(); - memcpy(avReg,SuperFX.pvRegisters,0x40); - - /* Print the pipe string */ - printf(tmp); - - /* Execute the instruction in the pipe */ - vPipe = FxPipe(); - vError = FxEmulate(1); - - /* Check if any registers changed (and print them if they did) */ - for(i=0; i<16; i++) - { - uint32 a = 0; - uint32 r1 = ((uint32)avReg[i*2]) | (((uint32)avReg[(i*2)+1])<<8); - uint32 r2 = (uint32)(SuperFX.pvRegisters[i*2]) | (((uint32)SuperFX.pvRegisters[(i*2)+1])<<8); - if(i==15) - a = OPCODE_BYTES(vPipe); - if(((r1+a)&0xffff) != r2) - printf(" r%d=$%04x",i,r2); - } - { - /* Check SFR */ - uint32 r1 = ((uint32)avReg[0x30]) | (((uint32)avReg[0x31])<<8); - uint32 r2 = (uint32)(SuperFX.pvRegisters[0x30]) | (((uint32)SuperFX.pvRegisters[0x31])<<8); - if((r1&(1<<1)) != (r2&(1<<1))) - printf(" Z=%d",(uint32)(!!(r2&(1<<1)))); - if((r1&(1<<2)) != (r2&(1<<2))) - printf(" CY=%d",(uint32)(!!(r2&(1<<2)))); - if((r1&(1<<3)) != (r2&(1<<3))) - printf(" S=%d",(uint32)(!!(r2&(1<<3)))); - if((r1&(1<<4)) != (r2&(1<<4))) - printf(" OV=%d",(uint32)(!!(r2&(1<<4)))); - if((r1&(1<<5)) != (r2&(1<<5))) - printf(" G=%d",(uint32)(!!(r2&(1<<5)))); - if((r1&(1<<6)) != (r2&(1<<6))) - printf(" R=%d",(uint32)(!!(r2&(1<<6)))); - if((r1&(1<<8)) != (r2&(1<<8))) - printf(" ALT1=%d",(uint32)(!!(r2&(1<<8)))); - if((r1&(1<<9)) != (r2&(1<<9))) - printf(" ALT2=%d",(uint32)(!!(r2&(1<<9)))); - if((r1&(1<<10)) != (r2&(1<<10))) - printf(" IL=%d",(uint32)(!!(r2&(1<<10)))); - if((r1&(1<<11)) != (r2&(1<<11))) - printf(" IH=%d",(uint32)(!!(r2&(1<<11)))); - if((r1&(1<<12)) != (r2&(1<<12))) - printf(" B=%d",(uint32)(!!(r2&(1<<12)))); - if((r1&(1<<15)) != (r2&(1<<15))) - printf(" IRQ=%d",(uint32)(!!(r2&(1<<15)))); - } - { - /* Check PBR */ - uint32 r1 = ((uint32)avReg[0x34]); - uint32 r2 = (uint32)(SuperFX.pvRegisters[0x34]); - if(r1 != r2) - printf(" PBR=$%02x",r2); - } - { - /* Check ROMBR */ - uint32 r1 = ((uint32)avReg[0x36]); - uint32 r2 = (uint32)(SuperFX.pvRegisters[0x36]); - if(r1 != r2) - printf(" ROMBR=$%02x",r2); - } - { - /* Check RAMBR */ - uint32 r1 = ((uint32)avReg[0x3c]); - uint32 r2 = (uint32)(SuperFX.pvRegisters[0x3c]); - if(r1 != r2) - printf(" RAMBR=$%02x",r2); - } - { - /* Check CBR */ - uint32 r1 = ((uint32)avReg[0x3e]) | (((uint32)avReg[0x3f])<<8); - uint32 r2 = (uint32)(SuperFX.pvRegisters[0x3e]) | (((uint32)SuperFX.pvRegisters[0x3f])<<8); - if(r1 != r2) - printf(" CBR=$%04x",r2); - } - { - /* Check COLR */ - if(vColr != FxGetColorRegister()) - printf(" COLR=$%02x",FxGetColorRegister()); - } - { - /* Check POR */ - if(vPor != FxGetPlotOptionRegister()) - printf(" POR=$%02x",FxGetPlotOptionRegister()); - } - printf ("\n"); - } - S9xExit (); - } - else - { - uint32 t = (Memory.FillRAM [0x3034] << 16) + - (Memory.FillRAM [0x301f] << 8) + - (Memory.FillRAM [0x301e] << 0); - -printf ("%06x: %d\n", t, FxEmulate (2000000)); -// FxEmulate (2000000); - } + if (tmp == -1)//0x018428) //0x01bfc3) //0x09edaf) //-1) //0x57edaf) + { + while (Memory.FillRAM [0x3030] & 0x20) + { + int i; + int32 vError; + uint8 avReg[0x40]; + char tmp[128]; + uint8 vPipe; + uint8 vColr; + uint8 vPor; + + FxPipeString(tmp); + /* Make the string 32 chars long */ + if (strlen(tmp) < 32) + { + memset(&tmp[strlen(tmp)], ' ', 32 - strlen(tmp)); + tmp[32] = 0; + } + + /* Copy registers (so we can see if any changed) */ + vColr = FxGetColorRegister(); + vPor = FxGetPlotOptionRegister(); + memcpy(avReg, SuperFX.pvRegisters, 0x40); + + /* Print the pipe string */ + printf(tmp); + + /* Execute the instruction in the pipe */ + vPipe = FxPipe(); + vError = FxEmulate(1); + + /* Check if any registers changed (and print them if they did) */ + for (i = 0; i < 16; i++) + { + uint32 a = 0; + uint32 r1 = ((uint32)avReg[i * 2]) | (((uint32)avReg[(i * 2) + 1]) << 8); + uint32 r2 = (uint32)(SuperFX.pvRegisters[i * 2]) | (((uint32) + SuperFX.pvRegisters[(i * 2) + 1]) << 8); + if (i == 15) + a = OPCODE_BYTES(vPipe); + if (((r1 + a) & 0xffff) != r2) + printf(" r%d=$%04x", i, r2); + } + { + /* Check SFR */ + uint32 r1 = ((uint32)avReg[0x30]) | (((uint32)avReg[0x31]) << 8); + uint32 r2 = (uint32)(SuperFX.pvRegisters[0x30]) | (((uint32) + SuperFX.pvRegisters[0x31]) << 8); + if ((r1 & (1 << 1)) != (r2 & (1 << 1))) + printf(" Z=%d", (uint32)(!!(r2 & (1 << 1)))); + if ((r1 & (1 << 2)) != (r2 & (1 << 2))) + printf(" CY=%d", (uint32)(!!(r2 & (1 << 2)))); + if ((r1 & (1 << 3)) != (r2 & (1 << 3))) + printf(" S=%d", (uint32)(!!(r2 & (1 << 3)))); + if ((r1 & (1 << 4)) != (r2 & (1 << 4))) + printf(" OV=%d", (uint32)(!!(r2 & (1 << 4)))); + if ((r1 & (1 << 5)) != (r2 & (1 << 5))) + printf(" G=%d", (uint32)(!!(r2 & (1 << 5)))); + if ((r1 & (1 << 6)) != (r2 & (1 << 6))) + printf(" R=%d", (uint32)(!!(r2 & (1 << 6)))); + if ((r1 & (1 << 8)) != (r2 & (1 << 8))) + printf(" ALT1=%d", (uint32)(!!(r2 & (1 << 8)))); + if ((r1 & (1 << 9)) != (r2 & (1 << 9))) + printf(" ALT2=%d", (uint32)(!!(r2 & (1 << 9)))); + if ((r1 & (1 << 10)) != (r2 & (1 << 10))) + printf(" IL=%d", (uint32)(!!(r2 & (1 << 10)))); + if ((r1 & (1 << 11)) != (r2 & (1 << 11))) + printf(" IH=%d", (uint32)(!!(r2 & (1 << 11)))); + if ((r1 & (1 << 12)) != (r2 & (1 << 12))) + printf(" B=%d", (uint32)(!!(r2 & (1 << 12)))); + if ((r1 & (1 << 15)) != (r2 & (1 << 15))) + printf(" IRQ=%d", (uint32)(!!(r2 & (1 << 15)))); + } + { + /* Check PBR */ + uint32 r1 = ((uint32)avReg[0x34]); + uint32 r2 = (uint32)(SuperFX.pvRegisters[0x34]); + if (r1 != r2) + printf(" PBR=$%02x", r2); + } + { + /* Check ROMBR */ + uint32 r1 = ((uint32)avReg[0x36]); + uint32 r2 = (uint32)(SuperFX.pvRegisters[0x36]); + if (r1 != r2) + printf(" ROMBR=$%02x", r2); + } + { + /* Check RAMBR */ + uint32 r1 = ((uint32)avReg[0x3c]); + uint32 r2 = (uint32)(SuperFX.pvRegisters[0x3c]); + if (r1 != r2) + printf(" RAMBR=$%02x", r2); + } + { + /* Check CBR */ + uint32 r1 = ((uint32)avReg[0x3e]) | (((uint32)avReg[0x3f]) << 8); + uint32 r2 = (uint32)(SuperFX.pvRegisters[0x3e]) | (((uint32) + SuperFX.pvRegisters[0x3f]) << 8); + if (r1 != r2) + printf(" CBR=$%04x", r2); + } + { + /* Check COLR */ + if (vColr != FxGetColorRegister()) + printf(" COLR=$%02x", FxGetColorRegister()); + } + { + /* Check POR */ + if (vPor != FxGetPlotOptionRegister()) + printf(" POR=$%02x", FxGetPlotOptionRegister()); + } + printf("\n"); + } + S9xExit(); + } + else + { + uint32 t = (Memory.FillRAM [0x3034] << 16) + + (Memory.FillRAM [0x301f] << 8) + + (Memory.FillRAM [0x301e] << 0); + + printf("%06x: %d\n", t, FxEmulate(2000000)); + // FxEmulate (2000000); + } #if 0 - if (!(CPU.Flags & TRACE_FLAG)) - { - static int z = 1; - if (z == 0) - { - extern FILE *trace; - CPU.Flags |= TRACE_FLAG; - trace = fopen ("trace.log", "wb"); - } - else - z--; - } + if (!(CPU.Flags & TRACE_FLAG)) + { + static int z = 1; + if (z == 0) + { + extern FILE* trace; + CPU.Flags |= TRACE_FLAG; + trace = fopen("trace.log", "wb"); + } + else + z--; + } #endif - Memory.FillRAM [0x3030] &= ~0x20; - if (Memory.FillRAM [0x3031] & 0x80) - { - S9xSetIRQ (GSU_IRQ_SOURCE); - } + Memory.FillRAM [0x3030] &= ~0x20; + if (Memory.FillRAM [0x3031] & 0x80) + S9xSetIRQ(GSU_IRQ_SOURCE); #endif } #endif @@ -2880,258 +2977,258 @@ printf ("%06x: %d\n", t, FxEmulate (2000000)); uint8 REGISTER_4212() { - uint8 GetBank = 0; - if (CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE && - CPU.V_Counter < PPU.ScreenHeight + FIRST_VISIBLE_LINE + 3) - GetBank = 1; + uint8 GetBank = 0; + if (CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE && + CPU.V_Counter < PPU.ScreenHeight + FIRST_VISIBLE_LINE + 3) + GetBank = 1; - GetBank |= CPU.Cycles >= Settings.HBlankStart ? 0x40 : 0; - if (CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE) - GetBank |= 0x80; /* XXX: 0x80 or 0xc0 ? */ + GetBank |= CPU.Cycles >= Settings.HBlankStart ? 0x40 : 0; + if (CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE) + GetBank |= 0x80; /* XXX: 0x80 or 0xc0 ? */ - return (GetBank); + return (GetBank); } -void FLUSH_REDRAW () +void FLUSH_REDRAW() { - if (IPPU.PreviousLine != IPPU.CurrentLine) - S9xUpdateScreen (); + if (IPPU.PreviousLine != IPPU.CurrentLine) + S9xUpdateScreen(); } -void REGISTER_2104 (uint8 byte) +void REGISTER_2104(uint8 byte) { - if (PPU.OAMAddr & 0x100) - { - int addr = ((PPU.OAMAddr & 0x10f) << 1) + (PPU.OAMFlip & 1); - if (byte != PPU.OAMData [addr]){ - FLUSH_REDRAW (); - PPU.OAMData [addr] = byte; - IPPU.OBJChanged = TRUE; - - // X position high bit, and sprite size (x4) - struct SOBJ *pObj = &PPU.OBJ [(addr & 0x1f) * 4]; - - pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 0) & 1]; - pObj++->Size = byte & 2; - pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 2) & 1]; - pObj++->Size = byte & 8; - pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 4) & 1]; - pObj++->Size = byte & 32; - pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 6) & 1]; - pObj->Size = byte & 128; - } - PPU.OAMFlip ^= 1; - if(!(PPU.OAMFlip & 1)){ - ++PPU.OAMAddr; - PPU.OAMAddr &= 0x1ff; - if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1)) - { - PPU.FirstSprite = (PPU.OAMAddr&0xFE) >> 1; - IPPU.OBJChanged = TRUE; - } - } else { - if (PPU.OAMPriorityRotation && (PPU.OAMAddr&1)) IPPU.OBJChanged = TRUE; - } - } else if(!(PPU.OAMFlip & 1)){ - PPU.OAMWriteRegister &= 0xff00; - PPU.OAMWriteRegister |= byte; - PPU.OAMFlip |= 1; - if (PPU.OAMPriorityRotation && (PPU.OAMAddr&1)) IPPU.OBJChanged = TRUE; - } else { - PPU.OAMWriteRegister &= 0x00ff; - uint8 lowbyte = (uint8)(PPU.OAMWriteRegister); - uint8 highbyte = byte; - PPU.OAMWriteRegister |= byte << 8; - - int addr = (PPU.OAMAddr << 1); - - if (lowbyte != PPU.OAMData [addr] || - highbyte != PPU.OAMData [addr+1]) - { - FLUSH_REDRAW (); - PPU.OAMData [addr] = lowbyte; - PPU.OAMData [addr+1] = highbyte; - IPPU.OBJChanged = TRUE; - if (addr & 2) - { - // Tile - PPU.OBJ[addr = PPU.OAMAddr >> 1].Name = PPU.OAMWriteRegister & 0x1ff; - - // priority, h and v flip. - PPU.OBJ[addr].Palette = (highbyte >> 1) & 7; - PPU.OBJ[addr].Priority = (highbyte >> 4) & 3; - PPU.OBJ[addr].HFlip = (highbyte >> 6) & 1; - PPU.OBJ[addr].VFlip = (highbyte >> 7) & 1; - } - else - { - // X position (low) - PPU.OBJ[addr = PPU.OAMAddr >> 1].HPos &= 0xFF00; - PPU.OBJ[addr].HPos |= lowbyte; - - // Sprite Y position - PPU.OBJ[addr].VPos = highbyte; - } - } - PPU.OAMFlip &= ~1; - ++PPU.OAMAddr; - if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1)) - { - PPU.FirstSprite = (PPU.OAMAddr&0xFE) >> 1; + if (PPU.OAMAddr & 0x100) + { + int addr = ((PPU.OAMAddr & 0x10f) << 1) + (PPU.OAMFlip & 1); + if (byte != PPU.OAMData [addr]) + { + FLUSH_REDRAW(); + PPU.OAMData [addr] = byte; + IPPU.OBJChanged = TRUE; + + // X position high bit, and sprite size (x4) + struct SOBJ* pObj = &PPU.OBJ [(addr & 0x1f) * 4]; + + pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 0) & 1]; + pObj++->Size = byte & 2; + pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 2) & 1]; + pObj++->Size = byte & 8; + pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 4) & 1]; + pObj++->Size = byte & 32; + pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 6) & 1]; + pObj->Size = byte & 128; + } + PPU.OAMFlip ^= 1; + if (!(PPU.OAMFlip & 1)) + { + ++PPU.OAMAddr; + PPU.OAMAddr &= 0x1ff; + if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1)) + { + PPU.FirstSprite = (PPU.OAMAddr & 0xFE) >> 1; IPPU.OBJChanged = TRUE; - } - } + } + } + else + { + if (PPU.OAMPriorityRotation && (PPU.OAMAddr & 1)) IPPU.OBJChanged = TRUE; + } + } + else if (!(PPU.OAMFlip & 1)) + { + PPU.OAMWriteRegister &= 0xff00; + PPU.OAMWriteRegister |= byte; + PPU.OAMFlip |= 1; + if (PPU.OAMPriorityRotation && (PPU.OAMAddr & 1)) IPPU.OBJChanged = TRUE; + } + else + { + PPU.OAMWriteRegister &= 0x00ff; + uint8 lowbyte = (uint8)(PPU.OAMWriteRegister); + uint8 highbyte = byte; + PPU.OAMWriteRegister |= byte << 8; + + int addr = (PPU.OAMAddr << 1); + + if (lowbyte != PPU.OAMData [addr] || + highbyte != PPU.OAMData [addr + 1]) + { + FLUSH_REDRAW(); + PPU.OAMData [addr] = lowbyte; + PPU.OAMData [addr + 1] = highbyte; + IPPU.OBJChanged = TRUE; + if (addr & 2) + { + // Tile + PPU.OBJ[addr = PPU.OAMAddr >> 1].Name = PPU.OAMWriteRegister & 0x1ff; + + // priority, h and v flip. + PPU.OBJ[addr].Palette = (highbyte >> 1) & 7; + PPU.OBJ[addr].Priority = (highbyte >> 4) & 3; + PPU.OBJ[addr].HFlip = (highbyte >> 6) & 1; + PPU.OBJ[addr].VFlip = (highbyte >> 7) & 1; + } + else + { + // X position (low) + PPU.OBJ[addr = PPU.OAMAddr >> 1].HPos &= 0xFF00; + PPU.OBJ[addr].HPos |= lowbyte; + + // Sprite Y position + PPU.OBJ[addr].VPos = highbyte; + } + } + PPU.OAMFlip &= ~1; + ++PPU.OAMAddr; + if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1)) + { + PPU.FirstSprite = (PPU.OAMAddr & 0xFE) >> 1; + IPPU.OBJChanged = TRUE; + } + } - Memory.FillRAM [0x2104] = byte; + Memory.FillRAM [0x2104] = byte; } -void REGISTER_2118 (uint8 Byte) +void REGISTER_2118(uint8 Byte) { - uint32 address; - if (PPU.VMA.FullGraphicCount) - { - uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1; - address = (((PPU.VMA.Address & ~PPU.VMA.Mask1) + - (rem >> PPU.VMA.Shift) + - ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) & 0xffff; - Memory.VRAM [address] = Byte; - } - else - { - Memory.VRAM[address = (PPU.VMA.Address << 1) & 0xFFFF] = Byte; - } - IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; - IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; - IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; - if (!PPU.VMA.High) - { - PPU.VMA.Address += PPU.VMA.Increment; - } -// Memory.FillRAM [0x2118] = Byte; + uint32 address; + if (PPU.VMA.FullGraphicCount) + { + uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1; + address = (((PPU.VMA.Address & ~PPU.VMA.Mask1) + + (rem >> PPU.VMA.Shift) + + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) & 0xffff; + Memory.VRAM [address] = Byte; + } + else + Memory.VRAM[address = (PPU.VMA.Address << 1) & 0xFFFF] = Byte; + IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; + IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; + IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; + if (!PPU.VMA.High) + PPU.VMA.Address += PPU.VMA.Increment; + // Memory.FillRAM [0x2118] = Byte; } -void REGISTER_2118_tile (uint8 Byte) +void REGISTER_2118_tile(uint8 Byte) { - uint32 address; - uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1; - address = (((PPU.VMA.Address & ~PPU.VMA.Mask1) + - (rem >> PPU.VMA.Shift) + - ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) & 0xffff; - Memory.VRAM [address] = Byte; - IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; - IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; - IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; - if (!PPU.VMA.High) - PPU.VMA.Address += PPU.VMA.Increment; -// Memory.FillRAM [0x2118] = Byte; + uint32 address; + uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1; + address = (((PPU.VMA.Address & ~PPU.VMA.Mask1) + + (rem >> PPU.VMA.Shift) + + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) & 0xffff; + Memory.VRAM [address] = Byte; + IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; + IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; + IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; + if (!PPU.VMA.High) + PPU.VMA.Address += PPU.VMA.Increment; + // Memory.FillRAM [0x2118] = Byte; } -void REGISTER_2118_linear (uint8 Byte) +void REGISTER_2118_linear(uint8 Byte) { - uint32 address; - Memory.VRAM[address = (PPU.VMA.Address << 1) & 0xFFFF] = Byte; - IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; - IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; - IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; - if (!PPU.VMA.High) - PPU.VMA.Address += PPU.VMA.Increment; -// Memory.FillRAM [0x2118] = Byte; + uint32 address; + Memory.VRAM[address = (PPU.VMA.Address << 1) & 0xFFFF] = Byte; + IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; + IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; + IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; + if (!PPU.VMA.High) + PPU.VMA.Address += PPU.VMA.Increment; + // Memory.FillRAM [0x2118] = Byte; } -void REGISTER_2119 (uint8 Byte) +void REGISTER_2119(uint8 Byte) { - uint32 address; - if (PPU.VMA.FullGraphicCount) - { - uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1; - address = ((((PPU.VMA.Address & ~PPU.VMA.Mask1) + - (rem >> PPU.VMA.Shift) + - ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) + 1) & 0xFFFF; - Memory.VRAM [address] = Byte; - } - else - { - Memory.VRAM[address = ((PPU.VMA.Address << 1) + 1) & 0xFFFF] = Byte; - } - IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; - IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; - IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; - if (PPU.VMA.High) - { - PPU.VMA.Address += PPU.VMA.Increment; - } -// Memory.FillRAM [0x2119] = Byte; + uint32 address; + if (PPU.VMA.FullGraphicCount) + { + uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1; + address = ((((PPU.VMA.Address & ~PPU.VMA.Mask1) + + (rem >> PPU.VMA.Shift) + + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) + 1) & 0xFFFF; + Memory.VRAM [address] = Byte; + } + else + Memory.VRAM[address = ((PPU.VMA.Address << 1) + 1) & 0xFFFF] = Byte; + IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; + IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; + IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; + if (PPU.VMA.High) + PPU.VMA.Address += PPU.VMA.Increment; + // Memory.FillRAM [0x2119] = Byte; } -void REGISTER_2119_tile (uint8 Byte) +void REGISTER_2119_tile(uint8 Byte) { - uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1; - uint32 address = ((((PPU.VMA.Address & ~PPU.VMA.Mask1) + - (rem >> PPU.VMA.Shift) + - ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) + 1) & 0xFFFF; - Memory.VRAM [address] = Byte; - IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; - IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; - IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; - if (PPU.VMA.High) - PPU.VMA.Address += PPU.VMA.Increment; -// Memory.FillRAM [0x2119] = Byte; + uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1; + uint32 address = ((((PPU.VMA.Address & ~PPU.VMA.Mask1) + + (rem >> PPU.VMA.Shift) + + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) + 1) & 0xFFFF; + Memory.VRAM [address] = Byte; + IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; + IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; + IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; + if (PPU.VMA.High) + PPU.VMA.Address += PPU.VMA.Increment; + // Memory.FillRAM [0x2119] = Byte; } -void REGISTER_2119_linear (uint8 Byte) +void REGISTER_2119_linear(uint8 Byte) { - uint32 address; - Memory.VRAM[address = ((PPU.VMA.Address << 1) + 1) & 0xFFFF] = Byte; - IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; - IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; - IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; - if (PPU.VMA.High) - PPU.VMA.Address += PPU.VMA.Increment; -// Memory.FillRAM [0x2119] = Byte; + uint32 address; + Memory.VRAM[address = ((PPU.VMA.Address << 1) + 1) & 0xFFFF] = Byte; + IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; + IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; + IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; + if (PPU.VMA.High) + PPU.VMA.Address += PPU.VMA.Increment; + // Memory.FillRAM [0x2119] = Byte; } void REGISTER_2122(uint8 Byte) { - // CG-RAM (palette) write - - if (PPU.CGFLIP) - { - if ((Byte & 0x7f) != (PPU.CGDATA[PPU.CGADD] >> 8)) - { - FLUSH_REDRAW (); - PPU.CGDATA[PPU.CGADD] &= 0x00FF; - PPU.CGDATA[PPU.CGADD] |= (Byte & 0x7f) << 8; - IPPU.ColorsChanged = TRUE; - IPPU.Blue [PPU.CGADD] = IPPU.XB [(Byte >> 2) & 0x1f]; - IPPU.Green [PPU.CGADD] = IPPU.XB [(PPU.CGDATA[PPU.CGADD] >> 5) & 0x1f]; - IPPU.ScreenColors [PPU.CGADD] = (uint16) BUILD_PIXEL (IPPU.Red [PPU.CGADD], - IPPU.Green [PPU.CGADD], - IPPU.Blue [PPU.CGADD]); - } - PPU.CGADD++; - } - else - { - if (Byte != (uint8) (PPU.CGDATA[PPU.CGADD] & 0xff)) - { - FLUSH_REDRAW (); - PPU.CGDATA[PPU.CGADD] &= 0x7F00; - PPU.CGDATA[PPU.CGADD] |= Byte; - IPPU.ColorsChanged = TRUE; - IPPU.Red [PPU.CGADD] = IPPU.XB [Byte & 0x1f]; - IPPU.Green [PPU.CGADD] = IPPU.XB [(PPU.CGDATA[PPU.CGADD] >> 5) & 0x1f]; - IPPU.ScreenColors [PPU.CGADD] = (uint16) BUILD_PIXEL (IPPU.Red [PPU.CGADD], - IPPU.Green [PPU.CGADD], - IPPU.Blue [PPU.CGADD]); - } - } - PPU.CGFLIP ^= 1; -// Memory.FillRAM [0x2122] = Byte; + // CG-RAM (palette) write + + if (PPU.CGFLIP) + { + if ((Byte & 0x7f) != (PPU.CGDATA[PPU.CGADD] >> 8)) + { + FLUSH_REDRAW(); + PPU.CGDATA[PPU.CGADD] &= 0x00FF; + PPU.CGDATA[PPU.CGADD] |= (Byte & 0x7f) << 8; + IPPU.ColorsChanged = TRUE; + IPPU.Blue [PPU.CGADD] = IPPU.XB [(Byte >> 2) & 0x1f]; + IPPU.Green [PPU.CGADD] = IPPU.XB [(PPU.CGDATA[PPU.CGADD] >> 5) & 0x1f]; + IPPU.ScreenColors [PPU.CGADD] = (uint16) BUILD_PIXEL(IPPU.Red [PPU.CGADD], + IPPU.Green [PPU.CGADD], + IPPU.Blue [PPU.CGADD]); + } + PPU.CGADD++; + } + else + { + if (Byte != (uint8)(PPU.CGDATA[PPU.CGADD] & 0xff)) + { + FLUSH_REDRAW(); + PPU.CGDATA[PPU.CGADD] &= 0x7F00; + PPU.CGDATA[PPU.CGADD] |= Byte; + IPPU.ColorsChanged = TRUE; + IPPU.Red [PPU.CGADD] = IPPU.XB [Byte & 0x1f]; + IPPU.Green [PPU.CGADD] = IPPU.XB [(PPU.CGDATA[PPU.CGADD] >> 5) & 0x1f]; + IPPU.ScreenColors [PPU.CGADD] = (uint16) BUILD_PIXEL(IPPU.Red [PPU.CGADD], + IPPU.Green [PPU.CGADD], + IPPU.Blue [PPU.CGADD]); + } + } + PPU.CGFLIP ^= 1; + // Memory.FillRAM [0x2122] = Byte; } void REGISTER_2180(uint8 Byte) { - Memory.RAM[PPU.WRAM++] = Byte; - PPU.WRAM &= 0x1FFFF; - Memory.FillRAM [0x2180] = Byte; + Memory.RAM[PPU.WRAM++] = Byte; + PPU.WRAM &= 0x1FFFF; + Memory.FillRAM [0x2180] = Byte; } diff --git a/source/ppu.h b/source/ppu.h index efb892e..c01135f 100644 --- a/source/ppu.h +++ b/source/ppu.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -103,220 +103,226 @@ extern uint16 SignExtend [2]; #define MAX_4BIT_TILES 2048 #define MAX_8BIT_TILES 1024 -#define PPU_H_BEAM_IRQ_SOURCE (1 << 0) -#define PPU_V_BEAM_IRQ_SOURCE (1 << 1) -#define GSU_IRQ_SOURCE (1 << 2) -#define SA1_IRQ_SOURCE (1 << 7) -#define SA1_DMA_IRQ_SOURCE (1 << 5) +#define PPU_H_BEAM_IRQ_SOURCE (1 << 0) +#define PPU_V_BEAM_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 { - uint32 Count [6]; - uint32 Left [6][6]; - uint32 Right [6][6]; +struct ClipData +{ + uint32 Count [6]; + uint32 Left [6][6]; + uint32 Right [6][6]; }; -typedef struct { - bool8 ColorsChanged; - uint8 HDMA; - bool8 HDMAStarted; - uint8 MaxBrightness; - bool8 LatchedBlanking; - bool8 OBJChanged; - bool8 RenderThisFrame; - bool8 DirectColourMapsNeedRebuild; - uint32 FrameCount; - uint32 RenderedFramesCount; - uint32 DisplayedRenderedFrameCount; - uint32 SkippedFrames; - uint32 FrameSkip; - uint8 *TileCache [3]; - uint8 *TileCached [3]; +typedef struct +{ + bool8 ColorsChanged; + uint8 HDMA; + bool8 HDMAStarted; + uint8 MaxBrightness; + bool8 LatchedBlanking; + bool8 OBJChanged; + bool8 RenderThisFrame; + bool8 DirectColourMapsNeedRebuild; + uint32 FrameCount; + uint32 RenderedFramesCount; + uint32 DisplayedRenderedFrameCount; + uint32 SkippedFrames; + uint32 FrameSkip; + uint8* TileCache [3]; + uint8* TileCached [3]; #ifdef CORRECT_VRAM_READS - uint16 VRAMReadBuffer; + uint16 VRAMReadBuffer; #else - bool8 FirstVRAMRead; + bool8 FirstVRAMRead; #endif - bool8 DoubleHeightPixels; - bool8 Interlace; - bool8 InterlaceSprites; - bool8 DoubleWidthPixels; - bool8 HalfWidthPixels; - int RenderedScreenHeight; - int RenderedScreenWidth; - uint32 Red [256]; - uint32 Green [256]; - uint32 Blue [256]; - uint8 *XB; - uint16 ScreenColors [256]; - int PreviousLine; - int CurrentLine; - int Controller; - uint32 Joypads[5]; - uint32 SuperScope; - uint32 Mouse[2]; - int PrevMouseX[2]; - int PrevMouseY[2]; - struct ClipData Clip [2]; + bool8 DoubleHeightPixels; + bool8 Interlace; + bool8 InterlaceSprites; + bool8 DoubleWidthPixels; + bool8 HalfWidthPixels; + int RenderedScreenHeight; + int RenderedScreenWidth; + uint32 Red [256]; + uint32 Green [256]; + uint32 Blue [256]; + uint8* XB; + uint16 ScreenColors [256]; + int PreviousLine; + int CurrentLine; + int Controller; + uint32 Joypads[5]; + uint32 SuperScope; + uint32 Mouse[2]; + int PrevMouseX[2]; + int PrevMouseY[2]; + struct ClipData Clip [2]; } InternalPPU; struct SOBJ { - short HPos; - uint16 VPos; - uint16 Name; - uint8 VFlip; - uint8 HFlip; - uint8 Priority; - uint8 Palette; - uint8 Size; + short HPos; + uint16 VPos; + uint16 Name; + uint8 VFlip; + uint8 HFlip; + uint8 Priority; + uint8 Palette; + uint8 Size; }; -typedef struct{ - uint8 BGMode; - uint8 BG3Priority; - uint8 Brightness; - - struct { - bool8 High; - uint8 Increment; - uint16 Address; - uint16 Mask1; - uint16 FullGraphicCount; - uint16 Shift; - } VMA; - - struct { - uint16 SCBase; - uint16 VOffset; - uint16 HOffset; - uint8 BGSize; - uint16 NameBase; - uint16 SCSize; - } BG [4]; - - bool8 CGFLIP; - uint16 CGDATA [256]; - uint8 FirstSprite; - uint8 LastSprite; - struct SOBJ OBJ [128]; - uint8 OAMPriorityRotation; - uint16 OAMAddr; - uint8 RangeTimeOver; - - uint8 OAMFlip; - uint16 OAMTileAddress; - uint16 IRQVBeamPos; - uint16 IRQHBeamPos; - uint16 VBeamPosLatched; - uint16 HBeamPosLatched; - - uint8 HBeamFlip; - uint8 VBeamFlip; - uint8 HVBeamCounterLatched; - - short MatrixA; - short MatrixB; - short MatrixC; - short MatrixD; - short CentreX; - short CentreY; - uint8 Joypad1ButtonReadPos; - uint8 Joypad2ButtonReadPos; - - uint8 CGADD; - uint8 FixedColourRed; - uint8 FixedColourGreen; - uint8 FixedColourBlue; - uint16 SavedOAMAddr; - uint16 ScreenHeight; - uint32 WRAM; - uint8 BG_Forced; - bool8 ForcedBlanking; - bool8 OBJThroughMain; - bool8 OBJThroughSub; - uint8 OBJSizeSelect; - uint16 OBJNameBase; - bool8 OBJAddition; - uint8 OAMReadFlip; - uint8 OAMData [512 + 32]; - bool8 VTimerEnabled; - bool8 HTimerEnabled; - short HTimerPosition; - uint8 Mosaic; - bool8 BGMosaic [4]; - bool8 Mode7HFlip; - bool8 Mode7VFlip; - uint8 Mode7Repeat; - uint8 Window1Left; - uint8 Window1Right; - uint8 Window2Left; - uint8 Window2Right; - uint8 ClipCounts [6]; - uint8 ClipWindowOverlapLogic [6]; - uint8 ClipWindow1Enable [6]; - uint8 ClipWindow2Enable [6]; - bool8 ClipWindow1Inside [6]; - bool8 ClipWindow2Inside [6]; - bool8 RecomputeClipWindows; - uint8 CGFLIPRead; - uint16 OBJNameSelect; - bool8 Need16x8Mulitply; - uint8 Joypad3ButtonReadPos; - uint8 MouseSpeed[2]; - - // XXX Do these need to be added to snapshot.cpp? - uint16 OAMWriteRegister; - uint8 BGnxOFSbyte; - uint8 OpenBus1; - uint8 OpenBus2; -}SPPU; +typedef struct +{ + uint8 BGMode; + uint8 BG3Priority; + uint8 Brightness; + + struct + { + bool8 High; + uint8 Increment; + uint16 Address; + uint16 Mask1; + uint16 FullGraphicCount; + uint16 Shift; + } VMA; + + struct + { + uint16 SCBase; + uint16 VOffset; + uint16 HOffset; + uint8 BGSize; + uint16 NameBase; + uint16 SCSize; + } BG [4]; + + bool8 CGFLIP; + uint16 CGDATA [256]; + uint8 FirstSprite; + uint8 LastSprite; + struct SOBJ OBJ [128]; + uint8 OAMPriorityRotation; + uint16 OAMAddr; + uint8 RangeTimeOver; + + uint8 OAMFlip; + uint16 OAMTileAddress; + uint16 IRQVBeamPos; + uint16 IRQHBeamPos; + uint16 VBeamPosLatched; + uint16 HBeamPosLatched; + + uint8 HBeamFlip; + uint8 VBeamFlip; + uint8 HVBeamCounterLatched; + + short MatrixA; + short MatrixB; + short MatrixC; + short MatrixD; + short CentreX; + short CentreY; + uint8 Joypad1ButtonReadPos; + uint8 Joypad2ButtonReadPos; + + uint8 CGADD; + uint8 FixedColourRed; + uint8 FixedColourGreen; + uint8 FixedColourBlue; + uint16 SavedOAMAddr; + uint16 ScreenHeight; + uint32 WRAM; + uint8 BG_Forced; + bool8 ForcedBlanking; + bool8 OBJThroughMain; + bool8 OBJThroughSub; + uint8 OBJSizeSelect; + uint16 OBJNameBase; + bool8 OBJAddition; + uint8 OAMReadFlip; + uint8 OAMData [512 + 32]; + bool8 VTimerEnabled; + bool8 HTimerEnabled; + short HTimerPosition; + uint8 Mosaic; + bool8 BGMosaic [4]; + bool8 Mode7HFlip; + bool8 Mode7VFlip; + uint8 Mode7Repeat; + uint8 Window1Left; + uint8 Window1Right; + uint8 Window2Left; + uint8 Window2Right; + uint8 ClipCounts [6]; + uint8 ClipWindowOverlapLogic [6]; + uint8 ClipWindow1Enable [6]; + uint8 ClipWindow2Enable [6]; + bool8 ClipWindow1Inside [6]; + bool8 ClipWindow2Inside [6]; + bool8 RecomputeClipWindows; + uint8 CGFLIPRead; + uint16 OBJNameSelect; + bool8 Need16x8Mulitply; + uint8 Joypad3ButtonReadPos; + uint8 MouseSpeed[2]; + + // XXX Do these need to be added to snapshot.cpp? + uint16 OAMWriteRegister; + uint8 BGnxOFSbyte; + uint8 OpenBus1; + uint8 OpenBus2; +} SPPU; #define CLIP_OR 0 #define CLIP_AND 1 #define CLIP_XOR 2 #define CLIP_XNOR 3 -typedef struct { - bool8 TransferDirection; - bool8 AAddressFixed; - bool8 AAddressDecrement; - uint8 TransferMode; - - uint8 ABank; - uint16 AAddress; - uint16 Address; - uint8 BAddress; - - // General DMA only: - uint16 TransferBytes; - - // H-DMA only: - bool8 HDMAIndirectAddressing; - uint16 IndirectAddress; - uint8 IndirectBank; - uint8 Repeat; - uint8 LineCount; - uint8 FirstLine; -}SDMA; - -void S9xUpdateScreen (); -void S9xResetPPU (); -void S9xSoftResetPPU (); -void S9xFixColourBrightness (); -void S9xUpdateJoypads (); +typedef struct +{ + bool8 TransferDirection; + bool8 AAddressFixed; + bool8 AAddressDecrement; + uint8 TransferMode; + + uint8 ABank; + uint16 AAddress; + uint16 Address; + uint8 BAddress; + + // General DMA only: + uint16 TransferBytes; + + // H-DMA only: + bool8 HDMAIndirectAddressing; + uint16 IndirectAddress; + uint8 IndirectBank; + uint8 Repeat; + uint8 LineCount; + uint8 FirstLine; +} SDMA; + +void S9xUpdateScreen(); +void S9xResetPPU(); +void S9xSoftResetPPU(); +void S9xFixColourBrightness(); +void S9xUpdateJoypads(); void S9xProcessMouse(int which1); -void S9xSuperFXExec (); +void S9xSuperFXExec(); -void S9xSetPPU (uint8 Byte, uint16 Address); -uint8 S9xGetPPU (uint16 Address); -void S9xSetCPU (uint8 Byte, uint16 Address); -uint8 S9xGetCPU (uint16 Address); +void S9xSetPPU(uint8 Byte, uint16 Address); +uint8 S9xGetPPU(uint16 Address); +void S9xSetCPU(uint8 Byte, uint16 Address); +uint8 S9xGetCPU(uint16 Address); -void S9xInitC4 (); -void S9xSetC4 (uint8 Byte, uint16 Address); -uint8 S9xGetC4 (uint16 Address); -void S9xSetC4RAM (uint8 Byte, uint16 Address); -uint8 S9xGetC4RAM (uint16 Address); +void S9xInitC4(); +void S9xSetC4(uint8 Byte, uint16 Address); +uint8 S9xGetC4(uint16 Address); +void S9xSetC4RAM(uint8 Byte, uint16 Address); +uint8 S9xGetC4RAM(uint16 Address); extern SPPU PPU; extern SDMA DMA [8]; @@ -325,10 +331,11 @@ extern InternalPPU IPPU; #include "gfx.h" #include "memmap.h" -typedef struct{ - uint8 _5C77; - uint8 _5C78; - uint8 _5A22; +typedef struct +{ + uint8 _5C77; + uint8 _5C78; + uint8 _5A22; } SnesModel; extern SnesModel* Model; @@ -340,19 +347,19 @@ extern SnesModel M2SNES; #define MAX_5A22_VERSION 0x02 extern uint8 REGISTER_4212(); -extern void FLUSH_REDRAW (); -extern void REGISTER_2104 (uint8 byte); -extern void REGISTER_2118 (uint8 Byte); -extern void REGISTER_2118_tile (uint8 Byte); -extern void REGISTER_2118_linear (uint8 Byte); -extern void REGISTER_2119 (uint8 Byte); -extern void REGISTER_2119_tile (uint8 Byte); -extern void REGISTER_2119_linear (uint8 Byte); +extern void FLUSH_REDRAW(); +extern void REGISTER_2104(uint8 byte); +extern void REGISTER_2118(uint8 Byte); +extern void REGISTER_2118_tile(uint8 Byte); +extern void REGISTER_2118_linear(uint8 Byte); +extern void REGISTER_2119(uint8 Byte); +extern void REGISTER_2119_tile(uint8 Byte); +extern void REGISTER_2119_linear(uint8 Byte); extern void REGISTER_2122(uint8 Byte); extern void REGISTER_2180(uint8 Byte); //Platform specific input functions used by PPU.CPP -void JustifierButtons(uint32 *); +void JustifierButtons(uint32*); bool JustifierOffscreen(); #endif diff --git a/source/sa1.c b/source/sa1.c index 18207eb..4171903 100644 --- a/source/sa1.c +++ b/source/sa1.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -93,845 +93,842 @@ #include "sa1.h" -static void S9xSA1CharConv2 (); -static void S9xSA1DMA (); -static void S9xSA1ReadVariableLengthData (bool8 inc, bool8 no_shift); +static void S9xSA1CharConv2(); +static void S9xSA1DMA(); +static void S9xSA1ReadVariableLengthData(bool8 inc, bool8 no_shift); -void S9xSA1Init () +void S9xSA1Init() { - SA1.NMIActive = FALSE; - SA1.IRQActive = FALSE; - SA1.WaitingForInterrupt = FALSE; - SA1.Waiting = FALSE; - SA1.Flags = 0; - SA1.Executing = 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; - SA1.op1 = 0; - SA1.op2 = 0; - SA1.arithmetic_op = 0; - SA1.sum = 0; - SA1.overflow = FALSE; - SA1.S9xOpcodes=NULL; + SA1.NMIActive = FALSE; + SA1.IRQActive = FALSE; + SA1.WaitingForInterrupt = FALSE; + SA1.Waiting = FALSE; + SA1.Flags = 0; + SA1.Executing = 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; + SA1.op1 = 0; + SA1.op2 = 0; + SA1.arithmetic_op = 0; + SA1.sum = 0; + SA1.overflow = FALSE; + SA1.S9xOpcodes = NULL; } -void S9xSA1Reset () +void S9xSA1Reset() { - SA1.Registers.PB = 0; - SA1.Registers.PC = Memory.FillRAM [0x2203] | - (Memory.FillRAM [0x2204] << 8); - SA1.Registers.D.W = 0; - SA1.Registers.DB = 0; - SA1.Registers.SH = 1; - SA1.Registers.SL = 0xFF; - SA1.Registers.XH = 0; - SA1.Registers.YH = 0; - SA1.Registers.P.W = 0; - - SA1.ShiftedPB = 0; - SA1.ShiftedDB = 0; - SA1SetFlags (MemoryFlag | IndexFlag | IRQ | Emulation); - SA1ClearFlags (Decimal); - - SA1.WaitingForInterrupt = FALSE; - SA1.PC = NULL; - SA1.PCBase = NULL; - S9xSA1SetPCBase (SA1.Registers.PC); - SA1.S9xOpcodes = S9xSA1OpcodesM1X1; - - S9xSA1UnpackStatus(); - S9xSA1FixCycles (); - SA1.Executing = TRUE; - SA1.BWRAM = Memory.SRAM; - Memory.FillRAM [0x2225] = 0; + SA1.Registers.PB = 0; + SA1.Registers.PC = Memory.FillRAM [0x2203] | + (Memory.FillRAM [0x2204] << 8); + SA1.Registers.D.W = 0; + SA1.Registers.DB = 0; + SA1.Registers.SH = 1; + SA1.Registers.SL = 0xFF; + SA1.Registers.XH = 0; + SA1.Registers.YH = 0; + SA1.Registers.P.W = 0; + + SA1.ShiftedPB = 0; + SA1.ShiftedDB = 0; + SA1SetFlags(MemoryFlag | IndexFlag | IRQ | Emulation); + SA1ClearFlags(Decimal); + + SA1.WaitingForInterrupt = FALSE; + SA1.PC = NULL; + SA1.PCBase = NULL; + S9xSA1SetPCBase(SA1.Registers.PC); + SA1.S9xOpcodes = S9xSA1OpcodesM1X1; + + S9xSA1UnpackStatus(); + S9xSA1FixCycles(); + SA1.Executing = TRUE; + SA1.BWRAM = Memory.SRAM; + Memory.FillRAM [0x2225] = 0; } -void S9xSA1SetBWRAMMemMap (uint8 val) +void S9xSA1SetBWRAMMemMap(uint8 val) { - int c; - - if (val & 0x80) - { - for (c = 0; c < 0x400; c += 16) - { - SA1.Map [c + 6] = SA1.Map [c + 0x806] = (uint8 *) MAP_BWRAM_BITMAP2; - SA1.Map [c + 7] = SA1.Map [c + 0x807] = (uint8 *) MAP_BWRAM_BITMAP2; - SA1.WriteMap [c + 6] = SA1.WriteMap [c + 0x806] = (uint8 *) MAP_BWRAM_BITMAP2; - SA1.WriteMap [c + 7] = SA1.WriteMap [c + 0x807] = (uint8 *) MAP_BWRAM_BITMAP2; - } - SA1.BWRAM = Memory.SRAM + (val & 0x7f) * 0x2000 / 4; - } - else - { - for (c = 0; c < 0x400; c += 16) - { - SA1.Map [c + 6] = SA1.Map [c + 0x806] = (uint8 *) MAP_BWRAM; - SA1.Map [c + 7] = SA1.Map [c + 0x807] = (uint8 *) MAP_BWRAM; - SA1.WriteMap [c + 6] = SA1.WriteMap [c + 0x806] = (uint8 *) MAP_BWRAM; - SA1.WriteMap [c + 7] = SA1.WriteMap [c + 0x807] = (uint8 *) MAP_BWRAM; - } - SA1.BWRAM = Memory.SRAM + (val & 7) * 0x2000; - } + int c; + + if (val & 0x80) + { + for (c = 0; c < 0x400; c += 16) + { + SA1.Map [c + 6] = SA1.Map [c + 0x806] = (uint8*) MAP_BWRAM_BITMAP2; + SA1.Map [c + 7] = SA1.Map [c + 0x807] = (uint8*) MAP_BWRAM_BITMAP2; + SA1.WriteMap [c + 6] = SA1.WriteMap [c + 0x806] = (uint8*) MAP_BWRAM_BITMAP2; + SA1.WriteMap [c + 7] = SA1.WriteMap [c + 0x807] = (uint8*) MAP_BWRAM_BITMAP2; + } + SA1.BWRAM = Memory.SRAM + (val & 0x7f) * 0x2000 / 4; + } + else + { + for (c = 0; c < 0x400; c += 16) + { + SA1.Map [c + 6] = SA1.Map [c + 0x806] = (uint8*) MAP_BWRAM; + SA1.Map [c + 7] = SA1.Map [c + 0x807] = (uint8*) MAP_BWRAM; + SA1.WriteMap [c + 6] = SA1.WriteMap [c + 0x806] = (uint8*) MAP_BWRAM; + SA1.WriteMap [c + 7] = SA1.WriteMap [c + 0x807] = (uint8*) MAP_BWRAM; + } + SA1.BWRAM = Memory.SRAM + (val & 7) * 0x2000; + } } -void S9xFixSA1AfterSnapshotLoad () +void S9xFixSA1AfterSnapshotLoad() { - SA1.ShiftedPB = (uint32) SA1.Registers.PB << 16; - SA1.ShiftedDB = (uint32) SA1.Registers.DB << 16; - - S9xSA1SetPCBase (SA1.ShiftedPB + SA1.Registers.PC); - S9xSA1UnpackStatus (); - S9xSA1FixCycles (); - 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; + SA1.ShiftedPB = (uint32) SA1.Registers.PB << 16; + SA1.ShiftedDB = (uint32) SA1.Registers.DB << 16; + + S9xSA1SetPCBase(SA1.ShiftedPB + SA1.Registers.PC); + S9xSA1UnpackStatus(); + S9xSA1FixCycles(); + 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; } -uint8 S9xSA1GetByte (uint32 address) +uint8 S9xSA1GetByte(uint32 address) { - uint8 *GetAddress = SA1.Map [(address >> MEMMAP_SHIFT) & MEMMAP_MASK]; - if (GetAddress >= (uint8 *) MAP_LAST) - return (*(GetAddress + (address & 0xffff))); - - switch ((intptr_t) GetAddress) - { - case MAP_PPU: - return (S9xGetSA1 (address & 0xffff)); - case MAP_LOROM_SRAM: - case MAP_SA1RAM: - return (*(Memory.SRAM + (address & 0xffff))); - case MAP_BWRAM: - return (*(SA1.BWRAM + ((address & 0x7fff) - 0x6000))); - case MAP_BWRAM_BITMAP: - address -= 0x600000; - if (SA1.VirtualBitmapFormat == 2) - return ((Memory.SRAM [(address >> 2) & 0xffff] >> ((address & 3) << 1)) & 3); - else - return ((Memory.SRAM [(address >> 1) & 0xffff] >> ((address & 1) << 2)) & 15); - case MAP_BWRAM_BITMAP2: - address = (address & 0xffff) - 0x6000; - if (SA1.VirtualBitmapFormat == 2) - return ((SA1.BWRAM [(address >> 2) & 0xffff] >> ((address & 3) << 1)) & 3); - else - return ((SA1.BWRAM [(address >> 1) & 0xffff] >> ((address & 1) << 2)) & 15); - - case MAP_DEBUG: - default: - return OpenBus; - } + uint8* GetAddress = SA1.Map [(address >> MEMMAP_SHIFT) & MEMMAP_MASK]; + if (GetAddress >= (uint8*) MAP_LAST) + return (*(GetAddress + (address & 0xffff))); + + switch ((intptr_t) GetAddress) + { + case MAP_PPU: + return (S9xGetSA1(address & 0xffff)); + case MAP_LOROM_SRAM: + case MAP_SA1RAM: + return (*(Memory.SRAM + (address & 0xffff))); + case MAP_BWRAM: + return (*(SA1.BWRAM + ((address & 0x7fff) - 0x6000))); + case MAP_BWRAM_BITMAP: + address -= 0x600000; + if (SA1.VirtualBitmapFormat == 2) + return ((Memory.SRAM [(address >> 2) & 0xffff] >> ((address & 3) << 1)) & 3); + else + return ((Memory.SRAM [(address >> 1) & 0xffff] >> ((address & 1) << 2)) & 15); + case MAP_BWRAM_BITMAP2: + address = (address & 0xffff) - 0x6000; + if (SA1.VirtualBitmapFormat == 2) + return ((SA1.BWRAM [(address >> 2) & 0xffff] >> ((address & 3) << 1)) & 3); + else + return ((SA1.BWRAM [(address >> 1) & 0xffff] >> ((address & 1) << 2)) & 15); + + case MAP_DEBUG: + default: + return OpenBus; + } } -uint16 S9xSA1GetWord (uint32 address) +uint16 S9xSA1GetWord(uint32 address) { - OpenBus = S9xSA1GetByte (address); - return (OpenBus | (S9xSA1GetByte (address + 1) << 8)); + OpenBus = S9xSA1GetByte(address); + return (OpenBus | (S9xSA1GetByte(address + 1) << 8)); } -void S9xSA1SetByte (uint8 byte, uint32 address) +void S9xSA1SetByte(uint8 byte, uint32 address) { - uint8 *Setaddress = SA1.WriteMap [(address >> MEMMAP_SHIFT) & MEMMAP_MASK]; - - if (Setaddress >= (uint8 *) MAP_LAST) - { - *(Setaddress + (address & 0xffff)) = byte; - return; - } - - switch ((intptr_t) Setaddress) - { - case MAP_PPU: - S9xSetSA1 (byte, address & 0xffff); - return; - case MAP_SA1RAM: - case MAP_LOROM_SRAM: - *(Memory.SRAM + (address & 0xffff)) = byte; - return; - case MAP_BWRAM: - *(SA1.BWRAM + ((address & 0x7fff) - 0x6000)) = byte; - return; - case MAP_BWRAM_BITMAP: - address -= 0x600000; - if (SA1.VirtualBitmapFormat == 2) - { - uint8 *ptr = &Memory.SRAM [(address >> 2) & 0xffff]; - *ptr &= ~(3 << ((address & 3) << 1)); - *ptr |= (byte & 3) << ((address & 3) << 1); - } - else - { - uint8 *ptr = &Memory.SRAM [(address >> 1) & 0xffff]; - *ptr &= ~(15 << ((address & 1) << 2)); - *ptr |= (byte & 15) << ((address & 1) << 2); - } - break; - case MAP_BWRAM_BITMAP2: - address = (address & 0xffff) - 0x6000; - if (SA1.VirtualBitmapFormat == 2) - { - uint8 *ptr = &SA1.BWRAM [(address >> 2) & 0xffff]; - *ptr &= ~(3 << ((address & 3) << 1)); - *ptr |= (byte & 3) << ((address & 3) << 1); - } - else - { - uint8 *ptr = &SA1.BWRAM [(address >> 1) & 0xffff]; - *ptr &= ~(15 << ((address & 1) << 2)); - *ptr |= (byte & 15) << ((address & 1) << 2); - } - default: - return; - } + uint8* Setaddress = SA1.WriteMap [(address >> MEMMAP_SHIFT) & MEMMAP_MASK]; + + if (Setaddress >= (uint8*) MAP_LAST) + { + *(Setaddress + (address & 0xffff)) = byte; + return; + } + + switch ((intptr_t) Setaddress) + { + case MAP_PPU: + S9xSetSA1(byte, address & 0xffff); + return; + case MAP_SA1RAM: + case MAP_LOROM_SRAM: + *(Memory.SRAM + (address & 0xffff)) = byte; + return; + case MAP_BWRAM: + *(SA1.BWRAM + ((address & 0x7fff) - 0x6000)) = byte; + return; + case MAP_BWRAM_BITMAP: + address -= 0x600000; + if (SA1.VirtualBitmapFormat == 2) + { + uint8* ptr = &Memory.SRAM [(address >> 2) & 0xffff]; + *ptr &= ~(3 << ((address & 3) << 1)); + *ptr |= (byte & 3) << ((address & 3) << 1); + } + else + { + uint8* ptr = &Memory.SRAM [(address >> 1) & 0xffff]; + *ptr &= ~(15 << ((address & 1) << 2)); + *ptr |= (byte & 15) << ((address & 1) << 2); + } + break; + case MAP_BWRAM_BITMAP2: + address = (address & 0xffff) - 0x6000; + if (SA1.VirtualBitmapFormat == 2) + { + uint8* ptr = &SA1.BWRAM [(address >> 2) & 0xffff]; + *ptr &= ~(3 << ((address & 3) << 1)); + *ptr |= (byte & 3) << ((address & 3) << 1); + } + else + { + uint8* ptr = &SA1.BWRAM [(address >> 1) & 0xffff]; + *ptr &= ~(15 << ((address & 1) << 2)); + *ptr |= (byte & 15) << ((address & 1) << 2); + } + default: + return; + } } -void S9xSA1SetWord (uint16 Word, uint32 address) +void S9xSA1SetWord(uint16 Word, uint32 address) { - S9xSA1SetByte ((uint8) Word, address); - S9xSA1SetByte ((uint8) (Word >> 8), address + 1); + S9xSA1SetByte((uint8) Word, address); + S9xSA1SetByte((uint8)(Word >> 8), address + 1); } -void S9xSA1SetPCBase (uint32 address) +void S9xSA1SetPCBase(uint32 address) { - uint8 *GetAddress = SA1.Map [(address >> MEMMAP_SHIFT) & MEMMAP_MASK]; - if (GetAddress >= (uint8 *) MAP_LAST) - { - SA1.PCBase = GetAddress; - SA1.PC = GetAddress + (address & 0xffff); - return; - } - - switch ((intptr_t) GetAddress) - { - case MAP_PPU: - SA1.PCBase = Memory.FillRAM - 0x2000; - SA1.PC = SA1.PCBase + (address & 0xffff); - return; - - case MAP_CPU: - SA1.PCBase = Memory.FillRAM - 0x4000; - SA1.PC = SA1.PCBase + (address & 0xffff); - return; - - case MAP_DSP: - SA1.PCBase = Memory.FillRAM - 0x6000; - SA1.PC = SA1.PCBase + (address & 0xffff); - return; - - case MAP_SA1RAM: - case MAP_LOROM_SRAM: - SA1.PCBase = Memory.SRAM; - SA1.PC = SA1.PCBase + (address & 0xffff); - return; - - case MAP_BWRAM: - SA1.PCBase = SA1.BWRAM - 0x6000; - SA1.PC = SA1.PCBase + (address & 0xffff); - return; - case MAP_HIROM_SRAM: - SA1.PCBase = Memory.SRAM - 0x6000; - SA1.PC = SA1.PCBase + (address & 0xffff); - return; - - case MAP_DEBUG: - - default: - case MAP_NONE: - SA1.PCBase = Memory.RAM; - SA1.PC = Memory.RAM + (address & 0xffff); - return; - } + uint8* GetAddress = SA1.Map [(address >> MEMMAP_SHIFT) & MEMMAP_MASK]; + if (GetAddress >= (uint8*) MAP_LAST) + { + SA1.PCBase = GetAddress; + SA1.PC = GetAddress + (address & 0xffff); + return; + } + + switch ((intptr_t) GetAddress) + { + case MAP_PPU: + SA1.PCBase = Memory.FillRAM - 0x2000; + SA1.PC = SA1.PCBase + (address & 0xffff); + return; + + case MAP_CPU: + SA1.PCBase = Memory.FillRAM - 0x4000; + SA1.PC = SA1.PCBase + (address & 0xffff); + return; + + case MAP_DSP: + SA1.PCBase = Memory.FillRAM - 0x6000; + SA1.PC = SA1.PCBase + (address & 0xffff); + return; + + case MAP_SA1RAM: + case MAP_LOROM_SRAM: + SA1.PCBase = Memory.SRAM; + SA1.PC = SA1.PCBase + (address & 0xffff); + return; + + case MAP_BWRAM: + SA1.PCBase = SA1.BWRAM - 0x6000; + SA1.PC = SA1.PCBase + (address & 0xffff); + return; + case MAP_HIROM_SRAM: + SA1.PCBase = Memory.SRAM - 0x6000; + SA1.PC = SA1.PCBase + (address & 0xffff); + return; + + case MAP_DEBUG: + + default: + case MAP_NONE: + SA1.PCBase = Memory.RAM; + SA1.PC = Memory.RAM + (address & 0xffff); + return; + } } -void S9xSA1ExecuteDuringSleep () +void S9xSA1ExecuteDuringSleep() { #if 0 - if (SA1.Executing) - { - while (CPU.Cycles < CPU.NextEvent) - { - S9xSA1MainLoop (); - CPU.Cycles += TWO_CYCLES * 2; - } - } + if (SA1.Executing) + { + while (CPU.Cycles < CPU.NextEvent) + { + S9xSA1MainLoop(); + CPU.Cycles += TWO_CYCLES * 2; + } + } #endif } -void S9xSetSA1MemMap (uint32 which1, uint8 map) +void S9xSetSA1MemMap(uint32 which1, uint8 map) { - int c; - int start = which1 * 0x100 + 0xc00; - int start2 = which1 * 0x200; - - if (which1 >= 2) - start2 += 0x400; - - for (c = 0; c < 0x100; c += 16) - { - uint8 *block = &Memory.ROM [(map & 7) * 0x100000 + (c << 12)]; - int i; - - for (i = c; i < c + 16; i++) - Memory.Map [start + i] = SA1.Map [start + i] = block; - } - - for (c = 0; c < 0x200; c += 16) - { - uint8 *block = &Memory.ROM [(map & 7) * 0x100000 + (c << 11) - 0x8000]; - int i; - - for (i = c + 8; i < c + 16; i++) - Memory.Map [start2 + i] = SA1.Map [start2 + i] = block; - } + int c; + int start = which1 * 0x100 + 0xc00; + int start2 = which1 * 0x200; + + if (which1 >= 2) + start2 += 0x400; + + for (c = 0; c < 0x100; c += 16) + { + uint8* block = &Memory.ROM [(map & 7) * 0x100000 + (c << 12)]; + int i; + + for (i = c; i < c + 16; i++) + Memory.Map [start + i] = SA1.Map [start + i] = block; + } + + for (c = 0; c < 0x200; c += 16) + { + uint8* block = &Memory.ROM [(map & 7) * 0x100000 + (c << 11) - 0x8000]; + int i; + + for (i = c + 8; i < c + 16; i++) + Memory.Map [start2 + i] = SA1.Map [start2 + i] = block; + } } -uint8 S9xGetSA1 (uint32 address) +uint8 S9xGetSA1(uint32 address) { -// printf ("R: %04x\n", address); - switch (address) - { - case 0x2300: - return ((uint8) ((Memory.FillRAM [0x2209] & 0x5f) | - (CPU.IRQActive & (SA1_IRQ_SOURCE | SA1_DMA_IRQ_SOURCE)))); - case 0x2301: - return ((Memory.FillRAM [0x2200] & 0xf) | - (Memory.FillRAM [0x2301] & 0xf0)); - case 0x2306: - return ((uint8) SA1.sum); - case 0x2307: - return ((uint8) (SA1.sum >> 8)); - case 0x2308: - return ((uint8) (SA1.sum >> 16)); - case 0x2309: - return ((uint8) (SA1.sum >> 24)); - case 0x230a: - return ((uint8) (SA1.sum >> 32)); - case 0x230c: - return (Memory.FillRAM [0x230c]); - case 0x230d: - { - uint8 byte = Memory.FillRAM [0x230d]; - - if (Memory.FillRAM [0x2258] & 0x80) - { - S9xSA1ReadVariableLengthData (TRUE, FALSE); - } - return (byte); - } - default: - printf ("R: %04x\n", address); - break; - } - return (Memory.FillRAM [address]); + // printf ("R: %04x\n", address); + switch (address) + { + case 0x2300: + return ((uint8)((Memory.FillRAM [0x2209] & 0x5f) | + (CPU.IRQActive & (SA1_IRQ_SOURCE | SA1_DMA_IRQ_SOURCE)))); + case 0x2301: + return ((Memory.FillRAM [0x2200] & 0xf) | + (Memory.FillRAM [0x2301] & 0xf0)); + case 0x2306: + return ((uint8) SA1.sum); + case 0x2307: + return ((uint8)(SA1.sum >> 8)); + case 0x2308: + return ((uint8)(SA1.sum >> 16)); + case 0x2309: + return ((uint8)(SA1.sum >> 24)); + case 0x230a: + return ((uint8)(SA1.sum >> 32)); + case 0x230c: + return (Memory.FillRAM [0x230c]); + case 0x230d: + { + uint8 byte = Memory.FillRAM [0x230d]; + + if (Memory.FillRAM [0x2258] & 0x80) + S9xSA1ReadVariableLengthData(TRUE, FALSE); + return (byte); + } + default: + printf("R: %04x\n", address); + break; + } + return (Memory.FillRAM [address]); } -void S9xSetSA1 (uint8 byte, uint32 address) +void S9xSetSA1(uint8 byte, uint32 address) { -//printf ("W: %02x -> %04x\n", byte, address); - switch (address) - { - case 0x2200: - SA1.Waiting = (byte & 0x60) != 0; -// SA1.Executing = !SA1.Waiting && SA1.S9xOpcodes; - - if (!(byte & 0x20) && (Memory.FillRAM [0x2200] & 0x20)) - { - S9xSA1Reset (); - } - if (byte & 0x80) - { - Memory.FillRAM [0x2301] |= 0x80; - if (Memory.FillRAM [0x220a] & 0x80) - { - SA1.Flags |= IRQ_PENDING_FLAG; - SA1.IRQActive |= SNES_IRQ_SOURCE; - SA1.Executing = !SA1.Waiting && SA1.S9xOpcodes; - } - } - if (byte & 0x10) - { - Memory.FillRAM [0x2301] |= 0x10; - if (Memory.FillRAM [0x220a] & 0x10) - { - } - } - 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: - if (((byte ^ Memory.FillRAM [0x220a]) & 0x80) && - (Memory.FillRAM [0x2301] & byte & 0x80)) - { - SA1.Flags |= IRQ_PENDING_FLAG; - SA1.IRQActive |= SNES_IRQ_SOURCE; -// SA1.Executing = !SA1.Waiting; - } - if (((byte ^ Memory.FillRAM [0x220a]) & 0x40) && - (Memory.FillRAM [0x2301] & byte & 0x40)) - { - SA1.Flags |= IRQ_PENDING_FLAG; - SA1.IRQActive |= TIMER_IRQ_SOURCE; -// SA1.Executing = !SA1.Waiting; - } - if (((byte ^ Memory.FillRAM [0x220a]) & 0x20) && - (Memory.FillRAM [0x2301] & byte & 0x20)) - { - SA1.Flags |= IRQ_PENDING_FLAG; - SA1.IRQActive |= DMA_IRQ_SOURCE; -// SA1.Executing = !SA1.Waiting; - } - if (((byte ^ Memory.FillRAM [0x220a]) & 0x10) && - (Memory.FillRAM [0x2301] & byte & 0x10)) - { + //printf ("W: %02x -> %04x\n", byte, address); + switch (address) + { + case 0x2200: + SA1.Waiting = (byte & 0x60) != 0; + // SA1.Executing = !SA1.Waiting && SA1.S9xOpcodes; + + if (!(byte & 0x20) && (Memory.FillRAM [0x2200] & 0x20)) + S9xSA1Reset(); + if (byte & 0x80) + { + Memory.FillRAM [0x2301] |= 0x80; + if (Memory.FillRAM [0x220a] & 0x80) + { + SA1.Flags |= IRQ_PENDING_FLAG; + SA1.IRQActive |= SNES_IRQ_SOURCE; + SA1.Executing = !SA1.Waiting && SA1.S9xOpcodes; + } + } + if (byte & 0x10) + { + Memory.FillRAM [0x2301] |= 0x10; + if (Memory.FillRAM [0x220a] & 0x10) + { + } + } + 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: + if (((byte ^ Memory.FillRAM [0x220a]) & 0x80) && + (Memory.FillRAM [0x2301] & byte & 0x80)) + { + SA1.Flags |= IRQ_PENDING_FLAG; + SA1.IRQActive |= SNES_IRQ_SOURCE; + // SA1.Executing = !SA1.Waiting; + } + if (((byte ^ Memory.FillRAM [0x220a]) & 0x40) && + (Memory.FillRAM [0x2301] & byte & 0x40)) + { + SA1.Flags |= IRQ_PENDING_FLAG; + SA1.IRQActive |= TIMER_IRQ_SOURCE; + // SA1.Executing = !SA1.Waiting; + } + if (((byte ^ Memory.FillRAM [0x220a]) & 0x20) && + (Memory.FillRAM [0x2301] & byte & 0x20)) + { + SA1.Flags |= IRQ_PENDING_FLAG; + SA1.IRQActive |= DMA_IRQ_SOURCE; + // SA1.Executing = !SA1.Waiting; + } + if (((byte ^ Memory.FillRAM [0x220a]) & 0x10) && + (Memory.FillRAM [0x2301] & byte & 0x10)) + { #if 0 - printf ("###SA1 NMI\n"); + printf("###SA1 NMI\n"); #endif - } - break; - case 0x220b: - if (byte & 0x80) - { - SA1.IRQActive &= ~SNES_IRQ_SOURCE; - Memory.FillRAM [0x2301] &= ~0x80; - } - if (byte & 0x40) - { - SA1.IRQActive &= ~TIMER_IRQ_SOURCE; - Memory.FillRAM [0x2301] &= ~0x40; - } - if (byte & 0x20) - { - SA1.IRQActive &= ~DMA_IRQ_SOURCE; - Memory.FillRAM [0x2301] &= ~0x20; - } - if (byte & 0x10) - { - // Clear NMI - Memory.FillRAM [0x2301] &= ~0x10; - } - if (!SA1.IRQActive) - SA1.Flags &= ~IRQ_PENDING_FLAG; - break; - case 0x220c: -// printf ("SNES NMI vector: %04x\n", byte | (Memory.FillRAM [0x220d] << 8)); - 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: + } + break; + case 0x220b: + if (byte & 0x80) + { + SA1.IRQActive &= ~SNES_IRQ_SOURCE; + Memory.FillRAM [0x2301] &= ~0x80; + } + if (byte & 0x40) + { + SA1.IRQActive &= ~TIMER_IRQ_SOURCE; + Memory.FillRAM [0x2301] &= ~0x40; + } + if (byte & 0x20) + { + SA1.IRQActive &= ~DMA_IRQ_SOURCE; + Memory.FillRAM [0x2301] &= ~0x20; + } + if (byte & 0x10) + { + // Clear NMI + Memory.FillRAM [0x2301] &= ~0x10; + } + if (!SA1.IRQActive) + SA1.Flags &= ~IRQ_PENDING_FLAG; + break; + case 0x220c: + // printf ("SNES NMI vector: %04x\n", byte | (Memory.FillRAM [0x220d] << 8)); + 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"); + 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"); #endif - break; - case 0x2211: - printf ("Timer reset\n"); - break; - case 0x2212: - printf ("H-Timer %04x\n", byte | (Memory.FillRAM [0x2213] << 8)); - break; - case 0x2213: - printf ("H-Timer %04x\n", (byte << 8) | Memory.FillRAM [0x2212]); - break; - case 0x2214: - printf ("V-Timer %04x\n", byte | (Memory.FillRAM [0x2215] << 8)); - break; - case 0x2215: - printf ("V-Timer %04x\n", (byte << 8) | Memory.FillRAM [0x2214]); - break; - case 0x2220: - case 0x2221: - case 0x2222: - case 0x2223: - S9xSetSA1MemMap (address - 0x2220, byte); -// printf ("MMC: %02x\n", byte); - break; - case 0x2224: -// printf ("BWRAM image SNES %02x -> 0x6000\n", byte); - Memory.BWRAM = Memory.SRAM + (byte & 7) * 0x2000; - break; - case 0x2225: -// printf ("BWRAM image SA1 %02x -> 0x6000 (%02x)\n", byte, Memory.FillRAM [address]); - if (byte != Memory.FillRAM [address]) - S9xSA1SetBWRAMMemMap (byte); - break; - case 0x2226: -// printf ("BW-RAM SNES write %s\n", (byte & 0x80) ? "enabled" : "disabled"); - break; - case 0x2227: -// printf ("BW-RAM SA1 write %s\n", (byte & 0x80) ? "enabled" : "disabled"); - 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: + break; + case 0x2211: + printf("Timer reset\n"); + break; + case 0x2212: + printf("H-Timer %04x\n", byte | (Memory.FillRAM [0x2213] << 8)); + break; + case 0x2213: + printf("H-Timer %04x\n", (byte << 8) | Memory.FillRAM [0x2212]); + break; + case 0x2214: + printf("V-Timer %04x\n", byte | (Memory.FillRAM [0x2215] << 8)); + break; + case 0x2215: + printf("V-Timer %04x\n", (byte << 8) | Memory.FillRAM [0x2214]); + break; + case 0x2220: + case 0x2221: + case 0x2222: + case 0x2223: + S9xSetSA1MemMap(address - 0x2220, byte); + // printf ("MMC: %02x\n", byte); + break; + case 0x2224: + // printf ("BWRAM image SNES %02x -> 0x6000\n", byte); + Memory.BWRAM = Memory.SRAM + (byte & 7) * 0x2000; + break; + case 0x2225: + // printf ("BWRAM image SA1 %02x -> 0x6000 (%02x)\n", byte, Memory.FillRAM [address]); + if (byte != Memory.FillRAM [address]) + S9xSA1SetBWRAMMemMap(byte); + break; + case 0x2226: + // printf ("BW-RAM SNES write %s\n", (byte & 0x80) ? "enabled" : "disabled"); + break; + case 0x2227: + // printf ("BW-RAM SA1 write %s\n", (byte & 0x80) ? "enabled" : "disabled"); + 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]); + 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: - if (byte & 0x80) - SA1.in_char_dma = FALSE; + break; + case 0x2231: + 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); + 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; + 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)); + printf("DMA source start %06x\n", + Memory.FillRAM [0x2232] | (Memory.FillRAM [0x2233] << 8) | + (Memory.FillRAM [0x2234] << 16)); #endif - break; - case 0x2235: - Memory.FillRAM [address] = byte; - break; - case 0x2236: - Memory.FillRAM [address] = byte; - if ((Memory.FillRAM [0x2230] & 0xa4) == 0x80) - { - // Normal DMA to I-RAM - S9xSA1DMA (); - } - else - if ((Memory.FillRAM [0x2230] & 0xb0) == 0xb0) - { - Memory.FillRAM [0x2300] |= 0x20; - if (Memory.FillRAM [0x2201] & 0x20) - S9xSetIRQ (SA1_DMA_IRQ_SOURCE); - SA1.in_char_dma = TRUE; - } - break; - case 0x2237: - Memory.FillRAM [address] = byte; - if ((Memory.FillRAM [0x2230] & 0xa4) == 0x84) - { - // Normal DMA to BW-RAM - S9xSA1DMA (); - } + break; + case 0x2235: + Memory.FillRAM [address] = byte; + break; + case 0x2236: + Memory.FillRAM [address] = byte; + if ((Memory.FillRAM [0x2230] & 0xa4) == 0x80) + { + // Normal DMA to I-RAM + S9xSA1DMA(); + } + else if ((Memory.FillRAM [0x2230] & 0xb0) == 0xb0) + { + Memory.FillRAM [0x2300] |= 0x20; + if (Memory.FillRAM [0x2201] & 0x20) + S9xSetIRQ(SA1_DMA_IRQ_SOURCE); + SA1.in_char_dma = TRUE; + } + break; + case 0x2237: + Memory.FillRAM [address] = 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)); + 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; + break; + case 0x2238: + case 0x2239: + Memory.FillRAM [address] = byte; #if 0 - printf ("DMA length %04x\n", - Memory.FillRAM [0x2238] | (Memory.FillRAM [0x2239] << 8)); + printf("DMA length %04x\n", + Memory.FillRAM [0x2238] | (Memory.FillRAM [0x2239] << 8)); #endif - break; - case 0x223f: - SA1.VirtualBitmapFormat = (byte & 0x80) ? 2 : 4; - //printf ("virtual VRAM depth %d\n", (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: + break; + case 0x223f: + SA1.VirtualBitmapFormat = (byte & 0x80) ? 2 : 4; + //printf ("virtual VRAM depth %d\n", (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 (); - } + if (!(SA1.Flags & TRACE_FLAG)) + { + TraceSA1(); + Trace(); + } #endif - Memory.FillRAM [address] = byte; - break; - - case 0x224f: - Memory.FillRAM [address] = byte; - if ((Memory.FillRAM [0x2230] & 0xb0) == 0xa0) - { - // Char conversion 2 DMA enabled - // memmove converted: Same malloc but constant non-overlapping addresses [Neb] - memcpy (&Memory.ROM [MAX_ROM_SIZE - 0x10000] + SA1.in_char_dma * 16, - &Memory.FillRAM [0x2240], 16); - SA1.in_char_dma = (SA1.in_char_dma + 1) & 7; - if ((SA1.in_char_dma & 3) == 0) - { - S9xSA1CharConv2 (); - } - } - break; - case 0x2250: - if (byte & 2) - SA1.sum = 0; - SA1.arithmetic_op = byte & 3; - break; - - case 0x2251: - SA1.op1 = (SA1.op1 & 0xff00) | byte; - break; - case 0x2252: - SA1.op1 = (SA1.op1 & 0xff) | (byte << 8); - break; - case 0x2253: - SA1.op2 = (SA1.op2 & 0xff00) | byte; - break; - case 0x2254: - SA1.op2 = (SA1.op2 & 0xff) | (byte << 8); - switch (SA1.arithmetic_op) - { - case 0: // multiply - SA1.sum = SA1.op1 * SA1.op2; - break; - case 1: // divide - if (SA1.op2 == 0) - SA1.sum = SA1.op1 << 16; - else - { - SA1.sum = (SA1.op1 / (int) ((uint16) SA1.op2)) | - ((SA1.op1 % (int) ((uint16) SA1.op2)) << 16); - } - break; - case 2: - default: // cumulative sum - SA1.sum += SA1.op1 * SA1.op2; - if (SA1.sum & ((int64) 0xffffff << 32)) - SA1.overflow = TRUE; - break; - } - break; - case 0x2258: // Variable bit-field length/auto inc/start. - Memory.FillRAM [0x2258] = byte; - S9xSA1ReadVariableLengthData (TRUE, FALSE); - return; - case 0x2259: - case 0x225a: - case 0x225b: // Variable bit-field start address - Memory.FillRAM [address] = byte; - // XXX: ??? - SA1.variable_bit_pos = 0; - S9xSA1ReadVariableLengthData (FALSE, TRUE); - return; - default: -// printf ("W: %02x->%04x\n", byte, address); - break; - } - if (address >= 0x2200 && address <= 0x22ff) - Memory.FillRAM [address] = byte; + Memory.FillRAM [address] = byte; + break; + + case 0x224f: + Memory.FillRAM [address] = byte; + if ((Memory.FillRAM [0x2230] & 0xb0) == 0xa0) + { + // Char conversion 2 DMA enabled + // memmove converted: Same malloc but constant non-overlapping addresses [Neb] + memcpy(&Memory.ROM [MAX_ROM_SIZE - 0x10000] + SA1.in_char_dma * 16, + &Memory.FillRAM [0x2240], 16); + SA1.in_char_dma = (SA1.in_char_dma + 1) & 7; + if ((SA1.in_char_dma & 3) == 0) + S9xSA1CharConv2(); + } + break; + case 0x2250: + if (byte & 2) + SA1.sum = 0; + SA1.arithmetic_op = byte & 3; + break; + + case 0x2251: + SA1.op1 = (SA1.op1 & 0xff00) | byte; + break; + case 0x2252: + SA1.op1 = (SA1.op1 & 0xff) | (byte << 8); + break; + case 0x2253: + SA1.op2 = (SA1.op2 & 0xff00) | byte; + break; + case 0x2254: + SA1.op2 = (SA1.op2 & 0xff) | (byte << 8); + switch (SA1.arithmetic_op) + { + case 0: // multiply + SA1.sum = SA1.op1 * SA1.op2; + break; + case 1: // divide + if (SA1.op2 == 0) + SA1.sum = SA1.op1 << 16; + else + { + SA1.sum = (SA1.op1 / (int)((uint16) SA1.op2)) | + ((SA1.op1 % (int)((uint16) SA1.op2)) << 16); + } + break; + case 2: + default: // cumulative sum + SA1.sum += SA1.op1 * SA1.op2; + if (SA1.sum & ((int64) 0xffffff << 32)) + SA1.overflow = TRUE; + break; + } + break; + case 0x2258: // Variable bit-field length/auto inc/start. + Memory.FillRAM [0x2258] = byte; + S9xSA1ReadVariableLengthData(TRUE, FALSE); + return; + case 0x2259: + case 0x225a: + case 0x225b: // Variable bit-field start address + Memory.FillRAM [address] = byte; + // XXX: ??? + SA1.variable_bit_pos = 0; + S9xSA1ReadVariableLengthData(FALSE, TRUE); + return; + default: + // printf ("W: %02x->%04x\n", byte, address); + break; + } + if (address >= 0x2200 && address <= 0x22ff) + Memory.FillRAM [address] = byte; } -static void S9xSA1CharConv2 () +static void S9xSA1CharConv2() { - int l,b; - uint32 dest = Memory.FillRAM [0x2235] | (Memory.FillRAM [0x2236] << 8); - uint32 offset = (SA1.in_char_dma & 7) ? 0 : 1; - int depth = (Memory.FillRAM [0x2231] & 3) == 0 ? 8 : - (Memory.FillRAM [0x2231] & 3) == 1 ? 4 : 2; - int bytes_per_char = 8 * depth; - uint8 *p = &Memory.FillRAM [0x3000] + dest + offset * bytes_per_char; - uint8 *q = &Memory.ROM [MAX_ROM_SIZE - 0x10000] + offset * 64; - - switch (depth) - { - case 2: - break; - case 4: - break; - case 8: - for (l = 0; l < 8; l++, q += 8) - { - for (b = 0; b < 8; b++) - { - uint8 r = *(q + b); - *(p + 0) = (*(p + 0) << 1) | ((r >> 0) & 1); - *(p + 1) = (*(p + 1) << 1) | ((r >> 1) & 1); - *(p + 16) = (*(p + 16) << 1) | ((r >> 2) & 1); - *(p + 17) = (*(p + 17) << 1) | ((r >> 3) & 1); - *(p + 32) = (*(p + 32) << 1) | ((r >> 4) & 1); - *(p + 33) = (*(p + 33) << 1) | ((r >> 5) & 1); - *(p + 48) = (*(p + 48) << 1) | ((r >> 6) & 1); - *(p + 49) = (*(p + 49) << 1) | ((r >> 7) & 1); - } - p += 2; - } - break; - } + int l, b; + uint32 dest = Memory.FillRAM [0x2235] | (Memory.FillRAM [0x2236] << 8); + uint32 offset = (SA1.in_char_dma & 7) ? 0 : 1; + int depth = (Memory.FillRAM [0x2231] & 3) == 0 ? 8 : + (Memory.FillRAM [0x2231] & 3) == 1 ? 4 : 2; + int bytes_per_char = 8 * depth; + uint8* p = &Memory.FillRAM [0x3000] + dest + offset * bytes_per_char; + uint8* q = &Memory.ROM [MAX_ROM_SIZE - 0x10000] + offset * 64; + + switch (depth) + { + case 2: + break; + case 4: + break; + case 8: + for (l = 0; l < 8; l++, q += 8) + { + for (b = 0; b < 8; b++) + { + uint8 r = *(q + b); + *(p + 0) = (*(p + 0) << 1) | ((r >> 0) & 1); + *(p + 1) = (*(p + 1) << 1) | ((r >> 1) & 1); + *(p + 16) = (*(p + 16) << 1) | ((r >> 2) & 1); + *(p + 17) = (*(p + 17) << 1) | ((r >> 3) & 1); + *(p + 32) = (*(p + 32) << 1) | ((r >> 4) & 1); + *(p + 33) = (*(p + 33) << 1) | ((r >> 5) & 1); + *(p + 48) = (*(p + 48) << 1) | ((r >> 6) & 1); + *(p + 49) = (*(p + 49) << 1) | ((r >> 7) & 1); + } + p += 2; + } + break; + } } -static void S9xSA1DMA () +static void S9xSA1DMA() { - uint32 src = Memory.FillRAM [0x2232] | - (Memory.FillRAM [0x2233] << 8) | - (Memory.FillRAM [0x2234] << 16); - uint32 dst = Memory.FillRAM [0x2235] | - (Memory.FillRAM [0x2236] << 8) | - (Memory.FillRAM [0x2237] << 16); - uint32 len = Memory.FillRAM [0x2238] | - (Memory.FillRAM [0x2239] << 8); - - uint8 *s; - uint8 *d; - - switch (Memory.FillRAM [0x2230] & 3) - { - case 0: // ROM - s = SA1.Map [(src >> MEMMAP_SHIFT) & MEMMAP_MASK]; - if (s >= (uint8 *) MAP_LAST) - s += (src & 0xffff); - else - s = Memory.ROM + (src & 0xffff); - break; - case 1: // BW-RAM - src &= Memory.SRAMMask; - len &= Memory.SRAMMask; - s = Memory.SRAM + src; - break; - default: - case 2: - src &= 0x3ff; - len &= 0x3ff; - s = &Memory.FillRAM [0x3000] + src; - break; - } - - if (Memory.FillRAM [0x2230] & 4) - { - dst &= Memory.SRAMMask; - len &= Memory.SRAMMask; - d = Memory.SRAM + dst; - } - else - { - dst &= 0x3ff; - len &= 0x3ff; - d = &Memory.FillRAM [0x3000] + dst; - } - // memmove required: Can overlap arbitrarily [Neb] - memmove (d, s, len); - Memory.FillRAM [0x2301] |= 0x20; - - if (Memory.FillRAM [0x220a] & 0x20) - { - SA1.Flags |= IRQ_PENDING_FLAG; - SA1.IRQActive |= DMA_IRQ_SOURCE; -// SA1.Executing = !SA1.Waiting; - } + uint32 src = Memory.FillRAM [0x2232] | + (Memory.FillRAM [0x2233] << 8) | + (Memory.FillRAM [0x2234] << 16); + uint32 dst = Memory.FillRAM [0x2235] | + (Memory.FillRAM [0x2236] << 8) | + (Memory.FillRAM [0x2237] << 16); + uint32 len = Memory.FillRAM [0x2238] | + (Memory.FillRAM [0x2239] << 8); + + uint8* s; + uint8* d; + + switch (Memory.FillRAM [0x2230] & 3) + { + case 0: // ROM + s = SA1.Map [(src >> MEMMAP_SHIFT) & MEMMAP_MASK]; + if (s >= (uint8*) MAP_LAST) + s += (src & 0xffff); + else + s = Memory.ROM + (src & 0xffff); + break; + case 1: // BW-RAM + src &= Memory.SRAMMask; + len &= Memory.SRAMMask; + s = Memory.SRAM + src; + break; + default: + case 2: + src &= 0x3ff; + len &= 0x3ff; + s = &Memory.FillRAM [0x3000] + src; + break; + } + + if (Memory.FillRAM [0x2230] & 4) + { + dst &= Memory.SRAMMask; + len &= Memory.SRAMMask; + d = Memory.SRAM + dst; + } + else + { + dst &= 0x3ff; + len &= 0x3ff; + d = &Memory.FillRAM [0x3000] + dst; + } + // memmove required: Can overlap arbitrarily [Neb] + memmove(d, s, len); + Memory.FillRAM [0x2301] |= 0x20; + + if (Memory.FillRAM [0x220a] & 0x20) + { + SA1.Flags |= IRQ_PENDING_FLAG; + SA1.IRQActive |= DMA_IRQ_SOURCE; + // SA1.Executing = !SA1.Waiting; + } } -void S9xSA1ReadVariableLengthData (bool8 inc, bool8 no_shift) +void S9xSA1ReadVariableLengthData(bool8 inc, bool8 no_shift) { - uint32 addr = Memory.FillRAM [0x2259] | - (Memory.FillRAM [0x225a] << 8) | - (Memory.FillRAM [0x225b] << 16); - uint8 shift = Memory.FillRAM [0x2258] & 15; - - if (no_shift) - shift = 0; - else - if (shift == 0) - shift = 16; - - uint8 s = shift + SA1.variable_bit_pos; - - if (s >= 16) - { - addr += (s >> 4) << 1; - s &= 15; - } - uint32 data = S9xSA1GetWord (addr) | - (S9xSA1GetWord (addr + 2) << 16); - - data >>= s; - Memory.FillRAM [0x230c] = (uint8) data; - Memory.FillRAM [0x230d] = (uint8) (data >> 8); - if (inc) - { - SA1.variable_bit_pos = (SA1.variable_bit_pos + shift) & 15; - Memory.FillRAM [0x2259] = (uint8) addr; - Memory.FillRAM [0x225a] = (uint8) (addr >> 8); - Memory.FillRAM [0x225b] = (uint8) (addr >> 16); - } + uint32 addr = Memory.FillRAM [0x2259] | + (Memory.FillRAM [0x225a] << 8) | + (Memory.FillRAM [0x225b] << 16); + uint8 shift = Memory.FillRAM [0x2258] & 15; + + if (no_shift) + shift = 0; + else if (shift == 0) + shift = 16; + + uint8 s = shift + SA1.variable_bit_pos; + + if (s >= 16) + { + addr += (s >> 4) << 1; + s &= 15; + } + uint32 data = S9xSA1GetWord(addr) | + (S9xSA1GetWord(addr + 2) << 16); + + data >>= s; + Memory.FillRAM [0x230c] = (uint8) data; + Memory.FillRAM [0x230d] = (uint8)(data >> 8); + if (inc) + { + SA1.variable_bit_pos = (SA1.variable_bit_pos + shift) & 15; + Memory.FillRAM [0x2259] = (uint8) addr; + Memory.FillRAM [0x225a] = (uint8)(addr >> 8); + Memory.FillRAM [0x225b] = (uint8)(addr >> 16); + } } diff --git a/source/sa1.h b/source/sa1.h index fffb3b1..740d615 100644 --- a/source/sa1.h +++ b/source/sa1.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -93,57 +93,59 @@ #include "memmap.h" #include "cpuexec.h" -typedef struct { - uint8 PB; - uint8 DB; - pair P; - pair A; - pair D; - pair S; - pair X; - pair Y; - uint16 PC; -}SSA1Registers; - -typedef struct{ - SOpcodes *S9xOpcodes; - uint8 _Carry; - uint8 _Zero; - uint8 _Negative; - uint8 _Overflow; - bool8 CPUExecuting; - uint32 ShiftedPB; - uint32 ShiftedDB; - uint32 Flags; - bool8 Executing; - bool8 NMIActive; - bool8 IRQActive; - bool8 WaitingForInterrupt; - bool8 Waiting; -// uint8 WhichEvent; - uint8 *PC; - uint8 *PCBase; - uint8 *BWRAM; - uint8 *PCAtOpcodeStart; - uint8 *WaitAddress; - uint32 WaitCounter; - uint8 *WaitByteAddress1; - uint8 *WaitByteAddress2; -// long Cycles; -// long NextEvent; -// long V_Counter; - uint8 *Map [MEMMAP_NUM_BLOCKS]; - uint8 *WriteMap [MEMMAP_NUM_BLOCKS]; - int16 op1; - int16 op2; - int arithmetic_op; - int64 sum; - bool8 overflow; - uint8 VirtualBitmapFormat; - bool8 in_char_dma; - uint8 variable_bit_pos; - SSA1Registers Registers; -}SSA1; +typedef struct +{ + uint8 PB; + uint8 DB; + pair P; + pair A; + pair D; + pair S; + pair X; + pair Y; + uint16 PC; +} SSA1Registers; + +typedef struct +{ + SOpcodes* S9xOpcodes; + uint8 _Carry; + uint8 _Zero; + uint8 _Negative; + uint8 _Overflow; + bool8 CPUExecuting; + uint32 ShiftedPB; + uint32 ShiftedDB; + uint32 Flags; + bool8 Executing; + bool8 NMIActive; + bool8 IRQActive; + bool8 WaitingForInterrupt; + bool8 Waiting; + // uint8 WhichEvent; + uint8* PC; + uint8* PCBase; + uint8* BWRAM; + uint8* PCAtOpcodeStart; + uint8* WaitAddress; + uint32 WaitCounter; + uint8* WaitByteAddress1; + uint8* WaitByteAddress2; + // long Cycles; + // long NextEvent; + // long V_Counter; + uint8* Map [MEMMAP_NUM_BLOCKS]; + uint8* WriteMap [MEMMAP_NUM_BLOCKS]; + int16 op1; + int16 op2; + int arithmetic_op; + int64 sum; + bool8 overflow; + uint8 VirtualBitmapFormat; + bool8 in_char_dma; + uint8 variable_bit_pos; + SSA1Registers Registers; +} SSA1; #define SA1CheckZero() (SA1._Zero == 0) #define SA1CheckCarry() (SA1._Carry) @@ -160,13 +162,13 @@ typedef struct{ #define SA1CheckFlag(f) (SA1.Registers.PL & (f)) -uint8 S9xSA1GetByte (uint32); -uint16 S9xSA1GetWord (uint32); -void S9xSA1SetByte (uint8, uint32); -void S9xSA1SetWord (uint16, uint32); -void S9xSA1SetPCBase (uint32); -uint8 S9xGetSA1 (uint32); -void S9xSetSA1 (uint8, uint32); +uint8 S9xSA1GetByte(uint32); +uint16 S9xSA1GetWord(uint32); +void S9xSA1SetByte(uint8, uint32); +void S9xSA1SetWord(uint16, uint32); +void S9xSA1SetPCBase(uint32); +uint8 S9xGetSA1(uint32); +void S9xSetSA1(uint8, uint32); extern SOpcodes S9xSA1OpcodesM1X1 [256]; extern SOpcodes S9xSA1OpcodesM1X0 [256]; @@ -174,49 +176,48 @@ extern SOpcodes S9xSA1OpcodesM0X1 [256]; extern SOpcodes S9xSA1OpcodesM0X0 [256]; extern SSA1 SA1; -void S9xSA1MainLoop (); -void S9xSA1Init (); -void S9xFixSA1AfterSnapshotLoad (); -void S9xSA1ExecuteDuringSleep (); +void S9xSA1MainLoop(); +void S9xSA1Init(); +void S9xFixSA1AfterSnapshotLoad(); +void S9xSA1ExecuteDuringSleep(); -#define SNES_IRQ_SOURCE (1 << 7) +#define SNES_IRQ_SOURCE (1 << 7) #define TIMER_IRQ_SOURCE (1 << 6) -#define DMA_IRQ_SOURCE (1 << 5) +#define DMA_IRQ_SOURCE (1 << 5) STATIC inline void S9xSA1UnpackStatus() { - SA1._Zero = (SA1.Registers.PL & Zero) == 0; - SA1._Negative = (SA1.Registers.PL & Negative); - SA1._Carry = (SA1.Registers.PL & Carry); - SA1._Overflow = (SA1.Registers.PL & Overflow) >> 6; + SA1._Zero = (SA1.Registers.PL & Zero) == 0; + SA1._Negative = (SA1.Registers.PL & Negative); + SA1._Carry = (SA1.Registers.PL & Carry); + SA1._Overflow = (SA1.Registers.PL & Overflow) >> 6; } STATIC inline void S9xSA1PackStatus() { - SA1.Registers.PL &= ~(Zero | Negative | Carry | Overflow); - SA1.Registers.PL |= SA1._Carry | ((SA1._Zero == 0) << 1) | - (SA1._Negative & 0x80) | (SA1._Overflow << 6); + SA1.Registers.PL &= ~(Zero | Negative | Carry | Overflow); + SA1.Registers.PL |= SA1._Carry | ((SA1._Zero == 0) << 1) | + (SA1._Negative & 0x80) | (SA1._Overflow << 6); } -STATIC inline void S9xSA1FixCycles () +STATIC inline void S9xSA1FixCycles() { - if (SA1CheckEmulation ()) - SA1.S9xOpcodes = S9xSA1OpcodesM1X1; - else - if (SA1CheckMemory ()) - { - if (SA1CheckIndex ()) - SA1.S9xOpcodes = S9xSA1OpcodesM1X1; - else - SA1.S9xOpcodes = S9xSA1OpcodesM1X0; - } - else - { - if (SA1CheckIndex ()) - SA1.S9xOpcodes = S9xSA1OpcodesM0X1; - else - SA1.S9xOpcodes = S9xSA1OpcodesM0X0; - } + if (SA1CheckEmulation()) + SA1.S9xOpcodes = S9xSA1OpcodesM1X1; + else if (SA1CheckMemory()) + { + if (SA1CheckIndex()) + SA1.S9xOpcodes = S9xSA1OpcodesM1X1; + else + SA1.S9xOpcodes = S9xSA1OpcodesM1X0; + } + else + { + if (SA1CheckIndex()) + SA1.S9xOpcodes = S9xSA1OpcodesM0X1; + else + SA1.S9xOpcodes = S9xSA1OpcodesM0X0; + } } #endif diff --git a/source/sa1cpu.c b/source/sa1cpu.c index de8a094..ddabd09 100644 --- a/source/sa1cpu.c +++ b/source/sa1cpu.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -202,44 +202,44 @@ #include "cpuops.c" -void S9xSA1MainLoop () +void S9xSA1MainLoop() { - int i; + int i; #if 0 - if (SA1.Flags & NMI_FLAG) - { - SA1.Flags &= ~NMI_FLAG; - if (SA1.WaitingForInterrupt) - { - SA1.WaitingForInterrupt = FALSE; - SA1.PC++; - } - S9xSA1Opcode_NMI (); - } + if (SA1.Flags & NMI_FLAG) + { + SA1.Flags &= ~NMI_FLAG; + if (SA1.WaitingForInterrupt) + { + SA1.WaitingForInterrupt = FALSE; + SA1.PC++; + } + S9xSA1Opcode_NMI(); + } #endif - if (SA1.Flags & IRQ_PENDING_FLAG) - { - if (SA1.IRQActive) - { - if (SA1.WaitingForInterrupt) - { - SA1.WaitingForInterrupt = FALSE; - SA1.PC++; - } - if (!SA1CheckFlag (IRQ)) - S9xSA1Opcode_IRQ (); - } - else - SA1.Flags &= ~IRQ_PENDING_FLAG; - } - - for (i = 0; i < 3 && SA1.Executing; i++) - { + if (SA1.Flags & IRQ_PENDING_FLAG) + { + if (SA1.IRQActive) + { + if (SA1.WaitingForInterrupt) + { + SA1.WaitingForInterrupt = FALSE; + SA1.PC++; + } + if (!SA1CheckFlag(IRQ)) + S9xSA1Opcode_IRQ(); + } + else + SA1.Flags &= ~IRQ_PENDING_FLAG; + } + + for (i = 0; i < 3 && SA1.Executing; i++) + { #ifdef CPU_SHUTDOWN - SA1.PCAtOpcodeStart = SA1.PC; + SA1.PCAtOpcodeStart = SA1.PC; #endif - (*SA1.S9xOpcodes [*SA1.PC++].S9xOpcode) (); - } + (*SA1.S9xOpcodes [*SA1.PC++].S9xOpcode)(); + } } diff --git a/source/sar.h b/source/sar.h index 119c5b8..14d89d9 100644 --- a/source/sar.h +++ b/source/sar.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -91,7 +91,7 @@ #define _SAR_H_ #ifdef HAVE_CONFIG_H - #include +#include #endif #include "port.h" @@ -107,32 +107,36 @@ #define SAR64(b, n) ((b)>>(n)) #else -static inline int8 SAR8(const int8 b, const int n){ +static inline int8 SAR8(const int8 b, const int n) +{ #ifndef RIGHTSHIFT_INT8_IS_SAR - if(b<0) return (b>>n)|(-1<<(8-n)); + if (b < 0) return (b >> n) | (-1 << (8 - n)); #endif - return b>>n; + return b >> n; } -static inline int16 SAR16(const int16 b, const int n){ +static inline int16 SAR16(const int16 b, const int n) +{ #ifndef RIGHTSHIFT_INT16_IS_SAR - if(b<0) return (b>>n)|(-1<<(16-n)); + if (b < 0) return (b >> n) | (-1 << (16 - n)); #endif - return b>>n; + return b >> n; } -static inline int32 SAR32(const int32 b, const int n){ +static inline int32 SAR32(const int32 b, const int n) +{ #ifndef RIGHTSHIFT_INT32_IS_SAR - if(b<0) return (b>>n)|(-1<<(32-n)); + if (b < 0) return (b >> n) | (-1 << (32 - n)); #endif - return b>>n; + return b >> n; } -static inline int64 SAR64(const int64 b, const int n){ +static inline int64 SAR64(const int64 b, const int n) +{ #ifndef RIGHTSHIFT_INT64_IS_SAR - if(b<0) return (b>>n)|(-1<<(64-n)); + if (b < 0) return (b >> n) | (-1 << (64 - n)); #endif - return b>>n; + return b >> n; } #endif diff --git a/source/screenshot.c b/source/screenshot.c index f33b240..fc3cccb 100644 --- a/source/screenshot.c +++ b/source/screenshot.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,53 +43,53 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ #ifdef HAVE_CONFIG_H - #include +#include #endif #include @@ -112,124 +112,141 @@ #include "ppu.h" #include "screenshot.h" -bool8 S9xDoScreenshot(int width, int height){ +bool8 S9xDoScreenshot(int width, int height) +{ #ifdef HAVE_LIBPNG - FILE *fp; - png_structp png_ptr; - png_infop info_ptr; - png_color_8 sig_bit; - png_color pngpal[256]; - int imgwidth; - int imgheight; - const char *fname=S9xGetFilenameInc(".png"); - - Settings.TakeScreenshot=FALSE; - - if((fp=fopen(fname, "wb"))==NULL){ - perror("Screenshot failed"); - return FALSE; - } - - png_ptr=png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if(!png_ptr){ - fclose(fp); - unlink(fname); - return FALSE; - } - info_ptr=png_create_info_struct(png_ptr); - if(!info_ptr){ - png_destroy_write_struct(&png_ptr, (png_infopp)NULL); - fclose(fp); - unlink(fname); - return FALSE; - } - - if(setjmp(png_jmpbuf(png_ptr))){ - perror("Screenshot: setjmp"); - png_destroy_write_struct(&png_ptr, &info_ptr); - fclose(fp); - unlink(fname); - return FALSE; - } - - imgwidth=width; - imgheight=height; - if(Settings.StretchScreenshots==1){ - if(width<=256 && height>SNES_HEIGHT_EXTENDED) imgwidth=width<<1; - if(width>256 && height<=SNES_HEIGHT_EXTENDED) imgheight=height<<1; - } else if(Settings.StretchScreenshots==2){ - if(width<=256) imgwidth=width<<1; - if(height<=SNES_HEIGHT_EXTENDED) imgheight=height<<1; - } - - png_init_io(png_ptr, fp); - if(!Settings.SixteenBit){ - // BJ: credit sanmaiwashi for the idea to do palettized pngs, and to - // S9xSetPalette in x11.cpp for how to calculate the RGB values - int b=IPPU.MaxBrightness*140; - for(int i=0; i<256; i++){ - pngpal[i].red = (PPU.CGDATA[i] & 0x1f)*b>>8; - pngpal[i].green = ((PPU.CGDATA[i] >> 5) & 0x1f)*b>>8; - pngpal[i].blue = ((PPU.CGDATA[i] >> 10) & 0x1f)*b>>8; - } - png_set_PLTE(png_ptr, info_ptr, pngpal, 256); - } - png_set_IHDR(png_ptr, info_ptr, imgwidth, imgheight, 8, - (Settings.SixteenBit?PNG_COLOR_TYPE_RGB:PNG_COLOR_TYPE_PALETTE), - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - - if(Settings.SixteenBit){ - /* 5 bits per color */ - sig_bit.red=5; - sig_bit.green=5; - sig_bit.blue=5; - png_set_sBIT(png_ptr, info_ptr, &sig_bit); - png_set_shift(png_ptr, &sig_bit); - } - - png_write_info(png_ptr, info_ptr); - - png_set_packing(png_ptr); - - png_byte *row_pointer=new png_byte [png_get_rowbytes(png_ptr, info_ptr)]; - uint8 *screen=GFX.Screen; - for(int y=0; y SNES_HEIGHT_EXTENDED) imgwidth = width << 1; + if (width > 256 && height <= SNES_HEIGHT_EXTENDED) imgheight = height << 1; + } + else if (Settings.StretchScreenshots == 2) + { + if (width <= 256) imgwidth = width << 1; + if (height <= SNES_HEIGHT_EXTENDED) imgheight = height << 1; + } + + png_init_io(png_ptr, fp); + if (!Settings.SixteenBit) + { + // BJ: credit sanmaiwashi for the idea to do palettized pngs, and to + // S9xSetPalette in x11.cpp for how to calculate the RGB values + int b = IPPU.MaxBrightness * 140; + for (int i = 0; i < 256; i++) + { + pngpal[i].red = (PPU.CGDATA[i] & 0x1f) * b >> 8; + pngpal[i].green = ((PPU.CGDATA[i] >> 5) & 0x1f) * b >> 8; + pngpal[i].blue = ((PPU.CGDATA[i] >> 10) & 0x1f) * b >> 8; + } + png_set_PLTE(png_ptr, info_ptr, pngpal, 256); + } + png_set_IHDR(png_ptr, info_ptr, imgwidth, imgheight, 8, + (Settings.SixteenBit ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_PALETTE), + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); + + if (Settings.SixteenBit) + { + /* 5 bits per color */ + sig_bit.red = 5; + sig_bit.green = 5; + sig_bit.blue = 5; + png_set_sBIT(png_ptr, info_ptr, &sig_bit); + png_set_shift(png_ptr, &sig_bit); + } + + png_write_info(png_ptr, info_ptr); + + png_set_packing(png_ptr); + + png_byte* row_pointer = new png_byte [png_get_rowbytes(png_ptr, info_ptr)]; + uint8* screen = GFX.Screen; + for (int y = 0; y < height; y++, screen += GFX.Pitch) + { + png_byte* rowpix = row_pointer; + for (int x = 0; x < width; x++) + { + if (Settings.SixteenBit) + { + uint32 r, g, b; + DECOMPOSE_PIXEL((*(uint16*)(screen + 2 * x)), r, g, b); + *(rowpix++) = r; + *(rowpix++) = g; + *(rowpix++) = b; + if (imgwidth != width) + { + *(rowpix++) = r; + *(rowpix++) = g; + *(rowpix++) = b; } - } - png_write_row(png_ptr, row_pointer); - if(imgheight!=height) - png_write_row(png_ptr, row_pointer); - } - - delete [] row_pointer; - - png_write_end(png_ptr, info_ptr); - png_destroy_write_struct(&png_ptr, &info_ptr); - - fclose(fp); - fprintf(stderr, "%s saved.\n", fname); - return TRUE; + } + else + { + *(rowpix++) = *(uint8*)(screen + x); + if (imgwidth != width) + *(rowpix++) = *(uint8*)(screen + x); + } + } + png_write_row(png_ptr, row_pointer); + if (imgheight != height) + png_write_row(png_ptr, row_pointer); + } + + delete [] row_pointer; + + png_write_end(png_ptr, info_ptr); + png_destroy_write_struct(&png_ptr, &info_ptr); + + fclose(fp); + fprintf(stderr, "%s saved.\n", fname); + return TRUE; #else - perror("Screenshot support not available (libpng was not found at build time)"); - return FALSE; + perror("Screenshot support not available (libpng was not found at build time)"); + return FALSE; #endif } diff --git a/source/screenshot.h b/source/screenshot.h index ce44e42..929428e 100644 --- a/source/screenshot.h +++ b/source/screenshot.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ diff --git a/source/sdd1.c b/source/sdd1.c index 1ba8187..de7fd5e 100644 --- a/source/sdd1.c +++ b/source/sdd1.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -97,87 +97,87 @@ #include #endif -void S9xSetSDD1MemoryMap (uint32 bank, uint32 value) +void S9xSetSDD1MemoryMap(uint32 bank, uint32 value) { - bank = 0xc00 + bank * 0x100; - value = value * 1024 * 1024; + bank = 0xc00 + bank * 0x100; + value = value * 1024 * 1024; - int c; + int c; - for (c = 0; c < 0x100; c += 16) - { - uint8 *block = &Memory.ROM [value + (c << 12)]; - int i; + for (c = 0; c < 0x100; c += 16) + { + uint8* block = &Memory.ROM [value + (c << 12)]; + int i; - for (i = c; i < c + 16; i++) - Memory.Map [i + bank] = block; - } + for (i = c; i < c + 16; i++) + Memory.Map [i + bank] = block; + } } -void S9xResetSDD1 () +void S9xResetSDD1() { - memset (&Memory.FillRAM [0x4800], 0, 4); - int i; - for (i = 0; i < 4; i++) - { - Memory.FillRAM [0x4804 + i] = i; - S9xSetSDD1MemoryMap (i, i); - } + memset(&Memory.FillRAM [0x4800], 0, 4); + int i; + for (i = 0; i < 4; i++) + { + Memory.FillRAM [0x4804 + i] = i; + S9xSetSDD1MemoryMap(i, i); + } } -void S9xSDD1PostLoadState () +void S9xSDD1PostLoadState() { int i; - for (i = 0; i < 4; i++) - S9xSetSDD1MemoryMap (i, Memory.FillRAM [0x4804 + i]); + for (i = 0; i < 4; i++) + S9xSetSDD1MemoryMap(i, Memory.FillRAM [0x4804 + i]); } -static int S9xCompareSDD1LoggedDataEntries (const void *p1, const void *p2) +static int S9xCompareSDD1LoggedDataEntries(const void* p1, const void* p2) { - uint8 *b1 = (uint8 *) p1; - uint8 *b2 = (uint8 *) p2; - uint32 a1 = (*b1 << 16) + (*(b1 + 1) << 8) + *(b1 + 2); - uint32 a2 = (*b2 << 16) + (*(b2 + 1) << 8) + *(b2 + 2); + uint8* b1 = (uint8*) p1; + uint8* b2 = (uint8*) p2; + uint32 a1 = (*b1 << 16) + (*(b1 + 1) << 8) + *(b1 + 2); + uint32 a2 = (*b2 << 16) + (*(b2 + 1) << 8) + *(b2 + 2); - return (a1 - a2); + return (a1 - a2); } -void S9xSDD1SaveLoggedData () +void S9xSDD1SaveLoggedData() { - if (Memory.SDD1LoggedDataCount != Memory.SDD1LoggedDataCountPrev) - { - qsort (Memory.SDD1LoggedData, Memory.SDD1LoggedDataCount, 8, - S9xCompareSDD1LoggedDataEntries); - - FILE *fs = fopen (S9xGetFilename (".dat"), "wb"); - - if (fs) - { - fwrite (Memory.SDD1LoggedData, 8, - Memory.SDD1LoggedDataCount, fs); - fclose (fs); + if (Memory.SDD1LoggedDataCount != Memory.SDD1LoggedDataCountPrev) + { + qsort(Memory.SDD1LoggedData, Memory.SDD1LoggedDataCount, 8, + S9xCompareSDD1LoggedDataEntries); + + FILE* fs = fopen(S9xGetFilename(".dat"), "wb"); + + if (fs) + { + fwrite(Memory.SDD1LoggedData, 8, + Memory.SDD1LoggedDataCount, fs); + fclose(fs); #if defined(__linux) - chown (S9xGetFilename (".dat"), getuid (), getgid ()); + chown(S9xGetFilename(".dat"), getuid(), getgid()); #endif - } - Memory.SDD1LoggedDataCountPrev = Memory.SDD1LoggedDataCount; - } + } + Memory.SDD1LoggedDataCountPrev = Memory.SDD1LoggedDataCount; + } } -void S9xSDD1LoadLoggedData () +void S9xSDD1LoadLoggedData() { - FILE *fs = fopen (S9xGetFilename (".dat"), "rb"); + FILE* fs = fopen(S9xGetFilename(".dat"), "rb"); - Memory.SDD1LoggedDataCount = Memory.SDD1LoggedDataCountPrev = 0; + Memory.SDD1LoggedDataCount = Memory.SDD1LoggedDataCountPrev = 0; - if (fs) - { - int c = fread (Memory.SDD1LoggedData, 8, - MEMMAP_MAX_SDD1_LOGGED_ENTRIES, fs); + if (fs) + { + int c = fread(Memory.SDD1LoggedData, 8, + MEMMAP_MAX_SDD1_LOGGED_ENTRIES, fs); - if (c != EOF) - Memory.SDD1LoggedDataCount = Memory.SDD1LoggedDataCountPrev = c; - fclose (fs); - } + if (c != EOF) + Memory.SDD1LoggedDataCount = Memory.SDD1LoggedDataCountPrev = c; + fclose(fs); + } } diff --git a/source/sdd1.h b/source/sdd1.h index 15c97ae..48c6362 100644 --- a/source/sdd1.h +++ b/source/sdd1.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,56 +43,56 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ #ifndef _SDD1_H_ #define _SDD1_H_ -void S9xSetSDD1MemoryMap (uint32 bank, uint32 value); -void S9xResetSDD1 (); -void S9xSDD1PostLoadState (); -void S9xSDD1SaveLoggedData (); -void S9xSDD1LoadLoggedData (); +void S9xSetSDD1MemoryMap(uint32 bank, uint32 value); +void S9xResetSDD1(); +void S9xSDD1PostLoadState(); +void S9xSDD1SaveLoggedData(); +void S9xSDD1LoadLoggedData(); #endif diff --git a/source/sdd1emu.c b/source/sdd1emu.c index bc32b43..c7005ec 100644 --- a/source/sdd1emu.c +++ b/source/sdd1emu.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -92,8 +92,8 @@ * of thanks and credit for figuring this out. * * Andreas says: - * The author is greatly indebted with The Dumper, without whose help and - * patience providing him with real S-DD1 data the research had never been + * The author is greatly indebted with The Dumper, without whose help and + * patience providing him with real S-DD1 data the research had never been * possible. He also wish to note that in the very beggining of his research, * Neviksti had done some steps in the right direction. By last, the author is * indirectly indebted to all the people that worked and contributed in the @@ -106,7 +106,7 @@ static int valid_bits; static uint16 in_stream; -static uint8 *in_buf; +static uint8* in_buf; static uint8 bit_ctr[8]; static uint8 context_states[32]; static int context_MPS[32]; @@ -115,300 +115,343 @@ static int high_context_bits; static int low_context_bits; static int prev_bits[8]; -static struct { - uint8 code_size; - uint8 MPS_next; - uint8 LPS_next; -} evolution_table[] = { - /* 0 */ { 0,25,25}, - /* 1 */ { 0, 2, 1}, - /* 2 */ { 0, 3, 1}, - /* 3 */ { 0, 4, 2}, - /* 4 */ { 0, 5, 3}, - /* 5 */ { 1, 6, 4}, - /* 6 */ { 1, 7, 5}, - /* 7 */ { 1, 8, 6}, - /* 8 */ { 1, 9, 7}, - /* 9 */ { 2,10, 8}, - /* 10 */ { 2,11, 9}, - /* 11 */ { 2,12,10}, - /* 12 */ { 2,13,11}, - /* 13 */ { 3,14,12}, - /* 14 */ { 3,15,13}, - /* 15 */ { 3,16,14}, - /* 16 */ { 3,17,15}, - /* 17 */ { 4,18,16}, - /* 18 */ { 4,19,17}, - /* 19 */ { 5,20,18}, - /* 20 */ { 5,21,19}, - /* 21 */ { 6,22,20}, - /* 22 */ { 6,23,21}, - /* 23 */ { 7,24,22}, - /* 24 */ { 7,24,23}, - /* 25 */ { 0,26, 1}, - /* 26 */ { 1,27, 2}, - /* 27 */ { 2,28, 4}, - /* 28 */ { 3,29, 8}, - /* 29 */ { 4,30,12}, - /* 30 */ { 5,31,16}, - /* 31 */ { 6,32,18}, - /* 32 */ { 7,24,22} +static struct +{ + uint8 code_size; + uint8 MPS_next; + uint8 LPS_next; +} evolution_table[] = +{ + /* 0 */ { 0, 25, 25}, + /* 1 */ { 0, 2, 1}, + /* 2 */ { 0, 3, 1}, + /* 3 */ { 0, 4, 2}, + /* 4 */ { 0, 5, 3}, + /* 5 */ { 1, 6, 4}, + /* 6 */ { 1, 7, 5}, + /* 7 */ { 1, 8, 6}, + /* 8 */ { 1, 9, 7}, + /* 9 */ { 2, 10, 8}, + /* 10 */ { 2, 11, 9}, + /* 11 */ { 2, 12, 10}, + /* 12 */ { 2, 13, 11}, + /* 13 */ { 3, 14, 12}, + /* 14 */ { 3, 15, 13}, + /* 15 */ { 3, 16, 14}, + /* 16 */ { 3, 17, 15}, + /* 17 */ { 4, 18, 16}, + /* 18 */ { 4, 19, 17}, + /* 19 */ { 5, 20, 18}, + /* 20 */ { 5, 21, 19}, + /* 21 */ { 6, 22, 20}, + /* 22 */ { 6, 23, 21}, + /* 23 */ { 7, 24, 22}, + /* 24 */ { 7, 24, 23}, + /* 25 */ { 0, 26, 1}, + /* 26 */ { 1, 27, 2}, + /* 27 */ { 2, 28, 4}, + /* 28 */ { 3, 29, 8}, + /* 29 */ { 4, 30, 12}, + /* 30 */ { 5, 31, 16}, + /* 31 */ { 6, 32, 18}, + /* 32 */ { 7, 24, 22} }; -static uint8 run_table[128] = { - 128, 64, 96, 32, 112, 48, 80, 16, 120, 56, 88, 24, 104, 40, 72, - 8, 124, 60, 92, 28, 108, 44, 76, 12, 116, 52, 84, 20, 100, 36, - 68, 4, 126, 62, 94, 30, 110, 46, 78, 14, 118, 54, 86, 22, 102, - 38, 70, 6, 122, 58, 90, 26, 106, 42, 74, 10, 114, 50, 82, 18, - 98, 34, 66, 2, 127, 63, 95, 31, 111, 47, 79, 15, 119, 55, 87, - 23, 103, 39, 71, 7, 123, 59, 91, 27, 107, 43, 75, 11, 115, 51, - 83, 19, 99, 35, 67, 3, 125, 61, 93, 29, 109, 45, 77, 13, 117, - 53, 85, 21, 101, 37, 69, 5, 121, 57, 89, 25, 105, 41, 73, 9, - 113, 49, 81, 17, 97, 33, 65, 1 +static uint8 run_table[128] = +{ + 128, 64, 96, 32, 112, 48, 80, 16, 120, 56, 88, 24, 104, 40, 72, + 8, 124, 60, 92, 28, 108, 44, 76, 12, 116, 52, 84, 20, 100, 36, + 68, 4, 126, 62, 94, 30, 110, 46, 78, 14, 118, 54, 86, 22, 102, + 38, 70, 6, 122, 58, 90, 26, 106, 42, 74, 10, 114, 50, 82, 18, + 98, 34, 66, 2, 127, 63, 95, 31, 111, 47, 79, 15, 119, 55, 87, + 23, 103, 39, 71, 7, 123, 59, 91, 27, 107, 43, 75, 11, 115, 51, + 83, 19, 99, 35, 67, 3, 125, 61, 93, 29, 109, 45, 77, 13, 117, + 53, 85, 21, 101, 37, 69, 5, 121, 57, 89, 25, 105, 41, 73, 9, + 113, 49, 81, 17, 97, 33, 65, 1 }; -static inline uint8 GetCodeword(int bits){ - uint8 tmp; - - if(!valid_bits){ - in_stream|=*(in_buf++); - valid_bits=8; - } - in_stream<<=1; - valid_bits--; - in_stream^=0x8000; - if(in_stream&0x8000) return 0x80+(1<>8) | (0x7f>>bits); - in_stream<<=bits; - valid_bits-=bits; - if(valid_bits<0){ - in_stream |= (*(in_buf++))<<(-valid_bits); - valid_bits+=8; - } - return run_table[tmp]; +static inline uint8 GetCodeword(int bits) +{ + uint8 tmp; + + if (!valid_bits) + { + in_stream |= *(in_buf++); + valid_bits = 8; + } + in_stream <<= 1; + valid_bits--; + in_stream ^= 0x8000; + if (in_stream & 0x8000) return 0x80 + (1 << bits); + tmp = (in_stream >> 8) | (0x7f >> bits); + in_stream <<= bits; + valid_bits -= bits; + if (valid_bits < 0) + { + in_stream |= (*(in_buf++)) << (-valid_bits); + valid_bits += 8; + } + return run_table[tmp]; } -static inline uint8 GolombGetBit(int code_size){ - if(!bit_ctr[code_size]) bit_ctr[code_size]=GetCodeword(code_size); - bit_ctr[code_size]--; - if(bit_ctr[code_size]==0x80){ - bit_ctr[code_size]=0; - return 2; /* secret code for 'last zero'. ones are always last. */ - } - return (bit_ctr[code_size]==0)?1:0; +static inline uint8 GolombGetBit(int code_size) +{ + if (!bit_ctr[code_size]) bit_ctr[code_size] = GetCodeword(code_size); + bit_ctr[code_size]--; + if (bit_ctr[code_size] == 0x80) + { + bit_ctr[code_size] = 0; + return 2; /* secret code for 'last zero'. ones are always last. */ + } + return (bit_ctr[code_size] == 0) ? 1 : 0; } -static inline uint8 ProbGetBit(uint8 context){ - uint8 state=context_states[context]; - uint8 bit=GolombGetBit(evolution_table[state].code_size); - - if(bit&1){ - context_states[context]=evolution_table[state].LPS_next; - if(state<2){ - context_MPS[context]^=1; - return context_MPS[context]; /* just inverted, so just return it */ - } else{ - return context_MPS[context]^1; /* we know bit is 1, so use a constant */ - } - } else if(bit){ - context_states[context]=evolution_table[state].MPS_next; - /* zero here, zero there, no difference so drop through. */ - } - return context_MPS[context]; /* we know bit is 0, so don't bother xoring */ +static inline uint8 ProbGetBit(uint8 context) +{ + uint8 state = context_states[context]; + uint8 bit = GolombGetBit(evolution_table[state].code_size); + + if (bit & 1) + { + context_states[context] = evolution_table[state].LPS_next; + if (state < 2) + { + context_MPS[context] ^= 1; + return context_MPS[context]; /* just inverted, so just return it */ + } + else + { + return context_MPS[context] ^ 1; /* we know bit is 1, so use a constant */ + } + } + else if (bit) + { + context_states[context] = evolution_table[state].MPS_next; + /* zero here, zero there, no difference so drop through. */ + } + return context_MPS[context]; /* we know bit is 0, so don't bother xoring */ } -static inline uint8 GetBit(uint8 cur_bitplane){ - uint8 bit; - - bit=ProbGetBit(((cur_bitplane&1)<<4) - | ((prev_bits[cur_bitplane]&high_context_bits)>>5) - | (prev_bits[cur_bitplane]&low_context_bits)); +static inline uint8 GetBit(uint8 cur_bitplane) +{ + uint8 bit; + + bit = ProbGetBit(((cur_bitplane & 1) << 4) + | ((prev_bits[cur_bitplane] & high_context_bits) >> 5) + | (prev_bits[cur_bitplane] & low_context_bits)); - prev_bits[cur_bitplane] <<= 1; - prev_bits[cur_bitplane] |= bit; - return bit; + prev_bits[cur_bitplane] <<= 1; + prev_bits[cur_bitplane] |= bit; + return bit; } -void SDD1_decompress(uint8 *out, uint8 *in, int len){ - uint8 bit, i, plane; - uint8 byte1, byte2; - - if(len==0) len=0x10000; - - bitplane_type=in[0]>>6; - - switch(in[0]&0x30){ - case 0x00: - high_context_bits=0x01c0; - low_context_bits =0x0001; - break; - case 0x10: - high_context_bits=0x0180; - low_context_bits =0x0001; - break; - case 0x20: - high_context_bits=0x00c0; - low_context_bits =0x0001; - break; - case 0x30: - high_context_bits=0x0180; - low_context_bits =0x0003; - break; - } - - in_stream=(in[0]<<11) | (in[1]<<3); - valid_bits=5; - in_buf=in+2; - memset(bit_ctr, 0, sizeof(bit_ctr)); - memset(context_states, 0, sizeof(context_states)); - memset(context_MPS, 0, sizeof(context_MPS)); - memset(prev_bits, 0, sizeof(prev_bits)); - - switch(bitplane_type){ - case 0: - while(1) { - for(byte1=byte2=0, bit=0x80; bit; bit>>=1){ - if(GetBit(0)) byte1 |= bit; - if(GetBit(1)) byte2 |= bit; - } - *(out++)=byte1; - if(!--len) return; - *(out++)=byte2; - if(!--len) return; - } - break; - case 1: - i=plane=0; - while(1) { - for(byte1=byte2=0, bit=0x80; bit; bit>>=1){ - if(GetBit(plane)) byte1 |= bit; - if(GetBit(plane+1)) byte2 |= bit; - } - *(out++)=byte1; - if(!--len) return; - *(out++)=byte2; - if(!--len) return; - if(!(i+=32)) plane = (plane+2)&7; - } - break; - case 2: - i=plane=0; - while(1) { - for(byte1=byte2=0, bit=0x80; bit; bit>>=1){ - if(GetBit(plane)) byte1 |= bit; - if(GetBit(plane+1)) byte2 |= bit; - } - *(out++)=byte1; - if(!--len) return; - *(out++)=byte2; - if(!--len) return; - if(!(i+=32)) plane ^= 2; - } - break; - case 3: - do { - for(byte1=plane=0, bit=1; bit; bit<<=1, plane++){ - if(GetBit(plane)) byte1 |= bit; - } - *(out++)=byte1; - } while(--len); - break; - } +void SDD1_decompress(uint8* out, uint8* in, int len) +{ + uint8 bit, i, plane; + uint8 byte1, byte2; + + if (len == 0) len = 0x10000; + + bitplane_type = in[0] >> 6; + + switch (in[0] & 0x30) + { + case 0x00: + high_context_bits = 0x01c0; + low_context_bits = 0x0001; + break; + case 0x10: + high_context_bits = 0x0180; + low_context_bits = 0x0001; + break; + case 0x20: + high_context_bits = 0x00c0; + low_context_bits = 0x0001; + break; + case 0x30: + high_context_bits = 0x0180; + low_context_bits = 0x0003; + break; + } + + in_stream = (in[0] << 11) | (in[1] << 3); + valid_bits = 5; + in_buf = in + 2; + memset(bit_ctr, 0, sizeof(bit_ctr)); + memset(context_states, 0, sizeof(context_states)); + memset(context_MPS, 0, sizeof(context_MPS)); + memset(prev_bits, 0, sizeof(prev_bits)); + + switch (bitplane_type) + { + case 0: + while (1) + { + for (byte1 = byte2 = 0, bit = 0x80; bit; bit >>= 1) + { + if (GetBit(0)) byte1 |= bit; + if (GetBit(1)) byte2 |= bit; + } + *(out++) = byte1; + if (!--len) return; + *(out++) = byte2; + if (!--len) return; + } + break; + case 1: + i = plane = 0; + while (1) + { + for (byte1 = byte2 = 0, bit = 0x80; bit; bit >>= 1) + { + if (GetBit(plane)) byte1 |= bit; + if (GetBit(plane + 1)) byte2 |= bit; + } + *(out++) = byte1; + if (!--len) return; + *(out++) = byte2; + if (!--len) return; + if (!(i += 32)) plane = (plane + 2) & 7; + } + break; + case 2: + i = plane = 0; + while (1) + { + for (byte1 = byte2 = 0, bit = 0x80; bit; bit >>= 1) + { + if (GetBit(plane)) byte1 |= bit; + if (GetBit(plane + 1)) byte2 |= bit; + } + *(out++) = byte1; + if (!--len) return; + *(out++) = byte2; + if (!--len) return; + if (!(i += 32)) plane ^= 2; + } + break; + case 3: + do + { + for (byte1 = plane = 0, bit = 1; bit; bit <<= 1, plane++) + { + if (GetBit(plane)) byte1 |= bit; + } + *(out++) = byte1; + } + while (--len); + break; + } } static uint8 cur_plane; static uint8 num_bits; static uint8 next_byte; -void SDD1_init(uint8 *in){ - bitplane_type=in[0]>>6; - - switch(in[0]&0x30){ - case 0x00: - high_context_bits=0x01c0; - low_context_bits =0x0001; - break; - case 0x10: - high_context_bits=0x0180; - low_context_bits =0x0001; - break; - case 0x20: - high_context_bits=0x00c0; - low_context_bits =0x0001; - break; - case 0x30: - high_context_bits=0x0180; - low_context_bits =0x0003; - break; - } - - in_stream=(in[0]<<11) | (in[1]<<3); - valid_bits=5; - in_buf=in+2; - memset(bit_ctr, 0, sizeof(bit_ctr)); - memset(context_states, 0, sizeof(context_states)); - memset(context_MPS, 0, sizeof(context_MPS)); - memset(prev_bits, 0, sizeof(prev_bits)); - - cur_plane=0; - num_bits=0; +void SDD1_init(uint8* in) +{ + bitplane_type = in[0] >> 6; + + switch (in[0] & 0x30) + { + case 0x00: + high_context_bits = 0x01c0; + low_context_bits = 0x0001; + break; + case 0x10: + high_context_bits = 0x0180; + low_context_bits = 0x0001; + break; + case 0x20: + high_context_bits = 0x00c0; + low_context_bits = 0x0001; + break; + case 0x30: + high_context_bits = 0x0180; + low_context_bits = 0x0003; + break; + } + + in_stream = (in[0] << 11) | (in[1] << 3); + valid_bits = 5; + in_buf = in + 2; + memset(bit_ctr, 0, sizeof(bit_ctr)); + memset(context_states, 0, sizeof(context_states)); + memset(context_MPS, 0, sizeof(context_MPS)); + memset(prev_bits, 0, sizeof(prev_bits)); + + cur_plane = 0; + num_bits = 0; } -uint8 SDD1_get_byte(void){ - uint8 bit; - uint8 byte=0; - - switch(bitplane_type){ - case 0: - num_bits+=16; - if(num_bits&16){ - next_byte=0; - for(bit=0x80; bit; bit>>=1){ - if(GetBit(0)) byte |= bit; - if(GetBit(1)) next_byte |= bit; - } - return byte; - } else { - return next_byte; - } - - case 1: - num_bits+=16; - if(num_bits&16){ - next_byte=0; - for(bit=0x80; bit; bit>>=1){ - if(GetBit(cur_plane)) byte |= bit; - if(GetBit(cur_plane+1)) next_byte |= bit; - } - return byte; - } else { - if(!num_bits) cur_plane = (cur_plane+2)&7; - return next_byte; - } - - case 2: - num_bits+=16; - if(num_bits&16){ - next_byte=0; - for(bit=0x80; bit; bit>>=1){ - if(GetBit(cur_plane)) byte |= bit; - if(GetBit(cur_plane+1)) next_byte |= bit; - } - return byte; - } else { - if(!num_bits) cur_plane ^= 2; - return next_byte; - } - - case 3: - for(cur_plane=0, bit=1; bit; bit<<=1, cur_plane++){ - if(GetBit(cur_plane)) byte |= bit; - } - return byte; - - default: - /* should never happen */ - return 0; - } +uint8 SDD1_get_byte(void) +{ + uint8 bit; + uint8 byte = 0; + + switch (bitplane_type) + { + case 0: + num_bits += 16; + if (num_bits & 16) + { + next_byte = 0; + for (bit = 0x80; bit; bit >>= 1) + { + if (GetBit(0)) byte |= bit; + if (GetBit(1)) next_byte |= bit; + } + return byte; + } + else + return next_byte; + + case 1: + num_bits += 16; + if (num_bits & 16) + { + next_byte = 0; + for (bit = 0x80; bit; bit >>= 1) + { + if (GetBit(cur_plane)) byte |= bit; + if (GetBit(cur_plane + 1)) next_byte |= bit; + } + return byte; + } + else + { + if (!num_bits) cur_plane = (cur_plane + 2) & 7; + return next_byte; + } + + case 2: + num_bits += 16; + if (num_bits & 16) + { + next_byte = 0; + for (bit = 0x80; bit; bit >>= 1) + { + if (GetBit(cur_plane)) byte |= bit; + if (GetBit(cur_plane + 1)) next_byte |= bit; + } + return byte; + } + else + { + if (!num_bits) cur_plane ^= 2; + return next_byte; + } + + case 3: + for (cur_plane = 0, bit = 1; bit; bit <<= 1, cur_plane++) + { + if (GetBit(cur_plane)) byte |= bit; + } + return byte; + + default: + /* should never happen */ + return 0; + } } diff --git a/source/sdd1emu.h b/source/sdd1emu.h index 4e95a0e..642454f 100644 --- a/source/sdd1emu.h +++ b/source/sdd1emu.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -91,9 +91,9 @@ //#include "port.h" -void SDD1_decompress(uint8 *out, uint8 *in, int output_length); +void SDD1_decompress(uint8* out, uint8* in, int output_length); -void SDD1_init(uint8 *in); +void SDD1_init(uint8* in); uint8 SDD1_get_byte(void); #endif diff --git a/source/seta.c b/source/seta.c index e5df1f6..cce8330 100644 --- a/source/seta.c +++ b/source/seta.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,61 +43,61 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ #include "seta.h" -void (*SetSETA)(uint32, uint8)=&S9xSetST010; -uint8 (*GetSETA)(uint32)=&S9xGetST010; +void (*SetSETA)(uint32, uint8) = &S9xSetST010; +uint8(*GetSETA)(uint32) = &S9xGetST010; uint8 S9xGetSetaDSP(uint32 Address) { - return GetSETA(Address); + return GetSETA(Address); } void S9xSetSetaDSP(uint8 Byte, uint32 Address) { - SetSETA(Address, Byte); + SetSETA(Address, Byte); } diff --git a/source/seta.h b/source/seta.h index 34d04d1..d50e588 100644 --- a/source/seta.h +++ b/source/seta.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -98,7 +98,7 @@ #define ST_018 0x03 uint8 S9xGetSetaDSP(uint32 Address); -void S9xSetSetaDSP(uint8 byte,uint32 Address); +void S9xSetSetaDSP(uint8 byte, uint32 Address); uint8 S9xGetST018(uint32 Address); void S9xSetST018(uint8 Byte, uint32 Address); @@ -108,43 +108,43 @@ uint8 S9xGetST011(uint32 Address); void S9xSetST011(uint32 Address, uint8 Byte); extern void (*SetSETA)(uint32, uint8); -extern uint8 (*GetSETA)(uint32); +extern uint8(*GetSETA)(uint32); typedef struct SETA_ST010_STRUCT { - uint8 input_params[16]; - uint8 output_params[16]; - uint8 op_reg; - uint8 execute; - bool8 control_enable; + uint8 input_params[16]; + uint8 output_params[16]; + uint8 op_reg; + uint8 execute; + bool8 control_enable; } ST010_Regs; typedef struct SETA_ST011_STRUCT { - bool8 waiting4command; - uint8 status; - uint8 command; - uint32 in_count; - uint32 in_index; - uint32 out_count; - uint32 out_index; - uint8 parameters [512]; - uint8 output [512]; + bool8 waiting4command; + uint8 status; + uint8 command; + uint32 in_count; + uint32 in_index; + uint32 out_count; + uint32 out_index; + uint8 parameters [512]; + uint8 output [512]; } ST011_Regs; typedef struct SETA_ST018_STRUCT { - bool8 waiting4command; - uint8 status; - uint8 part_command; - uint8 pass; - uint32 command; - uint32 in_count; - uint32 in_index; - uint32 out_count; - uint32 out_index; - uint8 parameters [512]; - uint8 output [512]; + bool8 waiting4command; + uint8 status; + uint8 part_command; + uint8 pass; + uint32 command; + uint32 in_count; + uint32 in_index; + uint32 out_count; + uint32 out_index; + uint8 parameters [512]; + uint8 output [512]; } ST018_Regs; #endif diff --git a/source/seta010.c b/source/seta010.c index 926f615..75deb74 100644 --- a/source/seta010.c +++ b/source/seta010.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -90,29 +90,30 @@ #include "memmap.h" // Mode 7 scaling constants for all raster lines -const int16 ST010_M7Scale[176] = { - 0x0380, 0x0325, 0x02da, 0x029c, 0x0268, 0x023b, 0x0215, 0x01f3, - 0x01d5, 0x01bb, 0x01a3, 0x018e, 0x017b, 0x016a, 0x015a, 0x014b, - 0x013e, 0x0132, 0x0126, 0x011c, 0x0112, 0x0109, 0x0100, 0x00f8, - 0x00f0, 0x00e9, 0x00e3, 0x00dc, 0x00d6, 0x00d1, 0x00cb, 0x00c6, - 0x00c1, 0x00bd, 0x00b8, 0x00b4, 0x00b0, 0x00ac, 0x00a8, 0x00a5, - 0x00a2, 0x009e, 0x009b, 0x0098, 0x0095, 0x0093, 0x0090, 0x008d, - 0x008b, 0x0088, 0x0086, 0x0084, 0x0082, 0x0080, 0x007e, 0x007c, - 0x007a, 0x0078, 0x0076, 0x0074, 0x0073, 0x0071, 0x006f, 0x006e, - 0x006c, 0x006b, 0x0069, 0x0068, 0x0067, 0x0065, 0x0064, 0x0063, - 0x0062, 0x0060, 0x005f, 0x005e, 0x005d, 0x005c, 0x005b, 0x005a, - 0x0059, 0x0058, 0x0057, 0x0056, 0x0055, 0x0054, 0x0053, 0x0052, - 0x0051, 0x0051, 0x0050, 0x004f, 0x004e, 0x004d, 0x004d, 0x004c, - 0x004b, 0x004b, 0x004a, 0x0049, 0x0048, 0x0048, 0x0047, 0x0047, - 0x0046, 0x0045, 0x0045, 0x0044, 0x0044, 0x0043, 0x0042, 0x0042, - 0x0041, 0x0041, 0x0040, 0x0040, 0x003f, 0x003f, 0x003e, 0x003e, - 0x003d, 0x003d, 0x003c, 0x003c, 0x003b, 0x003b, 0x003a, 0x003a, - 0x003a, 0x0039, 0x0039, 0x0038, 0x0038, 0x0038, 0x0037, 0x0037, - 0x0036, 0x0036, 0x0036, 0x0035, 0x0035, 0x0035, 0x0034, 0x0034, - 0x0034, 0x0033, 0x0033, 0x0033, 0x0032, 0x0032, 0x0032, 0x0031, - 0x0031, 0x0031, 0x0030, 0x0030, 0x0030, 0x0030, 0x002f, 0x002f, - 0x002f, 0x002e, 0x002e, 0x002e, 0x002e, 0x002d, 0x002d, 0x002d, - 0x002d, 0x002c, 0x002c, 0x002c, 0x002c, 0x002b, 0x002b, 0x002b +const int16 ST010_M7Scale[176] = +{ + 0x0380, 0x0325, 0x02da, 0x029c, 0x0268, 0x023b, 0x0215, 0x01f3, + 0x01d5, 0x01bb, 0x01a3, 0x018e, 0x017b, 0x016a, 0x015a, 0x014b, + 0x013e, 0x0132, 0x0126, 0x011c, 0x0112, 0x0109, 0x0100, 0x00f8, + 0x00f0, 0x00e9, 0x00e3, 0x00dc, 0x00d6, 0x00d1, 0x00cb, 0x00c6, + 0x00c1, 0x00bd, 0x00b8, 0x00b4, 0x00b0, 0x00ac, 0x00a8, 0x00a5, + 0x00a2, 0x009e, 0x009b, 0x0098, 0x0095, 0x0093, 0x0090, 0x008d, + 0x008b, 0x0088, 0x0086, 0x0084, 0x0082, 0x0080, 0x007e, 0x007c, + 0x007a, 0x0078, 0x0076, 0x0074, 0x0073, 0x0071, 0x006f, 0x006e, + 0x006c, 0x006b, 0x0069, 0x0068, 0x0067, 0x0065, 0x0064, 0x0063, + 0x0062, 0x0060, 0x005f, 0x005e, 0x005d, 0x005c, 0x005b, 0x005a, + 0x0059, 0x0058, 0x0057, 0x0056, 0x0055, 0x0054, 0x0053, 0x0052, + 0x0051, 0x0051, 0x0050, 0x004f, 0x004e, 0x004d, 0x004d, 0x004c, + 0x004b, 0x004b, 0x004a, 0x0049, 0x0048, 0x0048, 0x0047, 0x0047, + 0x0046, 0x0045, 0x0045, 0x0044, 0x0044, 0x0043, 0x0042, 0x0042, + 0x0041, 0x0041, 0x0040, 0x0040, 0x003f, 0x003f, 0x003e, 0x003e, + 0x003d, 0x003d, 0x003c, 0x003c, 0x003b, 0x003b, 0x003a, 0x003a, + 0x003a, 0x0039, 0x0039, 0x0038, 0x0038, 0x0038, 0x0037, 0x0037, + 0x0036, 0x0036, 0x0036, 0x0035, 0x0035, 0x0035, 0x0034, 0x0034, + 0x0034, 0x0033, 0x0033, 0x0033, 0x0032, 0x0032, 0x0032, 0x0031, + 0x0031, 0x0031, 0x0030, 0x0030, 0x0030, 0x0030, 0x002f, 0x002f, + 0x002f, 0x002e, 0x002e, 0x002e, 0x002e, 0x002d, 0x002d, 0x002d, + 0x002d, 0x002c, 0x002c, 0x002c, 0x002c, 0x002b, 0x002b, 0x002b }; // H-DMA hack @@ -129,158 +130,227 @@ ST010_Regs ST010; uint8 S9xGetST010(uint32 Address) { - if(!(Address&0x80000)) - return 0x80; - - if((Address&0xFFF)==0x20) - return ST010.op_reg; - if ((Address&0xFFF)==0x21) - return ST010.execute; - return Memory.SRAM[Address&Memory.SRAMMask]; + if (!(Address & 0x80000)) + return 0x80; + + if ((Address & 0xFFF) == 0x20) + return ST010.op_reg; + if ((Address & 0xFFF) == 0x21) + return ST010.execute; + return Memory.SRAM[Address & Memory.SRAMMask]; } -const int16 ST010_SinTable[256] = { - 0x0000, 0x0324, 0x0648, 0x096a, 0x0c8c, 0x0fab, 0x12c8, 0x15e2, - 0x18f9, 0x1c0b, 0x1f1a, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, - 0x30fb, 0x33df, 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, - 0x471c, 0x49b4, 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, - 0x5a82, 0x5cb3, 0x5ed7, 0x60eb, 0x62f1, 0x64e8, 0x66cf, 0x68a6, - 0x6a6d, 0x6c23, 0x6dc9, 0x6f5e, 0x70e2, 0x7254, 0x73b5, 0x7504, - 0x7641, 0x776b, 0x7884, 0x7989, 0x7a7c, 0x7b5c, 0x7c29, 0x7ce3, - 0x7d89, 0x7e1d, 0x7e9c, 0x7f09, 0x7f61, 0x7fa6, 0x7fd8, 0x7ff5, - 0x7fff, 0x7ff5, 0x7fd8, 0x7fa6, 0x7f61, 0x7f09, 0x7e9c, 0x7e1d, - 0x7d89, 0x7ce3, 0x7c29, 0x7b5c, 0x7a7c, 0x7989, 0x7884, 0x776b, - 0x7641, 0x7504, 0x73b5, 0x7254, 0x70e2, 0x6f5e, 0x6dc9, 0x6c23, - 0x6a6d, 0x68a6, 0x66cf, 0x64e8, 0x62f1, 0x60eb, 0x5ed7, 0x5cb3, - 0x5a82, 0x5842, 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, - 0x471c, 0x447a, 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33df, - 0x30fb, 0x2e11, 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f1a, 0x1c0b, - 0x18f8, 0x15e2, 0x12c8, 0x0fab, 0x0c8c, 0x096a, 0x0648, 0x0324, - 0x0000, -0x0324, -0x0648, -0x096b, -0x0c8c, -0x0fab, -0x12c8, -0x15e2, - -0x18f9, -0x1c0b, -0x1f1a, -0x2223, -0x2528, -0x2826, -0x2b1f, -0x2e11, - -0x30fb, -0x33df, -0x36ba, -0x398d, -0x3c56, -0x3f17, -0x41ce, -0x447a, - -0x471c, -0x49b4, -0x4c3f, -0x4ebf, -0x5133, -0x539b, -0x55f5, -0x5842, - -0x5a82, -0x5cb3, -0x5ed7, -0x60ec, -0x62f1, -0x64e8, -0x66cf, -0x68a6, - -0x6a6d, -0x6c23, -0x6dc9, -0x6f5e, -0x70e2, -0x7254, -0x73b5, -0x7504, - -0x7641, -0x776b, -0x7884, -0x7989, -0x7a7c, -0x7b5c, -0x7c29, -0x7ce3, - -0x7d89, -0x7e1d, -0x7e9c, -0x7f09, -0x7f61, -0x7fa6, -0x7fd8, -0x7ff5, - -0x7fff, -0x7ff5, -0x7fd8, -0x7fa6, -0x7f61, -0x7f09, -0x7e9c, -0x7e1d, - -0x7d89, -0x7ce3, -0x7c29, -0x7b5c, -0x7a7c, -0x7989, -0x7883, -0x776b, - -0x7641, -0x7504, -0x73b5, -0x7254, -0x70e2, -0x6f5e, -0x6dc9, -0x6c23, - -0x6a6d, -0x68a6, -0x66cf, -0x64e8, -0x62f1, -0x60eb, -0x5ed7, -0x5cb3, - -0x5a82, -0x5842, -0x55f5, -0x539a, -0x5133, -0x4ebf, -0x4c3f, -0x49b3, - -0x471c, -0x447a, -0x41cd, -0x3f17, -0x3c56, -0x398c, -0x36b9, -0x33de, - -0x30fb, -0x2e10, -0x2b1f, -0x2826, -0x2527, -0x2223, -0x1f19, -0x1c0b, - -0x18f8, -0x15e2, -0x12c8, -0x0fab, -0x0c8b, -0x096a, -0x0647, -0x0324}; - -const unsigned char ST010_ArcTan[32][32] = { - { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}, - { 0x80, 0xa0, 0xad, 0xb3, 0xb6, 0xb8, 0xb9, 0xba, 0xbb, 0xbb, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, - 0xbd, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, 0xbf}, - { 0x80, 0x93, 0xa0, 0xa8, 0xad, 0xb0, 0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, - 0xbb, 0xbb, 0xbb, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd}, - { 0x80, 0x8d, 0x98, 0xa0, 0xa6, 0xaa, 0xad, 0xb0, 0xb1, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb7, 0xb8, - 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbc, 0xbc, 0xbc, 0xbc}, - { 0x80, 0x8a, 0x93, 0x9a, 0xa0, 0xa5, 0xa8, 0xab, 0xad, 0xaf, 0xb0, 0xb2, 0xb3, 0xb4, 0xb5, 0xb5, - 0xb6, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, 0xba, 0xbb, 0xbb}, - { 0x80, 0x88, 0x90, 0x96, 0x9b, 0xa0, 0xa4, 0xa7, 0xa9, 0xab, 0xad, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, - 0xb4, 0xb4, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9}, - { 0x80, 0x87, 0x8d, 0x93, 0x98, 0x9c, 0xa0, 0xa3, 0xa6, 0xa8, 0xaa, 0xac, 0xad, 0xae, 0xb0, 0xb0, - 0xb1, 0xb2, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8}, - { 0x80, 0x86, 0x8b, 0x90, 0x95, 0x99, 0x9d, 0xa0, 0xa3, 0xa5, 0xa7, 0xa9, 0xaa, 0xac, 0xad, 0xae, - 0xaf, 0xb0, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7}, - { 0x80, 0x85, 0x8a, 0x8f, 0x93, 0x97, 0x9a, 0x9d, 0xa0, 0xa2, 0xa5, 0xa6, 0xa8, 0xaa, 0xab, 0xac, - 0xad, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb5, 0xb5}, - { 0x80, 0x85, 0x89, 0x8d, 0x91, 0x95, 0x98, 0x9b, 0x9e, 0xa0, 0xa0, 0xa4, 0xa6, 0xa7, 0xa9, 0xaa, - 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb4}, - { 0x80, 0x84, 0x88, 0x8c, 0x90, 0x93, 0x96, 0x99, 0x9b, 0x9e, 0xa0, 0xa2, 0xa4, 0xa5, 0xa7, 0xa8, - 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf, 0xb0, 0xb0, 0xb1, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3}, - { 0x80, 0x84, 0x87, 0x8b, 0x8e, 0x91, 0x94, 0x97, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa3, 0xa5, 0xa6, - 0xa7, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb1, 0xb2, 0xb2}, - { 0x80, 0x83, 0x87, 0x8a, 0x8d, 0x90, 0x93, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa3, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xb0, 0xb0, 0xb0, 0xb1}, - { 0x80, 0x83, 0x86, 0x89, 0x8c, 0x8f, 0x92, 0x94, 0x96, 0x99, 0x9b, 0x9d, 0x9e, 0xa0, 0xa2, 0xa3, - 0xa4, 0xa5, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xb0}, - { 0x80, 0x83, 0x86, 0x89, 0x8b, 0x8e, 0x90, 0x93, 0x95, 0x97, 0x99, 0x9b, 0x9d, 0x9e, 0xa0, 0xa1, - 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf}, - { 0x80, 0x83, 0x85, 0x88, 0x8b, 0x8d, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9b, 0x9d, 0x9f, 0xa0, - 0xa1, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae}, - { 0x80, 0x83, 0x85, 0x88, 0x8a, 0x8c, 0x8f, 0x91, 0x93, 0x95, 0x97, 0x99, 0x9a, 0x9c, 0x9d, 0x9f, - 0xa0, 0xa1, 0xa2, 0xa3, 0xa5, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xab, 0xac, 0xad}, - { 0x80, 0x82, 0x85, 0x87, 0x89, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x97, 0x99, 0x9b, 0x9c, 0x9d, - 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xac}, - { 0x80, 0x82, 0x85, 0x87, 0x89, 0x8b, 0x8d, 0x8f, 0x91, 0x93, 0x95, 0x96, 0x98, 0x99, 0x9b, 0x9c, - 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab}, - { 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x95, 0x97, 0x98, 0x9a, 0x9b, - 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa}, - { 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x91, 0x93, 0x94, 0x96, 0x97, 0x99, 0x9a, - 0x9b, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa9}, - { 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8b, 0x8d, 0x8f, 0x90, 0x92, 0x94, 0x95, 0x97, 0x98, 0x99, - 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8}, - { 0x80, 0x82, 0x84, 0x86, 0x87, 0x89, 0x8b, 0x8d, 0x8e, 0x90, 0x91, 0x93, 0x94, 0x96, 0x97, 0x98, - 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa3, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7}, - { 0x80, 0x82, 0x84, 0x85, 0x87, 0x89, 0x8a, 0x8c, 0x8e, 0x8f, 0x91, 0x92, 0x94, 0x95, 0x96, 0x98, - 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5, 0xa6}, - { 0x80, 0x82, 0x83, 0x85, 0x87, 0x88, 0x8a, 0x8c, 0x8d, 0x8f, 0x90, 0x92, 0x93, 0x94, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5}, - { 0x80, 0x82, 0x83, 0x85, 0x86, 0x88, 0x8a, 0x8b, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa4}, - { 0x80, 0x82, 0x83, 0x85, 0x86, 0x88, 0x89, 0x8b, 0x8c, 0x8e, 0x8f, 0x90, 0x92, 0x93, 0x94, 0x95, - 0x96, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4}, - { 0x80, 0x82, 0x83, 0x85, 0x86, 0x87, 0x89, 0x8a, 0x8c, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x93, 0x95, - 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa1, 0xa2, 0xa3}, - { 0x80, 0x81, 0x83, 0x84, 0x86, 0x87, 0x89, 0x8a, 0x8b, 0x8d, 0x8e, 0x8f, 0x90, 0x92, 0x93, 0x94, - 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa1, 0xa2}, - { 0x80, 0x81, 0x83, 0x84, 0x86, 0x87, 0x88, 0x8a, 0x8b, 0x8c, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, - 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, 0xa1, 0xa1}, - { 0x80, 0x81, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8b, 0x8c, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x93, - 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, 0xa1}, - { 0x80, 0x81, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, - 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0}}; +const int16 ST010_SinTable[256] = +{ + 0x0000, 0x0324, 0x0648, 0x096a, 0x0c8c, 0x0fab, 0x12c8, 0x15e2, + 0x18f9, 0x1c0b, 0x1f1a, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, + 0x30fb, 0x33df, 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, + 0x471c, 0x49b4, 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, + 0x5a82, 0x5cb3, 0x5ed7, 0x60eb, 0x62f1, 0x64e8, 0x66cf, 0x68a6, + 0x6a6d, 0x6c23, 0x6dc9, 0x6f5e, 0x70e2, 0x7254, 0x73b5, 0x7504, + 0x7641, 0x776b, 0x7884, 0x7989, 0x7a7c, 0x7b5c, 0x7c29, 0x7ce3, + 0x7d89, 0x7e1d, 0x7e9c, 0x7f09, 0x7f61, 0x7fa6, 0x7fd8, 0x7ff5, + 0x7fff, 0x7ff5, 0x7fd8, 0x7fa6, 0x7f61, 0x7f09, 0x7e9c, 0x7e1d, + 0x7d89, 0x7ce3, 0x7c29, 0x7b5c, 0x7a7c, 0x7989, 0x7884, 0x776b, + 0x7641, 0x7504, 0x73b5, 0x7254, 0x70e2, 0x6f5e, 0x6dc9, 0x6c23, + 0x6a6d, 0x68a6, 0x66cf, 0x64e8, 0x62f1, 0x60eb, 0x5ed7, 0x5cb3, + 0x5a82, 0x5842, 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, + 0x471c, 0x447a, 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33df, + 0x30fb, 0x2e11, 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f1a, 0x1c0b, + 0x18f8, 0x15e2, 0x12c8, 0x0fab, 0x0c8c, 0x096a, 0x0648, 0x0324, + 0x0000, -0x0324, -0x0648, -0x096b, -0x0c8c, -0x0fab, -0x12c8, -0x15e2, + -0x18f9, -0x1c0b, -0x1f1a, -0x2223, -0x2528, -0x2826, -0x2b1f, -0x2e11, + -0x30fb, -0x33df, -0x36ba, -0x398d, -0x3c56, -0x3f17, -0x41ce, -0x447a, + -0x471c, -0x49b4, -0x4c3f, -0x4ebf, -0x5133, -0x539b, -0x55f5, -0x5842, + -0x5a82, -0x5cb3, -0x5ed7, -0x60ec, -0x62f1, -0x64e8, -0x66cf, -0x68a6, + -0x6a6d, -0x6c23, -0x6dc9, -0x6f5e, -0x70e2, -0x7254, -0x73b5, -0x7504, + -0x7641, -0x776b, -0x7884, -0x7989, -0x7a7c, -0x7b5c, -0x7c29, -0x7ce3, + -0x7d89, -0x7e1d, -0x7e9c, -0x7f09, -0x7f61, -0x7fa6, -0x7fd8, -0x7ff5, + -0x7fff, -0x7ff5, -0x7fd8, -0x7fa6, -0x7f61, -0x7f09, -0x7e9c, -0x7e1d, + -0x7d89, -0x7ce3, -0x7c29, -0x7b5c, -0x7a7c, -0x7989, -0x7883, -0x776b, + -0x7641, -0x7504, -0x73b5, -0x7254, -0x70e2, -0x6f5e, -0x6dc9, -0x6c23, + -0x6a6d, -0x68a6, -0x66cf, -0x64e8, -0x62f1, -0x60eb, -0x5ed7, -0x5cb3, + -0x5a82, -0x5842, -0x55f5, -0x539a, -0x5133, -0x4ebf, -0x4c3f, -0x49b3, + -0x471c, -0x447a, -0x41cd, -0x3f17, -0x3c56, -0x398c, -0x36b9, -0x33de, + -0x30fb, -0x2e10, -0x2b1f, -0x2826, -0x2527, -0x2223, -0x1f19, -0x1c0b, + -0x18f8, -0x15e2, -0x12c8, -0x0fab, -0x0c8b, -0x096a, -0x0647, -0x0324 +}; + +const unsigned char ST010_ArcTan[32][32] = +{ + { + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 + }, + { + 0x80, 0xa0, 0xad, 0xb3, 0xb6, 0xb8, 0xb9, 0xba, 0xbb, 0xbb, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, + 0xbd, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, 0xbf + }, + { + 0x80, 0x93, 0xa0, 0xa8, 0xad, 0xb0, 0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, + 0xbb, 0xbb, 0xbb, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd + }, + { + 0x80, 0x8d, 0x98, 0xa0, 0xa6, 0xaa, 0xad, 0xb0, 0xb1, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb7, 0xb8, + 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbc, 0xbc, 0xbc, 0xbc + }, + { + 0x80, 0x8a, 0x93, 0x9a, 0xa0, 0xa5, 0xa8, 0xab, 0xad, 0xaf, 0xb0, 0xb2, 0xb3, 0xb4, 0xb5, 0xb5, + 0xb6, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, 0xba, 0xbb, 0xbb + }, + { + 0x80, 0x88, 0x90, 0x96, 0x9b, 0xa0, 0xa4, 0xa7, 0xa9, 0xab, 0xad, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, + 0xb4, 0xb4, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9 + }, + { + 0x80, 0x87, 0x8d, 0x93, 0x98, 0x9c, 0xa0, 0xa3, 0xa6, 0xa8, 0xaa, 0xac, 0xad, 0xae, 0xb0, 0xb0, + 0xb1, 0xb2, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8 + }, + { + 0x80, 0x86, 0x8b, 0x90, 0x95, 0x99, 0x9d, 0xa0, 0xa3, 0xa5, 0xa7, 0xa9, 0xaa, 0xac, 0xad, 0xae, + 0xaf, 0xb0, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7 + }, + { + 0x80, 0x85, 0x8a, 0x8f, 0x93, 0x97, 0x9a, 0x9d, 0xa0, 0xa2, 0xa5, 0xa6, 0xa8, 0xaa, 0xab, 0xac, + 0xad, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb5, 0xb5 + }, + { + 0x80, 0x85, 0x89, 0x8d, 0x91, 0x95, 0x98, 0x9b, 0x9e, 0xa0, 0xa0, 0xa4, 0xa6, 0xa7, 0xa9, 0xaa, + 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb4 + }, + { + 0x80, 0x84, 0x88, 0x8c, 0x90, 0x93, 0x96, 0x99, 0x9b, 0x9e, 0xa0, 0xa2, 0xa4, 0xa5, 0xa7, 0xa8, + 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf, 0xb0, 0xb0, 0xb1, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3 + }, + { + 0x80, 0x84, 0x87, 0x8b, 0x8e, 0x91, 0x94, 0x97, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa3, 0xa5, 0xa6, + 0xa7, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb1, 0xb2, 0xb2 + }, + { + 0x80, 0x83, 0x87, 0x8a, 0x8d, 0x90, 0x93, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa3, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xb0, 0xb0, 0xb0, 0xb1 + }, + { + 0x80, 0x83, 0x86, 0x89, 0x8c, 0x8f, 0x92, 0x94, 0x96, 0x99, 0x9b, 0x9d, 0x9e, 0xa0, 0xa2, 0xa3, + 0xa4, 0xa5, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xb0 + }, + { + 0x80, 0x83, 0x86, 0x89, 0x8b, 0x8e, 0x90, 0x93, 0x95, 0x97, 0x99, 0x9b, 0x9d, 0x9e, 0xa0, 0xa1, + 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf + }, + { + 0x80, 0x83, 0x85, 0x88, 0x8b, 0x8d, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9b, 0x9d, 0x9f, 0xa0, + 0xa1, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae + }, + { + 0x80, 0x83, 0x85, 0x88, 0x8a, 0x8c, 0x8f, 0x91, 0x93, 0x95, 0x97, 0x99, 0x9a, 0x9c, 0x9d, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa5, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xab, 0xac, 0xad + }, + { + 0x80, 0x82, 0x85, 0x87, 0x89, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x97, 0x99, 0x9b, 0x9c, 0x9d, + 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xac + }, + { + 0x80, 0x82, 0x85, 0x87, 0x89, 0x8b, 0x8d, 0x8f, 0x91, 0x93, 0x95, 0x96, 0x98, 0x99, 0x9b, 0x9c, + 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab + }, + { + 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x95, 0x97, 0x98, 0x9a, 0x9b, + 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa + }, + { + 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x91, 0x93, 0x94, 0x96, 0x97, 0x99, 0x9a, + 0x9b, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa9 + }, + { + 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8b, 0x8d, 0x8f, 0x90, 0x92, 0x94, 0x95, 0x97, 0x98, 0x99, + 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8 + }, + { + 0x80, 0x82, 0x84, 0x86, 0x87, 0x89, 0x8b, 0x8d, 0x8e, 0x90, 0x91, 0x93, 0x94, 0x96, 0x97, 0x98, + 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa3, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7 + }, + { + 0x80, 0x82, 0x84, 0x85, 0x87, 0x89, 0x8a, 0x8c, 0x8e, 0x8f, 0x91, 0x92, 0x94, 0x95, 0x96, 0x98, + 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5, 0xa6 + }, + { + 0x80, 0x82, 0x83, 0x85, 0x87, 0x88, 0x8a, 0x8c, 0x8d, 0x8f, 0x90, 0x92, 0x93, 0x94, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5 + }, + { + 0x80, 0x82, 0x83, 0x85, 0x86, 0x88, 0x8a, 0x8b, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa4 + }, + { + 0x80, 0x82, 0x83, 0x85, 0x86, 0x88, 0x89, 0x8b, 0x8c, 0x8e, 0x8f, 0x90, 0x92, 0x93, 0x94, 0x95, + 0x96, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4 + }, + { + 0x80, 0x82, 0x83, 0x85, 0x86, 0x87, 0x89, 0x8a, 0x8c, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x93, 0x95, + 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa1, 0xa2, 0xa3 + }, + { + 0x80, 0x81, 0x83, 0x84, 0x86, 0x87, 0x89, 0x8a, 0x8b, 0x8d, 0x8e, 0x8f, 0x90, 0x92, 0x93, 0x94, + 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa1, 0xa2 + }, + { + 0x80, 0x81, 0x83, 0x84, 0x86, 0x87, 0x88, 0x8a, 0x8b, 0x8c, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, + 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, 0xa1, 0xa1 + }, + { + 0x80, 0x81, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8b, 0x8c, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x93, + 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, 0xa1 + }, + { + 0x80, 0x81, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, + 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0 + } +}; short ST010_Sin(short Theta) { - return ST010_SinTable[(Theta >> 8) & 0xff]; + return ST010_SinTable[(Theta >> 8) & 0xff]; } short ST010_Cos(short Theta) { - return ST010_SinTable[((Theta + 0x4000) >> 8) & 0xff]; + return ST010_SinTable[((Theta + 0x4000) >> 8) & 0xff]; } -void ST010_OP01(short x0, short y0, short* x1, short* y1, short* Quadrant, short* Theta) +void ST010_OP01(short x0, short y0, short* x1, short* y1, short* Quadrant, + short* Theta) { - if ((x0 < 0) && (y0 < 0)) - { + if ((x0 < 0) && (y0 < 0)) + { *x1 = -x0; *y1 = -y0; *Quadrant = -0x8000; - } - else if (x0 < 0) - { + } + else if (x0 < 0) + { *x1 = y0; *y1 = -x0; *Quadrant = -0x4000; - } - else if (y0 < 0) - { + } + else if (y0 < 0) + { *x1 = -y0; *y1 = x0; *Quadrant = 0x4000; - } - else - { + } + else + { *x1 = x0; *y1 = y0; *Quadrant = 0x0000; - } + } while ((*x1 > 0x1f) || (*y1 > 0x1f)) - { + { if (*x1 > 1) *x1 >>= 1; if (*y1 > 1) *y1 >>= 1; - } + } if (*y1 == 0) *Quadrant += 0x4000; @@ -293,460 +363,469 @@ void ST010_Scale(short Multiplier, short X0, short Y0, int* X1, int* Y1) *Y1 = Y0 * Multiplier << 1; } -void ST010_Multiply(short Multiplicand, short Multiplier, int *Product) +void ST010_Multiply(short Multiplicand, short Multiplier, int* Product) { *Product = Multiplicand * Multiplier << 1; } -void ST010_Rotate(short Theta, short X0, short Y0, short *X1, short *Y1) +void ST010_Rotate(short Theta, short X0, short Y0, short* X1, short* Y1) { *X1 = (Y0 * ST010_Sin(Theta) >> 15) + (X0 * ST010_Cos(Theta) >> 15); *Y1 = (Y0 * ST010_Cos(Theta) >> 15) - (X0 * ST010_Sin(Theta) >> 15); } -void SETA_Distance(short Y0, short X0, short *Distance) +void SETA_Distance(short Y0, short X0, short* Distance) { - if (X0 < 0) X0 = -X0; - if (Y0 < 0) Y0 = -Y0; + if (X0 < 0) X0 = -X0; + if (Y0 < 0) Y0 = -Y0; *Distance = ((X0 * 0x7af0) + 0x4000) >> 15; } -void ST010_SortDrivers(uint16 Positions, uint16 Places[32], uint16 Drivers[32]) +void ST010_SortDrivers(uint16 Positions, uint16 Places[32], uint16 Drivers[32]) { - bool Sorted; - uint16 Temp; + bool Sorted; + uint16 Temp; - if (Positions > 1) - do { - Sorted = true; + if (Positions > 1) + do + { + Sorted = true; int i; for (i = 0; i < Positions - 1; i++) - if (Places[i] < Places[i + 1]) - { - Temp = Places[i + 1]; - Places[i + 1] = Places[i]; - Places[i] = Temp; - - Temp = Drivers[i + 1]; - Drivers[i + 1] = Drivers[i]; - Drivers[i] = Temp; - - Sorted = false; - } - Positions--; - } while (!Sorted); + if (Places[i] < Places[i + 1]) + { + Temp = Places[i + 1]; + Places[i + 1] = Places[i]; + Places[i] = Temp; + + Temp = Drivers[i + 1]; + Drivers[i + 1] = Drivers[i]; + Drivers[i] = Temp; + + Sorted = false; + } + Positions--; + } + while (!Sorted); } #define ST010_WORD(offset) (Memory.SRAM[offset + 1] << 8) | Memory.SRAM[offset] void S9xSetST010(uint32 Address, uint8 Byte) { - if(!(Address&0x80000)) - { - ST010.control_enable=TRUE; - return; - } - //printf("Write %06X:%02X\n", Address, Byte); - - if((Address &0xFFF) ==0x20 && ST010.control_enable) - ST010.op_reg=Byte; - if((Address &0xFFF) ==0x21 && ST010.control_enable) - ST010.execute=Byte; - else Memory.SRAM[Address&Memory.SRAMMask]=Byte; - - if(ST010.execute&0x80) - { - switch(ST010.op_reg) - { - // Sorts Driver Placements - // - // Input - // 0x0024-0x0025 : Positions - // 0x0040-0x007f : Places - // 0x0080-0x00ff : Drivers - // Output - // 0x0040-0x007f : Places - // 0x0080-0x00ff : Drivers - // - case 0x02: - { + if (!(Address & 0x80000)) + { + ST010.control_enable = TRUE; + return; + } + //printf("Write %06X:%02X\n", Address, Byte); + + if ((Address & 0xFFF) == 0x20 && ST010.control_enable) + ST010.op_reg = Byte; + if ((Address & 0xFFF) == 0x21 && ST010.control_enable) + ST010.execute = Byte; + else Memory.SRAM[Address & Memory.SRAMMask] = Byte; + + if (ST010.execute & 0x80) + { + switch (ST010.op_reg) + { + // Sorts Driver Placements + // + // Input + // 0x0024-0x0025 : Positions + // 0x0040-0x007f : Places + // 0x0080-0x00ff : Drivers + // Output + // 0x0040-0x007f : Places + // 0x0080-0x00ff : Drivers + // + case 0x02: + { #ifdef FAST_LSB_WORD_ACCESS - ST010_SortDrivers(*(short*)&SRAM[0x0024], (uint16*) (SRAM + 0x0040), (uint16*) (SRAM + 0x0080)); + ST010_SortDrivers(*(short*)&SRAM[0x0024], (uint16*)(SRAM + 0x0040), + (uint16*)(SRAM + 0x0080)); #else - uint16 Places[32]; - uint16 Positions = ST010_WORD(0x0024); - int Pos, Offset; - - Offset = 0; - - for (Pos = 0; Pos < Positions; Pos++) - { - Places[Pos] = ST010_WORD(0x0040 + Offset); - Offset += 2; - } - - ST010_SortDrivers(Positions, Places, (uint16*) (Memory.SRAM + 0x0080)); - - Offset = 0; - - for (Pos = 0; Pos < Positions; Pos++) - { - Memory.SRAM[0x0040 + Offset]=(uint8)(Places[Pos]); - Memory.SRAM[0x0041 + Offset]=(uint8)(Places[Pos] >> 8); - Offset += 2; - } -#endif - break; - - } - - // Two Dimensional Coordinate Scale - // - // Input - // 0x0000-0x0001 : X0 (signed) - // 0x0002-0x0003 : Y0 (signed) - // 0x0004-0x0005 : Multiplier (signed) - // Output - // 0x0010-0x0013 : X1 (signed) - // 0x0014-0x0017 : Y1 (signed) - // - case 0x03: - { + uint16 Places[32]; + uint16 Positions = ST010_WORD(0x0024); + int Pos, Offset; + + Offset = 0; + + for (Pos = 0; Pos < Positions; Pos++) + { + Places[Pos] = ST010_WORD(0x0040 + Offset); + Offset += 2; + } + + ST010_SortDrivers(Positions, Places, (uint16*)(Memory.SRAM + 0x0080)); + + Offset = 0; + + for (Pos = 0; Pos < Positions; Pos++) + { + Memory.SRAM[0x0040 + Offset] = (uint8)(Places[Pos]); + Memory.SRAM[0x0041 + Offset] = (uint8)(Places[Pos] >> 8); + Offset += 2; + } +#endif + break; + + } + + // Two Dimensional Coordinate Scale + // + // Input + // 0x0000-0x0001 : X0 (signed) + // 0x0002-0x0003 : Y0 (signed) + // 0x0004-0x0005 : Multiplier (signed) + // Output + // 0x0010-0x0013 : X1 (signed) + // 0x0014-0x0017 : Y1 (signed) + // + case 0x03: + { #ifdef FAST_LSB_WORD_ACCESS - ST010_Scale(*(short*)&Memory.SRAM[0x0004], *(short*)&Memory.SRAM[0x0000], *(short*)&Memory.SRAM[0x0002], - (int&) Memory.SRAM[0x0010], (int&) Memory.SRAM[0x0014]); + ST010_Scale(*(short*)&Memory.SRAM[0x0004], *(short*)&Memory.SRAM[0x0000], + *(short*)&Memory.SRAM[0x0002], + (int &) Memory.SRAM[0x0010], (int &) Memory.SRAM[0x0014]); #else - int x1, y1; - - ST010_Scale(ST010_WORD(0x0004), ST010_WORD(0x0000), ST010_WORD(0x0002), &x1, &y1); - - Memory.SRAM[0x0010]=(uint8)(x1); - Memory.SRAM[0x0011]=(uint8)(x1 >> 8); - Memory.SRAM[0x0012]=(uint8)(x1 >> 16); - Memory.SRAM[0x0013]=(uint8)(x1 >> 24); - Memory.SRAM[0x0014]=(uint8)(y1); - Memory.SRAM[0x0015]=(uint8)(y1 >> 8); - Memory.SRAM[0x0016]=(uint8)(y1 >> 16); - Memory.SRAM[0x0017]=(uint8)(y1 >> 24); + int x1, y1; + + ST010_Scale(ST010_WORD(0x0004), ST010_WORD(0x0000), ST010_WORD(0x0002), &x1, + &y1); + + Memory.SRAM[0x0010] = (uint8)(x1); + Memory.SRAM[0x0011] = (uint8)(x1 >> 8); + Memory.SRAM[0x0012] = (uint8)(x1 >> 16); + Memory.SRAM[0x0013] = (uint8)(x1 >> 24); + Memory.SRAM[0x0014] = (uint8)(y1); + Memory.SRAM[0x0015] = (uint8)(y1 >> 8); + Memory.SRAM[0x0016] = (uint8)(y1 >> 16); + Memory.SRAM[0x0017] = (uint8)(y1 >> 24); #endif - break; - } - - // 16-bit Multiplication - // - // Input - // 0x0000-0x0001 : Multiplcand (signed) - // 0x0002-0x0003 : Multiplier (signed) - // Output - // 0x0010-0x0013 : Product (signed) - // - case 0x06: - { + break; + } + + // 16-bit Multiplication + // + // Input + // 0x0000-0x0001 : Multiplcand (signed) + // 0x0002-0x0003 : Multiplier (signed) + // Output + // 0x0010-0x0013 : Product (signed) + // + case 0x06: + { #ifdef FAST_LSB_WORD_ACCESS - ST010_Multiply(*(short*)&Memory.SRAM[0x0000], *(short*)&Memory.SRAM[0x0002], (int&) Memory.SRAM[0x0010]); + ST010_Multiply(*(short*)&Memory.SRAM[0x0000], *(short*)&Memory.SRAM[0x0002], + (int &) Memory.SRAM[0x0010]); #else - int Product; + int Product; - ST010_Multiply(ST010_WORD(0x0000), ST010_WORD(0x0002), &Product); + ST010_Multiply(ST010_WORD(0x0000), ST010_WORD(0x0002), &Product); - Memory.SRAM[0x0010]=(uint8)(Product); - Memory.SRAM[0x0011]=(uint8)(Product >> 8); - Memory.SRAM[0x0012]=(uint8)(Product >> 16); - Memory.SRAM[0x0013]=(uint8)(Product >> 24); + Memory.SRAM[0x0010] = (uint8)(Product); + Memory.SRAM[0x0011] = (uint8)(Product >> 8); + Memory.SRAM[0x0012] = (uint8)(Product >> 16); + Memory.SRAM[0x0013] = (uint8)(Product >> 24); #endif - break; - } - - // Mode 7 Raster Data Calculation - // - // Input - // 0x0000-0x0001 : Angle (signed) - // Output - // 0x00f0-0x024f : Mode 7 Matrix A - // 0x0250-0x03af : Mode 7 Matrix B - // 0x03b0-0x050f : Mode 7 Matrix C - // 0x0510-0x066f : Mode 7 Matrix D - // - case 0x07: - { - int16 data; - int32 offset = 0; - int16 Theta = ST010_WORD(0x0000); - - int32 line; - for (line = 0; line < 176; line++) - { - // Calculate Mode 7 Matrix A/D data - data = ST010_M7Scale[line] * ST010_Cos(Theta) >> 15; - - Memory.SRAM[0x00f0 + offset]=(uint8)(data); - Memory.SRAM[0x00f1 + offset]=(uint8)(data >> 8); - Memory.SRAM[0x0510 + offset]=(uint8)(data); - Memory.SRAM[0x0511 + offset]=(uint8)(data >> 8); - - // Calculate Mode 7 Matrix B/C data - data = ST010_M7Scale[line] * ST010_Sin(Theta) >> 15; - - Memory.SRAM[0x0250 + offset]=(uint8)(data); - Memory.SRAM[0x0251 + offset]=(uint8)(data >> 8); - - if (data) data = ~data; - - Memory.SRAM[0x03b0 + offset]=(uint8)(data); - Memory.SRAM[0x03b1 + offset]=(uint8)(data >> 8); - - offset += 2; - } - - // Shift Angle for use with Lookup table - Memory.SRAM[0x00] = Memory.SRAM[0x01]; - Memory.SRAM[0x01] = 0x00; - - break; - } - - // Two dimensional Coordinate Rotation - // - // Input - // 0x0000-0x0001 : X0 (signed) - // 0x0002-0x0003 : Y0 (signed) - // 0x0004-0x0005 : Angle (signed) - // Output - // 0x0010-0x0011 : X1 (signed) - // 0x0012-0x0013 : Y1 (signed) - // - case 0x08: - { + break; + } + + // Mode 7 Raster Data Calculation + // + // Input + // 0x0000-0x0001 : Angle (signed) + // Output + // 0x00f0-0x024f : Mode 7 Matrix A + // 0x0250-0x03af : Mode 7 Matrix B + // 0x03b0-0x050f : Mode 7 Matrix C + // 0x0510-0x066f : Mode 7 Matrix D + // + case 0x07: + { + int16 data; + int32 offset = 0; + int16 Theta = ST010_WORD(0x0000); + + int32 line; + for (line = 0; line < 176; line++) + { + // Calculate Mode 7 Matrix A/D data + data = ST010_M7Scale[line] * ST010_Cos(Theta) >> 15; + + Memory.SRAM[0x00f0 + offset] = (uint8)(data); + Memory.SRAM[0x00f1 + offset] = (uint8)(data >> 8); + Memory.SRAM[0x0510 + offset] = (uint8)(data); + Memory.SRAM[0x0511 + offset] = (uint8)(data >> 8); + + // Calculate Mode 7 Matrix B/C data + data = ST010_M7Scale[line] * ST010_Sin(Theta) >> 15; + + Memory.SRAM[0x0250 + offset] = (uint8)(data); + Memory.SRAM[0x0251 + offset] = (uint8)(data >> 8); + + if (data) data = ~data; + + Memory.SRAM[0x03b0 + offset] = (uint8)(data); + Memory.SRAM[0x03b1 + offset] = (uint8)(data >> 8); + + offset += 2; + } + + // Shift Angle for use with Lookup table + Memory.SRAM[0x00] = Memory.SRAM[0x01]; + Memory.SRAM[0x01] = 0x00; + + break; + } + + // Two dimensional Coordinate Rotation + // + // Input + // 0x0000-0x0001 : X0 (signed) + // 0x0002-0x0003 : Y0 (signed) + // 0x0004-0x0005 : Angle (signed) + // Output + // 0x0010-0x0011 : X1 (signed) + // 0x0012-0x0013 : Y1 (signed) + // + case 0x08: + { #ifdef FAST_LSB_WORD_ACCESS - ST010_Rotate(*(short*)&Memory.SRAM[0x0004], *(short*)&Memory.SRAM[0x0000], *(short*)&Memory.SRAM[0x0002], - (short&) Memory.SRAM[0x0010], (short&) Memory.SRAM[0x0012]); + ST010_Rotate(*(short*)&Memory.SRAM[0x0004], *(short*)&Memory.SRAM[0x0000], + *(short*)&Memory.SRAM[0x0002], + (short &) Memory.SRAM[0x0010], (short &) Memory.SRAM[0x0012]); #else - short x1, y1; + short x1, y1; - ST010_Rotate(ST010_WORD(0x0004), ST010_WORD(0x0000), ST010_WORD(0x0002), &x1, &y1); + ST010_Rotate(ST010_WORD(0x0004), ST010_WORD(0x0000), ST010_WORD(0x0002), &x1, + &y1); - Memory.SRAM[0x0010]=(uint8)(x1); - Memory.SRAM[0x0011]=(uint8)(x1 >> 8); - Memory.SRAM[0x0012]=(uint8)(y1); - Memory.SRAM[0x0013]=(uint8)(y1 >> 8); + Memory.SRAM[0x0010] = (uint8)(x1); + Memory.SRAM[0x0011] = (uint8)(x1 >> 8); + Memory.SRAM[0x0012] = (uint8)(y1); + Memory.SRAM[0x0013] = (uint8)(y1 >> 8); #endif - break; - } - - // Input - // 0x0000-0x0001 : DX (signed) - // 0x0002-0x0003 : DY (signed) - // Output - // 0x0010-0x0011 : Angle (signed) - // - case 0x01: - { - Memory.SRAM[0x0006] = Memory.SRAM[0x0002]; - Memory.SRAM[0x0007] = Memory.SRAM[0x0003]; + break; + } + + // Input + // 0x0000-0x0001 : DX (signed) + // 0x0002-0x0003 : DY (signed) + // Output + // 0x0010-0x0011 : Angle (signed) + // + case 0x01: + { + Memory.SRAM[0x0006] = Memory.SRAM[0x0002]; + Memory.SRAM[0x0007] = Memory.SRAM[0x0003]; #ifdef FAST_LSB_WORD_ACCESS - ST010_OP01(*(short*)&Memory.SRAM[0x0000], *(short*)&Memory.SRAM[0x0002], - (short*) &Memory.SRAM[0x0000], (short*) &Memory.SRAM[0x0002], - (short*) &Memory.SRAM[0x0004], (short*) &Memory.SRAM[0x0010]); + ST010_OP01(*(short*)&Memory.SRAM[0x0000], *(short*)&Memory.SRAM[0x0002], + (short*) &Memory.SRAM[0x0000], (short*) &Memory.SRAM[0x0002], + (short*) &Memory.SRAM[0x0004], (short*) &Memory.SRAM[0x0010]); #else - short x1, y1, Quadrant, Theta; - - ST010_OP01(ST010_WORD(0x0000), ST010_WORD(0x0002), &x1, &y1, &Quadrant, &Theta); - - Memory.SRAM[0x0000]=(uint8)(x1); - Memory.SRAM[0x0001]=(uint8)(x1 >> 8); - Memory.SRAM[0x0002]=(uint8)(y1); - Memory.SRAM[0x0003]=(uint8)(y1 >> 8); - Memory.SRAM[0x0004]=(uint8)(Quadrant); - Memory.SRAM[0x0005]=(uint8)(Quadrant >> 8); - Memory.SRAM[0x0010]=(uint8)(Theta); - Memory.SRAM[0x0011]=(uint8)(Theta >> 8); + short x1, y1, Quadrant, Theta; + + ST010_OP01(ST010_WORD(0x0000), ST010_WORD(0x0002), &x1, &y1, &Quadrant, &Theta); + + Memory.SRAM[0x0000] = (uint8)(x1); + Memory.SRAM[0x0001] = (uint8)(x1 >> 8); + Memory.SRAM[0x0002] = (uint8)(y1); + Memory.SRAM[0x0003] = (uint8)(y1 >> 8); + Memory.SRAM[0x0004] = (uint8)(Quadrant); + Memory.SRAM[0x0005] = (uint8)(Quadrant >> 8); + Memory.SRAM[0x0010] = (uint8)(Theta); + Memory.SRAM[0x0011] = (uint8)(Theta >> 8); #endif - break; - } + break; + } - // calculate the vector length of (x,y) - case 0x04: - { - int16 square, x,y; + // calculate the vector length of (x,y) + case 0x04: + { + int16 square, x, y; #ifdef FAST_LSB_WORD_ACCESS - x=*((int16*)Memory.SRAM); - y=*((int16*)&Memory.SRAM[2]); + x = *((int16*)Memory.SRAM); + y = *((int16*)&Memory.SRAM[2]); #else - x=Memory.SRAM[0]|(Memory.SRAM[1]<<8); - y=Memory.SRAM[2]|(Memory.SRAM[3]<<8); + x = Memory.SRAM[0] | (Memory.SRAM[1] << 8); + y = Memory.SRAM[2] | (Memory.SRAM[3] << 8); #endif - square=(int16)sqrt((double)(y*y+x*x)); - //SETA_Distance( x,y,square ); + square = (int16)sqrt((double)(y * y + x * x)); + //SETA_Distance( x,y,square ); #ifdef FAST_LSB_WORD_ACCESS - *((int16*)&Memory.SRAM[0x10])=square; + *((int16*)&Memory.SRAM[0x10]) = square; #else - Memory.SRAM[0x10]=(uint8)(square); - Memory.SRAM[0x11]=(uint8)(square>>8); + Memory.SRAM[0x10] = (uint8)(square); + Memory.SRAM[0x11] = (uint8)(square >> 8); #endif - break; - } - - // calculate AI orientation based on specific guidelines - case 0x05: - { - int dx,dy; - int16 a1,b1,c1; - uint16 o1; - - bool wrap=false; - - // target (x,y) coordinates - int16 ypos_max = ST010_WORD(0x00C0); - int16 xpos_max = ST010_WORD(0x00C2); - - // current coordinates and direction - int32 ypos = Memory.SRAM[0xC4]|(Memory.SRAM[0xC5]<<8)|(Memory.SRAM[0xC6]<<16)|(Memory.SRAM[0xC7]<<24); - int32 xpos = Memory.SRAM[0xC8]|(Memory.SRAM[0xC9]<<8)|(Memory.SRAM[0xCA]<<16)|(Memory.SRAM[0xCB]<<24); - uint16 rot = Memory.SRAM[0xCC]|(Memory.SRAM[0xCD]<<8); - - // physics - uint16 speed = ST010_WORD(0x00D4); - uint16 accel = ST010_WORD(0x00D6); - uint16 speed_max = ST010_WORD(0x00D8); - - // special condition acknowledgment - int16 system = ST010_WORD(0x00DA); - int16 flags = ST010_WORD(0x00DC); - - // new target coordinates - int16 ypos_new = ST010_WORD(0x00DE); - int16 xpos_new = ST010_WORD(0x00E0); - - // mask upper bit - xpos_new &= 0x7FFF; - - // get the current distance - dx = xpos_max-(xpos>>16); - dy = ypos_max-(ypos>>16); - - // quirk: clear and move in9 - Memory.SRAM[0xD2]=0xFF; - Memory.SRAM[0xD3]=0xFF; - Memory.SRAM[0xDA]=0; - Memory.SRAM[0xDB]=0; - - // grab the target angle - ST010_OP01(dy,dx,&a1,&b1,&c1,(int16*)&o1); - - // check for wrapping - //if((o1<0x6000 && rot>0xA000) || - // (rot<0x6000 && o1>0xA000)) - //if(o10x8000) - { - o1+=0x8000; - rot+=0x8000; - wrap=true; - } - //o1=0x0000; - //rot=0xFF00; - - uint16 old_speed; - - old_speed = speed; - - // special case - if(abs(o1-rot)==0x8000) - { - speed = 0x100; - } - // slow down for sharp curves - else if(abs(o1-rot)>=0x1000) - { - uint32 slow = abs(o1-rot); - slow >>= 4; // scaling - speed -= slow; - } - // otherwise accelerate - else - { - speed += accel; - if(speed > speed_max) - { - // clip speed - speed = speed_max; - } - } - - // prevent negative/positive overflow - if(abs(old_speed-speed)>0x8000) { - if(old_speedrot && (o1-rot)>0x80) || - (o1=0x80) ) - { - if(o1rot) rot+=0x280; - } - - // turn off wrapping - if(wrap) rot-=0x8000; - - // now check the distances (store for later) - dx = (xpos_max<<16)-xpos; - dy = (ypos_max<<16)-ypos; - dx>>=16; - dy>>=16; - - // if we're in so many units of the target, signal it - if( ( system && (dy<=6 && dy>=-8) && (dx<=126 && dx>=-128)) || - (!system && (dx<=6 && dx>=-8) && (dy<=126 && dy>=-128)) ) - { - // announce our new destination and flag it - xpos_max = xpos_new&0x7FFF; - ypos_max = ypos_new; - flags |= 0x08; - } - - // update position - xpos -= (ST010_Cos(rot) * 0x400 >> 15) * (speed >> 8) << 1; - ypos -= (ST010_Sin(rot) * 0x400 >> 15) * (speed >> 8) << 1; - - // quirk: mask upper byte - xpos &= 0x1FFFFFFF; - ypos &= 0x1FFFFFFF; - - Memory.SRAM[0x00C0]=(uint8)(ypos_max); - Memory.SRAM[0x00C1]=(uint8)(ypos_max >> 8); - Memory.SRAM[0x00C2]=(uint8)(xpos_max); - Memory.SRAM[0x00C3]=(uint8)(xpos_max >> 8); - Memory.SRAM[0x00C4]=(uint8)(ypos); - Memory.SRAM[0x00C5]=(uint8)(ypos >> 8); - Memory.SRAM[0x00C6]=(uint8)(ypos >> 16); - Memory.SRAM[0x00C7]=(uint8)(ypos >> 24); - Memory.SRAM[0x00C8]=(uint8)(xpos); - Memory.SRAM[0x00C9]=(uint8)(xpos >> 8); - Memory.SRAM[0x00CA]=(uint8)(xpos >> 16); - Memory.SRAM[0x00CB]=(uint8)(xpos >> 24); - Memory.SRAM[0x00CC]=(uint8)(rot); - Memory.SRAM[0x00CD]=(uint8)(rot >> 8); - Memory.SRAM[0x00D4]=(uint8)(speed); - Memory.SRAM[0x00D5]=(uint8)(speed >> 8); - Memory.SRAM[0x00DC]=(uint8)(flags); - Memory.SRAM[0x00DD]=(uint8)(flags >> 8); - - break; - } - - default: - printf("Unknown Op\n"); - break; - } - - // lower signal: op processed - ST010.op_reg=0; - ST010.execute=0; - } + break; + } + + // calculate AI orientation based on specific guidelines + case 0x05: + { + int dx, dy; + int16 a1, b1, c1; + uint16 o1; + + bool wrap = false; + + // target (x,y) coordinates + int16 ypos_max = ST010_WORD(0x00C0); + int16 xpos_max = ST010_WORD(0x00C2); + + // current coordinates and direction + int32 ypos = Memory.SRAM[0xC4] | (Memory.SRAM[0xC5] << 8) | + (Memory.SRAM[0xC6] << 16) | (Memory.SRAM[0xC7] << 24); + int32 xpos = Memory.SRAM[0xC8] | (Memory.SRAM[0xC9] << 8) | + (Memory.SRAM[0xCA] << 16) | (Memory.SRAM[0xCB] << 24); + uint16 rot = Memory.SRAM[0xCC] | (Memory.SRAM[0xCD] << 8); + + // physics + uint16 speed = ST010_WORD(0x00D4); + uint16 accel = ST010_WORD(0x00D6); + uint16 speed_max = ST010_WORD(0x00D8); + + // special condition acknowledgment + int16 system = ST010_WORD(0x00DA); + int16 flags = ST010_WORD(0x00DC); + + // new target coordinates + int16 ypos_new = ST010_WORD(0x00DE); + int16 xpos_new = ST010_WORD(0x00E0); + + // mask upper bit + xpos_new &= 0x7FFF; + + // get the current distance + dx = xpos_max - (xpos >> 16); + dy = ypos_max - (ypos >> 16); + + // quirk: clear and move in9 + Memory.SRAM[0xD2] = 0xFF; + Memory.SRAM[0xD3] = 0xFF; + Memory.SRAM[0xDA] = 0; + Memory.SRAM[0xDB] = 0; + + // grab the target angle + ST010_OP01(dy, dx, &a1, &b1, &c1, (int16*)&o1); + + // check for wrapping + //if((o1<0x6000 && rot>0xA000) || + // (rot<0x6000 && o1>0xA000)) + //if(o1 0x8000) + { + o1 += 0x8000; + rot += 0x8000; + wrap = true; + } + //o1=0x0000; + //rot=0xFF00; + + uint16 old_speed; + + old_speed = speed; + + // special case + if (abs(o1 - rot) == 0x8000) + speed = 0x100; + // slow down for sharp curves + else if (abs(o1 - rot) >= 0x1000) + { + uint32 slow = abs(o1 - rot); + slow >>= 4; // scaling + speed -= slow; + } + // otherwise accelerate + else + { + speed += accel; + if (speed > speed_max) + { + // clip speed + speed = speed_max; + } + } + + // prevent negative/positive overflow + if (abs(old_speed - speed) > 0x8000) + { + if (old_speed < speed) speed = 0; + else speed = 0xff00; + } + + // adjust direction by so many degrees + // be careful of negative adjustments + if ((o1 > rot && (o1 - rot) > 0x80) || + (o1 < rot && (rot - o1) >= 0x80)) + { + if (o1 < rot) rot -= 0x280; + else if (o1 > rot) rot += 0x280; + } + + // turn off wrapping + if (wrap) rot -= 0x8000; + + // now check the distances (store for later) + dx = (xpos_max << 16) - xpos; + dy = (ypos_max << 16) - ypos; + dx >>= 16; + dy >>= 16; + + // if we're in so many units of the target, signal it + if ((system && (dy <= 6 && dy >= -8) && (dx <= 126 && dx >= -128)) || + (!system && (dx <= 6 && dx >= -8) && (dy <= 126 && dy >= -128))) + { + // announce our new destination and flag it + xpos_max = xpos_new & 0x7FFF; + ypos_max = ypos_new; + flags |= 0x08; + } + + // update position + xpos -= (ST010_Cos(rot) * 0x400 >> 15) * (speed >> 8) << 1; + ypos -= (ST010_Sin(rot) * 0x400 >> 15) * (speed >> 8) << 1; + + // quirk: mask upper byte + xpos &= 0x1FFFFFFF; + ypos &= 0x1FFFFFFF; + + Memory.SRAM[0x00C0] = (uint8)(ypos_max); + Memory.SRAM[0x00C1] = (uint8)(ypos_max >> 8); + Memory.SRAM[0x00C2] = (uint8)(xpos_max); + Memory.SRAM[0x00C3] = (uint8)(xpos_max >> 8); + Memory.SRAM[0x00C4] = (uint8)(ypos); + Memory.SRAM[0x00C5] = (uint8)(ypos >> 8); + Memory.SRAM[0x00C6] = (uint8)(ypos >> 16); + Memory.SRAM[0x00C7] = (uint8)(ypos >> 24); + Memory.SRAM[0x00C8] = (uint8)(xpos); + Memory.SRAM[0x00C9] = (uint8)(xpos >> 8); + Memory.SRAM[0x00CA] = (uint8)(xpos >> 16); + Memory.SRAM[0x00CB] = (uint8)(xpos >> 24); + Memory.SRAM[0x00CC] = (uint8)(rot); + Memory.SRAM[0x00CD] = (uint8)(rot >> 8); + Memory.SRAM[0x00D4] = (uint8)(speed); + Memory.SRAM[0x00D5] = (uint8)(speed >> 8); + Memory.SRAM[0x00DC] = (uint8)(flags); + Memory.SRAM[0x00DD] = (uint8)(flags >> 8); + + break; + } + + default: + printf("Unknown Op\n"); + break; + } + + // lower signal: op processed + ST010.op_reg = 0; + ST010.execute = 0; + } } diff --git a/source/seta011.c b/source/seta011.c index 5137098..df6d696 100644 --- a/source/seta011.c +++ b/source/seta011.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -100,134 +100,149 @@ static int line = 0; uint8 S9xGetST011(uint32 Address) { - uint8 t; - uint16 address = (uint16) Address & 0xFFFF; - - // line counter - line++; - - // status check - if (address == 0x01) - { - t = 0xFF; - } - // read directly from s-ram - else - { - t = Memory.SRAM[address]; - } - - // debug -// if(address<0x150) -// printf( "ST011 R: %06X %02X\n", Address, t); - - return t; + uint8 t; + uint16 address = (uint16) Address & 0xFFFF; + + // line counter + line++; + + // status check + if (address == 0x01) + t = 0xFF; + // read directly from s-ram + else + t = Memory.SRAM[address]; + + // debug + // if(address<0x150) + // printf( "ST011 R: %06X %02X\n", Address, t); + + return t; } void S9xSetST011(uint32 Address, uint8 Byte) { - uint16 address = (uint16) Address & 0xFFFF; - static bool reset = false; - - // debug - line++; - - if(!reset) - { - // bootup values - ST011.waiting4command = true; - reset = true; - } - - // debug -// if(address<0x150) -// printf( "ST011 W: %06X %02X\n", Address, Byte ); - - Memory.SRAM[address]=Byte; - - // op commands/data goes through this address - if(address==0x00) - { - // check for new commands - if (ST011.waiting4command) - { - ST011.waiting4command = false; - ST011.command = Byte; - ST011.in_index = 0; - ST011.out_index = 0; - switch(ST011.command) - { - case 0x01: ST011.in_count = 12*10+8; break; - case 0x02: ST011.in_count = 4; break; - case 0x04: ST011.in_count = 0; break; - case 0x05: ST011.in_count = 0; break; - case 0x06: ST011.in_count = 0; break; - case 0x07: ST011.in_count = 0; break; - case 0x0E: ST011.in_count = 0; break; - default: ST011.waiting4command=true; break; - } - } - else - { - ST011.parameters [ST011.in_index] = Byte; - ST011.in_index++; - } - } - - if (ST011.in_count==ST011.in_index) - { - // Actually execute the command - ST011.waiting4command = true; - ST011.out_index = 0; - switch (ST011.command) - { - // unknown: download playboard - case 0x01: - { - // 9x9 board data: top to bottom, left to right - // Values represent piece types and ownership + uint16 address = (uint16) Address & 0xFFFF; + static bool reset = false; + + // debug + line++; + + if (!reset) + { + // bootup values + ST011.waiting4command = true; + reset = true; + } + + // debug + // if(address<0x150) + // printf( "ST011 W: %06X %02X\n", Address, Byte ); + + Memory.SRAM[address] = Byte; + + // op commands/data goes through this address + if (address == 0x00) + { + // check for new commands + if (ST011.waiting4command) + { + ST011.waiting4command = false; + ST011.command = Byte; + ST011.in_index = 0; + ST011.out_index = 0; + switch (ST011.command) + { + case 0x01: + ST011.in_count = 12 * 10 + 8; + break; + case 0x02: + ST011.in_count = 4; + break; + case 0x04: + ST011.in_count = 0; + break; + case 0x05: + ST011.in_count = 0; + break; + case 0x06: + ST011.in_count = 0; + break; + case 0x07: + ST011.in_count = 0; + break; + case 0x0E: + ST011.in_count = 0; + break; + default: + ST011.waiting4command = true; + break; + } + } + else + { + ST011.parameters [ST011.in_index] = Byte; + ST011.in_index++; + } + } + + if (ST011.in_count == ST011.in_index) + { + // Actually execute the command + ST011.waiting4command = true; + ST011.out_index = 0; + switch (ST011.command) + { + // unknown: download playboard + case 0x01: + { + // 9x9 board data: top to bottom, left to right + // Values represent piece types and ownership int lcv; - for(lcv=0; lcv<9; lcv++ ) - memcpy( board[lcv], ST011.parameters+lcv*10, 9*1 ); - } - break; - - // unknown - case 0x02: break; - - // unknown - case 0x04: - { - // outputs - Memory.SRAM[0x12C] = 0x00; - //Memory.SRAM[0x12D] = 0x00; - Memory.SRAM[0x12E] = 0x00; - } - break; - - // unknown - case 0x05: - { - // outputs - Memory.SRAM[0x12C] = 0x00; - //Memory.SRAM[0x12D] = 0x00; - Memory.SRAM[0x12E] = 0x00; - } - break; - - // unknown - case 0x06: break; - case 0x07: break; - - // unknown - case 0x0E: - { - // outputs - Memory.SRAM[0x12C] = 0x00; - Memory.SRAM[0x12D] = 0x00; - } - break; - } - } + for (lcv = 0; lcv < 9; lcv++) + memcpy(board[lcv], ST011.parameters + lcv * 10, 9 * 1); + } + break; + + // unknown + case 0x02: + break; + + // unknown + case 0x04: + { + // outputs + Memory.SRAM[0x12C] = 0x00; + //Memory.SRAM[0x12D] = 0x00; + Memory.SRAM[0x12E] = 0x00; + } + break; + + // unknown + case 0x05: + { + // outputs + Memory.SRAM[0x12C] = 0x00; + //Memory.SRAM[0x12D] = 0x00; + Memory.SRAM[0x12E] = 0x00; + } + break; + + // unknown + case 0x06: + break; + case 0x07: + break; + + // unknown + case 0x0E: + { + // outputs + Memory.SRAM[0x12C] = 0x00; + Memory.SRAM[0x12D] = 0x00; + } + break; + } + } } diff --git a/source/seta018.c b/source/seta018.c index 75b02b2..33a1bb1 100644 --- a/source/seta018.c +++ b/source/seta018.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -91,162 +91,168 @@ ST018_Regs ST018; -static int line; // line counter +static int line; // line counter uint8 S9xGetST018(uint32 Address) { - uint8 t = 0; // Initialise to some value for the compiler - uint16 address = (uint16) Address & 0xFFFF; - - line++; - - // these roles may be flipped - // op output - if (address == 0x3804) - { - if (ST018.out_count) - { - t = (uint8) ST018.output [ST018.out_index]; - ST018.out_index++; - if (ST018.out_count==ST018.out_index) - ST018.out_count=0; - } - else - t = 0x81; - } - // status register - else if (address == 0x3800) - t = ST018.status; - - printf( "ST018 R: %06X %02X\n", Address, t); - - return t; + uint8 t = 0; // Initialise to some value for the compiler + uint16 address = (uint16) Address & 0xFFFF; + + line++; + + // these roles may be flipped + // op output + if (address == 0x3804) + { + if (ST018.out_count) + { + t = (uint8) ST018.output [ST018.out_index]; + ST018.out_index++; + if (ST018.out_count == ST018.out_index) + ST018.out_count = 0; + } + else + t = 0x81; + } + // status register + else if (address == 0x3800) + t = ST018.status; + + printf("ST018 R: %06X %02X\n", Address, t); + + return t; } void S9xSetST018(uint8 Byte, uint32 Address) { - uint16 address = (uint16) Address&0xFFFF; - static bool reset = false; - - printf( "ST018 W: %06X %02X\n", Address, Byte ); - - line++; - - if (!reset) - { - // bootup values - ST018.waiting4command = true; - ST018.part_command = 0; - reset = true; - } - - Memory.SRAM[address]=Byte; - - // default status for now - ST018.status = 0x00; - - // op data goes through this address - if (address==0x3804) - { - // check for new commands: 3 bytes length - if(ST018.waiting4command && ST018.part_command==2) - { - ST018.waiting4command = false; - ST018.command <<= 8; - ST018.command |= Byte; - ST018.in_index = 0; - ST018.out_index = 0; - ST018.part_command = 0; // 3-byte commands - ST018.pass = 0; // data streams into the chip - switch(ST018.command & 0xFFFFFF) - { - case 0x0100: ST018.in_count = 0; break; - case 0xFF00: ST018.in_count = 0; break; - default: ST018.waiting4command = true; break; - } - } - else if(ST018.waiting4command) - { - // 3-byte commands - ST018.part_command++; - ST018.command <<= 8; - ST018.command |= Byte; - } - } - // extra parameters - else if (address==0x3802) - { - ST018.parameters[ST018.in_index] = Byte; - ST018.in_index++; - } - - if (ST018.in_count==ST018.in_index) - { - // Actually execute the command - ST018.waiting4command = true; - ST018.in_index = 0; - ST018.out_index = 0; - switch (ST018.command) - { - // hardware check? - case 0x0100: - ST018.waiting4command = false; - ST018.pass++; - if (ST018.pass==1) - { - ST018.in_count = 1; - ST018.out_count = 2; - - // Overload's research - ST018.output[0x00] = 0x81; - ST018.output[0x01] = 0x81; - } - else - { - //ST018.in_count = 1; - ST018.out_count = 3; - - // no reason to change this - //ST018.output[0x00] = 0x81; - //ST018.output[0x01] = 0x81; - ST018.output[0x02] = 0x81; - - // done processing requests - if (ST018.pass==3) - ST018.waiting4command = true; - } - break; - - // unknown: feels like a security detection - // format identical to 0x0100 - case 0xFF00: - ST018.waiting4command = false; - ST018.pass++; - if (ST018.pass==1) - { - ST018.in_count = 1; - ST018.out_count = 2; - - // Overload's research - ST018.output[0x00] = 0x81; - ST018.output[0x01] = 0x81; - } - else - { - //ST018.in_count = 1; - ST018.out_count = 3; - - // no reason to change this - //ST018.output[0x00] = 0x81; - //ST018.output[0x01] = 0x81; - ST018.output[0x02] = 0x81; - - // done processing requests - if (ST018.pass==3) - ST018.waiting4command = true; - } - break; - } - } + uint16 address = (uint16) Address & 0xFFFF; + static bool reset = false; + + printf("ST018 W: %06X %02X\n", Address, Byte); + + line++; + + if (!reset) + { + // bootup values + ST018.waiting4command = true; + ST018.part_command = 0; + reset = true; + } + + Memory.SRAM[address] = Byte; + + // default status for now + ST018.status = 0x00; + + // op data goes through this address + if (address == 0x3804) + { + // check for new commands: 3 bytes length + if (ST018.waiting4command && ST018.part_command == 2) + { + ST018.waiting4command = false; + ST018.command <<= 8; + ST018.command |= Byte; + ST018.in_index = 0; + ST018.out_index = 0; + ST018.part_command = 0; // 3-byte commands + ST018.pass = 0; // data streams into the chip + switch (ST018.command & 0xFFFFFF) + { + case 0x0100: + ST018.in_count = 0; + break; + case 0xFF00: + ST018.in_count = 0; + break; + default: + ST018.waiting4command = true; + break; + } + } + else if (ST018.waiting4command) + { + // 3-byte commands + ST018.part_command++; + ST018.command <<= 8; + ST018.command |= Byte; + } + } + // extra parameters + else if (address == 0x3802) + { + ST018.parameters[ST018.in_index] = Byte; + ST018.in_index++; + } + + if (ST018.in_count == ST018.in_index) + { + // Actually execute the command + ST018.waiting4command = true; + ST018.in_index = 0; + ST018.out_index = 0; + switch (ST018.command) + { + // hardware check? + case 0x0100: + ST018.waiting4command = false; + ST018.pass++; + if (ST018.pass == 1) + { + ST018.in_count = 1; + ST018.out_count = 2; + + // Overload's research + ST018.output[0x00] = 0x81; + ST018.output[0x01] = 0x81; + } + else + { + //ST018.in_count = 1; + ST018.out_count = 3; + + // no reason to change this + //ST018.output[0x00] = 0x81; + //ST018.output[0x01] = 0x81; + ST018.output[0x02] = 0x81; + + // done processing requests + if (ST018.pass == 3) + ST018.waiting4command = true; + } + break; + + // unknown: feels like a security detection + // format identical to 0x0100 + case 0xFF00: + ST018.waiting4command = false; + ST018.pass++; + if (ST018.pass == 1) + { + ST018.in_count = 1; + ST018.out_count = 2; + + // Overload's research + ST018.output[0x00] = 0x81; + ST018.output[0x01] = 0x81; + } + else + { + //ST018.in_count = 1; + ST018.out_count = 3; + + // no reason to change this + //ST018.output[0x00] = 0x81; + //ST018.output[0x01] = 0x81; + ST018.output[0x02] = 0x81; + + // done processing requests + if (ST018.pass == 3) + ST018.waiting4command = true; + } + break; + } + } } diff --git a/source/snaporig.c b/source/snaporig.c index 8e97028..c68f677 100644 --- a/source/snaporig.c +++ b/source/snaporig.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -119,351 +119,356 @@ SOrigSoundData OrigSoundData; struct SOrigAPURegisters OrigAPURegisters; char ROMFilename [1025]; -static int ReadOrigSnapshot (STREAM); +static int ReadOrigSnapshot(STREAM); -bool8 S9xLoadOrigSnapshot (const char *filename) +bool8 S9xLoadOrigSnapshot(const char* filename) { - FILE* fp; + FILE* fp; - fp = fopen(filename, "r"); - if(NULL == fp) - return (FALSE); + fp = fopen(filename, "r"); + if (NULL == fp) + return (FALSE); - int result; - if ((result = ReadOrigSnapshot (fp)) != SUCCESS) - { - fclose(fp); - return (FALSE); - } + int result; + if ((result = ReadOrigSnapshot(fp)) != SUCCESS) + { + fclose(fp); + return (FALSE); + } - fclose(fp); - return (TRUE); + fclose(fp); + return (TRUE); } -static int ReadBlock (const char *key, void *block, int max_len, STREAM snap) +static int ReadBlock(const char* key, void* block, int max_len, STREAM snap) { - char buffer [20]; - int len = 0; - int rem = 0; - - if (READ_STREAM (buffer, 11, snap) != 11 || - strncmp (buffer, key, 4) != 0 || - (len = atoi (&buffer [4])) == 0) - return (WRONG_FORMAT); - - if (len > max_len) - { - rem = len - max_len; - len = max_len; - } - if (READ_STREAM (block, len, snap) != len) - return (WRONG_FORMAT); - - if (rem) - { - char *junk = (char*)malloc(rem); - READ_STREAM (junk, rem, snap); - free(junk); - } - - return (SUCCESS); + char buffer [20]; + int len = 0; + int rem = 0; + + if (READ_STREAM(buffer, 11, snap) != 11 || + strncmp(buffer, key, 4) != 0 || + (len = atoi(&buffer [4])) == 0) + return (WRONG_FORMAT); + + if (len > max_len) + { + rem = len - max_len; + len = max_len; + } + if (READ_STREAM(block, len, snap) != len) + return (WRONG_FORMAT); + + if (rem) + { + char* junk = (char*)malloc(rem); + READ_STREAM(junk, rem, snap); + free(junk); + } + + return (SUCCESS); } -static int ReadOrigSnapshot (STREAM snap) +static int ReadOrigSnapshot(STREAM snap) { - char buffer [_MAX_PATH]; - char rom_filename [_MAX_PATH]; - int result; - int i; - int j; - - int version; - int len = strlen (ORIG_SNAPSHOT_MAGIC) + 1 + 4 + 1; - if (READ_STREAM (buffer, len, snap) != len) - return (WRONG_FORMAT); - if (strncmp (buffer, ORIG_SNAPSHOT_MAGIC, strlen (ORIG_SNAPSHOT_MAGIC)) != 0) - return (WRONG_FORMAT); - if ((version = atoi (&buffer [strlen (SNAPSHOT_MAGIC) + 1])) > ORIG_SNAPSHOT_VERSION) - return (WRONG_VERSION); - - if ((result = ReadBlock ("NAM:", rom_filename, _MAX_PATH, snap)) != SUCCESS) - return (result); - - if ((result = ReadBlock ("HiR:", buffer, 0x41, snap)) != SUCCESS) - return (result); - - if (strcasecmp (rom_filename, Memory.ROMFilename) != 0 && - strcasecmp (S9xBasename (rom_filename), S9xBasename (Memory.ROMFilename)) != 0) - { - S9xMessage (S9X_WARNING, S9X_FREEZE_ROM_NAME, - "Current loaded ROM image doesn't match that required by freeze-game file."); - } - - S9xReset (); - S9xSetSoundMute (TRUE); - if ((result = ReadBlock ("CPU:", &OrigCPU, sizeof (OrigCPU), snap)) != SUCCESS) - return (result); - OrigCPU.FastROMSpeed = OrigCPU.FastROMSpeed_old; - FixROMSpeed (); - if (version == 3) - { - OrigCPU.Cycles = OrigCPU.Cycles_old; - OrigCPU.NextEvent = OrigCPU.NextEvent_old; - OrigCPU.V_Counter = OrigCPU.V_Counter_old; - OrigCPU.MemSpeed = OrigCPU.MemSpeed_old; - OrigCPU.MemSpeedx2 = OrigCPU.MemSpeedx2_old; - OrigCPU.FastROMSpeed = OrigCPU.FastROMSpeed_old; - } - CPU.Flags = OrigCPU.Flags; - CPU.BranchSkip = OrigCPU.BranchSkip; - CPU.NMIActive = OrigCPU.NMIActive; - CPU.IRQActive = OrigCPU.IRQActive; - CPU.WaitingForInterrupt = OrigCPU.WaitingForInterrupt; - CPU.WhichEvent = OrigCPU.WhichEvent; - CPU.Cycles = OrigCPU.Cycles; - CPU.NextEvent = OrigCPU.NextEvent; - CPU.V_Counter = OrigCPU.V_Counter; - CPU.MemSpeed = OrigCPU.MemSpeed; - CPU.MemSpeedx2 = OrigCPU.MemSpeedx2; - CPU.FastROMSpeed = OrigCPU.FastROMSpeed; - - if ((result = ReadBlock ("REG:", &OrigRegisters, sizeof (OrigRegisters), snap)) != SUCCESS) - return (result); - - ICPU.Registers = *(SRegisters *) &OrigRegisters; - - if ((result = ReadBlock ("PPU:", &OrigPPU, sizeof (OrigPPU), snap)) != SUCCESS) - return (result); - - if (version == 2) - { - OrigPPU.OBJNameSelect = OrigPPU.OBJNameSelect_old << 13; - OrigPPU.OBJNameBase <<= 1; - OrigPPU.OBJNameSelect <<= 13; - } - PPU.BGMode = OrigPPU.BGMode; - PPU.BG3Priority = OrigPPU.BG3Priority; - PPU.Brightness = OrigPPU.Brightness; - - PPU.VMA.High = OrigPPU.VMA.High; - PPU.VMA.Increment = OrigPPU.VMA.Increment; - PPU.VMA.Address = OrigPPU.VMA.Address; - PPU.VMA.Mask1 = OrigPPU.VMA.Mask1; - PPU.VMA.FullGraphicCount = OrigPPU.VMA.FullGraphicCount; - PPU.VMA.Shift = OrigPPU.VMA.Shift; - - for (i = 0; i < 4; i++) - { - PPU.BG[i].SCBase = OrigPPU.BG[i].SCBase; - PPU.BG[i].VOffset = OrigPPU.BG[i].VOffset; - PPU.BG[i].HOffset = OrigPPU.BG[i].HOffset; - PPU.BG[i].BGSize = OrigPPU.BG[i].BGSize; - PPU.BG[i].NameBase = OrigPPU.BG[i].NameBase; - PPU.BG[i].SCSize = OrigPPU.BG[i].SCSize; - } - - PPU.CGFLIP = OrigPPU.CGFLIP; - for (i = 0; i < 256; i++) - PPU.CGDATA [i] = OrigPPU.CGDATA [i]; - PPU.FirstSprite = OrigPPU.FirstSprite; - for (i = 0; i < 128; i++) - { - PPU.OBJ[i].HPos = OrigPPU.OBJ [i].HPos; - PPU.OBJ[i].VPos = OrigPPU.OBJ [i].VPos; - PPU.OBJ[i].Name = OrigPPU.OBJ [i].Name; - PPU.OBJ[i].VFlip = OrigPPU.OBJ [i].VFlip; - PPU.OBJ[i].HFlip = OrigPPU.OBJ [i].HFlip; - PPU.OBJ[i].Priority = OrigPPU.OBJ [i].Priority; - PPU.OBJ[i].Palette = OrigPPU.OBJ [i].Palette; - PPU.OBJ[i].Size = OrigPPU.OBJ [i].Size; - } - PPU.OAMPriorityRotation = OrigPPU.OAMPriorityRotation; - PPU.OAMAddr = OrigPPU.OAMAddr; - - PPU.OAMFlip = OrigPPU.OAMFlip; - PPU.OAMTileAddress = OrigPPU.OAMTileAddress; - PPU.IRQVBeamPos = OrigPPU.IRQVBeamPos; - PPU.IRQHBeamPos = OrigPPU.IRQHBeamPos; - PPU.VBeamPosLatched = OrigPPU.VBeamPosLatched; - PPU.HBeamPosLatched = OrigPPU.HBeamPosLatched; - - PPU.HBeamFlip = OrigPPU.HBeamFlip; - PPU.VBeamFlip = OrigPPU.VBeamFlip; - PPU.HVBeamCounterLatched = OrigPPU.HVBeamCounterLatched; - - PPU.MatrixA = OrigPPU.MatrixA; - PPU.MatrixB = OrigPPU.MatrixB; - PPU.MatrixC = OrigPPU.MatrixC; - PPU.MatrixD = OrigPPU.MatrixD; - PPU.CentreX = OrigPPU.CentreX; - PPU.CentreY = OrigPPU.CentreY; - PPU.Joypad1ButtonReadPos = OrigPPU.Joypad1ButtonReadPos; - PPU.Joypad2ButtonReadPos = OrigPPU.Joypad2ButtonReadPos; - PPU.Joypad3ButtonReadPos = OrigPPU.Joypad3ButtonReadPos; - - PPU.CGADD = OrigPPU.CGADD; - PPU.FixedColourRed = OrigPPU.FixedColourRed; - PPU.FixedColourGreen = OrigPPU.FixedColourGreen; - PPU.FixedColourBlue = OrigPPU.FixedColourBlue; - PPU.SavedOAMAddr = OrigPPU.SavedOAMAddr; - PPU.ScreenHeight = OrigPPU.ScreenHeight; - PPU.WRAM = OrigPPU.WRAM; - PPU.ForcedBlanking = OrigPPU.ForcedBlanking; - PPU.OBJNameSelect = OrigPPU.OBJNameSelect; - PPU.OBJSizeSelect = OrigPPU.OBJSizeSelect; - PPU.OBJNameBase = OrigPPU.OBJNameBase; - PPU.OAMReadFlip = OrigPPU.OAMReadFlip; - // memmove converted: Different data segments [Neb] - memcpy (PPU.OAMData, OrigPPU.OAMData, sizeof (PPU.OAMData)); - PPU.VTimerEnabled = OrigPPU.VTimerEnabled; - PPU.HTimerEnabled = OrigPPU.HTimerEnabled; - PPU.HTimerPosition = OrigPPU.HTimerPosition; - PPU.Mosaic = OrigPPU.Mosaic; - // memmove converted: Different data segments [Neb] - memcpy (PPU.BGMosaic, OrigPPU.BGMosaic, sizeof (PPU.BGMosaic)); - PPU.Mode7HFlip = OrigPPU.Mode7HFlip; - PPU.Mode7VFlip = OrigPPU.Mode7VFlip; - PPU.Mode7Repeat = OrigPPU.Mode7Repeat; - PPU.Window1Left = OrigPPU.Window1Left; - PPU.Window1Right = OrigPPU.Window1Right; - PPU.Window2Left = OrigPPU.Window2Left; - PPU.Window2Right = OrigPPU.Window2Right; - for (i = 0; i < 6; i++) - { - PPU.ClipWindowOverlapLogic [i] = OrigPPU.ClipWindowOverlapLogic [i]; - PPU.ClipWindow1Enable [i] = OrigPPU.ClipWindow1Enable [i]; - PPU.ClipWindow2Enable [i] = OrigPPU.ClipWindow2Enable [i]; - PPU.ClipWindow1Inside [i] = OrigPPU.ClipWindow1Inside [i]; - PPU.ClipWindow2Inside [i] = OrigPPU.ClipWindow2Inside [i]; - } - PPU.CGFLIPRead = OrigPPU.CGFLIPRead; - PPU.Need16x8Mulitply = OrigPPU.Need16x8Mulitply; - - IPPU.ColorsChanged = TRUE; - IPPU.OBJChanged = TRUE; - S9xFixColourBrightness (); - IPPU.RenderThisFrame = FALSE; - - if ((result = ReadBlock ("DMA:", OrigDMA, sizeof (OrigDMA), snap)) != SUCCESS) - return (result); - - for (i = 0; i < 8; i++) - { - DMA[i].TransferDirection = OrigDMA[i].TransferDirection; - DMA[i].AAddressFixed = OrigDMA[i].AAddressFixed; - DMA[i].AAddressDecrement = OrigDMA[i].AAddressDecrement; - DMA[i].TransferMode = OrigDMA[i].TransferMode; - DMA[i].ABank = OrigDMA[i].ABank; - DMA[i].AAddress = OrigDMA[i].AAddress; - DMA[i].Address = OrigDMA[i].Address; - DMA[i].BAddress = OrigDMA[i].BAddress; - DMA[i].TransferBytes = OrigDMA[i].TransferBytes; - DMA[i].HDMAIndirectAddressing = OrigDMA[i].HDMAIndirectAddressing; - DMA[i].IndirectAddress = OrigDMA[i].IndirectAddress; - DMA[i].IndirectBank = OrigDMA[i].IndirectBank; - DMA[i].Repeat = OrigDMA[i].Repeat; - DMA[i].LineCount = OrigDMA[i].LineCount; - DMA[i].FirstLine = OrigDMA[i].FirstLine; - } - - if ((result = ReadBlock ("VRA:", Memory.VRAM, 0x10000, snap)) != SUCCESS) - return (result); - if ((result = ReadBlock ("RAM:", Memory.RAM, 0x20000, snap)) != SUCCESS) - return (result); - if ((result = ReadBlock ("SRA:", Memory.SRAM, 0x10000, snap)) != SUCCESS) - return (result); - if ((result = ReadBlock ("FIL:", Memory.FillRAM, 0x8000, snap)) != SUCCESS) - return (result); - if (ReadBlock ("APU:", &OrigAPU, sizeof (OrigAPU), snap) == SUCCESS) - { - APU = *(SAPU *) &OrigAPU; - - if ((result = ReadBlock ("ARE:", &OrigAPURegisters, - sizeof (OrigAPURegisters), snap)) != SUCCESS) - return (result); - IAPU.Registers = *(SAPURegisters *) &OrigAPURegisters; - if ((result = ReadBlock ("ARA:", IAPU.RAM, 0x10000, snap)) != SUCCESS) - return (result); - if ((result = ReadBlock ("SOU:", &OrigSoundData, - sizeof (SOrigSoundData), snap)) != SUCCESS) - return (result); - - - SoundData.master_volume [0] = OrigSoundData.master_volume_left; - SoundData.master_volume [1] = OrigSoundData.master_volume_right; - SoundData.echo_volume [0] = OrigSoundData.echo_volume_left; - SoundData.echo_volume [1] = OrigSoundData.echo_volume_right; - - SoundData.echo_enable = OrigSoundData.echo_enable; - SoundData.echo_feedback = OrigSoundData.echo_feedback; - SoundData.echo_ptr = OrigSoundData.echo_ptr; - SoundData.echo_buffer_size = OrigSoundData.echo_buffer_size; - SoundData.echo_write_enabled = OrigSoundData.echo_write_enabled; - SoundData.echo_channel_enable = OrigSoundData.echo_channel_enable; - SoundData.pitch_mod = OrigSoundData.pitch_mod; - - for (i = 0; i < 3; i++) - SoundData.dummy [i] = OrigSoundData.dummy [i]; - for (i = 0; i < NUM_CHANNELS; i++) - { - SoundData.channels [i].state = OrigSoundData.channels [i].state; - SoundData.channels [i].type = OrigSoundData.channels [i].type; - SoundData.channels [i].volume_left = OrigSoundData.channels [i].volume_left; - SoundData.channels [i].volume_right = OrigSoundData.channels [i].volume_right; - SoundData.channels [i].hertz = OrigSoundData.channels [i].frequency; - SoundData.channels [i].count = OrigSoundData.channels [i].count; - SoundData.channels [i].loop = OrigSoundData.channels [i].loop; - SoundData.channels [i].envx = OrigSoundData.channels [i].envx; - SoundData.channels [i].left_vol_level = OrigSoundData.channels [i].left_vol_level; - SoundData.channels [i].right_vol_level = OrigSoundData.channels [i].right_vol_level; - SoundData.channels [i].envx_target = OrigSoundData.channels [i].envx_target; - SoundData.channels [i].env_error = OrigSoundData.channels [i].env_error; - SoundData.channels [i].erate = OrigSoundData.channels [i].erate; - SoundData.channels [i].direction = OrigSoundData.channels [i].direction; - SoundData.channels [i].attack_rate = OrigSoundData.channels [i].attack_rate; - SoundData.channels [i].decay_rate = OrigSoundData.channels [i].decay_rate; - SoundData.channels [i].sustain_rate = OrigSoundData.channels [i].sustain_rate; - SoundData.channels [i].release_rate = OrigSoundData.channels [i].release_rate; - SoundData.channels [i].sustain_level = OrigSoundData.channels [i].sustain_level; - SoundData.channels [i].sample = OrigSoundData.channels [i].sample; - for (j = 0; j < 16; j++) - SoundData.channels [i].decoded [j] = OrigSoundData.channels [i].decoded [j]; - - for (j = 0; j < 2; j++) - SoundData.channels [i].previous [j] = OrigSoundData.channels [i].previous [j]; - - SoundData.channels [i].sample_number = OrigSoundData.channels [i].sample_number; - SoundData.channels [i].last_block = OrigSoundData.channels [i].last_block; - SoundData.channels [i].needs_decode = OrigSoundData.channels [i].needs_decode; - SoundData.channels [i].block_pointer = OrigSoundData.channels [i].block_pointer; - SoundData.channels [i].sample_pointer = OrigSoundData.channels [i].sample_pointer; - SoundData.channels [i].mode = OrigSoundData.channels [i].mode; - } - - S9xSetSoundMute (FALSE); - IAPU.PC = IAPU.RAM + IAPU.Registers.PC; - S9xAPUUnpackStatus (); - if (APUCheckDirectPage ()) - IAPU.DirectPage = IAPU.RAM + 0x100; - else - IAPU.DirectPage = IAPU.RAM; - Settings.APUEnabled = TRUE; - IAPU.APUExecuting = TRUE; - } - else - { - Settings.APUEnabled = FALSE; - IAPU.APUExecuting = FALSE; - S9xSetSoundMute (TRUE); - } - S9xFixSoundAfterSnapshotLoad (); - ICPU.ShiftedPB = ICPU.Registers.PB << 16; - ICPU.ShiftedDB = ICPU.Registers.DB << 16; - S9xSetPCBase (ICPU.ShiftedPB + ICPU.Registers.PC); - S9xUnpackStatus (); - S9xFixCycles (); - S9xReschedule (); - - return (SUCCESS); + char buffer [_MAX_PATH]; + char rom_filename [_MAX_PATH]; + int result; + int i; + int j; + + int version; + int len = strlen(ORIG_SNAPSHOT_MAGIC) + 1 + 4 + 1; + if (READ_STREAM(buffer, len, snap) != len) + return (WRONG_FORMAT); + if (strncmp(buffer, ORIG_SNAPSHOT_MAGIC, strlen(ORIG_SNAPSHOT_MAGIC)) != 0) + return (WRONG_FORMAT); + if ((version = atoi(&buffer [strlen(SNAPSHOT_MAGIC) + 1])) > + ORIG_SNAPSHOT_VERSION) + return (WRONG_VERSION); + + if ((result = ReadBlock("NAM:", rom_filename, _MAX_PATH, snap)) != SUCCESS) + return (result); + + if ((result = ReadBlock("HiR:", buffer, 0x41, snap)) != SUCCESS) + return (result); + + if (strcasecmp(rom_filename, Memory.ROMFilename) != 0 && + strcasecmp(S9xBasename(rom_filename), S9xBasename(Memory.ROMFilename)) != 0) + { + S9xMessage(S9X_WARNING, S9X_FREEZE_ROM_NAME, + "Current loaded ROM image doesn't match that required by freeze-game file."); + } + + S9xReset(); + S9xSetSoundMute(TRUE); + if ((result = ReadBlock("CPU:", &OrigCPU, sizeof(OrigCPU), snap)) != SUCCESS) + return (result); + OrigCPU.FastROMSpeed = OrigCPU.FastROMSpeed_old; + FixROMSpeed(); + if (version == 3) + { + OrigCPU.Cycles = OrigCPU.Cycles_old; + OrigCPU.NextEvent = OrigCPU.NextEvent_old; + OrigCPU.V_Counter = OrigCPU.V_Counter_old; + OrigCPU.MemSpeed = OrigCPU.MemSpeed_old; + OrigCPU.MemSpeedx2 = OrigCPU.MemSpeedx2_old; + OrigCPU.FastROMSpeed = OrigCPU.FastROMSpeed_old; + } + CPU.Flags = OrigCPU.Flags; + CPU.BranchSkip = OrigCPU.BranchSkip; + CPU.NMIActive = OrigCPU.NMIActive; + CPU.IRQActive = OrigCPU.IRQActive; + CPU.WaitingForInterrupt = OrigCPU.WaitingForInterrupt; + CPU.WhichEvent = OrigCPU.WhichEvent; + CPU.Cycles = OrigCPU.Cycles; + CPU.NextEvent = OrigCPU.NextEvent; + CPU.V_Counter = OrigCPU.V_Counter; + CPU.MemSpeed = OrigCPU.MemSpeed; + CPU.MemSpeedx2 = OrigCPU.MemSpeedx2; + CPU.FastROMSpeed = OrigCPU.FastROMSpeed; + + if ((result = ReadBlock("REG:", &OrigRegisters, sizeof(OrigRegisters), + snap)) != SUCCESS) + return (result); + + ICPU.Registers = *(SRegisters*) &OrigRegisters; + + if ((result = ReadBlock("PPU:", &OrigPPU, sizeof(OrigPPU), snap)) != SUCCESS) + return (result); + + if (version == 2) + { + OrigPPU.OBJNameSelect = OrigPPU.OBJNameSelect_old << 13; + OrigPPU.OBJNameBase <<= 1; + OrigPPU.OBJNameSelect <<= 13; + } + PPU.BGMode = OrigPPU.BGMode; + PPU.BG3Priority = OrigPPU.BG3Priority; + PPU.Brightness = OrigPPU.Brightness; + + PPU.VMA.High = OrigPPU.VMA.High; + PPU.VMA.Increment = OrigPPU.VMA.Increment; + PPU.VMA.Address = OrigPPU.VMA.Address; + PPU.VMA.Mask1 = OrigPPU.VMA.Mask1; + PPU.VMA.FullGraphicCount = OrigPPU.VMA.FullGraphicCount; + PPU.VMA.Shift = OrigPPU.VMA.Shift; + + for (i = 0; i < 4; i++) + { + PPU.BG[i].SCBase = OrigPPU.BG[i].SCBase; + PPU.BG[i].VOffset = OrigPPU.BG[i].VOffset; + PPU.BG[i].HOffset = OrigPPU.BG[i].HOffset; + PPU.BG[i].BGSize = OrigPPU.BG[i].BGSize; + PPU.BG[i].NameBase = OrigPPU.BG[i].NameBase; + PPU.BG[i].SCSize = OrigPPU.BG[i].SCSize; + } + + PPU.CGFLIP = OrigPPU.CGFLIP; + for (i = 0; i < 256; i++) + PPU.CGDATA [i] = OrigPPU.CGDATA [i]; + PPU.FirstSprite = OrigPPU.FirstSprite; + for (i = 0; i < 128; i++) + { + PPU.OBJ[i].HPos = OrigPPU.OBJ [i].HPos; + PPU.OBJ[i].VPos = OrigPPU.OBJ [i].VPos; + PPU.OBJ[i].Name = OrigPPU.OBJ [i].Name; + PPU.OBJ[i].VFlip = OrigPPU.OBJ [i].VFlip; + PPU.OBJ[i].HFlip = OrigPPU.OBJ [i].HFlip; + PPU.OBJ[i].Priority = OrigPPU.OBJ [i].Priority; + PPU.OBJ[i].Palette = OrigPPU.OBJ [i].Palette; + PPU.OBJ[i].Size = OrigPPU.OBJ [i].Size; + } + PPU.OAMPriorityRotation = OrigPPU.OAMPriorityRotation; + PPU.OAMAddr = OrigPPU.OAMAddr; + + PPU.OAMFlip = OrigPPU.OAMFlip; + PPU.OAMTileAddress = OrigPPU.OAMTileAddress; + PPU.IRQVBeamPos = OrigPPU.IRQVBeamPos; + PPU.IRQHBeamPos = OrigPPU.IRQHBeamPos; + PPU.VBeamPosLatched = OrigPPU.VBeamPosLatched; + PPU.HBeamPosLatched = OrigPPU.HBeamPosLatched; + + PPU.HBeamFlip = OrigPPU.HBeamFlip; + PPU.VBeamFlip = OrigPPU.VBeamFlip; + PPU.HVBeamCounterLatched = OrigPPU.HVBeamCounterLatched; + + PPU.MatrixA = OrigPPU.MatrixA; + PPU.MatrixB = OrigPPU.MatrixB; + PPU.MatrixC = OrigPPU.MatrixC; + PPU.MatrixD = OrigPPU.MatrixD; + PPU.CentreX = OrigPPU.CentreX; + PPU.CentreY = OrigPPU.CentreY; + PPU.Joypad1ButtonReadPos = OrigPPU.Joypad1ButtonReadPos; + PPU.Joypad2ButtonReadPos = OrigPPU.Joypad2ButtonReadPos; + PPU.Joypad3ButtonReadPos = OrigPPU.Joypad3ButtonReadPos; + + PPU.CGADD = OrigPPU.CGADD; + PPU.FixedColourRed = OrigPPU.FixedColourRed; + PPU.FixedColourGreen = OrigPPU.FixedColourGreen; + PPU.FixedColourBlue = OrigPPU.FixedColourBlue; + PPU.SavedOAMAddr = OrigPPU.SavedOAMAddr; + PPU.ScreenHeight = OrigPPU.ScreenHeight; + PPU.WRAM = OrigPPU.WRAM; + PPU.ForcedBlanking = OrigPPU.ForcedBlanking; + PPU.OBJNameSelect = OrigPPU.OBJNameSelect; + PPU.OBJSizeSelect = OrigPPU.OBJSizeSelect; + PPU.OBJNameBase = OrigPPU.OBJNameBase; + PPU.OAMReadFlip = OrigPPU.OAMReadFlip; + // memmove converted: Different data segments [Neb] + memcpy(PPU.OAMData, OrigPPU.OAMData, sizeof(PPU.OAMData)); + PPU.VTimerEnabled = OrigPPU.VTimerEnabled; + PPU.HTimerEnabled = OrigPPU.HTimerEnabled; + PPU.HTimerPosition = OrigPPU.HTimerPosition; + PPU.Mosaic = OrigPPU.Mosaic; + // memmove converted: Different data segments [Neb] + memcpy(PPU.BGMosaic, OrigPPU.BGMosaic, sizeof(PPU.BGMosaic)); + PPU.Mode7HFlip = OrigPPU.Mode7HFlip; + PPU.Mode7VFlip = OrigPPU.Mode7VFlip; + PPU.Mode7Repeat = OrigPPU.Mode7Repeat; + PPU.Window1Left = OrigPPU.Window1Left; + PPU.Window1Right = OrigPPU.Window1Right; + PPU.Window2Left = OrigPPU.Window2Left; + PPU.Window2Right = OrigPPU.Window2Right; + for (i = 0; i < 6; i++) + { + PPU.ClipWindowOverlapLogic [i] = OrigPPU.ClipWindowOverlapLogic [i]; + PPU.ClipWindow1Enable [i] = OrigPPU.ClipWindow1Enable [i]; + PPU.ClipWindow2Enable [i] = OrigPPU.ClipWindow2Enable [i]; + PPU.ClipWindow1Inside [i] = OrigPPU.ClipWindow1Inside [i]; + PPU.ClipWindow2Inside [i] = OrigPPU.ClipWindow2Inside [i]; + } + PPU.CGFLIPRead = OrigPPU.CGFLIPRead; + PPU.Need16x8Mulitply = OrigPPU.Need16x8Mulitply; + + IPPU.ColorsChanged = TRUE; + IPPU.OBJChanged = TRUE; + S9xFixColourBrightness(); + IPPU.RenderThisFrame = FALSE; + + if ((result = ReadBlock("DMA:", OrigDMA, sizeof(OrigDMA), snap)) != SUCCESS) + return (result); + + for (i = 0; i < 8; i++) + { + DMA[i].TransferDirection = OrigDMA[i].TransferDirection; + DMA[i].AAddressFixed = OrigDMA[i].AAddressFixed; + DMA[i].AAddressDecrement = OrigDMA[i].AAddressDecrement; + DMA[i].TransferMode = OrigDMA[i].TransferMode; + DMA[i].ABank = OrigDMA[i].ABank; + DMA[i].AAddress = OrigDMA[i].AAddress; + DMA[i].Address = OrigDMA[i].Address; + DMA[i].BAddress = OrigDMA[i].BAddress; + DMA[i].TransferBytes = OrigDMA[i].TransferBytes; + DMA[i].HDMAIndirectAddressing = OrigDMA[i].HDMAIndirectAddressing; + DMA[i].IndirectAddress = OrigDMA[i].IndirectAddress; + DMA[i].IndirectBank = OrigDMA[i].IndirectBank; + DMA[i].Repeat = OrigDMA[i].Repeat; + DMA[i].LineCount = OrigDMA[i].LineCount; + DMA[i].FirstLine = OrigDMA[i].FirstLine; + } + + if ((result = ReadBlock("VRA:", Memory.VRAM, 0x10000, snap)) != SUCCESS) + return (result); + if ((result = ReadBlock("RAM:", Memory.RAM, 0x20000, snap)) != SUCCESS) + return (result); + if ((result = ReadBlock("SRA:", Memory.SRAM, 0x10000, snap)) != SUCCESS) + return (result); + if ((result = ReadBlock("FIL:", Memory.FillRAM, 0x8000, snap)) != SUCCESS) + return (result); + if (ReadBlock("APU:", &OrigAPU, sizeof(OrigAPU), snap) == SUCCESS) + { + APU = *(SAPU*) &OrigAPU; + + if ((result = ReadBlock("ARE:", &OrigAPURegisters, + sizeof(OrigAPURegisters), snap)) != SUCCESS) + return (result); + IAPU.Registers = *(SAPURegisters*) &OrigAPURegisters; + if ((result = ReadBlock("ARA:", IAPU.RAM, 0x10000, snap)) != SUCCESS) + return (result); + if ((result = ReadBlock("SOU:", &OrigSoundData, + sizeof(SOrigSoundData), snap)) != SUCCESS) + return (result); + + + SoundData.master_volume [0] = OrigSoundData.master_volume_left; + SoundData.master_volume [1] = OrigSoundData.master_volume_right; + SoundData.echo_volume [0] = OrigSoundData.echo_volume_left; + SoundData.echo_volume [1] = OrigSoundData.echo_volume_right; + + SoundData.echo_enable = OrigSoundData.echo_enable; + SoundData.echo_feedback = OrigSoundData.echo_feedback; + SoundData.echo_ptr = OrigSoundData.echo_ptr; + SoundData.echo_buffer_size = OrigSoundData.echo_buffer_size; + SoundData.echo_write_enabled = OrigSoundData.echo_write_enabled; + SoundData.echo_channel_enable = OrigSoundData.echo_channel_enable; + SoundData.pitch_mod = OrigSoundData.pitch_mod; + + for (i = 0; i < 3; i++) + SoundData.dummy [i] = OrigSoundData.dummy [i]; + for (i = 0; i < NUM_CHANNELS; i++) + { + SoundData.channels [i].state = OrigSoundData.channels [i].state; + SoundData.channels [i].type = OrigSoundData.channels [i].type; + SoundData.channels [i].volume_left = OrigSoundData.channels [i].volume_left; + SoundData.channels [i].volume_right = OrigSoundData.channels [i].volume_right; + SoundData.channels [i].hertz = OrigSoundData.channels [i].frequency; + SoundData.channels [i].count = OrigSoundData.channels [i].count; + SoundData.channels [i].loop = OrigSoundData.channels [i].loop; + SoundData.channels [i].envx = OrigSoundData.channels [i].envx; + SoundData.channels [i].left_vol_level = + OrigSoundData.channels [i].left_vol_level; + SoundData.channels [i].right_vol_level = + OrigSoundData.channels [i].right_vol_level; + SoundData.channels [i].envx_target = OrigSoundData.channels [i].envx_target; + SoundData.channels [i].env_error = OrigSoundData.channels [i].env_error; + SoundData.channels [i].erate = OrigSoundData.channels [i].erate; + SoundData.channels [i].direction = OrigSoundData.channels [i].direction; + SoundData.channels [i].attack_rate = OrigSoundData.channels [i].attack_rate; + SoundData.channels [i].decay_rate = OrigSoundData.channels [i].decay_rate; + SoundData.channels [i].sustain_rate = OrigSoundData.channels [i].sustain_rate; + SoundData.channels [i].release_rate = OrigSoundData.channels [i].release_rate; + SoundData.channels [i].sustain_level = OrigSoundData.channels [i].sustain_level; + SoundData.channels [i].sample = OrigSoundData.channels [i].sample; + for (j = 0; j < 16; j++) + SoundData.channels [i].decoded [j] = OrigSoundData.channels [i].decoded [j]; + + for (j = 0; j < 2; j++) + SoundData.channels [i].previous [j] = OrigSoundData.channels [i].previous [j]; + + SoundData.channels [i].sample_number = OrigSoundData.channels [i].sample_number; + SoundData.channels [i].last_block = OrigSoundData.channels [i].last_block; + SoundData.channels [i].needs_decode = OrigSoundData.channels [i].needs_decode; + SoundData.channels [i].block_pointer = OrigSoundData.channels [i].block_pointer; + SoundData.channels [i].sample_pointer = + OrigSoundData.channels [i].sample_pointer; + SoundData.channels [i].mode = OrigSoundData.channels [i].mode; + } + + S9xSetSoundMute(FALSE); + IAPU.PC = IAPU.RAM + IAPU.Registers.PC; + S9xAPUUnpackStatus(); + if (APUCheckDirectPage()) + IAPU.DirectPage = IAPU.RAM + 0x100; + else + IAPU.DirectPage = IAPU.RAM; + Settings.APUEnabled = TRUE; + IAPU.APUExecuting = TRUE; + } + else + { + Settings.APUEnabled = FALSE; + IAPU.APUExecuting = FALSE; + S9xSetSoundMute(TRUE); + } + S9xFixSoundAfterSnapshotLoad(); + ICPU.ShiftedPB = ICPU.Registers.PB << 16; + ICPU.ShiftedDB = ICPU.Registers.DB << 16; + S9xSetPCBase(ICPU.ShiftedPB + ICPU.Registers.PC); + S9xUnpackStatus(); + S9xFixCycles(); + S9xReschedule(); + + return (SUCCESS); } diff --git a/source/snaporig.h b/source/snaporig.h index cc9c09e..bb7da7d 100644 --- a/source/snaporig.h +++ b/source/snaporig.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -92,287 +92,307 @@ #define ORIG_SNAPSHOT_MAGIC "#!snes96" #define ORIG_SNAPSHOT_VERSION 4 -bool8 S9xLoadOrigSnapshot (const char *filename); - -struct SOrigCPUState{ - uint32 Flags; - short Cycles_old; - short NextEvent_old; - uint8 CurrentFrame; - uint8 FastROMSpeed_old_old; - uint16 V_Counter_old; - bool8 BranchSkip; - bool8 NMIActive; - bool8 IRQActive; - bool8 WaitingForInterrupt; - bool8 InDMA; - uint8 WhichEvent; - uint8 *PC; - uint8 *PCBase; - uint16 MemSpeed_old; - uint16 MemSpeedx2_old; - uint16 FastROMSpeed_old; - bool8 FastDP; - uint8 *PCAtOpcodeStart; - uint8 *WaitAddress; - uint32 WaitCounter; - long Cycles; - long NextEvent; - long V_Counter; - long MemSpeed; - long MemSpeedx2; - long FastROMSpeed; +bool8 S9xLoadOrigSnapshot(const char* filename); + +struct SOrigCPUState +{ + uint32 Flags; + short Cycles_old; + short NextEvent_old; + uint8 CurrentFrame; + uint8 FastROMSpeed_old_old; + uint16 V_Counter_old; + bool8 BranchSkip; + bool8 NMIActive; + bool8 IRQActive; + bool8 WaitingForInterrupt; + bool8 InDMA; + uint8 WhichEvent; + uint8* PC; + uint8* PCBase; + uint16 MemSpeed_old; + uint16 MemSpeedx2_old; + uint16 FastROMSpeed_old; + bool8 FastDP; + uint8* PCAtOpcodeStart; + uint8* WaitAddress; + uint32 WaitCounter; + long Cycles; + long NextEvent; + long V_Counter; + long MemSpeed; + long MemSpeedx2; + long FastROMSpeed; }; struct SOrigAPU { - uint32 Cycles; - bool8 ShowROM; - uint8 Flags; - uint8 KeyedChannels; - uint8 OutPorts [4]; - uint8 DSP [0x80]; - uint8 ExtraRAM [64]; - uint16 Timer [3]; - uint16 TimerTarget [3]; - bool8 TimerEnabled [3]; - bool8 TimerValueWritten [3]; + uint32 Cycles; + bool8 ShowROM; + uint8 Flags; + uint8 KeyedChannels; + uint8 OutPorts [4]; + uint8 DSP [0x80]; + uint8 ExtraRAM [64]; + uint16 Timer [3]; + uint16 TimerTarget [3]; + bool8 TimerEnabled [3]; + bool8 TimerValueWritten [3]; }; typedef union { #ifdef LSB_FIRST - struct { uint8 A, Y; } B; + struct + { + uint8 A, Y; + } B; #else - struct { uint8 Y, A; } B; + struct + { + uint8 Y, A; + } B; #endif - uint16 W; + uint16 W; } OrigYAndA; -struct SOrigAPURegisters{ - uint8 P; - OrigYAndA YA; - uint8 X; - uint8 S; - uint16 PC; +struct SOrigAPURegisters +{ + uint8 P; + OrigYAndA YA; + uint8 X; + uint8 S; + uint16 PC; }; #define ORIG_MAX_BUFFER_SIZE (1024 * 4) #define NUM_CHANNELS 8 -typedef struct { - int state; - int type; - short volume_left; - short volume_right; - int frequency; - int count; - signed short wave [ORIG_MAX_BUFFER_SIZE]; - bool8 loop; - int envx; - short left_vol_level; - short right_vol_level; - short envx_target; - unsigned long int env_error; - unsigned long erate; - int direction; - unsigned long attack_rate; - unsigned long decay_rate; - unsigned long sustain_rate; - unsigned long release_rate; - unsigned long sustain_level; - signed short sample; - signed short decoded [16]; - signed short previous [2]; - uint16 sample_number; - bool8 last_block; - bool8 needs_decode; - uint32 block_pointer; - uint32 sample_pointer; - int *echo_buf_ptr; - int mode; - uint32 dummy [8]; +typedef struct +{ + int state; + int type; + short volume_left; + short volume_right; + int frequency; + int count; + signed short wave [ORIG_MAX_BUFFER_SIZE]; + bool8 loop; + int envx; + short left_vol_level; + short right_vol_level; + short envx_target; + unsigned long int env_error; + unsigned long erate; + int direction; + unsigned long attack_rate; + unsigned long decay_rate; + unsigned long sustain_rate; + unsigned long release_rate; + unsigned long sustain_level; + signed short sample; + signed short decoded [16]; + signed short previous [2]; + uint16 sample_number; + bool8 last_block; + bool8 needs_decode; + uint32 block_pointer; + uint32 sample_pointer; + int* echo_buf_ptr; + int mode; + uint32 dummy [8]; } OrigChannel; typedef struct { - short master_volume_left; - short master_volume_right; - short echo_volume_left; - short echo_volume_right; - int echo_enable; - int echo_feedback; - int echo_ptr; - int echo_buffer_size; - int echo_write_enabled; - int echo_channel_enable; - int pitch_mod; - // Just incase they are needed in the future, for snapshot compatibility. - uint32 dummy [3]; - OrigChannel channels [NUM_CHANNELS]; + short master_volume_left; + short master_volume_right; + short echo_volume_left; + short echo_volume_right; + int echo_enable; + int echo_feedback; + int echo_ptr; + int echo_buffer_size; + int echo_write_enabled; + int echo_channel_enable; + int pitch_mod; + // Just incase they are needed in the future, for snapshot compatibility. + uint32 dummy [3]; + OrigChannel channels [NUM_CHANNELS]; } SOrigSoundData; struct SOrigOBJ { - short HPos; - uint16 VPos; - uint16 Name; - uint8 VFlip; - uint8 HFlip; - uint8 Priority; - uint8 Palette; - uint8 Size; - uint8 Prev; - uint8 Next; + short HPos; + uint16 VPos; + uint16 Name; + uint8 VFlip; + uint8 HFlip; + uint8 Priority; + uint8 Palette; + uint8 Size; + uint8 Prev; + uint8 Next; }; -struct SOrigPPU { - uint8 BGMode; - uint8 BG3Priority; - uint8 Brightness; - - struct { - bool8 High; - uint8 Increment; - uint16 Address; - uint16 Mask1; - uint16 FullGraphicCount; - uint16 Shift; - } VMA; - - struct { - uint8 TileSize; - uint16 TileAddress; - uint8 Width; - uint8 Height; - uint16 SCBase; - uint16 VOffset; - uint16 HOffset; - bool8 ThroughMain; - bool8 ThroughSub; - uint8 BGSize; - uint16 NameBase; - uint16 SCSize; - bool8 Addition; - } BG [4]; - - bool8 CGFLIP; - uint16 CGDATA [256]; - uint8 FirstSprite; - uint8 LastSprite; - struct SOrigOBJ OBJ [129]; - uint8 OAMPriorityRotation; - uint16 OAMAddr; - - uint8 OAMFlip; - uint16 OAMTileAddress; - uint16 IRQVBeamPos; - uint16 IRQHBeamPos; - uint16 VBeamPosLatched; - uint16 HBeamPosLatched; - - uint8 HBeamFlip; - uint8 VBeamFlip; - uint8 HVBeamCounterLatched; - - short MatrixA; - short MatrixB; - short MatrixC; - short MatrixD; - short CentreX; - short CentreY; - uint8 Joypad1ButtonReadPos; - uint8 Joypad2ButtonReadPos; - - uint8 CGADD; - uint8 FixedColourRed; - uint8 FixedColourGreen; - uint8 FixedColourBlue; - uint16 SavedOAMAddr; - uint16 ScreenHeight; - uint32 WRAM; - uint8 BG_Forced; - bool8 ForcedBlanking; - bool8 OBJThroughMain; - bool8 OBJThroughSub; - uint8 OBJSizeSelect; - uint8 OBJNameSelect_old; - uint16 OBJNameBase; - bool8 OBJAddition; - uint8 OAMReadFlip; - uint8 OAMData [512 + 32]; - bool8 VTimerEnabled; - bool8 HTimerEnabled; - short HTimerPosition; - uint8 Mosaic; - bool8 BGMosaic [4]; - bool8 Mode7HFlip; - bool8 Mode7VFlip; - uint8 Mode7Repeat; - uint8 Window1Left; - uint8 Window1Right; - uint8 Window2Left; - uint8 Window2Right; - uint8 ClipCounts [6]; - uint8 ClipLeftEdges [3][6]; - uint8 ClipRightEdges [3][6]; - uint8 ClipWindowOverlapLogic [6]; - uint8 ClipWindow1Enable [6]; - uint8 ClipWindow2Enable [6]; - bool8 ClipWindow1Inside [6]; - bool8 ClipWindow2Inside [6]; - bool8 RecomputeClipWindows; - uint8 CGFLIPRead; - uint16 OBJNameSelect; - bool8 Need16x8Mulitply; - uint8 Joypad3ButtonReadPos; - uint8 MouseSpeed[2]; +struct SOrigPPU +{ + uint8 BGMode; + uint8 BG3Priority; + uint8 Brightness; + + struct + { + bool8 High; + uint8 Increment; + uint16 Address; + uint16 Mask1; + uint16 FullGraphicCount; + uint16 Shift; + } VMA; + + struct + { + uint8 TileSize; + uint16 TileAddress; + uint8 Width; + uint8 Height; + uint16 SCBase; + uint16 VOffset; + uint16 HOffset; + bool8 ThroughMain; + bool8 ThroughSub; + uint8 BGSize; + uint16 NameBase; + uint16 SCSize; + bool8 Addition; + } BG [4]; + + bool8 CGFLIP; + uint16 CGDATA [256]; + uint8 FirstSprite; + uint8 LastSprite; + struct SOrigOBJ OBJ [129]; + uint8 OAMPriorityRotation; + uint16 OAMAddr; + + uint8 OAMFlip; + uint16 OAMTileAddress; + uint16 IRQVBeamPos; + uint16 IRQHBeamPos; + uint16 VBeamPosLatched; + uint16 HBeamPosLatched; + + uint8 HBeamFlip; + uint8 VBeamFlip; + uint8 HVBeamCounterLatched; + + short MatrixA; + short MatrixB; + short MatrixC; + short MatrixD; + short CentreX; + short CentreY; + uint8 Joypad1ButtonReadPos; + uint8 Joypad2ButtonReadPos; + + uint8 CGADD; + uint8 FixedColourRed; + uint8 FixedColourGreen; + uint8 FixedColourBlue; + uint16 SavedOAMAddr; + uint16 ScreenHeight; + uint32 WRAM; + uint8 BG_Forced; + bool8 ForcedBlanking; + bool8 OBJThroughMain; + bool8 OBJThroughSub; + uint8 OBJSizeSelect; + uint8 OBJNameSelect_old; + uint16 OBJNameBase; + bool8 OBJAddition; + uint8 OAMReadFlip; + uint8 OAMData [512 + 32]; + bool8 VTimerEnabled; + bool8 HTimerEnabled; + short HTimerPosition; + uint8 Mosaic; + bool8 BGMosaic [4]; + bool8 Mode7HFlip; + bool8 Mode7VFlip; + uint8 Mode7Repeat; + uint8 Window1Left; + uint8 Window1Right; + uint8 Window2Left; + uint8 Window2Right; + uint8 ClipCounts [6]; + uint8 ClipLeftEdges [3][6]; + uint8 ClipRightEdges [3][6]; + uint8 ClipWindowOverlapLogic [6]; + uint8 ClipWindow1Enable [6]; + uint8 ClipWindow2Enable [6]; + bool8 ClipWindow1Inside [6]; + bool8 ClipWindow2Inside [6]; + bool8 RecomputeClipWindows; + uint8 CGFLIPRead; + uint16 OBJNameSelect; + bool8 Need16x8Mulitply; + uint8 Joypad3ButtonReadPos; + uint8 MouseSpeed[2]; }; -struct SOrigDMA { - bool8 TransferDirection; - bool8 AAddressFixed; - bool8 AAddressDecrement; - uint8 TransferMode; - - uint8 ABank; - uint16 AAddress; - uint16 Address; - uint8 BAddress; - - // General DMA only: - uint16 TransferBytes; - - // H-DMA only: - bool8 HDMAIndirectAddressing; - uint16 IndirectAddress; - uint8 IndirectBank; - uint8 Repeat; - uint8 LineCount; - uint8 FirstLine; - bool8 JustStarted; +struct SOrigDMA +{ + bool8 TransferDirection; + bool8 AAddressFixed; + bool8 AAddressDecrement; + uint8 TransferMode; + + uint8 ABank; + uint16 AAddress; + uint16 Address; + uint8 BAddress; + + // General DMA only: + uint16 TransferBytes; + + // H-DMA only: + bool8 HDMAIndirectAddressing; + uint16 IndirectAddress; + uint8 IndirectBank; + uint8 Repeat; + uint8 LineCount; + uint8 FirstLine; + bool8 JustStarted; }; typedef union { #ifdef LSB_FIRST - struct { uint8 l,h; } B; + struct + { + uint8 l, h; + } B; #else - struct { uint8 h,l; } B; + struct + { + uint8 h, l; + } B; #endif - uint16 W; + uint16 W; } OrigPair; -struct SOrigRegisters{ - uint8 PB; - uint8 DB; - OrigPair P; - OrigPair A; - OrigPair D; - OrigPair S; - OrigPair X; - OrigPair Y; - uint16 PC; +struct SOrigRegisters +{ + uint8 PB; + uint8 DB; + OrigPair P; + OrigPair A; + OrigPair D; + OrigPair S; + OrigPair X; + OrigPair Y; + uint16 PC; }; #endif diff --git a/source/snapshot.c b/source/snapshot.c index 88b2ec7..fae963d 100644 --- a/source/snapshot.c +++ b/source/snapshot.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -114,24 +114,26 @@ #include "sdd1.h" #include "spc7110.h" -extern uint8 *SRAM; +extern uint8* SRAM; #ifdef ZSNES_FX -void S9xSuperFXPreSaveState (); -void S9xSuperFXPostSaveState (); -void S9xSuperFXPostLoadState (); +void S9xSuperFXPreSaveState(); +void S9xSuperFXPostSaveState(); +void S9xSuperFXPostLoadState(); #endif -bool8 S9xUnfreezeZSNES (const char *filename); +bool8 S9xUnfreezeZSNES(const char* filename); -typedef struct { - int offset; - int size; - int type; +typedef struct +{ + int offset; + int size; + int type; } FreezeData; -enum { - INT_V, uint8_ARRAY_V, uint16_ARRAY_V, uint32_ARRAY_V +enum +{ + INT_V, uint8_ARRAY_V, uint16_ARRAY_V, uint32_ARRAY_V }; #define Offset(field,structure) \ @@ -141,93 +143,97 @@ enum { typedef struct { - uint32 MovieInputDataSize; -}SnapshotMovieInfo; + uint32 MovieInputDataSize; +} SnapshotMovieInfo; #undef OFFSET #define OFFSET(f) Offset(f,SnapshotMovieInfo *) -static FreezeData SnapMovie [] = { - {OFFSET (MovieInputDataSize), 4, INT_V}, +static FreezeData SnapMovie [] = +{ + {OFFSET(MovieInputDataSize), 4, INT_V}, }; #undef OFFSET #define OFFSET(f) Offset(f,SCPUState *) -static FreezeData SnapCPU [] = { - {OFFSET (Flags), 4, INT_V}, - {OFFSET (BranchSkip), 1, INT_V}, - {OFFSET (NMIActive), 1, INT_V}, - {OFFSET (IRQActive), 1, INT_V}, - {OFFSET (WaitingForInterrupt), 1, INT_V}, - {OFFSET (WhichEvent), 1, INT_V}, - {OFFSET (Cycles), 4, INT_V}, - {OFFSET (NextEvent), 4, INT_V}, - {OFFSET (V_Counter), 4, INT_V}, - {OFFSET (MemSpeed), 4, INT_V}, - {OFFSET (MemSpeedx2), 4, INT_V}, - {OFFSET (FastROMSpeed), 4, INT_V} +static FreezeData SnapCPU [] = +{ + {OFFSET(Flags), 4, INT_V}, + {OFFSET(BranchSkip), 1, INT_V}, + {OFFSET(NMIActive), 1, INT_V}, + {OFFSET(IRQActive), 1, INT_V}, + {OFFSET(WaitingForInterrupt), 1, INT_V}, + {OFFSET(WhichEvent), 1, INT_V}, + {OFFSET(Cycles), 4, INT_V}, + {OFFSET(NextEvent), 4, INT_V}, + {OFFSET(V_Counter), 4, INT_V}, + {OFFSET(MemSpeed), 4, INT_V}, + {OFFSET(MemSpeedx2), 4, INT_V}, + {OFFSET(FastROMSpeed), 4, INT_V} }; #undef OFFSET #define OFFSET(f) Offset(f,SRegisters *) -static FreezeData SnapRegisters [] = { - {OFFSET (PB), 1, INT_V}, - {OFFSET (DB), 1, INT_V}, - {OFFSET (P.W), 2, INT_V}, - {OFFSET (A.W), 2, INT_V}, - {OFFSET (D.W), 2, INT_V}, - {OFFSET (S.W), 2, INT_V}, - {OFFSET (X.W), 2, INT_V}, - {OFFSET (Y.W), 2, INT_V}, - {OFFSET (PC), 2, INT_V} +static FreezeData SnapRegisters [] = +{ + {OFFSET(PB), 1, INT_V}, + {OFFSET(DB), 1, INT_V}, + {OFFSET(P.W), 2, INT_V}, + {OFFSET(A.W), 2, INT_V}, + {OFFSET(D.W), 2, INT_V}, + {OFFSET(S.W), 2, INT_V}, + {OFFSET(X.W), 2, INT_V}, + {OFFSET(Y.W), 2, INT_V}, + {OFFSET(PC), 2, INT_V} }; #undef OFFSET #define OFFSET(f) Offset(f,SPPU *) -static FreezeData SnapPPU [] = { - {OFFSET (BGMode), 1, INT_V}, - {OFFSET (BG3Priority), 1, INT_V}, - {OFFSET (Brightness), 1, INT_V}, - {OFFSET (VMA.High), 1, INT_V}, - {OFFSET (VMA.Increment), 1, INT_V}, - {OFFSET (VMA.Address), 2, INT_V}, - {OFFSET (VMA.Mask1), 2, INT_V}, - {OFFSET (VMA.FullGraphicCount), 2, INT_V}, - {OFFSET (VMA.Shift), 2, INT_V}, - {OFFSET (BG[0].SCBase), 2, INT_V}, - {OFFSET (BG[0].VOffset), 2, INT_V}, - {OFFSET (BG[0].HOffset), 2, INT_V}, - {OFFSET (BG[0].BGSize), 1, INT_V}, - {OFFSET (BG[0].NameBase), 2, INT_V}, - {OFFSET (BG[0].SCSize), 2, INT_V}, - - {OFFSET (BG[1].SCBase), 2, INT_V}, - {OFFSET (BG[1].VOffset), 2, INT_V}, - {OFFSET (BG[1].HOffset), 2, INT_V}, - {OFFSET (BG[1].BGSize), 1, INT_V}, - {OFFSET (BG[1].NameBase), 2, INT_V}, - {OFFSET (BG[1].SCSize), 2, INT_V}, - - {OFFSET (BG[2].SCBase), 2, INT_V}, - {OFFSET (BG[2].VOffset), 2, INT_V}, - {OFFSET (BG[2].HOffset), 2, INT_V}, - {OFFSET (BG[2].BGSize), 1, INT_V}, - {OFFSET (BG[2].NameBase), 2, INT_V}, - {OFFSET (BG[2].SCSize), 2, INT_V}, - - {OFFSET (BG[3].SCBase), 2, INT_V}, - {OFFSET (BG[3].VOffset), 2, INT_V}, - {OFFSET (BG[3].HOffset), 2, INT_V}, - {OFFSET (BG[3].BGSize), 1, INT_V}, - {OFFSET (BG[3].NameBase), 2, INT_V}, - {OFFSET (BG[3].SCSize), 2, INT_V}, - - {OFFSET (CGFLIP), 1, INT_V}, - {OFFSET (CGDATA), 256, uint16_ARRAY_V}, - {OFFSET (FirstSprite), 1, INT_V}, +static FreezeData SnapPPU [] = +{ + {OFFSET(BGMode), 1, INT_V}, + {OFFSET(BG3Priority), 1, INT_V}, + {OFFSET(Brightness), 1, INT_V}, + {OFFSET(VMA.High), 1, INT_V}, + {OFFSET(VMA.Increment), 1, INT_V}, + {OFFSET(VMA.Address), 2, INT_V}, + {OFFSET(VMA.Mask1), 2, INT_V}, + {OFFSET(VMA.FullGraphicCount), 2, INT_V}, + {OFFSET(VMA.Shift), 2, INT_V}, + {OFFSET(BG[0].SCBase), 2, INT_V}, + {OFFSET(BG[0].VOffset), 2, INT_V}, + {OFFSET(BG[0].HOffset), 2, INT_V}, + {OFFSET(BG[0].BGSize), 1, INT_V}, + {OFFSET(BG[0].NameBase), 2, INT_V}, + {OFFSET(BG[0].SCSize), 2, INT_V}, + + {OFFSET(BG[1].SCBase), 2, INT_V}, + {OFFSET(BG[1].VOffset), 2, INT_V}, + {OFFSET(BG[1].HOffset), 2, INT_V}, + {OFFSET(BG[1].BGSize), 1, INT_V}, + {OFFSET(BG[1].NameBase), 2, INT_V}, + {OFFSET(BG[1].SCSize), 2, INT_V}, + + {OFFSET(BG[2].SCBase), 2, INT_V}, + {OFFSET(BG[2].VOffset), 2, INT_V}, + {OFFSET(BG[2].HOffset), 2, INT_V}, + {OFFSET(BG[2].BGSize), 1, INT_V}, + {OFFSET(BG[2].NameBase), 2, INT_V}, + {OFFSET(BG[2].SCSize), 2, INT_V}, + + {OFFSET(BG[3].SCBase), 2, INT_V}, + {OFFSET(BG[3].VOffset), 2, INT_V}, + {OFFSET(BG[3].HOffset), 2, INT_V}, + {OFFSET(BG[3].BGSize), 1, INT_V}, + {OFFSET(BG[3].NameBase), 2, INT_V}, + {OFFSET(BG[3].SCSize), 2, INT_V}, + + {OFFSET(CGFLIP), 1, INT_V}, + {OFFSET(CGDATA), 256, uint16_ARRAY_V}, + {OFFSET(FirstSprite), 1, INT_V}, #define O(N) \ {OFFSET (OBJ[N].HPos), 2, INT_V}, \ {OFFSET (OBJ[N].VPos), 2, INT_V}, \ @@ -237,90 +243,91 @@ static FreezeData SnapPPU [] = { {OFFSET (OBJ[N].Priority), 1, INT_V}, \ {OFFSET (OBJ[N].Palette), 1, INT_V}, \ {OFFSET (OBJ[N].Size), 1, INT_V} - - O( 0), O( 1), O( 2), O( 3), O( 4), O( 5), O( 6), O( 7), - O( 8), O( 9), O( 10), O( 11), O( 12), O( 13), O( 14), O( 15), - O( 16), O( 17), O( 18), O( 19), O( 20), O( 21), O( 22), O( 23), - O( 24), O( 25), O( 26), O( 27), O( 28), O( 29), O( 30), O( 31), - O( 32), O( 33), O( 34), O( 35), O( 36), O( 37), O( 38), O( 39), - O( 40), O( 41), O( 42), O( 43), O( 44), O( 45), O( 46), O( 47), - O( 48), O( 49), O( 50), O( 51), O( 52), O( 53), O( 54), O( 55), - O( 56), O( 57), O( 58), O( 59), O( 60), O( 61), O( 62), O( 63), - O( 64), O( 65), O( 66), O( 67), O( 68), O( 69), O( 70), O( 71), - O( 72), O( 73), O( 74), O( 75), O( 76), O( 77), O( 78), O( 79), - O( 80), O( 81), O( 82), O( 83), O( 84), O( 85), O( 86), O( 87), - O( 88), O( 89), O( 90), O( 91), O( 92), O( 93), O( 94), O( 95), - O( 96), O( 97), O( 98), O( 99), O(100), O(101), O(102), O(103), - O(104), O(105), O(106), O(107), O(108), O(109), O(110), O(111), - O(112), O(113), O(114), O(115), O(116), O(117), O(118), O(119), - O(120), O(121), O(122), O(123), O(124), O(125), O(126), O(127), + + O(0), O(1), O(2), O(3), O(4), O(5), O(6), O(7), + O(8), O(9), O(10), O(11), O(12), O(13), O(14), O(15), + O(16), O(17), O(18), O(19), O(20), O(21), O(22), O(23), + O(24), O(25), O(26), O(27), O(28), O(29), O(30), O(31), + O(32), O(33), O(34), O(35), O(36), O(37), O(38), O(39), + O(40), O(41), O(42), O(43), O(44), O(45), O(46), O(47), + O(48), O(49), O(50), O(51), O(52), O(53), O(54), O(55), + O(56), O(57), O(58), O(59), O(60), O(61), O(62), O(63), + O(64), O(65), O(66), O(67), O(68), O(69), O(70), O(71), + O(72), O(73), O(74), O(75), O(76), O(77), O(78), O(79), + O(80), O(81), O(82), O(83), O(84), O(85), O(86), O(87), + O(88), O(89), O(90), O(91), O(92), O(93), O(94), O(95), + O(96), O(97), O(98), O(99), O(100), O(101), O(102), O(103), + O(104), O(105), O(106), O(107), O(108), O(109), O(110), O(111), + O(112), O(113), O(114), O(115), O(116), O(117), O(118), O(119), + O(120), O(121), O(122), O(123), O(124), O(125), O(126), O(127), #undef O - {OFFSET (OAMPriorityRotation), 1, INT_V}, - {OFFSET (OAMAddr), 2, INT_V}, - {OFFSET (OAMFlip), 1, INT_V}, - {OFFSET (OAMTileAddress), 2, INT_V}, - {OFFSET (IRQVBeamPos), 2, INT_V}, - {OFFSET (IRQHBeamPos), 2, INT_V}, - {OFFSET (VBeamPosLatched), 2, INT_V}, - {OFFSET (HBeamPosLatched), 2, INT_V}, - {OFFSET (HBeamFlip), 1, INT_V}, - {OFFSET (VBeamFlip), 1, INT_V}, - {OFFSET (HVBeamCounterLatched), 1, INT_V}, - {OFFSET (MatrixA), 2, INT_V}, - {OFFSET (MatrixB), 2, INT_V}, - {OFFSET (MatrixC), 2, INT_V}, - {OFFSET (MatrixD), 2, INT_V}, - {OFFSET (CentreX), 2, INT_V}, - {OFFSET (CentreY), 2, INT_V}, - {OFFSET (Joypad1ButtonReadPos), 1, INT_V}, - {OFFSET (Joypad2ButtonReadPos), 1, INT_V}, - {OFFSET (Joypad3ButtonReadPos), 1, INT_V}, - {OFFSET (CGADD), 1, INT_V}, - {OFFSET (FixedColourRed), 1, INT_V}, - {OFFSET (FixedColourGreen), 1, INT_V}, - {OFFSET (FixedColourBlue), 1, INT_V}, - {OFFSET (SavedOAMAddr), 2, INT_V}, - {OFFSET (ScreenHeight), 2, INT_V}, - {OFFSET (WRAM), 4, INT_V}, - {OFFSET (ForcedBlanking), 1, INT_V}, - {OFFSET (OBJNameSelect), 2, INT_V}, - {OFFSET (OBJSizeSelect), 1, INT_V}, - {OFFSET (OBJNameBase), 2, INT_V}, - {OFFSET (OAMReadFlip), 1, INT_V}, - {OFFSET (VTimerEnabled), 1, INT_V}, - {OFFSET (HTimerEnabled), 1, INT_V}, - {OFFSET (HTimerPosition), 2, INT_V}, - {OFFSET (Mosaic), 1, INT_V}, - {OFFSET (Mode7HFlip), 1, INT_V}, - {OFFSET (Mode7VFlip), 1, INT_V}, - {OFFSET (Mode7Repeat), 1, INT_V}, - {OFFSET (Window1Left), 1, INT_V}, - {OFFSET (Window1Right), 1, INT_V}, - {OFFSET (Window2Left), 1, INT_V}, - {OFFSET (Window2Right), 1, INT_V}, + {OFFSET(OAMPriorityRotation), 1, INT_V}, + {OFFSET(OAMAddr), 2, INT_V}, + {OFFSET(OAMFlip), 1, INT_V}, + {OFFSET(OAMTileAddress), 2, INT_V}, + {OFFSET(IRQVBeamPos), 2, INT_V}, + {OFFSET(IRQHBeamPos), 2, INT_V}, + {OFFSET(VBeamPosLatched), 2, INT_V}, + {OFFSET(HBeamPosLatched), 2, INT_V}, + {OFFSET(HBeamFlip), 1, INT_V}, + {OFFSET(VBeamFlip), 1, INT_V}, + {OFFSET(HVBeamCounterLatched), 1, INT_V}, + {OFFSET(MatrixA), 2, INT_V}, + {OFFSET(MatrixB), 2, INT_V}, + {OFFSET(MatrixC), 2, INT_V}, + {OFFSET(MatrixD), 2, INT_V}, + {OFFSET(CentreX), 2, INT_V}, + {OFFSET(CentreY), 2, INT_V}, + {OFFSET(Joypad1ButtonReadPos), 1, INT_V}, + {OFFSET(Joypad2ButtonReadPos), 1, INT_V}, + {OFFSET(Joypad3ButtonReadPos), 1, INT_V}, + {OFFSET(CGADD), 1, INT_V}, + {OFFSET(FixedColourRed), 1, INT_V}, + {OFFSET(FixedColourGreen), 1, INT_V}, + {OFFSET(FixedColourBlue), 1, INT_V}, + {OFFSET(SavedOAMAddr), 2, INT_V}, + {OFFSET(ScreenHeight), 2, INT_V}, + {OFFSET(WRAM), 4, INT_V}, + {OFFSET(ForcedBlanking), 1, INT_V}, + {OFFSET(OBJNameSelect), 2, INT_V}, + {OFFSET(OBJSizeSelect), 1, INT_V}, + {OFFSET(OBJNameBase), 2, INT_V}, + {OFFSET(OAMReadFlip), 1, INT_V}, + {OFFSET(VTimerEnabled), 1, INT_V}, + {OFFSET(HTimerEnabled), 1, INT_V}, + {OFFSET(HTimerPosition), 2, INT_V}, + {OFFSET(Mosaic), 1, INT_V}, + {OFFSET(Mode7HFlip), 1, INT_V}, + {OFFSET(Mode7VFlip), 1, INT_V}, + {OFFSET(Mode7Repeat), 1, INT_V}, + {OFFSET(Window1Left), 1, INT_V}, + {OFFSET(Window1Right), 1, INT_V}, + {OFFSET(Window2Left), 1, INT_V}, + {OFFSET(Window2Right), 1, INT_V}, #define O(N) \ {OFFSET (ClipWindowOverlapLogic[N]), 1, INT_V}, \ {OFFSET (ClipWindow1Enable[N]), 1, INT_V}, \ {OFFSET (ClipWindow2Enable[N]), 1, INT_V}, \ {OFFSET (ClipWindow1Inside[N]), 1, INT_V}, \ {OFFSET (ClipWindow2Inside[N]), 1, INT_V} - - O(0), O(1), O(2), O(3), O(4), O(5), - + + O(0), O(1), O(2), O(3), O(4), O(5), + #undef O - - {OFFSET (CGFLIPRead), 1, INT_V}, - {OFFSET (Need16x8Mulitply), 1, INT_V}, - {OFFSET (BGMosaic), 4, uint8_ARRAY_V}, - {OFFSET (OAMData), 512 + 32, uint8_ARRAY_V}, - {OFFSET (Need16x8Mulitply), 1, INT_V}, - {OFFSET (MouseSpeed), 2, uint8_ARRAY_V} + + {OFFSET(CGFLIPRead), 1, INT_V}, + {OFFSET(Need16x8Mulitply), 1, INT_V}, + {OFFSET(BGMosaic), 4, uint8_ARRAY_V}, + {OFFSET(OAMData), 512 + 32, uint8_ARRAY_V}, + {OFFSET(Need16x8Mulitply), 1, INT_V}, + {OFFSET(MouseSpeed), 2, uint8_ARRAY_V} }; #undef OFFSET #define OFFSET(f) Offset(f,SDMA *) -static FreezeData SnapDMA [] = { +static FreezeData SnapDMA [] = +{ #define O(N) \ {OFFSET (TransferDirection) + N * sizeof (SDMA), 1, INT_V}, \ {OFFSET (AAddressFixed) + N * sizeof (SDMA), 1, INT_V}, \ @@ -337,55 +344,58 @@ static FreezeData SnapDMA [] = { {OFFSET (Repeat) + N * sizeof (SDMA), 1, INT_V}, \ {OFFSET (LineCount) + N * sizeof (SDMA), 1, INT_V}, \ {OFFSET (FirstLine) + N * sizeof (SDMA), 1, INT_V} - - O(0), O(1), O(2), O(3), O(4), O(5), O(6), O(7) + + O(0), O(1), O(2), O(3), O(4), O(5), O(6), O(7) #undef O }; #undef OFFSET #define OFFSET(f) Offset(f, SAPU *) -static FreezeData SnapAPU [] = { - {OFFSET (Cycles), 4, INT_V}, - {OFFSET (ShowROM), 1, INT_V}, - {OFFSET (Flags), 1, INT_V}, - {OFFSET (KeyedChannels), 1, INT_V}, - {OFFSET (OutPorts), 4, uint8_ARRAY_V}, - {OFFSET (DSP), 0x80, uint8_ARRAY_V}, - {OFFSET (ExtraRAM), 64, uint8_ARRAY_V}, - {OFFSET (Timer), 3, uint16_ARRAY_V}, - {OFFSET (TimerTarget), 3, uint16_ARRAY_V}, - {OFFSET (TimerEnabled), 3, uint8_ARRAY_V}, - {OFFSET (TimerValueWritten), 3, uint8_ARRAY_V} +static FreezeData SnapAPU [] = +{ + {OFFSET(Cycles), 4, INT_V}, + {OFFSET(ShowROM), 1, INT_V}, + {OFFSET(Flags), 1, INT_V}, + {OFFSET(KeyedChannels), 1, INT_V}, + {OFFSET(OutPorts), 4, uint8_ARRAY_V}, + {OFFSET(DSP), 0x80, uint8_ARRAY_V}, + {OFFSET(ExtraRAM), 64, uint8_ARRAY_V}, + {OFFSET(Timer), 3, uint16_ARRAY_V}, + {OFFSET(TimerTarget), 3, uint16_ARRAY_V}, + {OFFSET(TimerEnabled), 3, uint8_ARRAY_V}, + {OFFSET(TimerValueWritten), 3, uint8_ARRAY_V} }; #undef OFFSET #define OFFSET(f) Offset(f, SAPURegisters *) -static FreezeData SnapAPURegisters [] = { - {OFFSET (P), 1, INT_V}, - {OFFSET (YA.W), 2, INT_V}, - {OFFSET (X), 1, INT_V}, - {OFFSET (S), 1, INT_V}, - {OFFSET (PC), 2, INT_V}, +static FreezeData SnapAPURegisters [] = +{ + {OFFSET(P), 1, INT_V}, + {OFFSET(YA.W), 2, INT_V}, + {OFFSET(X), 1, INT_V}, + {OFFSET(S), 1, INT_V}, + {OFFSET(PC), 2, INT_V}, }; #undef OFFSET #define OFFSET(f) Offset(f,SSoundData *) -static FreezeData SnapSoundData [] = { - {OFFSET (master_volume [0]), 2, INT_V}, - {OFFSET (master_volume [1]), 2, INT_V}, - {OFFSET (echo_volume [0]), 2, INT_V}, - {OFFSET (echo_volume [1]), 2, INT_V}, - {OFFSET (echo_enable), 4, INT_V}, - {OFFSET (echo_feedback), 4, INT_V}, - {OFFSET (echo_ptr), 4, INT_V}, - {OFFSET (echo_buffer_size), 4, INT_V}, - {OFFSET (echo_write_enabled), 4, INT_V}, - {OFFSET (echo_channel_enable), 4, INT_V}, - {OFFSET (pitch_mod), 4, INT_V}, - {OFFSET (dummy), 3, uint32_ARRAY_V}, +static FreezeData SnapSoundData [] = +{ + {OFFSET(master_volume [0]), 2, INT_V}, + {OFFSET(master_volume [1]), 2, INT_V}, + {OFFSET(echo_volume [0]), 2, INT_V}, + {OFFSET(echo_volume [1]), 2, INT_V}, + {OFFSET(echo_enable), 4, INT_V}, + {OFFSET(echo_feedback), 4, INT_V}, + {OFFSET(echo_ptr), 4, INT_V}, + {OFFSET(echo_buffer_size), 4, INT_V}, + {OFFSET(echo_write_enabled), 4, INT_V}, + {OFFSET(echo_channel_enable), 4, INT_V}, + {OFFSET(pitch_mod), 4, INT_V}, + {OFFSET(dummy), 3, uint32_ARRAY_V}, #define O(N) \ {OFFSET (channels [N].state), 4, INT_V}, \ {OFFSET (channels [N].type), 4, INT_V}, \ @@ -415,485 +425,508 @@ static FreezeData SnapSoundData [] = { {OFFSET (channels [N].block_pointer), 4, INT_V}, \ {OFFSET (channels [N].sample_pointer), 4, INT_V}, \ {OFFSET (channels [N].mode), 4, INT_V} - - O(0), O(1), O(2), O(3), O(4), O(5), O(6), O(7) + + O(0), O(1), O(2), O(3), O(4), O(5), O(6), O(7) #undef O }; #undef OFFSET #define OFFSET(f) Offset(f,SSA1Registers *) -static FreezeData SnapSA1Registers [] = { - {OFFSET (PB), 1, INT_V}, - {OFFSET (DB), 1, INT_V}, - {OFFSET (P.W), 2, INT_V}, - {OFFSET (A.W), 2, INT_V}, - {OFFSET (D.W), 2, INT_V}, - {OFFSET (S.W), 2, INT_V}, - {OFFSET (X.W), 2, INT_V}, - {OFFSET (Y.W), 2, INT_V}, - {OFFSET (PC), 2, INT_V} +static FreezeData SnapSA1Registers [] = +{ + {OFFSET(PB), 1, INT_V}, + {OFFSET(DB), 1, INT_V}, + {OFFSET(P.W), 2, INT_V}, + {OFFSET(A.W), 2, INT_V}, + {OFFSET(D.W), 2, INT_V}, + {OFFSET(S.W), 2, INT_V}, + {OFFSET(X.W), 2, INT_V}, + {OFFSET(Y.W), 2, INT_V}, + {OFFSET(PC), 2, INT_V} }; #undef OFFSET #define OFFSET(f) Offset(f,SSA1 *) -static FreezeData SnapSA1 [] = { - {OFFSET (Flags), 4, INT_V}, - {OFFSET (NMIActive), 1, INT_V}, - {OFFSET (IRQActive), 1, INT_V}, - {OFFSET (WaitingForInterrupt), 1, INT_V}, - {OFFSET (op1), 2, INT_V}, - {OFFSET (op2), 2, INT_V}, - {OFFSET (arithmetic_op), 4, INT_V}, - {OFFSET (sum), 8, INT_V}, - {OFFSET (overflow), 1, INT_V} +static FreezeData SnapSA1 [] = +{ + {OFFSET(Flags), 4, INT_V}, + {OFFSET(NMIActive), 1, INT_V}, + {OFFSET(IRQActive), 1, INT_V}, + {OFFSET(WaitingForInterrupt), 1, INT_V}, + {OFFSET(op1), 2, INT_V}, + {OFFSET(op2), 2, INT_V}, + {OFFSET(arithmetic_op), 4, INT_V}, + {OFFSET(sum), 8, INT_V}, + {OFFSET(overflow), 1, INT_V} }; #undef OFFSET #define OFFSET(f) Offset(f,SPC7110Regs *) -static FreezeData SnapSPC7110 [] = { - {OFFSET (reg4800), 1, INT_V}, - {OFFSET (reg4801), 1, INT_V}, - {OFFSET (reg4802), 1, INT_V}, - {OFFSET (reg4803), 1, INT_V}, - {OFFSET (reg4804), 1, INT_V}, - {OFFSET (reg4805), 1, INT_V}, - {OFFSET (reg4806), 1, INT_V}, - {OFFSET (reg4807), 1, INT_V}, - {OFFSET (reg4808), 1, INT_V}, - {OFFSET (reg4809), 1, INT_V}, - {OFFSET (reg480A), 1, INT_V}, - {OFFSET (reg480B), 1, INT_V}, - {OFFSET (reg480C), 1, INT_V}, - {OFFSET (reg4811), 1, INT_V}, - {OFFSET (reg4812), 1, INT_V}, - {OFFSET (reg4813), 1, INT_V}, - {OFFSET (reg4814), 1, INT_V}, - {OFFSET (reg4815), 1, INT_V}, - {OFFSET (reg4816), 1, INT_V}, - {OFFSET (reg4817), 1, INT_V}, - {OFFSET (reg4818), 1, INT_V}, - {OFFSET (reg4820), 1, INT_V}, - {OFFSET (reg4821), 1, INT_V}, - {OFFSET (reg4822), 1, INT_V}, - {OFFSET (reg4823), 1, INT_V}, - {OFFSET (reg4824), 1, INT_V}, - {OFFSET (reg4825), 1, INT_V}, - {OFFSET (reg4826), 1, INT_V}, - {OFFSET (reg4827), 1, INT_V}, - {OFFSET (reg4828), 1, INT_V}, - {OFFSET (reg4829), 1, INT_V}, - {OFFSET (reg482A), 1, INT_V}, - {OFFSET (reg482B), 1, INT_V}, - {OFFSET (reg482C), 1, INT_V}, - {OFFSET (reg482D), 1, INT_V}, - {OFFSET (reg482E), 1, INT_V}, - {OFFSET (reg482F), 1, INT_V}, - {OFFSET (reg4830), 1, INT_V}, - {OFFSET (reg4831), 1, INT_V}, - {OFFSET (reg4832), 1, INT_V}, - {OFFSET (reg4833), 1, INT_V}, - {OFFSET (reg4834), 1, INT_V}, - {OFFSET (reg4840), 1, INT_V}, - {OFFSET (reg4841), 1, INT_V}, - {OFFSET (reg4842), 1, INT_V}, - {OFFSET (AlignBy), 1, INT_V}, - {OFFSET (written), 1, INT_V}, - {OFFSET (offset_add), 1, INT_V}, - {OFFSET (DataRomOffset), 4, INT_V}, - {OFFSET (DataRomSize), 4, INT_V}, - {OFFSET (bank50Internal), 4, INT_V}, - {OFFSET (bank50), 0x10000, uint8_ARRAY_V} +static FreezeData SnapSPC7110 [] = +{ + {OFFSET(reg4800), 1, INT_V}, + {OFFSET(reg4801), 1, INT_V}, + {OFFSET(reg4802), 1, INT_V}, + {OFFSET(reg4803), 1, INT_V}, + {OFFSET(reg4804), 1, INT_V}, + {OFFSET(reg4805), 1, INT_V}, + {OFFSET(reg4806), 1, INT_V}, + {OFFSET(reg4807), 1, INT_V}, + {OFFSET(reg4808), 1, INT_V}, + {OFFSET(reg4809), 1, INT_V}, + {OFFSET(reg480A), 1, INT_V}, + {OFFSET(reg480B), 1, INT_V}, + {OFFSET(reg480C), 1, INT_V}, + {OFFSET(reg4811), 1, INT_V}, + {OFFSET(reg4812), 1, INT_V}, + {OFFSET(reg4813), 1, INT_V}, + {OFFSET(reg4814), 1, INT_V}, + {OFFSET(reg4815), 1, INT_V}, + {OFFSET(reg4816), 1, INT_V}, + {OFFSET(reg4817), 1, INT_V}, + {OFFSET(reg4818), 1, INT_V}, + {OFFSET(reg4820), 1, INT_V}, + {OFFSET(reg4821), 1, INT_V}, + {OFFSET(reg4822), 1, INT_V}, + {OFFSET(reg4823), 1, INT_V}, + {OFFSET(reg4824), 1, INT_V}, + {OFFSET(reg4825), 1, INT_V}, + {OFFSET(reg4826), 1, INT_V}, + {OFFSET(reg4827), 1, INT_V}, + {OFFSET(reg4828), 1, INT_V}, + {OFFSET(reg4829), 1, INT_V}, + {OFFSET(reg482A), 1, INT_V}, + {OFFSET(reg482B), 1, INT_V}, + {OFFSET(reg482C), 1, INT_V}, + {OFFSET(reg482D), 1, INT_V}, + {OFFSET(reg482E), 1, INT_V}, + {OFFSET(reg482F), 1, INT_V}, + {OFFSET(reg4830), 1, INT_V}, + {OFFSET(reg4831), 1, INT_V}, + {OFFSET(reg4832), 1, INT_V}, + {OFFSET(reg4833), 1, INT_V}, + {OFFSET(reg4834), 1, INT_V}, + {OFFSET(reg4840), 1, INT_V}, + {OFFSET(reg4841), 1, INT_V}, + {OFFSET(reg4842), 1, INT_V}, + {OFFSET(AlignBy), 1, INT_V}, + {OFFSET(written), 1, INT_V}, + {OFFSET(offset_add), 1, INT_V}, + {OFFSET(DataRomOffset), 4, INT_V}, + {OFFSET(DataRomSize), 4, INT_V}, + {OFFSET(bank50Internal), 4, INT_V}, + {OFFSET(bank50), 0x10000, uint8_ARRAY_V} }; #undef OFFSET #define OFFSET(f) Offset(f,struct SPC7110RTC *) -static FreezeData SnapS7RTC [] = { - {OFFSET (reg), 16, uint8_ARRAY_V}, - {OFFSET (index), 2, INT_V}, - {OFFSET (control), 1, INT_V}, - {OFFSET (init), 1, INT_V}, - {OFFSET (last_used),4,INT_V} +static FreezeData SnapS7RTC [] = +{ + {OFFSET(reg), 16, uint8_ARRAY_V}, + {OFFSET(index), 2, INT_V}, + {OFFSET(control), 1, INT_V}, + {OFFSET(init), 1, INT_V}, + {OFFSET(last_used), 4, INT_V} }; //static char ROMFilename [_MAX_PATH]; //static char SnapshotFilename [_MAX_PATH]; -void FreezeStruct (STREAM stream, const char *name, void *base, FreezeData *fields, - int num_fields); -void FreezeBlock (STREAM stream, const char *name, uint8 *block, int size); +void FreezeStruct(STREAM stream, const char* name, void* base, + FreezeData* fields, + int num_fields); +void FreezeBlock(STREAM stream, const char* name, uint8* block, int size); -int UnfreezeStruct (STREAM stream, const char *name, void *base, FreezeData *fields, - int num_fields); -int UnfreezeBlock (STREAM stream, const char *name, uint8 *block, int size); +int UnfreezeStruct(STREAM stream, const char* name, void* base, + FreezeData* fields, + int num_fields); +int UnfreezeBlock(STREAM stream, const char* name, uint8* block, int size); -int UnfreezeStructCopy (STREAM stream, const char *name, uint8** block, FreezeData *fields, int num_fields); +int UnfreezeStructCopy(STREAM stream, const char* name, uint8** block, + FreezeData* fields, int num_fields); -void UnfreezeStructFromCopy (void *base, FreezeData *fields, int num_fields, uint8* block); +void UnfreezeStructFromCopy(void* base, FreezeData* fields, int num_fields, + uint8* block); -int UnfreezeBlockCopy (STREAM stream, const char *name, uint8** block, int size); +int UnfreezeBlockCopy(STREAM stream, const char* name, uint8** block, int size); -bool8 Snapshot (const char *filename) +bool8 Snapshot(const char* filename) { - return (S9xFreezeGame (filename)); + return (S9xFreezeGame(filename)); } -bool8 S9xFreezeGame (const char *filename) +bool8 S9xFreezeGame(const char* filename) { - FILE* fp; - fp = fopen(filename, "w"); - if(NULL == fp) - return (FALSE); - - fseek(fp, 4, SEEK_SET); //Valid data offset 4 bytes - S9xFreezeToStream (fp); - fclose(fp); -#if 0 //Not support moive now - if(S9xMovieActive()) - { - sprintf(String, "Movie snapshot %s", S9xBasename (filename)); - S9xMessage (S9X_INFO, S9X_FREEZE_FILE_INFO, String); - } - else - { - sprintf(String, "Saved %s", S9xBasename (filename)); - S9xMessage (S9X_INFO, S9X_FREEZE_FILE_INFO, String); - } + FILE* fp; + fp = fopen(filename, "w"); + if (NULL == fp) + return (FALSE); + + fseek(fp, 4, SEEK_SET); //Valid data offset 4 bytes + S9xFreezeToStream(fp); + fclose(fp); +#if 0 //Not support moive now + if (S9xMovieActive()) + { + sprintf(String, "Movie snapshot %s", S9xBasename(filename)); + S9xMessage(S9X_INFO, S9X_FREEZE_FILE_INFO, String); + } + else + { + sprintf(String, "Saved %s", S9xBasename(filename)); + S9xMessage(S9X_INFO, S9X_FREEZE_FILE_INFO, String); + } #endif - return (TRUE); + return (TRUE); } -bool8 S9xLoadSnapshot (const char *filename) +bool8 S9xLoadSnapshot(const char* filename) { - return (S9xUnfreezeGame (filename)); + return (S9xUnfreezeGame(filename)); } -bool8 S9xUnfreezeGame (const char *filename) +bool8 S9xUnfreezeGame(const char* filename) { - if (S9xLoadOrigSnapshot (filename)) - return (TRUE); - - if (S9xUnfreezeZSNES (filename)) - return (TRUE); - - FILE* fp; - fp = fopen(filename, "r"); - if(NULL == fp) - return (FALSE); - - fseek(fp, 4, SEEK_SET); //Valid data offset 4 bytes - - int result; - if ((result = S9xUnfreezeFromStream (fp)) != SUCCESS) - { + if (S9xLoadOrigSnapshot(filename)) + return (TRUE); + + if (S9xUnfreezeZSNES(filename)) + return (TRUE); + + FILE* fp; + fp = fopen(filename, "r"); + if (NULL == fp) + return (FALSE); + + fseek(fp, 4, SEEK_SET); //Valid data offset 4 bytes + + int result; + if ((result = S9xUnfreezeFromStream(fp)) != SUCCESS) + { #if 0 - switch (result) - { - case WRONG_FORMAT: - S9xMessage (S9X_ERROR, S9X_WRONG_FORMAT, - "File not in Snes9x freeze format"); - break; - case WRONG_VERSION: - S9xMessage (S9X_ERROR, S9X_WRONG_VERSION, - "Incompatable Snes9x freeze file format version"); - break; - case WRONG_MOVIE_SNAPSHOT: - S9xMessage (S9X_ERROR, S9X_WRONG_MOVIE_SNAPSHOT, MOVIE_ERR_SNAPSHOT_WRONG_MOVIE); - break; - case NOT_A_MOVIE_SNAPSHOT: - S9xMessage (S9X_ERROR, S9X_NOT_A_MOVIE_SNAPSHOT, MOVIE_ERR_SNAPSHOT_NOT_MOVIE); - break; - default: - case FILE_NOT_FOUND: - sprintf (String, "ROM image \"%s\" for freeze file not found", - ROMFilename); - S9xMessage (S9X_ERROR, S9X_ROM_NOT_FOUND, String); - break; - } + switch (result) + { + case WRONG_FORMAT: + S9xMessage(S9X_ERROR, S9X_WRONG_FORMAT, + "File not in Snes9x freeze format"); + break; + case WRONG_VERSION: + S9xMessage(S9X_ERROR, S9X_WRONG_VERSION, + "Incompatable Snes9x freeze file format version"); + break; + case WRONG_MOVIE_SNAPSHOT: + S9xMessage(S9X_ERROR, S9X_WRONG_MOVIE_SNAPSHOT, MOVIE_ERR_SNAPSHOT_WRONG_MOVIE); + break; + case NOT_A_MOVIE_SNAPSHOT: + S9xMessage(S9X_ERROR, S9X_NOT_A_MOVIE_SNAPSHOT, MOVIE_ERR_SNAPSHOT_NOT_MOVIE); + break; + default: + case FILE_NOT_FOUND: + sprintf(String, "ROM image \"%s\" for freeze file not found", + ROMFilename); + S9xMessage(S9X_ERROR, S9X_ROM_NOT_FOUND, String); + break; + } #endif - fclose(fp); - return (FALSE); - } -#if 0 //Not support movie now - if(!S9xMovieActive()) - { - sprintf(String, "Loaded %s", S9xBasename (filename)); - S9xMessage (S9X_INFO, S9X_FREEZE_FILE_INFO, String); - } + fclose(fp); + return (FALSE); + } +#if 0 //Not support movie now + if (!S9xMovieActive()) + { + sprintf(String, "Loaded %s", S9xBasename(filename)); + S9xMessage(S9X_INFO, S9X_FREEZE_FILE_INFO, String); + } #endif - fclose(fp); - return (TRUE); + fclose(fp); + return (TRUE); } -void S9xFreezeToStream (STREAM stream) +void S9xFreezeToStream(STREAM stream) { - char buffer [1024]; - int i; - - S9xSetSoundMute (TRUE); + char buffer [1024]; + int i; + + S9xSetSoundMute(TRUE); #ifdef ZSNES_FX - if (Settings.SuperFX) - S9xSuperFXPreSaveState (); + if (Settings.SuperFX) + S9xSuperFXPreSaveState(); #endif - - S9xUpdateRTC(); - S9xSRTCPreSaveState (); - - for (i = 0; i < 8; i++) - { - SoundData.channels [i].previous16 [0] = (int16) SoundData.channels [i].previous [0]; - SoundData.channels [i].previous16 [1] = (int16) SoundData.channels [i].previous [1]; - } - sprintf (buffer, "%s:%04d\n", SNAPSHOT_MAGIC, SNAPSHOT_VERSION); - WRITE_STREAM (buffer, strlen (buffer), stream); - sprintf (buffer, "NAM:%06d:%s%c", strlen (Memory.ROMFilename) + 1, - Memory.ROMFilename, 0); - WRITE_STREAM (buffer, strlen (buffer) + 1, stream); - FreezeStruct (stream, "CPU", &CPU, SnapCPU, COUNT (SnapCPU)); - FreezeStruct (stream, "REG", &ICPU.Registers, SnapRegisters, COUNT (SnapRegisters)); - FreezeStruct (stream, "PPU", &PPU, SnapPPU, COUNT (SnapPPU)); - FreezeStruct (stream, "DMA", DMA, SnapDMA, COUNT (SnapDMA)); - - // RAM and VRAM - FreezeBlock (stream, "VRA", Memory.VRAM, 0x10000); - FreezeBlock (stream, "RAM", Memory.RAM, 0x20000); - FreezeBlock (stream, "SRA", Memory.SRAM, 0x20000); - FreezeBlock (stream, "FIL", Memory.FillRAM, 0x8000); - if (Settings.APUEnabled) - { - // APU - FreezeStruct (stream, "APU", &APU, SnapAPU, COUNT (SnapAPU)); - FreezeStruct (stream, "ARE", &IAPU.Registers, SnapAPURegisters, - COUNT (SnapAPURegisters)); - FreezeBlock (stream, "ARA", IAPU.RAM, 0x10000); - FreezeStruct (stream, "SOU", &SoundData, SnapSoundData, - COUNT (SnapSoundData)); - } - if (Settings.SA1) - { - SA1.Registers.PC = SA1.PC - SA1.PCBase; - S9xSA1PackStatus (); - FreezeStruct (stream, "SA1", &SA1, SnapSA1, COUNT (SnapSA1)); - FreezeStruct (stream, "SAR", &SA1.Registers, SnapSA1Registers, - COUNT (SnapSA1Registers)); - } - - if (Settings.SPC7110) - { - FreezeStruct (stream, "SP7", &s7r, SnapSPC7110, COUNT (SnapSPC7110)); - } - if(Settings.SPC7110RTC) - { - FreezeStruct (stream, "RTC", &rtc_f9, SnapS7RTC, COUNT (SnapS7RTC)); - } - - S9xSetSoundMute (FALSE); + + S9xUpdateRTC(); + S9xSRTCPreSaveState(); + + for (i = 0; i < 8; i++) + { + SoundData.channels [i].previous16 [0] = (int16) + SoundData.channels [i].previous [0]; + SoundData.channels [i].previous16 [1] = (int16) + SoundData.channels [i].previous [1]; + } + sprintf(buffer, "%s:%04d\n", SNAPSHOT_MAGIC, SNAPSHOT_VERSION); + WRITE_STREAM(buffer, strlen(buffer), stream); + sprintf(buffer, "NAM:%06d:%s%c", strlen(Memory.ROMFilename) + 1, + Memory.ROMFilename, 0); + WRITE_STREAM(buffer, strlen(buffer) + 1, stream); + FreezeStruct(stream, "CPU", &CPU, SnapCPU, COUNT(SnapCPU)); + FreezeStruct(stream, "REG", &ICPU.Registers, SnapRegisters, + COUNT(SnapRegisters)); + FreezeStruct(stream, "PPU", &PPU, SnapPPU, COUNT(SnapPPU)); + FreezeStruct(stream, "DMA", DMA, SnapDMA, COUNT(SnapDMA)); + + // RAM and VRAM + FreezeBlock(stream, "VRA", Memory.VRAM, 0x10000); + FreezeBlock(stream, "RAM", Memory.RAM, 0x20000); + FreezeBlock(stream, "SRA", Memory.SRAM, 0x20000); + FreezeBlock(stream, "FIL", Memory.FillRAM, 0x8000); + if (Settings.APUEnabled) + { + // APU + FreezeStruct(stream, "APU", &APU, SnapAPU, COUNT(SnapAPU)); + FreezeStruct(stream, "ARE", &IAPU.Registers, SnapAPURegisters, + COUNT(SnapAPURegisters)); + FreezeBlock(stream, "ARA", IAPU.RAM, 0x10000); + FreezeStruct(stream, "SOU", &SoundData, SnapSoundData, + COUNT(SnapSoundData)); + } + if (Settings.SA1) + { + SA1.Registers.PC = SA1.PC - SA1.PCBase; + S9xSA1PackStatus(); + FreezeStruct(stream, "SA1", &SA1, SnapSA1, COUNT(SnapSA1)); + FreezeStruct(stream, "SAR", &SA1.Registers, SnapSA1Registers, + COUNT(SnapSA1Registers)); + } + + if (Settings.SPC7110) + FreezeStruct(stream, "SP7", &s7r, SnapSPC7110, COUNT(SnapSPC7110)); + if (Settings.SPC7110RTC) + FreezeStruct(stream, "RTC", &rtc_f9, SnapS7RTC, COUNT(SnapS7RTC)); + + S9xSetSoundMute(FALSE); #ifdef ZSNES_FX - if (Settings.SuperFX) - S9xSuperFXPostSaveState (); + if (Settings.SuperFX) + S9xSuperFXPostSaveState(); #endif } -int S9xUnfreezeFromStream (STREAM stream) +int S9xUnfreezeFromStream(STREAM stream) { - char buffer [_MAX_PATH + 1]; - char rom_filename [_MAX_PATH + 1]; - int result; - - int version; - unsigned int len = strlen (SNAPSHOT_MAGIC) + 1 + 4 + 1; - if (READ_STREAM (buffer, len, stream) != len) - return (WRONG_FORMAT); - if (strncmp (buffer, SNAPSHOT_MAGIC, strlen (SNAPSHOT_MAGIC)) != 0) - return (WRONG_FORMAT); - if ((version = atoi (&buffer [strlen (SNAPSHOT_MAGIC) + 1])) > SNAPSHOT_VERSION) - return (WRONG_VERSION); - - if ((result = UnfreezeBlock (stream, "NAM", (uint8 *) rom_filename, _MAX_PATH)) != SUCCESS) - return (result); - - if (strcasecmp (rom_filename, Memory.ROMFilename) != 0 && - strcasecmp (S9xBasename (rom_filename), S9xBasename (Memory.ROMFilename)) != 0) - { - S9xMessage (S9X_WARNING, S9X_FREEZE_ROM_NAME, - "Current loaded ROM image doesn't match that required by freeze-game file."); - } - -// ## begin load ## - uint8* local_cpu = NULL; - uint8* local_registers = NULL; - uint8* local_ppu = NULL; - uint8* local_dma = NULL; - uint8* local_vram = NULL; - uint8* local_ram = NULL; - uint8* local_sram = NULL; - uint8* local_fillram = NULL; - uint8* local_apu = NULL; - uint8* local_apu_registers = NULL; - uint8* local_apu_ram = NULL; - uint8* local_apu_sounddata = NULL; - uint8* local_sa1 = NULL; - uint8* local_sa1_registers = NULL; - uint8* local_spc = NULL; - uint8* local_spc_rtc = NULL; - uint8* local_movie_data = NULL; - - do - { - if ((result = UnfreezeStructCopy (stream, "CPU", &local_cpu, SnapCPU, COUNT (SnapCPU))) != SUCCESS) - break; - if ((result = UnfreezeStructCopy (stream, "REG", &local_registers, SnapRegisters, COUNT (SnapRegisters))) != SUCCESS) - break; - if ((result = UnfreezeStructCopy (stream, "PPU", &local_ppu, SnapPPU, COUNT (SnapPPU))) != SUCCESS) - break; - if ((result = UnfreezeStructCopy (stream, "DMA", &local_dma, SnapDMA, COUNT (SnapDMA))) != SUCCESS) - break; - if ((result = UnfreezeBlockCopy (stream, "VRA", &local_vram, 0x10000)) != SUCCESS) - break; - if ((result = UnfreezeBlockCopy (stream, "RAM", &local_ram, 0x20000)) != SUCCESS) - break; - if ((result = UnfreezeBlockCopy (stream, "SRA", &local_sram, 0x20000)) != SUCCESS) - break; - if ((result = UnfreezeBlockCopy (stream, "FIL", &local_fillram, 0x8000)) != SUCCESS) - break; - if (UnfreezeStructCopy (stream, "APU", &local_apu, SnapAPU, COUNT (SnapAPU)) == SUCCESS) - { - if ((result = UnfreezeStructCopy (stream, "ARE", &local_apu_registers, SnapAPURegisters, COUNT (SnapAPURegisters))) != SUCCESS) - break; - if ((result = UnfreezeBlockCopy (stream, "ARA", &local_apu_ram, 0x10000)) != SUCCESS) - break; - if ((result = UnfreezeStructCopy (stream, "SOU", &local_apu_sounddata, SnapSoundData, COUNT (SnapSoundData))) != SUCCESS) - break; - } - if ((result = UnfreezeStructCopy (stream, "SA1", &local_sa1, SnapSA1, COUNT(SnapSA1))) == SUCCESS) - { - if ((result = UnfreezeStructCopy (stream, "SAR", &local_sa1_registers, SnapSA1Registers, COUNT (SnapSA1Registers))) != SUCCESS) - break; - } - - if ((result = UnfreezeStructCopy (stream, "SP7", &local_spc, SnapSPC7110, COUNT(SnapSPC7110))) != SUCCESS) - { - if(Settings.SPC7110) - break; - } - if ((result = UnfreezeStructCopy (stream, "RTC", &local_spc_rtc, SnapS7RTC, COUNT (SnapS7RTC))) != SUCCESS) - { - if(Settings.SPC7110RTC) - break; - } - - result=SUCCESS; - - } while(false); -// ## end load ## - - if (result == SUCCESS) - { - uint32 old_flags = CPU.Flags; - uint32 sa1_old_flags = SA1.Flags; - S9xReset (); - S9xSetSoundMute (TRUE); - - UnfreezeStructFromCopy (&CPU, SnapCPU, COUNT (SnapCPU), local_cpu); - UnfreezeStructFromCopy (&ICPU.Registers, SnapRegisters, COUNT (SnapRegisters), local_registers); - UnfreezeStructFromCopy (&PPU, SnapPPU, COUNT (SnapPPU), local_ppu); - UnfreezeStructFromCopy (DMA, SnapDMA, COUNT (SnapDMA), local_dma); - memcpy (Memory.VRAM, local_vram, 0x10000); - memcpy (Memory.RAM, local_ram, 0x20000); - memcpy (Memory.SRAM, local_sram, 0x20000); - memcpy (Memory.FillRAM, local_fillram, 0x8000); - if(local_apu) - { - UnfreezeStructFromCopy (&APU, SnapAPU, COUNT (SnapAPU), local_apu); - UnfreezeStructFromCopy (&IAPU.Registers, SnapAPURegisters, COUNT (SnapAPURegisters), local_apu_registers); - memcpy (IAPU.RAM, local_apu_ram, 0x10000); - UnfreezeStructFromCopy (&SoundData, SnapSoundData, COUNT (SnapSoundData), local_apu_sounddata); - } - if(local_sa1) - { - UnfreezeStructFromCopy (&SA1, SnapSA1, COUNT (SnapSA1), local_sa1); - UnfreezeStructFromCopy (&SA1.Registers, SnapSA1Registers, COUNT (SnapSA1Registers), local_sa1_registers); - } - if(local_spc) - { - UnfreezeStructFromCopy (&s7r, SnapSPC7110, COUNT (SnapSPC7110), local_spc); - } - if(local_spc_rtc) - { - UnfreezeStructFromCopy (&rtc_f9, SnapS7RTC, COUNT (SnapS7RTC), local_spc_rtc); - } - - FixROMSpeed (); - CPU.Flags |= old_flags & (DEBUG_MODE_FLAG | TRACE_FLAG | - SINGLE_STEP_FLAG | FRAME_ADVANCE_FLAG); - - IPPU.ColorsChanged = TRUE; - IPPU.OBJChanged = TRUE; - CPU.InDMA = FALSE; - S9xFixColourBrightness (); - IPPU.RenderThisFrame = FALSE; - - if (local_apu) - { - S9xSetSoundMute (FALSE); - IAPU.PC = IAPU.RAM + IAPU.Registers.PC; - S9xAPUUnpackStatus (); - if (APUCheckDirectPage ()) - IAPU.DirectPage = IAPU.RAM + 0x100; - else - IAPU.DirectPage = IAPU.RAM; - Settings.APUEnabled = TRUE; - IAPU.APUExecuting = TRUE; - } - else - { - Settings.APUEnabled = FALSE; - IAPU.APUExecuting = FALSE; - S9xSetSoundMute (TRUE); - } - - if (local_sa1) - { - S9xFixSA1AfterSnapshotLoad (); - SA1.Flags |= sa1_old_flags & (TRACE_FLAG); - } - - if (local_spc_rtc) - { - S9xUpdateRTC(); - } - - S9xFixSoundAfterSnapshotLoad (); - - uint8 hdma_byte = Memory.FillRAM[0x420c]; - S9xSetCPU(hdma_byte, 0x420c); - - if(!Memory.FillRAM[0x4213]){ - // most likely an old savestate - Memory.FillRAM[0x4213]=Memory.FillRAM[0x4201]; - if(!Memory.FillRAM[0x4213]) - Memory.FillRAM[0x4213]=Memory.FillRAM[0x4201]=0xFF; - } - - ICPU.ShiftedPB = ICPU.Registers.PB << 16; - ICPU.ShiftedDB = ICPU.Registers.DB << 16; - S9xSetPCBase (ICPU.ShiftedPB + ICPU.Registers.PC); - S9xUnpackStatus (); - S9xFixCycles (); -// S9xReschedule (); // <-- this causes desync when recording or playing movies + char buffer [_MAX_PATH + 1]; + char rom_filename [_MAX_PATH + 1]; + int result; + + int version; + unsigned int len = strlen(SNAPSHOT_MAGIC) + 1 + 4 + 1; + if (READ_STREAM(buffer, len, stream) != len) + return (WRONG_FORMAT); + if (strncmp(buffer, SNAPSHOT_MAGIC, strlen(SNAPSHOT_MAGIC)) != 0) + return (WRONG_FORMAT); + if ((version = atoi(&buffer [strlen(SNAPSHOT_MAGIC) + 1])) > SNAPSHOT_VERSION) + return (WRONG_VERSION); + + if ((result = UnfreezeBlock(stream, "NAM", (uint8*) rom_filename, + _MAX_PATH)) != SUCCESS) + return (result); + + if (strcasecmp(rom_filename, Memory.ROMFilename) != 0 && + strcasecmp(S9xBasename(rom_filename), S9xBasename(Memory.ROMFilename)) != 0) + { + S9xMessage(S9X_WARNING, S9X_FREEZE_ROM_NAME, + "Current loaded ROM image doesn't match that required by freeze-game file."); + } + + // ## begin load ## + uint8* local_cpu = NULL; + uint8* local_registers = NULL; + uint8* local_ppu = NULL; + uint8* local_dma = NULL; + uint8* local_vram = NULL; + uint8* local_ram = NULL; + uint8* local_sram = NULL; + uint8* local_fillram = NULL; + uint8* local_apu = NULL; + uint8* local_apu_registers = NULL; + uint8* local_apu_ram = NULL; + uint8* local_apu_sounddata = NULL; + uint8* local_sa1 = NULL; + uint8* local_sa1_registers = NULL; + uint8* local_spc = NULL; + uint8* local_spc_rtc = NULL; + uint8* local_movie_data = NULL; + + do + { + if ((result = UnfreezeStructCopy(stream, "CPU", &local_cpu, SnapCPU, + COUNT(SnapCPU))) != SUCCESS) + break; + if ((result = UnfreezeStructCopy(stream, "REG", &local_registers, SnapRegisters, + COUNT(SnapRegisters))) != SUCCESS) + break; + if ((result = UnfreezeStructCopy(stream, "PPU", &local_ppu, SnapPPU, + COUNT(SnapPPU))) != SUCCESS) + break; + if ((result = UnfreezeStructCopy(stream, "DMA", &local_dma, SnapDMA, + COUNT(SnapDMA))) != SUCCESS) + break; + if ((result = UnfreezeBlockCopy(stream, "VRA", &local_vram, + 0x10000)) != SUCCESS) + break; + if ((result = UnfreezeBlockCopy(stream, "RAM", &local_ram, 0x20000)) != SUCCESS) + break; + if ((result = UnfreezeBlockCopy(stream, "SRA", &local_sram, + 0x20000)) != SUCCESS) + break; + if ((result = UnfreezeBlockCopy(stream, "FIL", &local_fillram, + 0x8000)) != SUCCESS) + break; + if (UnfreezeStructCopy(stream, "APU", &local_apu, SnapAPU, + COUNT(SnapAPU)) == SUCCESS) + { + if ((result = UnfreezeStructCopy(stream, "ARE", &local_apu_registers, + SnapAPURegisters, COUNT(SnapAPURegisters))) != SUCCESS) + break; + if ((result = UnfreezeBlockCopy(stream, "ARA", &local_apu_ram, + 0x10000)) != SUCCESS) + break; + if ((result = UnfreezeStructCopy(stream, "SOU", &local_apu_sounddata, + SnapSoundData, COUNT(SnapSoundData))) != SUCCESS) + break; + } + if ((result = UnfreezeStructCopy(stream, "SA1", &local_sa1, SnapSA1, + COUNT(SnapSA1))) == SUCCESS) + { + if ((result = UnfreezeStructCopy(stream, "SAR", &local_sa1_registers, + SnapSA1Registers, COUNT(SnapSA1Registers))) != SUCCESS) + break; + } + + if ((result = UnfreezeStructCopy(stream, "SP7", &local_spc, SnapSPC7110, + COUNT(SnapSPC7110))) != SUCCESS) + { + if (Settings.SPC7110) + break; + } + if ((result = UnfreezeStructCopy(stream, "RTC", &local_spc_rtc, SnapS7RTC, + COUNT(SnapS7RTC))) != SUCCESS) + { + if (Settings.SPC7110RTC) + break; + } + + result = SUCCESS; + + } + while (false); + // ## end load ## + + if (result == SUCCESS) + { + uint32 old_flags = CPU.Flags; + uint32 sa1_old_flags = SA1.Flags; + S9xReset(); + S9xSetSoundMute(TRUE); + + UnfreezeStructFromCopy(&CPU, SnapCPU, COUNT(SnapCPU), local_cpu); + UnfreezeStructFromCopy(&ICPU.Registers, SnapRegisters, COUNT(SnapRegisters), + local_registers); + UnfreezeStructFromCopy(&PPU, SnapPPU, COUNT(SnapPPU), local_ppu); + UnfreezeStructFromCopy(DMA, SnapDMA, COUNT(SnapDMA), local_dma); + memcpy(Memory.VRAM, local_vram, 0x10000); + memcpy(Memory.RAM, local_ram, 0x20000); + memcpy(Memory.SRAM, local_sram, 0x20000); + memcpy(Memory.FillRAM, local_fillram, 0x8000); + if (local_apu) + { + UnfreezeStructFromCopy(&APU, SnapAPU, COUNT(SnapAPU), local_apu); + UnfreezeStructFromCopy(&IAPU.Registers, SnapAPURegisters, + COUNT(SnapAPURegisters), local_apu_registers); + memcpy(IAPU.RAM, local_apu_ram, 0x10000); + UnfreezeStructFromCopy(&SoundData, SnapSoundData, COUNT(SnapSoundData), + local_apu_sounddata); + } + if (local_sa1) + { + UnfreezeStructFromCopy(&SA1, SnapSA1, COUNT(SnapSA1), local_sa1); + UnfreezeStructFromCopy(&SA1.Registers, SnapSA1Registers, + COUNT(SnapSA1Registers), local_sa1_registers); + } + if (local_spc) + UnfreezeStructFromCopy(&s7r, SnapSPC7110, COUNT(SnapSPC7110), local_spc); + if (local_spc_rtc) + UnfreezeStructFromCopy(&rtc_f9, SnapS7RTC, COUNT(SnapS7RTC), local_spc_rtc); + + FixROMSpeed(); + CPU.Flags |= old_flags & (DEBUG_MODE_FLAG | TRACE_FLAG | + SINGLE_STEP_FLAG | FRAME_ADVANCE_FLAG); + + IPPU.ColorsChanged = TRUE; + IPPU.OBJChanged = TRUE; + CPU.InDMA = FALSE; + S9xFixColourBrightness(); + IPPU.RenderThisFrame = FALSE; + + if (local_apu) + { + S9xSetSoundMute(FALSE); + IAPU.PC = IAPU.RAM + IAPU.Registers.PC; + S9xAPUUnpackStatus(); + if (APUCheckDirectPage()) + IAPU.DirectPage = IAPU.RAM + 0x100; + else + IAPU.DirectPage = IAPU.RAM; + Settings.APUEnabled = TRUE; + IAPU.APUExecuting = TRUE; + } + else + { + Settings.APUEnabled = FALSE; + IAPU.APUExecuting = FALSE; + S9xSetSoundMute(TRUE); + } + + if (local_sa1) + { + S9xFixSA1AfterSnapshotLoad(); + SA1.Flags |= sa1_old_flags & (TRACE_FLAG); + } + + if (local_spc_rtc) + S9xUpdateRTC(); + + S9xFixSoundAfterSnapshotLoad(); + + uint8 hdma_byte = Memory.FillRAM[0x420c]; + S9xSetCPU(hdma_byte, 0x420c); + + if (!Memory.FillRAM[0x4213]) + { + // most likely an old savestate + Memory.FillRAM[0x4213] = Memory.FillRAM[0x4201]; + if (!Memory.FillRAM[0x4213]) + Memory.FillRAM[0x4213] = Memory.FillRAM[0x4201] = 0xFF; + } + + ICPU.ShiftedPB = ICPU.Registers.PB << 16; + ICPU.ShiftedDB = ICPU.Registers.DB << 16; + S9xSetPCBase(ICPU.ShiftedPB + ICPU.Registers.PC); + S9xUnpackStatus(); + S9xFixCycles(); + // S9xReschedule (); // <-- this causes desync when recording or playing movies #ifdef ZSNES_FX - if (Settings.SuperFX) - S9xSuperFXPostLoadState (); + if (Settings.SuperFX) + S9xSuperFXPostLoadState(); #endif - - S9xSRTCPostLoadState (); - if (Settings.SDD1) - S9xSDD1PostLoadState (); - } + + S9xSRTCPostLoadState(); + if (Settings.SDD1) + S9xSDD1PostLoadState(); + } if (local_cpu) free(local_cpu); if (local_registers) free(local_registers); @@ -913,878 +946,883 @@ int S9xUnfreezeFromStream (STREAM stream) if (local_spc_rtc) free(local_spc_rtc); if (local_movie_data) free(local_movie_data); - return (result); + return (result); } -int FreezeSize (int size, int type) +int FreezeSize(int size, int type) { - switch (type) - { - case uint16_ARRAY_V: - return (size * 2); - case uint32_ARRAY_V: - return (size * 4); - default: - return (size); - } + switch (type) + { + case uint16_ARRAY_V: + return (size * 2); + case uint32_ARRAY_V: + return (size * 4); + default: + return (size); + } } -void FreezeStruct (STREAM stream, const char *name, void *base, FreezeData *fields, - int num_fields) +void FreezeStruct(STREAM stream, const char* name, void* base, + FreezeData* fields, + int num_fields) { - // Work out the size of the required block - int len = 0; - int i; - int j; - - for (i = 0; i < num_fields; i++) - { - if (fields [i].offset + FreezeSize (fields [i].size, - fields [i].type) > len) - len = fields [i].offset + FreezeSize (fields [i].size, - fields [i].type); - } - - uint8 *block = (uint8*) malloc(len); - uint8 *ptr = block; - uint16 word; - uint32 dword; - int64 qword; - - // Build the block ready to be streamed out - for (i = 0; i < num_fields; i++) - { - switch (fields [i].type) - { - case INT_V: - switch (fields [i].size) - { - case 1: - *ptr++ = *((uint8 *) base + fields [i].offset); - break; - case 2: - word = *((uint16 *) ((uint8 *) base + fields [i].offset)); - *ptr++ = (uint8) (word >> 8); - *ptr++ = (uint8) word; - break; - case 4: - dword = *((uint32 *) ((uint8 *) base + fields [i].offset)); - *ptr++ = (uint8) (dword >> 24); - *ptr++ = (uint8) (dword >> 16); - *ptr++ = (uint8) (dword >> 8); - *ptr++ = (uint8) dword; - break; - case 8: - qword = *((int64 *) ((uint8 *) base + fields [i].offset)); - *ptr++ = (uint8) (qword >> 56); - *ptr++ = (uint8) (qword >> 48); - *ptr++ = (uint8) (qword >> 40); - *ptr++ = (uint8) (qword >> 32); - *ptr++ = (uint8) (qword >> 24); - *ptr++ = (uint8) (qword >> 16); - *ptr++ = (uint8) (qword >> 8); - *ptr++ = (uint8) qword; - break; - } - break; - case uint8_ARRAY_V: - // memmove converted: Different mallocs [Neb] - memcpy (ptr, (uint8 *) base + fields [i].offset, fields [i].size); - ptr += fields [i].size; - break; - case uint16_ARRAY_V: - for (j = 0; j < fields [i].size; j++) - { - word = *((uint16 *) ((uint8 *) base + fields [i].offset + j * 2)); - *ptr++ = (uint8) (word >> 8); - *ptr++ = (uint8) word; - } - break; - case uint32_ARRAY_V: - for (j = 0; j < fields [i].size; j++) - { - dword = *((uint32 *) ((uint8 *) base + fields [i].offset + j * 4)); - *ptr++ = (uint8) (dword >> 24); - *ptr++ = (uint8) (dword >> 16); - *ptr++ = (uint8) (dword >> 8); - *ptr++ = (uint8) dword; - } - break; - } - } - - FreezeBlock (stream, name, block, len); - free(block); + // Work out the size of the required block + int len = 0; + int i; + int j; + + for (i = 0; i < num_fields; i++) + { + if (fields [i].offset + FreezeSize(fields [i].size, + fields [i].type) > len) + len = fields [i].offset + FreezeSize(fields [i].size, + fields [i].type); + } + + uint8* block = (uint8*) malloc(len); + uint8* ptr = block; + uint16 word; + uint32 dword; + int64 qword; + + // Build the block ready to be streamed out + for (i = 0; i < num_fields; i++) + { + switch (fields [i].type) + { + case INT_V: + switch (fields [i].size) + { + case 1: + *ptr++ = *((uint8*) base + fields [i].offset); + break; + case 2: + word = *((uint16*)((uint8*) base + fields [i].offset)); + *ptr++ = (uint8)(word >> 8); + *ptr++ = (uint8) word; + break; + case 4: + dword = *((uint32*)((uint8*) base + fields [i].offset)); + *ptr++ = (uint8)(dword >> 24); + *ptr++ = (uint8)(dword >> 16); + *ptr++ = (uint8)(dword >> 8); + *ptr++ = (uint8) dword; + break; + case 8: + qword = *((int64*)((uint8*) base + fields [i].offset)); + *ptr++ = (uint8)(qword >> 56); + *ptr++ = (uint8)(qword >> 48); + *ptr++ = (uint8)(qword >> 40); + *ptr++ = (uint8)(qword >> 32); + *ptr++ = (uint8)(qword >> 24); + *ptr++ = (uint8)(qword >> 16); + *ptr++ = (uint8)(qword >> 8); + *ptr++ = (uint8) qword; + break; + } + break; + case uint8_ARRAY_V: + // memmove converted: Different mallocs [Neb] + memcpy(ptr, (uint8*) base + fields [i].offset, fields [i].size); + ptr += fields [i].size; + break; + case uint16_ARRAY_V: + for (j = 0; j < fields [i].size; j++) + { + word = *((uint16*)((uint8*) base + fields [i].offset + j * 2)); + *ptr++ = (uint8)(word >> 8); + *ptr++ = (uint8) word; + } + break; + case uint32_ARRAY_V: + for (j = 0; j < fields [i].size; j++) + { + dword = *((uint32*)((uint8*) base + fields [i].offset + j * 4)); + *ptr++ = (uint8)(dword >> 24); + *ptr++ = (uint8)(dword >> 16); + *ptr++ = (uint8)(dword >> 8); + *ptr++ = (uint8) dword; + } + break; + } + } + + FreezeBlock(stream, name, block, len); + free(block); } -void FreezeBlock (STREAM stream, const char *name, uint8 *block, int size) +void FreezeBlock(STREAM stream, const char* name, uint8* block, int size) { - char buffer [512]; - sprintf (buffer, "%s:%06d:", name, size); - WRITE_STREAM (buffer, strlen (buffer), stream); - WRITE_STREAM ((char*)block, size, stream); - + char buffer [512]; + sprintf(buffer, "%s:%06d:", name, size); + WRITE_STREAM(buffer, strlen(buffer), stream); + WRITE_STREAM((char*)block, size, stream); + } -int UnfreezeStruct (STREAM stream, const char *name, void *base, FreezeData *fields, - int num_fields) +int UnfreezeStruct(STREAM stream, const char* name, void* base, + FreezeData* fields, + int num_fields) { - // Work out the size of the required block - int len = 0; - int i; - int j; - - for (i = 0; i < num_fields; i++) - { - if (fields [i].offset + FreezeSize (fields [i].size, - fields [i].type) > len) - len = fields [i].offset + FreezeSize (fields [i].size, - fields [i].type); - } - - uint8 *block = (uint8*) malloc(len); - uint8 *ptr = block; - uint16 word; - uint32 dword; - int64 qword; - int result; - - if ((result = UnfreezeBlock (stream, name, block, len)) != SUCCESS) - { + // Work out the size of the required block + int len = 0; + int i; + int j; + + for (i = 0; i < num_fields; i++) + { + if (fields [i].offset + FreezeSize(fields [i].size, + fields [i].type) > len) + len = fields [i].offset + FreezeSize(fields [i].size, + fields [i].type); + } + + uint8* block = (uint8*) malloc(len); + uint8* ptr = block; + uint16 word; + uint32 dword; + int64 qword; + int result; + + if ((result = UnfreezeBlock(stream, name, block, len)) != SUCCESS) + { free(block); - return (result); - } - - // Unpack the block of data into a C structure - for (i = 0; i < num_fields; i++) - { - switch (fields [i].type) - { - case INT_V: - switch (fields [i].size) - { - case 1: - *((uint8 *) base + fields [i].offset) = *ptr++; - break; - case 2: - word = *ptr++ << 8; - word |= *ptr++; - *((uint16 *) ((uint8 *) base + fields [i].offset)) = word; - break; - case 4: - dword = *ptr++ << 24; - dword |= *ptr++ << 16; - dword |= *ptr++ << 8; - dword |= *ptr++; - *((uint32 *) ((uint8 *) base + fields [i].offset)) = dword; - break; - case 8: - qword = (int64) *ptr++ << 56; - qword |= (int64) *ptr++ << 48; - qword |= (int64) *ptr++ << 40; - qword |= (int64) *ptr++ << 32; - qword |= (int64) *ptr++ << 24; - qword |= (int64) *ptr++ << 16; - qword |= (int64) *ptr++ << 8; - qword |= (int64) *ptr++; - *((int64 *) ((uint8 *) base + fields [i].offset)) = qword; - break; - } - break; - case uint8_ARRAY_V: - // memmove converted: Different mallocs [Neb] - memcpy ((uint8 *) base + fields [i].offset, ptr, fields [i].size); - ptr += fields [i].size; - break; - case uint16_ARRAY_V: - for (j = 0; j < fields [i].size; j++) - { - word = *ptr++ << 8; - word |= *ptr++; - *((uint16 *) ((uint8 *) base + fields [i].offset + j * 2)) = word; - } - break; - case uint32_ARRAY_V: - for (j = 0; j < fields [i].size; j++) - { - dword = *ptr++ << 24; - dword |= *ptr++ << 16; - dword |= *ptr++ << 8; - dword |= *ptr++; - *((uint32 *) ((uint8 *) base + fields [i].offset + j * 4)) = dword; - } - break; - } - } - - free(block); - return (result); + return (result); + } + + // Unpack the block of data into a C structure + for (i = 0; i < num_fields; i++) + { + switch (fields [i].type) + { + case INT_V: + switch (fields [i].size) + { + case 1: + *((uint8*) base + fields [i].offset) = *ptr++; + break; + case 2: + word = *ptr++ << 8; + word |= *ptr++; + *((uint16*)((uint8*) base + fields [i].offset)) = word; + break; + case 4: + dword = *ptr++ << 24; + dword |= *ptr++ << 16; + dword |= *ptr++ << 8; + dword |= *ptr++; + *((uint32*)((uint8*) base + fields [i].offset)) = dword; + break; + case 8: + qword = (int64) * ptr++ << 56; + qword |= (int64) * ptr++ << 48; + qword |= (int64) * ptr++ << 40; + qword |= (int64) * ptr++ << 32; + qword |= (int64) * ptr++ << 24; + qword |= (int64) * ptr++ << 16; + qword |= (int64) * ptr++ << 8; + qword |= (int64) * ptr++; + *((int64*)((uint8*) base + fields [i].offset)) = qword; + break; + } + break; + case uint8_ARRAY_V: + // memmove converted: Different mallocs [Neb] + memcpy((uint8*) base + fields [i].offset, ptr, fields [i].size); + ptr += fields [i].size; + break; + case uint16_ARRAY_V: + for (j = 0; j < fields [i].size; j++) + { + word = *ptr++ << 8; + word |= *ptr++; + *((uint16*)((uint8*) base + fields [i].offset + j * 2)) = word; + } + break; + case uint32_ARRAY_V: + for (j = 0; j < fields [i].size; j++) + { + dword = *ptr++ << 24; + dword |= *ptr++ << 16; + dword |= *ptr++ << 8; + dword |= *ptr++; + *((uint32*)((uint8*) base + fields [i].offset + j * 4)) = dword; + } + break; + } + } + + free(block); + return (result); } -int UnfreezeBlock (STREAM stream, const char *name, uint8 *block, int size) +int UnfreezeBlock(STREAM stream, const char* name, uint8* block, int size) { - char buffer [20]; - int len = 0; - int rem = 0; - int rew_len; - if (READ_STREAM (buffer, 11, stream) != 11 || - strncmp (buffer, name, 3) != 0 || buffer [3] != ':' || - (len = atoi (&buffer [4])) == 0) - { - REVERT_STREAM(stream, FIND_STREAM(stream)-11, 0); - return (WRONG_FORMAT); - } - - if (len > size) - { - rem = len - size; - len = size; - } - if ((rew_len=READ_STREAM ((char*)block, len, stream)) != len) - { - REVERT_STREAM(stream, FIND_STREAM(stream)-11-rew_len, 0); - return (WRONG_FORMAT); - } - if (rem) - { - char *junk = (char*) malloc(rem); - READ_STREAM (junk, rem, stream); + char buffer [20]; + int len = 0; + int rem = 0; + int rew_len; + if (READ_STREAM(buffer, 11, stream) != 11 || + strncmp(buffer, name, 3) != 0 || buffer [3] != ':' || + (len = atoi(&buffer [4])) == 0) + { + REVERT_STREAM(stream, FIND_STREAM(stream) - 11, 0); + return (WRONG_FORMAT); + } + + if (len > size) + { + rem = len - size; + len = size; + } + if ((rew_len = READ_STREAM((char*)block, len, stream)) != len) + { + REVERT_STREAM(stream, FIND_STREAM(stream) - 11 - rew_len, 0); + return (WRONG_FORMAT); + } + if (rem) + { + char* junk = (char*) malloc(rem); + READ_STREAM(junk, rem, stream); free(junk); - } - - return (SUCCESS); + } + + return (SUCCESS); } -int UnfreezeStructCopy (STREAM stream, const char *name, uint8** block, FreezeData *fields, int num_fields) +int UnfreezeStructCopy(STREAM stream, const char* name, uint8** block, + FreezeData* fields, int num_fields) { - // Work out the size of the required block - int len = 0; - int i; - - for (i = 0; i < num_fields; i++) - { - if (fields [i].offset + FreezeSize (fields [i].size, - fields [i].type) > len) - len = fields [i].offset + FreezeSize (fields [i].size, - fields [i].type); - } - - return (UnfreezeBlockCopy (stream, name, block, len)); + // Work out the size of the required block + int len = 0; + int i; + + for (i = 0; i < num_fields; i++) + { + if (fields [i].offset + FreezeSize(fields [i].size, + fields [i].type) > len) + len = fields [i].offset + FreezeSize(fields [i].size, + fields [i].type); + } + + return (UnfreezeBlockCopy(stream, name, block, len)); } -void UnfreezeStructFromCopy (void *base, FreezeData *fields, int num_fields, uint8* block) +void UnfreezeStructFromCopy(void* base, FreezeData* fields, int num_fields, + uint8* block) { - int i; - int j; - uint8 *ptr = block; - uint16 word; - uint32 dword; - int64 qword; - - // Unpack the block of data into a C structure - for (i = 0; i < num_fields; i++) - { - switch (fields [i].type) - { - case INT_V: - switch (fields [i].size) - { - case 1: - *((uint8 *) base + fields [i].offset) = *ptr++; - break; - case 2: - word = *ptr++ << 8; - word |= *ptr++; - *((uint16 *) ((uint8 *) base + fields [i].offset)) = word; - break; - case 4: - dword = *ptr++ << 24; - dword |= *ptr++ << 16; - dword |= *ptr++ << 8; - dword |= *ptr++; - *((uint32 *) ((uint8 *) base + fields [i].offset)) = dword; - break; - case 8: - qword = (int64) *ptr++ << 56; - qword |= (int64) *ptr++ << 48; - qword |= (int64) *ptr++ << 40; - qword |= (int64) *ptr++ << 32; - qword |= (int64) *ptr++ << 24; - qword |= (int64) *ptr++ << 16; - qword |= (int64) *ptr++ << 8; - qword |= (int64) *ptr++; - *((int64 *) ((uint8 *) base + fields [i].offset)) = qword; - break; - } - break; - case uint8_ARRAY_V: - // memmove required: Source could point within dest [Neb] - memmove ((uint8 *) base + fields [i].offset, ptr, fields [i].size); - ptr += fields [i].size; - break; - case uint16_ARRAY_V: - for (j = 0; j < fields [i].size; j++) - { - word = *ptr++ << 8; - word |= *ptr++; - *((uint16 *) ((uint8 *) base + fields [i].offset + j * 2)) = word; - } - break; - case uint32_ARRAY_V: - for (j = 0; j < fields [i].size; j++) - { - dword = *ptr++ << 24; - dword |= *ptr++ << 16; - dword |= *ptr++ << 8; - dword |= *ptr++; - *((uint32 *) ((uint8 *) base + fields [i].offset + j * 4)) = dword; - } - break; - } - } + int i; + int j; + uint8* ptr = block; + uint16 word; + uint32 dword; + int64 qword; + + // Unpack the block of data into a C structure + for (i = 0; i < num_fields; i++) + { + switch (fields [i].type) + { + case INT_V: + switch (fields [i].size) + { + case 1: + *((uint8*) base + fields [i].offset) = *ptr++; + break; + case 2: + word = *ptr++ << 8; + word |= *ptr++; + *((uint16*)((uint8*) base + fields [i].offset)) = word; + break; + case 4: + dword = *ptr++ << 24; + dword |= *ptr++ << 16; + dword |= *ptr++ << 8; + dword |= *ptr++; + *((uint32*)((uint8*) base + fields [i].offset)) = dword; + break; + case 8: + qword = (int64) * ptr++ << 56; + qword |= (int64) * ptr++ << 48; + qword |= (int64) * ptr++ << 40; + qword |= (int64) * ptr++ << 32; + qword |= (int64) * ptr++ << 24; + qword |= (int64) * ptr++ << 16; + qword |= (int64) * ptr++ << 8; + qword |= (int64) * ptr++; + *((int64*)((uint8*) base + fields [i].offset)) = qword; + break; + } + break; + case uint8_ARRAY_V: + // memmove required: Source could point within dest [Neb] + memmove((uint8*) base + fields [i].offset, ptr, fields [i].size); + ptr += fields [i].size; + break; + case uint16_ARRAY_V: + for (j = 0; j < fields [i].size; j++) + { + word = *ptr++ << 8; + word |= *ptr++; + *((uint16*)((uint8*) base + fields [i].offset + j * 2)) = word; + } + break; + case uint32_ARRAY_V: + for (j = 0; j < fields [i].size; j++) + { + dword = *ptr++ << 24; + dword |= *ptr++ << 16; + dword |= *ptr++ << 8; + dword |= *ptr++; + *((uint32*)((uint8*) base + fields [i].offset + j * 4)) = dword; + } + break; + } + } } -int UnfreezeBlockCopy (STREAM stream, const char *name, uint8** block, int size) +int UnfreezeBlockCopy(STREAM stream, const char* name, uint8** block, int size) { - *block = (uint8*) malloc(size); - int result; - - if ((result = UnfreezeBlock (stream, name, *block, size)) != SUCCESS) - { + *block = (uint8*) malloc(size); + int result; + + if ((result = UnfreezeBlock(stream, name, *block, size)) != SUCCESS) + { free((*block)); - *block = NULL; - return (result); - } - - return (result); + *block = NULL; + return (result); + } + + return (result); } extern uint8 spc_dump_dsp[0x100]; -bool8 S9xSPCDump (const char *filename) +bool8 S9xSPCDump(const char* filename) { - return (FALSE); + return (FALSE); #if 0 - static uint8 header [] = { - 'S', 'N', 'E', 'S', '-', 'S', 'P', 'C', '7', '0', '0', ' ', - 'S', 'o', 'u', 'n', 'd', ' ', 'F', 'i', 'l', 'e', ' ', - 'D', 'a', 't', 'a', ' ', 'v', '0', '.', '3', '0', 26, 26, 26 - }; - static uint8 version = { - 0x1e - }; - - FILE *fs; - - S9xSetSoundMute (TRUE); - - if (!(fs = fopen (filename, "wb"))) - return (FALSE); - - // The SPC file format: - // 0000: header: 'SNES-SPC700 Sound File Data v0.30',26,26,26 - // 0036: version: $1e - // 0037: SPC700 PC: - // 0039: SPC700 A: - // 0040: SPC700 X: - // 0041: SPC700 Y: - // 0042: SPC700 P: - // 0043: SPC700 S: - // 0044: Reserved: 0, 0, 0, 0 - // 0048: Title of game: 32 bytes - // 0000: Song name: 32 bytes - // 0000: Name of dumper: 32 bytes - // 0000: Comments: 32 bytes - // 0000: Date of SPC dump: 4 bytes - // 0000: Fade out time in milliseconds: 4 bytes - // 0000: Fade out length in milliseconds: 2 bytes - // 0000: Default channel enables: 1 bytes - // 0000: Emulator used to dump .SPC files: 1 byte, 1 == ZSNES - // 0000: Reserved: 36 bytes - // 0256: SPC700 RAM: 64K - // ----: DSP Registers: 256 bytes - - if (fwrite (header, sizeof (header), 1, fs) != 1 || - fputc (version, fs) == EOF || - fseek (fs, 37, SEEK_SET) == EOF || - fputc (APURegisters.PC & 0xff, fs) == EOF || - fputc (APURegisters.PC >> 8, fs) == EOF || - fputc (APURegisters.YA.B.A, fs) == EOF || - fputc (APURegisters.X, fs) == EOF || - fputc (APURegisters.YA.B.Y, fs) == EOF || - fputc (APURegisters.P, fs) == EOF || - fputc (APURegisters.S, fs) == EOF || - fseek (fs, 256, SEEK_SET) == EOF || - fwrite (IAPU.RAM, 0x10000, 1, fs) != 1 || - fwrite (spc_dump_dsp, 1, 256, fs) != 256 || - fwrite (APU.ExtraRAM, 64, 1, fs) != 1 || - fclose (fs) < 0) - { - S9xSetSoundMute (FALSE); - return (FALSE); - } - S9xSetSoundMute (FALSE); - return (TRUE); + static uint8 header [] = + { + 'S', 'N', 'E', 'S', '-', 'S', 'P', 'C', '7', '0', '0', ' ', + 'S', 'o', 'u', 'n', 'd', ' ', 'F', 'i', 'l', 'e', ' ', + 'D', 'a', 't', 'a', ' ', 'v', '0', '.', '3', '0', 26, 26, 26 + }; + static uint8 version = + { + 0x1e + }; + + FILE* fs; + + S9xSetSoundMute(TRUE); + + if (!(fs = fopen(filename, "wb"))) + return (FALSE); + + // The SPC file format: + // 0000: header: 'SNES-SPC700 Sound File Data v0.30',26,26,26 + // 0036: version: $1e + // 0037: SPC700 PC: + // 0039: SPC700 A: + // 0040: SPC700 X: + // 0041: SPC700 Y: + // 0042: SPC700 P: + // 0043: SPC700 S: + // 0044: Reserved: 0, 0, 0, 0 + // 0048: Title of game: 32 bytes + // 0000: Song name: 32 bytes + // 0000: Name of dumper: 32 bytes + // 0000: Comments: 32 bytes + // 0000: Date of SPC dump: 4 bytes + // 0000: Fade out time in milliseconds: 4 bytes + // 0000: Fade out length in milliseconds: 2 bytes + // 0000: Default channel enables: 1 bytes + // 0000: Emulator used to dump .SPC files: 1 byte, 1 == ZSNES + // 0000: Reserved: 36 bytes + // 0256: SPC700 RAM: 64K + // ----: DSP Registers: 256 bytes + + if (fwrite(header, sizeof(header), 1, fs) != 1 || + fputc(version, fs) == EOF || + fseek(fs, 37, SEEK_SET) == EOF || + fputc(APURegisters.PC & 0xff, fs) == EOF || + fputc(APURegisters.PC >> 8, fs) == EOF || + fputc(APURegisters.YA.B.A, fs) == EOF || + fputc(APURegisters.X, fs) == EOF || + fputc(APURegisters.YA.B.Y, fs) == EOF || + fputc(APURegisters.P, fs) == EOF || + fputc(APURegisters.S, fs) == EOF || + fseek(fs, 256, SEEK_SET) == EOF || + fwrite(IAPU.RAM, 0x10000, 1, fs) != 1 || + fwrite(spc_dump_dsp, 1, 256, fs) != 256 || + fwrite(APU.ExtraRAM, 64, 1, fs) != 1 || + fclose(fs) < 0) + { + S9xSetSoundMute(FALSE); + return (FALSE); + } + S9xSetSoundMute(FALSE); + return (TRUE); #endif } -bool8 S9xUnfreezeZSNES (const char *filename) +bool8 S9xUnfreezeZSNES(const char* filename) { - FILE *fs; - uint8 t [4000]; - - if (!(fs = fopen (filename, "rb"))) - return (FALSE); - - if (fread ((char*)t, 64, 1, fs) == 1 && - strncmp ((char *) t, "ZSNES Save State File V0.6", 26) == 0) - { - S9xReset (); - S9xSetSoundMute (TRUE); - - // 28 Curr cycle - CPU.V_Counter = READ_WORD (&t [29]); - // 33 instrset - Settings.APUEnabled = t [36]; - - // 34 bcycpl cycles per scanline - // 35 cycphb cyclers per hblank - - ICPU.Registers.A.W = READ_WORD (&t [41]); - ICPU.Registers.DB = t [43]; - ICPU.Registers.PB = t [44]; - ICPU.Registers.S.W = READ_WORD (&t [45]); - ICPU.Registers.D.W = READ_WORD (&t [47]); - ICPU.Registers.X.W = READ_WORD (&t [49]); - ICPU.Registers.Y.W = READ_WORD (&t [51]); - ICPU.Registers.P.W = READ_WORD (&t [53]); - ICPU.Registers.PC = READ_WORD (&t [55]); - - fread ((char*)t, 1, 8, fs); - fread ((char*)t, 1, 3019, fs); - S9xSetCPU (t [2], 0x4200); - Memory.FillRAM [0x4210] = t [3]; - PPU.IRQVBeamPos = READ_WORD (&t [4]); - PPU.IRQHBeamPos = READ_WORD (&t [2527]); - PPU.Brightness = t [6]; - PPU.ForcedBlanking = t [8] >> 7; - - int i; - for (i = 0; i < 544; i++) - S9xSetPPU (t [0464 + i], 0x2104); - - PPU.OBJNameBase = READ_WORD (&t [9]); - PPU.OBJNameSelect = READ_WORD (&t [13]) - PPU.OBJNameBase; - switch (t [18]) - { - case 4: - if (t [17] == 1) - PPU.OBJSizeSelect = 0; - else - PPU.OBJSizeSelect = 6; - break; - case 16: - if (t [17] == 1) - PPU.OBJSizeSelect = 1; - else - PPU.OBJSizeSelect = 3; - break; - default: - case 64: - if (t [17] == 1) - PPU.OBJSizeSelect = 2; - else - if (t [17] == 4) - PPU.OBJSizeSelect = 4; - else - PPU.OBJSizeSelect = 5; - break; - } - PPU.OAMAddr = READ_WORD (&t [25]); - PPU.SavedOAMAddr = READ_WORD (&t [27]); - PPU.FirstSprite = t [29]; - PPU.BGMode = t [30]; - PPU.BG3Priority = t [31]; - PPU.BG[0].BGSize = (t [32] >> 0) & 1; - PPU.BG[1].BGSize = (t [32] >> 1) & 1; - PPU.BG[2].BGSize = (t [32] >> 2) & 1; - PPU.BG[3].BGSize = (t [32] >> 3) & 1; - PPU.Mosaic = t [33] + 1; - PPU.BGMosaic [0] = (t [34] & 1) != 0; - PPU.BGMosaic [1] = (t [34] & 2) != 0; - PPU.BGMosaic [2] = (t [34] & 4) != 0; - PPU.BGMosaic [3] = (t [34] & 8) != 0; - PPU.BG [0].SCBase = READ_WORD (&t [35]) >> 1; - PPU.BG [1].SCBase = READ_WORD (&t [37]) >> 1; - PPU.BG [2].SCBase = READ_WORD (&t [39]) >> 1; - PPU.BG [3].SCBase = READ_WORD (&t [41]) >> 1; - PPU.BG [0].SCSize = t [67]; - PPU.BG [1].SCSize = t [68]; - PPU.BG [2].SCSize = t [69]; - PPU.BG [3].SCSize = t [70]; - PPU.BG[0].NameBase = READ_WORD (&t [71]) >> 1; - PPU.BG[1].NameBase = READ_WORD (&t [73]) >> 1; - PPU.BG[2].NameBase = READ_WORD (&t [75]) >> 1; - PPU.BG[3].NameBase = READ_WORD (&t [77]) >> 1; - PPU.BG[0].HOffset = READ_WORD (&t [79]); - PPU.BG[1].HOffset = READ_WORD (&t [81]); - PPU.BG[2].HOffset = READ_WORD (&t [83]); - PPU.BG[3].HOffset = READ_WORD (&t [85]); - PPU.BG[0].VOffset = READ_WORD (&t [89]); - PPU.BG[1].VOffset = READ_WORD (&t [91]); - PPU.BG[2].VOffset = READ_WORD (&t [93]); - PPU.BG[3].VOffset = READ_WORD (&t [95]); - PPU.VMA.Increment = READ_WORD (&t [97]) >> 1; - PPU.VMA.High = t [99]; + FILE* fs; + uint8 t [4000]; + + if (!(fs = fopen(filename, "rb"))) + return (FALSE); + + if (fread((char*)t, 64, 1, fs) == 1 && + strncmp((char*) t, "ZSNES Save State File V0.6", 26) == 0) + { + S9xReset(); + S9xSetSoundMute(TRUE); + + // 28 Curr cycle + CPU.V_Counter = READ_WORD(&t [29]); + // 33 instrset + Settings.APUEnabled = t [36]; + + // 34 bcycpl cycles per scanline + // 35 cycphb cyclers per hblank + + ICPU.Registers.A.W = READ_WORD(&t [41]); + ICPU.Registers.DB = t [43]; + ICPU.Registers.PB = t [44]; + ICPU.Registers.S.W = READ_WORD(&t [45]); + ICPU.Registers.D.W = READ_WORD(&t [47]); + ICPU.Registers.X.W = READ_WORD(&t [49]); + ICPU.Registers.Y.W = READ_WORD(&t [51]); + ICPU.Registers.P.W = READ_WORD(&t [53]); + ICPU.Registers.PC = READ_WORD(&t [55]); + + fread((char*)t, 1, 8, fs); + fread((char*)t, 1, 3019, fs); + S9xSetCPU(t [2], 0x4200); + Memory.FillRAM [0x4210] = t [3]; + PPU.IRQVBeamPos = READ_WORD(&t [4]); + PPU.IRQHBeamPos = READ_WORD(&t [2527]); + PPU.Brightness = t [6]; + PPU.ForcedBlanking = t [8] >> 7; + + int i; + for (i = 0; i < 544; i++) + S9xSetPPU(t [0464 + i], 0x2104); + + PPU.OBJNameBase = READ_WORD(&t [9]); + PPU.OBJNameSelect = READ_WORD(&t [13]) - PPU.OBJNameBase; + switch (t [18]) + { + case 4: + if (t [17] == 1) + PPU.OBJSizeSelect = 0; + else + PPU.OBJSizeSelect = 6; + break; + case 16: + if (t [17] == 1) + PPU.OBJSizeSelect = 1; + else + PPU.OBJSizeSelect = 3; + break; + default: + case 64: + if (t [17] == 1) + PPU.OBJSizeSelect = 2; + else if (t [17] == 4) + PPU.OBJSizeSelect = 4; + else + PPU.OBJSizeSelect = 5; + break; + } + PPU.OAMAddr = READ_WORD(&t [25]); + PPU.SavedOAMAddr = READ_WORD(&t [27]); + PPU.FirstSprite = t [29]; + PPU.BGMode = t [30]; + PPU.BG3Priority = t [31]; + PPU.BG[0].BGSize = (t [32] >> 0) & 1; + PPU.BG[1].BGSize = (t [32] >> 1) & 1; + PPU.BG[2].BGSize = (t [32] >> 2) & 1; + PPU.BG[3].BGSize = (t [32] >> 3) & 1; + PPU.Mosaic = t [33] + 1; + PPU.BGMosaic [0] = (t [34] & 1) != 0; + PPU.BGMosaic [1] = (t [34] & 2) != 0; + PPU.BGMosaic [2] = (t [34] & 4) != 0; + PPU.BGMosaic [3] = (t [34] & 8) != 0; + PPU.BG [0].SCBase = READ_WORD(&t [35]) >> 1; + PPU.BG [1].SCBase = READ_WORD(&t [37]) >> 1; + PPU.BG [2].SCBase = READ_WORD(&t [39]) >> 1; + PPU.BG [3].SCBase = READ_WORD(&t [41]) >> 1; + PPU.BG [0].SCSize = t [67]; + PPU.BG [1].SCSize = t [68]; + PPU.BG [2].SCSize = t [69]; + PPU.BG [3].SCSize = t [70]; + PPU.BG[0].NameBase = READ_WORD(&t [71]) >> 1; + PPU.BG[1].NameBase = READ_WORD(&t [73]) >> 1; + PPU.BG[2].NameBase = READ_WORD(&t [75]) >> 1; + PPU.BG[3].NameBase = READ_WORD(&t [77]) >> 1; + PPU.BG[0].HOffset = READ_WORD(&t [79]); + PPU.BG[1].HOffset = READ_WORD(&t [81]); + PPU.BG[2].HOffset = READ_WORD(&t [83]); + PPU.BG[3].HOffset = READ_WORD(&t [85]); + PPU.BG[0].VOffset = READ_WORD(&t [89]); + PPU.BG[1].VOffset = READ_WORD(&t [91]); + PPU.BG[2].VOffset = READ_WORD(&t [93]); + PPU.BG[3].VOffset = READ_WORD(&t [95]); + PPU.VMA.Increment = READ_WORD(&t [97]) >> 1; + PPU.VMA.High = t [99]; #ifndef CORRECT_VRAM_READS - IPPU.FirstVRAMRead = t [100]; + IPPU.FirstVRAMRead = t [100]; #endif - S9xSetPPU (t [2512], 0x2115); - PPU.VMA.Address = READ_DWORD (&t [101]); - for (i = 0; i < 512; i++) - S9xSetPPU (t [1488 + i], 0x2122); - - PPU.CGADD = (uint8) READ_WORD (&t [105]); - Memory.FillRAM [0x212c] = t [108]; - Memory.FillRAM [0x212d] = t [109]; - PPU.ScreenHeight = READ_WORD (&t [111]); - Memory.FillRAM [0x2133] = t [2526]; - Memory.FillRAM [0x4202] = t [113]; - Memory.FillRAM [0x4204] = t [114]; - Memory.FillRAM [0x4205] = t [115]; - Memory.FillRAM [0x4214] = t [116]; - Memory.FillRAM [0x4215] = t [117]; - Memory.FillRAM [0x4216] = t [118]; - Memory.FillRAM [0x4217] = t [119]; - PPU.VBeamPosLatched = READ_WORD (&t [122]); - PPU.HBeamPosLatched = READ_WORD (&t [120]); - PPU.Window1Left = t [127]; - PPU.Window1Right = t [128]; - PPU.Window2Left = t [129]; - PPU.Window2Right = t [130]; - S9xSetPPU (t [131] | (t [132] << 4), 0x2123); - S9xSetPPU (t [133] | (t [134] << 4), 0x2124); - S9xSetPPU (t [135] | (t [136] << 4), 0x2125); - S9xSetPPU (t [137], 0x212a); - S9xSetPPU (t [138], 0x212b); - S9xSetPPU (t [139], 0x212e); - S9xSetPPU (t [140], 0x212f); - S9xSetPPU (t [141], 0x211a); - PPU.MatrixA = READ_WORD (&t [142]); - PPU.MatrixB = READ_WORD (&t [144]); - PPU.MatrixC = READ_WORD (&t [146]); - PPU.MatrixD = READ_WORD (&t [148]); - PPU.CentreX = READ_WORD (&t [150]); - PPU.CentreY = READ_WORD (&t [152]); - // JoyAPos t[154] - // JoyBPos t[155] - Memory.FillRAM [0x2134] = t [156]; // Matrix mult - Memory.FillRAM [0x2135] = t [157]; // Matrix mult - Memory.FillRAM [0x2136] = t [158]; // Matrix mult - PPU.WRAM = READ_DWORD (&t [161]); - - for (i = 0; i < 128; i++) - S9xSetCPU (t [165 + i], 0x4300 + i); - - if (t [294]) - CPU.IRQActive |= PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE; - - S9xSetCPU (t [296], 0x420c); - // hdmadata t[297] + 8 * 19 - PPU.FixedColourRed = t [450]; - PPU.FixedColourGreen = t [451]; - PPU.FixedColourBlue = t [452]; - S9xSetPPU (t [454], 0x2130); - S9xSetPPU (t [455], 0x2131); - // vraminctype ... - - fread ((char*)Memory.RAM, 1, 128 * 1024, fs); - fread ((char*)Memory.VRAM, 1, 64 * 1024, fs); - - if (Settings.APUEnabled) - { - // SNES SPC700 RAM (64K) - fread ((char*)IAPU.RAM, 1, 64 * 1024, fs); - - // Junk 16 bytes - fread ((char*)t, 1, 16, fs); - - // SNES SPC700 state and internal ZSNES SPC700 emulation state - fread ((char*)t, 1, 304, fs); - - IAPU.Registers.PC = READ_DWORD (&t [0]); - IAPU.Registers.YA.B.A = t [4]; - IAPU.Registers.X = t [8]; - IAPU.Registers.YA.B.Y = t [12]; - IAPU.Registers.P = t [16]; - IAPU.Registers.S = t [24]; - - APU.Cycles = READ_DWORD (&t [32]); - APU.ShowROM = (IAPU.RAM [0xf1] & 0x80) != 0; - APU.OutPorts [0] = t [36]; - APU.OutPorts [1] = t [37]; - APU.OutPorts [2] = t [38]; - APU.OutPorts [3] = t [39]; - - APU.TimerEnabled [0] = (t [40] & 1) != 0; - APU.TimerEnabled [1] = (t [40] & 2) != 0; - APU.TimerEnabled [2] = (t [40] & 4) != 0; - S9xSetAPUTimer (0xfa, t [41]); - S9xSetAPUTimer (0xfb, t [42]); - S9xSetAPUTimer (0xfc, t [43]); - APU.Timer [0] = t [44]; - APU.Timer [1] = t [45]; - APU.Timer [2] = t [46]; - - // memmove converted: Different mallocs [Neb] - memcpy (APU.ExtraRAM, &t [48], 64); - - // Internal ZSNES sound DSP state - fread (t, 1, 1068, fs); - - // SNES sound DSP register values - fread (t, 1, 256, fs); - - uint8 saved = IAPU.RAM [0xf2]; - - for (i = 0; i < 128; i++) - { - switch (i) - { - case APU_KON: - case APU_KOFF: - break; - case APU_FLG: - t [i] &= ~APU_SOFT_RESET; - default: - IAPU.RAM [0xf2] = i; - S9xSetAPUDSP (t [i]); - break; - } - } - IAPU.RAM [0xf2] = APU_KON; - S9xSetAPUDSP (t [APU_KON]); - IAPU.RAM [0xf2] = saved; - - S9xSetSoundMute (FALSE); - IAPU.PC = IAPU.RAM + IAPU.Registers.PC; - S9xAPUUnpackStatus (); - if (APUCheckDirectPage ()) - IAPU.DirectPage = IAPU.RAM + 0x100; - else - IAPU.DirectPage = IAPU.RAM; - Settings.APUEnabled = TRUE; - IAPU.APUExecuting = TRUE; - } - else - { - Settings.APUEnabled = FALSE; - IAPU.APUExecuting = FALSE; - S9xSetSoundMute (TRUE); - } - - if (Settings.SuperFX) - { - fread (Memory.SRAM, 1, 64 * 1024, fs); - fseek (fs, 64 * 1024, SEEK_CUR); - fread (Memory.FillRAM + 0x7000, 1, 692, fs); - } - if (Settings.SA1) - { - fread (t, 1, 2741, fs); - S9xSetSA1 (t [4], 0x2200); // Control - S9xSetSA1 (t [12], 0x2203); // ResetV low - S9xSetSA1 (t [13], 0x2204); // ResetV hi - S9xSetSA1 (t [14], 0x2205); // NMI low - S9xSetSA1 (t [15], 0x2206); // NMI hi - S9xSetSA1 (t [16], 0x2207); // IRQ low - S9xSetSA1 (t [17], 0x2208); // IRQ hi - S9xSetSA1 (((READ_DWORD (&t [28]) - (4096*1024-0x6000))) >> 13, 0x2224); - S9xSetSA1 (t [36], 0x2201); - S9xSetSA1 (t [41], 0x2209); - - SA1.Registers.A.W = READ_DWORD (&t [592]); - SA1.Registers.X.W = READ_DWORD (&t [596]); - SA1.Registers.Y.W = READ_DWORD (&t [600]); - SA1.Registers.D.W = READ_DWORD (&t [604]); - SA1.Registers.DB = t [608]; - SA1.Registers.PB = t [612]; - SA1.Registers.S.W = READ_DWORD (&t [616]); - SA1.Registers.PC = READ_DWORD (&t [636]); - SA1.Registers.P.W = t [620] | (t [624] << 8); - - // memmove converted: Different mallocs [Neb] - // DS2 DMA notes: This code path is not used [Neb] - memcpy (&Memory.FillRAM [0x3000], t + 692, 2 * 1024); - - fread (Memory.SRAM, 1, 64 * 1024, fs); - fseek (fs, 64 * 1024, SEEK_CUR); - S9xFixSA1AfterSnapshotLoad (); - } - if(Settings.SPC7110) - { - uint32 temp; - fread(&s7r.bank50, 1,0x10000, fs); - - //NEWSYM SPCMultA, dd 0 4820-23 - fread(&temp, 1, 4, fs); - - s7r.reg4820=temp&(0x0FF); - s7r.reg4821=(temp>>8)&(0x0FF); - s7r.reg4822=(temp>>16)&(0x0FF); - s7r.reg4823=(temp>>24)&(0x0FF); - - //NEWSYM SPCMultB, dd 0 4824-5 - fread(&temp, 1,4,fs); - s7r.reg4824=temp&(0x0FF); - s7r.reg4825=(temp>>8)&(0x0FF); - - - //NEWSYM SPCDivEnd, dd 0 4826-7 - fread(&temp, 1,4,fs); - s7r.reg4826=temp&(0x0FF); - s7r.reg4827=(temp>>8)&(0x0FF); - - //NEWSYM SPCMulRes, dd 0 4828-B - fread(&temp, 1, 4, fs); - - s7r.reg4828=temp&(0x0FF); - s7r.reg4829=(temp>>8)&(0x0FF); - s7r.reg482A=(temp>>16)&(0x0FF); - s7r.reg482B=(temp>>24)&(0x0FF); - - //NEWSYM SPCDivRes, dd 0 482C-D - fread(&temp, 1,4,fs); - s7r.reg482C=temp&(0x0FF); - s7r.reg482D=(temp>>8)&(0x0FF); - - //NEWSYM SPC7110BankA, dd 020100h 4831-3 - fread(&temp, 1, 4, fs); - - s7r.reg4831=temp&(0x0FF); - s7r.reg4832=(temp>>8)&(0x0FF); - s7r.reg4833=(temp>>16)&(0x0FF); - - //NEWSYM SPC7110RTCStat, dd 0 4840,init,command, index - fread(&temp, 1, 4, fs); - - s7r.reg4840=temp&(0x0FF); - -//NEWSYM SPC7110RTC, db 00,00,00,00,00,00,01,00,01,00,00,00,00,00,0Fh,00 -fread(&temp, 1, 4, fs); -if(Settings.SPC7110RTC) -{ - rtc_f9.reg[0]=temp&(0x0FF); - rtc_f9.reg[1]=(temp>>8)&(0x0FF); - rtc_f9.reg[2]=(temp>>16)&(0x0FF); - rtc_f9.reg[3]=(temp>>24)&(0x0FF); -} -fread(&temp, 1, 4, fs); -if(Settings.SPC7110RTC) -{ - rtc_f9.reg[4]=temp&(0x0FF); - rtc_f9.reg[5]=(temp>>8)&(0x0FF); - rtc_f9.reg[6]=(temp>>16)&(0x0FF); - rtc_f9.reg[7]=(temp>>24)&(0x0FF); -} -fread(&temp, 1, 4, fs); -if(Settings.SPC7110RTC) -{ - rtc_f9.reg[8]=temp&(0x0FF); - rtc_f9.reg[9]=(temp>>8)&(0x0FF); - rtc_f9.reg[10]=(temp>>16)&(0x0FF); - rtc_f9.reg[11]=(temp>>24)&(0x0FF); -} -fread(&temp, 1, 4, fs); -if(Settings.SPC7110RTC) -{ - rtc_f9.reg[12]=temp&(0x0FF); - rtc_f9.reg[13]=(temp>>8)&(0x0FF); - rtc_f9.reg[14]=(temp>>16)&(0x0FF); - rtc_f9.reg[15]=(temp>>24)&(0x0FF); -} -//NEWSYM SPC7110RTCB, db 00,00,00,00,00,00,01,00,01,00,00,00,00,01,0Fh,06 -fread(&temp, 1, 4, fs); -fread(&temp, 1, 4, fs); -fread(&temp, 1, 4, fs); -fread(&temp, 1, 4, fs); - -//NEWSYM SPCROMPtr, dd 0 4811-4813 - fread(&temp, 1, 4, fs); - - s7r.reg4811=temp&(0x0FF); - s7r.reg4812=(temp>>8)&(0x0FF); - s7r.reg4813=(temp>>16)&(0x0FF); -//NEWSYM SPCROMtoI, dd SPCROMPtr - fread(&temp, 1, 4, fs); -//NEWSYM SPCROMAdj, dd 0 4814-5 - fread(&temp, 1, 4, fs); - s7r.reg4814=temp&(0x0FF); - s7r.reg4815=(temp>>8)&(0x0FF); -//NEWSYM SPCROMInc, dd 0 4816-7 - fread(&temp, 1, 4, fs); - s7r.reg4816=temp&(0x0FF); - s7r.reg4817=(temp>>8)&(0x0FF); -//NEWSYM SPCROMCom, dd 0 4818 -fread(&temp, 1, 4, fs); - - s7r.reg4818=temp&(0x0FF); -//NEWSYM SPCCompPtr, dd 0 4801-4804 (+b50i) if"manual" - fread(&temp, 1, 4, fs); - - //do table check - - s7r.reg4801=temp&(0x0FF); - s7r.reg4802=(temp>>8)&(0x0FF); - s7r.reg4803=(temp>>16)&(0x0FF); - s7r.reg4804=(temp>>24)&(0x0FF); -///NEWSYM SPCDecmPtr, dd 0 4805-6 +b50i - fread(&temp, 1, 4, fs); - s7r.reg4805=temp&(0x0FF); - s7r.reg4806=(temp>>8)&(0x0FF); -//NEWSYM SPCCompCounter, dd 0 4809-A - fread(&temp, 1, 4, fs); - s7r.reg4809=temp&(0x0FF); - s7r.reg480A=(temp>>8)&(0x0FF); -//NEWSYM SPCCompCommand, dd 0 480B - fread(&temp, 1, 4, fs); - - s7r.reg480B=temp&(0x0FF); -//NEWSYM SPCCheckFix, dd 0 written(if 1, then set writtne to max value!) - fread(&temp, 1, 4, fs); - if (temp&(0x0FF)) - s7r.written=0x1F; + S9xSetPPU(t [2512], 0x2115); + PPU.VMA.Address = READ_DWORD(&t [101]); + for (i = 0; i < 512; i++) + S9xSetPPU(t [1488 + i], 0x2122); + + PPU.CGADD = (uint8) READ_WORD(&t [105]); + Memory.FillRAM [0x212c] = t [108]; + Memory.FillRAM [0x212d] = t [109]; + PPU.ScreenHeight = READ_WORD(&t [111]); + Memory.FillRAM [0x2133] = t [2526]; + Memory.FillRAM [0x4202] = t [113]; + Memory.FillRAM [0x4204] = t [114]; + Memory.FillRAM [0x4205] = t [115]; + Memory.FillRAM [0x4214] = t [116]; + Memory.FillRAM [0x4215] = t [117]; + Memory.FillRAM [0x4216] = t [118]; + Memory.FillRAM [0x4217] = t [119]; + PPU.VBeamPosLatched = READ_WORD(&t [122]); + PPU.HBeamPosLatched = READ_WORD(&t [120]); + PPU.Window1Left = t [127]; + PPU.Window1Right = t [128]; + PPU.Window2Left = t [129]; + PPU.Window2Right = t [130]; + S9xSetPPU(t [131] | (t [132] << 4), 0x2123); + S9xSetPPU(t [133] | (t [134] << 4), 0x2124); + S9xSetPPU(t [135] | (t [136] << 4), 0x2125); + S9xSetPPU(t [137], 0x212a); + S9xSetPPU(t [138], 0x212b); + S9xSetPPU(t [139], 0x212e); + S9xSetPPU(t [140], 0x212f); + S9xSetPPU(t [141], 0x211a); + PPU.MatrixA = READ_WORD(&t [142]); + PPU.MatrixB = READ_WORD(&t [144]); + PPU.MatrixC = READ_WORD(&t [146]); + PPU.MatrixD = READ_WORD(&t [148]); + PPU.CentreX = READ_WORD(&t [150]); + PPU.CentreY = READ_WORD(&t [152]); + // JoyAPos t[154] + // JoyBPos t[155] + Memory.FillRAM [0x2134] = t [156]; // Matrix mult + Memory.FillRAM [0x2135] = t [157]; // Matrix mult + Memory.FillRAM [0x2136] = t [158]; // Matrix mult + PPU.WRAM = READ_DWORD(&t [161]); + + for (i = 0; i < 128; i++) + S9xSetCPU(t [165 + i], 0x4300 + i); + + if (t [294]) + CPU.IRQActive |= PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE; + + S9xSetCPU(t [296], 0x420c); + // hdmadata t[297] + 8 * 19 + PPU.FixedColourRed = t [450]; + PPU.FixedColourGreen = t [451]; + PPU.FixedColourBlue = t [452]; + S9xSetPPU(t [454], 0x2130); + S9xSetPPU(t [455], 0x2131); + // vraminctype ... + + fread((char*)Memory.RAM, 1, 128 * 1024, fs); + fread((char*)Memory.VRAM, 1, 64 * 1024, fs); + + if (Settings.APUEnabled) + { + // SNES SPC700 RAM (64K) + fread((char*)IAPU.RAM, 1, 64 * 1024, fs); + + // Junk 16 bytes + fread((char*)t, 1, 16, fs); + + // SNES SPC700 state and internal ZSNES SPC700 emulation state + fread((char*)t, 1, 304, fs); + + IAPU.Registers.PC = READ_DWORD(&t [0]); + IAPU.Registers.YA.B.A = t [4]; + IAPU.Registers.X = t [8]; + IAPU.Registers.YA.B.Y = t [12]; + IAPU.Registers.P = t [16]; + IAPU.Registers.S = t [24]; + + APU.Cycles = READ_DWORD(&t [32]); + APU.ShowROM = (IAPU.RAM [0xf1] & 0x80) != 0; + APU.OutPorts [0] = t [36]; + APU.OutPorts [1] = t [37]; + APU.OutPorts [2] = t [38]; + APU.OutPorts [3] = t [39]; + + APU.TimerEnabled [0] = (t [40] & 1) != 0; + APU.TimerEnabled [1] = (t [40] & 2) != 0; + APU.TimerEnabled [2] = (t [40] & 4) != 0; + S9xSetAPUTimer(0xfa, t [41]); + S9xSetAPUTimer(0xfb, t [42]); + S9xSetAPUTimer(0xfc, t [43]); + APU.Timer [0] = t [44]; + APU.Timer [1] = t [45]; + APU.Timer [2] = t [46]; + + // memmove converted: Different mallocs [Neb] + memcpy(APU.ExtraRAM, &t [48], 64); + + // Internal ZSNES sound DSP state + fread(t, 1, 1068, fs); + + // SNES sound DSP register values + fread(t, 1, 256, fs); + + uint8 saved = IAPU.RAM [0xf2]; + + for (i = 0; i < 128; i++) + { + switch (i) + { + case APU_KON: + case APU_KOFF: + break; + case APU_FLG: + t [i] &= ~APU_SOFT_RESET; + default: + IAPU.RAM [0xf2] = i; + S9xSetAPUDSP(t [i]); + break; + } + } + IAPU.RAM [0xf2] = APU_KON; + S9xSetAPUDSP(t [APU_KON]); + IAPU.RAM [0xf2] = saved; + + S9xSetSoundMute(FALSE); + IAPU.PC = IAPU.RAM + IAPU.Registers.PC; + S9xAPUUnpackStatus(); + if (APUCheckDirectPage()) + IAPU.DirectPage = IAPU.RAM + 0x100; + else + IAPU.DirectPage = IAPU.RAM; + Settings.APUEnabled = TRUE; + IAPU.APUExecuting = TRUE; + } else - s7r.written=0x00; -//NEWSYM SPCSignedVal, dd 0 482E -fread(&temp, 1, 4, fs); - - s7r.reg482E=temp&(0x0FF); - - } - fclose (fs); - - FixROMSpeed (); - IPPU.ColorsChanged = TRUE; - IPPU.OBJChanged = TRUE; - CPU.InDMA = FALSE; - S9xFixColourBrightness (); - IPPU.RenderThisFrame = FALSE; - - S9xFixSoundAfterSnapshotLoad (); - ICPU.ShiftedPB = ICPU.Registers.PB << 16; - ICPU.ShiftedDB = ICPU.Registers.DB << 16; - S9xSetPCBase (ICPU.ShiftedPB + ICPU.Registers.PC); - S9xUnpackStatus (); - S9xFixCycles (); - S9xReschedule (); + { + Settings.APUEnabled = FALSE; + IAPU.APUExecuting = FALSE; + S9xSetSoundMute(TRUE); + } + + if (Settings.SuperFX) + { + fread(Memory.SRAM, 1, 64 * 1024, fs); + fseek(fs, 64 * 1024, SEEK_CUR); + fread(Memory.FillRAM + 0x7000, 1, 692, fs); + } + if (Settings.SA1) + { + fread(t, 1, 2741, fs); + S9xSetSA1(t [4], 0x2200); // Control + S9xSetSA1(t [12], 0x2203); // ResetV low + S9xSetSA1(t [13], 0x2204); // ResetV hi + S9xSetSA1(t [14], 0x2205); // NMI low + S9xSetSA1(t [15], 0x2206); // NMI hi + S9xSetSA1(t [16], 0x2207); // IRQ low + S9xSetSA1(t [17], 0x2208); // IRQ hi + S9xSetSA1(((READ_DWORD(&t [28]) - (4096 * 1024 - 0x6000))) >> 13, 0x2224); + S9xSetSA1(t [36], 0x2201); + S9xSetSA1(t [41], 0x2209); + + SA1.Registers.A.W = READ_DWORD(&t [592]); + SA1.Registers.X.W = READ_DWORD(&t [596]); + SA1.Registers.Y.W = READ_DWORD(&t [600]); + SA1.Registers.D.W = READ_DWORD(&t [604]); + SA1.Registers.DB = t [608]; + SA1.Registers.PB = t [612]; + SA1.Registers.S.W = READ_DWORD(&t [616]); + SA1.Registers.PC = READ_DWORD(&t [636]); + SA1.Registers.P.W = t [620] | (t [624] << 8); + + // memmove converted: Different mallocs [Neb] + // DS2 DMA notes: This code path is not used [Neb] + memcpy(&Memory.FillRAM [0x3000], t + 692, 2 * 1024); + + fread(Memory.SRAM, 1, 64 * 1024, fs); + fseek(fs, 64 * 1024, SEEK_CUR); + S9xFixSA1AfterSnapshotLoad(); + } + if (Settings.SPC7110) + { + uint32 temp; + fread(&s7r.bank50, 1, 0x10000, fs); + + //NEWSYM SPCMultA, dd 0 4820-23 + fread(&temp, 1, 4, fs); + + s7r.reg4820 = temp & (0x0FF); + s7r.reg4821 = (temp >> 8) & (0x0FF); + s7r.reg4822 = (temp >> 16) & (0x0FF); + s7r.reg4823 = (temp >> 24) & (0x0FF); + + //NEWSYM SPCMultB, dd 0 4824-5 + fread(&temp, 1, 4, fs); + s7r.reg4824 = temp & (0x0FF); + s7r.reg4825 = (temp >> 8) & (0x0FF); + + + //NEWSYM SPCDivEnd, dd 0 4826-7 + fread(&temp, 1, 4, fs); + s7r.reg4826 = temp & (0x0FF); + s7r.reg4827 = (temp >> 8) & (0x0FF); + + //NEWSYM SPCMulRes, dd 0 4828-B + fread(&temp, 1, 4, fs); + + s7r.reg4828 = temp & (0x0FF); + s7r.reg4829 = (temp >> 8) & (0x0FF); + s7r.reg482A = (temp >> 16) & (0x0FF); + s7r.reg482B = (temp >> 24) & (0x0FF); + + //NEWSYM SPCDivRes, dd 0 482C-D + fread(&temp, 1, 4, fs); + s7r.reg482C = temp & (0x0FF); + s7r.reg482D = (temp >> 8) & (0x0FF); + + //NEWSYM SPC7110BankA, dd 020100h 4831-3 + fread(&temp, 1, 4, fs); + + s7r.reg4831 = temp & (0x0FF); + s7r.reg4832 = (temp >> 8) & (0x0FF); + s7r.reg4833 = (temp >> 16) & (0x0FF); + + //NEWSYM SPC7110RTCStat, dd 0 4840,init,command, index + fread(&temp, 1, 4, fs); + + s7r.reg4840 = temp & (0x0FF); + + //NEWSYM SPC7110RTC, db 00,00,00,00,00,00,01,00,01,00,00,00,00,00,0Fh,00 + fread(&temp, 1, 4, fs); + if (Settings.SPC7110RTC) + { + rtc_f9.reg[0] = temp & (0x0FF); + rtc_f9.reg[1] = (temp >> 8) & (0x0FF); + rtc_f9.reg[2] = (temp >> 16) & (0x0FF); + rtc_f9.reg[3] = (temp >> 24) & (0x0FF); + } + fread(&temp, 1, 4, fs); + if (Settings.SPC7110RTC) + { + rtc_f9.reg[4] = temp & (0x0FF); + rtc_f9.reg[5] = (temp >> 8) & (0x0FF); + rtc_f9.reg[6] = (temp >> 16) & (0x0FF); + rtc_f9.reg[7] = (temp >> 24) & (0x0FF); + } + fread(&temp, 1, 4, fs); + if (Settings.SPC7110RTC) + { + rtc_f9.reg[8] = temp & (0x0FF); + rtc_f9.reg[9] = (temp >> 8) & (0x0FF); + rtc_f9.reg[10] = (temp >> 16) & (0x0FF); + rtc_f9.reg[11] = (temp >> 24) & (0x0FF); + } + fread(&temp, 1, 4, fs); + if (Settings.SPC7110RTC) + { + rtc_f9.reg[12] = temp & (0x0FF); + rtc_f9.reg[13] = (temp >> 8) & (0x0FF); + rtc_f9.reg[14] = (temp >> 16) & (0x0FF); + rtc_f9.reg[15] = (temp >> 24) & (0x0FF); + } + //NEWSYM SPC7110RTCB, db 00,00,00,00,00,00,01,00,01,00,00,00,00,01,0Fh,06 + fread(&temp, 1, 4, fs); + fread(&temp, 1, 4, fs); + fread(&temp, 1, 4, fs); + fread(&temp, 1, 4, fs); + + //NEWSYM SPCROMPtr, dd 0 4811-4813 + fread(&temp, 1, 4, fs); + + s7r.reg4811 = temp & (0x0FF); + s7r.reg4812 = (temp >> 8) & (0x0FF); + s7r.reg4813 = (temp >> 16) & (0x0FF); + //NEWSYM SPCROMtoI, dd SPCROMPtr + fread(&temp, 1, 4, fs); + //NEWSYM SPCROMAdj, dd 0 4814-5 + fread(&temp, 1, 4, fs); + s7r.reg4814 = temp & (0x0FF); + s7r.reg4815 = (temp >> 8) & (0x0FF); + //NEWSYM SPCROMInc, dd 0 4816-7 + fread(&temp, 1, 4, fs); + s7r.reg4816 = temp & (0x0FF); + s7r.reg4817 = (temp >> 8) & (0x0FF); + //NEWSYM SPCROMCom, dd 0 4818 + fread(&temp, 1, 4, fs); + + s7r.reg4818 = temp & (0x0FF); + //NEWSYM SPCCompPtr, dd 0 4801-4804 (+b50i) if"manual" + fread(&temp, 1, 4, fs); + + //do table check + + s7r.reg4801 = temp & (0x0FF); + s7r.reg4802 = (temp >> 8) & (0x0FF); + s7r.reg4803 = (temp >> 16) & (0x0FF); + s7r.reg4804 = (temp >> 24) & (0x0FF); + ///NEWSYM SPCDecmPtr, dd 0 4805-6 +b50i + fread(&temp, 1, 4, fs); + s7r.reg4805 = temp & (0x0FF); + s7r.reg4806 = (temp >> 8) & (0x0FF); + //NEWSYM SPCCompCounter, dd 0 4809-A + fread(&temp, 1, 4, fs); + s7r.reg4809 = temp & (0x0FF); + s7r.reg480A = (temp >> 8) & (0x0FF); + //NEWSYM SPCCompCommand, dd 0 480B + fread(&temp, 1, 4, fs); + + s7r.reg480B = temp & (0x0FF); + //NEWSYM SPCCheckFix, dd 0 written(if 1, then set writtne to max value!) + fread(&temp, 1, 4, fs); + if (temp & (0x0FF)) + s7r.written = 0x1F; + else + s7r.written = 0x00; + //NEWSYM SPCSignedVal, dd 0 482E + fread(&temp, 1, 4, fs); + + s7r.reg482E = temp & (0x0FF); + + } + fclose(fs); + + FixROMSpeed(); + IPPU.ColorsChanged = TRUE; + IPPU.OBJChanged = TRUE; + CPU.InDMA = FALSE; + S9xFixColourBrightness(); + IPPU.RenderThisFrame = FALSE; + + S9xFixSoundAfterSnapshotLoad(); + ICPU.ShiftedPB = ICPU.Registers.PB << 16; + ICPU.ShiftedDB = ICPU.Registers.DB << 16; + S9xSetPCBase(ICPU.ShiftedPB + ICPU.Registers.PC); + S9xUnpackStatus(); + S9xFixCycles(); + S9xReschedule(); #ifdef ZSNES_FX - if (Settings.SuperFX) - S9xSuperFXPostLoadState (); + if (Settings.SuperFX) + S9xSuperFXPostLoadState(); #endif - return (TRUE); - } - fclose (fs); - return (FALSE); + return (TRUE); + } + fclose(fs); + return (FALSE); } diff --git a/source/snapshot.h b/source/snapshot.h index cb65c6c..d7af5de 100644 --- a/source/snapshot.h +++ b/source/snapshot.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -102,13 +102,13 @@ #define WRONG_MOVIE_SNAPSHOT (-4) #define NOT_A_MOVIE_SNAPSHOT (-5) -bool8 S9xFreezeGame (const char *filename); -bool8 S9xUnfreezeGame (const char *filename); -bool8 Snapshot (const char *filename); -bool8 S9xLoadSnapshot (const char *filename); -bool8 S9xSPCDump (const char *filename); -void S9xFreezeToStream (STREAM); -int S9xUnfreezeFromStream (STREAM); +bool8 S9xFreezeGame(const char* filename); +bool8 S9xUnfreezeGame(const char* filename); +bool8 Snapshot(const char* filename); +bool8 S9xLoadSnapshot(const char* filename); +bool8 S9xSPCDump(const char* filename); +void S9xFreezeToStream(STREAM); +int S9xUnfreezeFromStream(STREAM); #endif diff --git a/source/snes9x.h b/source/snes9x.h index 5590349..7d94fc7 100644 --- a/source/snes9x.h +++ b/source/snes9x.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -98,7 +98,7 @@ //#include "fs_api.h" //#include "ds2_malloc.h" -extern int cprintf(const char *fmt, ...); +extern int cprintf(const char* fmt, ...); #ifdef __WIN32__ #include "..\wsnes9x.h" @@ -120,7 +120,7 @@ extern int cprintf(const char *fmt, ...); #define WRITE_STREAM(p,l,s) gzwrite (s,p,l) #define OPEN_STREAM(f,m) gzopen (f,m) #define REOPEN_STREAM(f,m) gzdopen (f,m) -#define FIND_STREAM(f) gztell(f) +#define FIND_STREAM(f) gztell(f) #define REVERT_STREAM(f,o,s) gzseek(f,o,s) #define CLOSE_STREAM(s) gzclose (s) #else @@ -129,24 +129,24 @@ extern int cprintf(const char *fmt, ...); #define WRITE_STREAM(p,l,s) fwrite (p,1,l,s) #define OPEN_STREAM(f,m) fopen (f,m) #define REOPEN_STREAM(f,m) fdopen (f,m) -#define FIND_STREAM(f) ftell(f) -#define REVERT_STREAM(f,o,s) fseek(f,o,s) +#define FIND_STREAM(f) ftell(f) +#define REVERT_STREAM(f,o,s) fseek(f,o,s) #define CLOSE_STREAM(s) fclose (s) #endif /* SNES screen width and height */ -#define SNES_WIDTH 256 -#define SNES_HEIGHT 224 -#define SNES_HEIGHT_EXTENDED 239 -#define IMAGE_WIDTH (Settings.SupportHiRes ? SNES_WIDTH * 2 : SNES_WIDTH) -#define IMAGE_HEIGHT (Settings.SupportHiRes ? SNES_HEIGHT_EXTENDED * 2 : SNES_HEIGHT_EXTENDED) +#define SNES_WIDTH 256 +#define SNES_HEIGHT 224 +#define SNES_HEIGHT_EXTENDED 239 +#define IMAGE_WIDTH (Settings.SupportHiRes ? SNES_WIDTH * 2 : SNES_WIDTH) +#define IMAGE_HEIGHT (Settings.SupportHiRes ? SNES_HEIGHT_EXTENDED * 2 : SNES_HEIGHT_EXTENDED) #define SNES_MAX_NTSC_VCOUNTER 262 #define SNES_MAX_PAL_VCOUNTER 312 -#define SNES_HCOUNTER_MAX 342 -#define SPC700_TO_65C816_RATIO 2 -#define AUTO_FRAMERATE 200 +#define SNES_HCOUNTER_MAX 342 +#define SPC700_TO_65C816_RATIO 2 +#define AUTO_FRAMERATE 200 /* NTSC master clock signal 21.47727MHz * PPU: master clock / 4 @@ -172,73 +172,75 @@ extern int cprintf(const char *fmt, ...); #define TWO_CYCLES 12 -#define SNES_TR_MASK (1 << 4) -#define SNES_TL_MASK (1 << 5) -#define SNES_X_MASK (1 << 6) -#define SNES_A_MASK (1 << 7) -#define SNES_RIGHT_MASK (1 << 8) -#define SNES_LEFT_MASK (1 << 9) -#define SNES_DOWN_MASK (1 << 10) -#define SNES_UP_MASK (1 << 11) -#define SNES_START_MASK (1 << 12) +#define SNES_TR_MASK (1 << 4) +#define SNES_TL_MASK (1 << 5) +#define SNES_X_MASK (1 << 6) +#define SNES_A_MASK (1 << 7) +#define SNES_RIGHT_MASK (1 << 8) +#define SNES_LEFT_MASK (1 << 9) +#define SNES_DOWN_MASK (1 << 10) +#define SNES_UP_MASK (1 << 11) +#define SNES_START_MASK (1 << 12) #define SNES_SELECT_MASK (1 << 13) -#define SNES_Y_MASK (1 << 14) -#define SNES_B_MASK (1 << 15) - -enum { - SNES_MULTIPLAYER5, - SNES_JOYPAD, - SNES_MOUSE_SWAPPED, - SNES_MOUSE, - SNES_SUPERSCOPE, - SNES_JUSTIFIER, - SNES_JUSTIFIER_2, - SNES_MAX_CONTROLLER_OPTIONS +#define SNES_Y_MASK (1 << 14) +#define SNES_B_MASK (1 << 15) + +enum +{ + SNES_MULTIPLAYER5, + SNES_JOYPAD, + SNES_MOUSE_SWAPPED, + SNES_MOUSE, + SNES_SUPERSCOPE, + SNES_JUSTIFIER, + SNES_JUSTIFIER_2, + SNES_MAX_CONTROLLER_OPTIONS }; -#define DEBUG_MODE_FLAG (1 << 0) -#define TRACE_FLAG (1 << 1) +#define DEBUG_MODE_FLAG (1 << 0) +#define TRACE_FLAG (1 << 1) #define SINGLE_STEP_FLAG (1 << 2) -#define BREAK_FLAG (1 << 3) -#define SCAN_KEYS_FLAG (1 << 4) +#define BREAK_FLAG (1 << 3) +#define SCAN_KEYS_FLAG (1 << 4) #define SAVE_SNAPSHOT_FLAG (1 << 5) #define DELAYED_NMI_FLAG (1 << 6) -#define NMI_FLAG (1 << 7) +#define NMI_FLAG (1 << 7) #define PROCESS_SOUND_FLAG (1 << 8) #define FRAME_ADVANCE_FLAG (1 << 9) #define DELAYED_NMI_FLAG2 (1 << 10) #define IRQ_PENDING_FLAG (1 << 11) -typedef struct { - uint32 Flags; - bool8 BranchSkip; - bool8 NMIActive; - bool8 IRQActive; - bool8 WaitingForInterrupt; - bool8 InDMA; - uint8 WhichEvent; - uint8 *PC; - uint8 *PCBase; - uint8 *PCAtOpcodeStart; - uint8 *WaitAddress; - uint32 WaitCounter; - long Cycles; - long NextEvent; - long V_Counter; - long MemSpeed; - long MemSpeedx2; - long FastROMSpeed; - uint32 AutoSaveTimer; - bool8 SRAMModified; - uint32 NMITriggerPoint; - bool8 BRKTriggered; - bool8 TriedInterleavedMode2; - uint32 NMICycleCount; - uint32 IRQCycleCount; +typedef struct +{ + uint32 Flags; + bool8 BranchSkip; + bool8 NMIActive; + bool8 IRQActive; + bool8 WaitingForInterrupt; + bool8 InDMA; + uint8 WhichEvent; + uint8* PC; + uint8* PCBase; + uint8* PCAtOpcodeStart; + uint8* WaitAddress; + uint32 WaitCounter; + long Cycles; + long NextEvent; + long V_Counter; + long MemSpeed; + long MemSpeedx2; + long FastROMSpeed; + uint32 AutoSaveTimer; + bool8 SRAMModified; + uint32 NMITriggerPoint; + bool8 BRKTriggered; + bool8 TriedInterleavedMode2; + uint32 NMICycleCount; + uint32 IRQCycleCount; #ifdef DEBUG_MAXCOUNT - unsigned long GlobalLoopCount; + unsigned long GlobalLoopCount; #endif -}SCPUState; +} SCPUState; #define HBLANK_START_EVENT 0 #define HBLANK_END_EVENT 1 @@ -246,157 +248,158 @@ typedef struct { #define HTIMER_AFTER_EVENT 3 #define NO_EVENT 4 -typedef struct { - /* CPU options */ - bool8 APUEnabled; - bool8 Shutdown; - uint8 SoundSkipMethod; - long H_Max; - long HBlankStart; - long CyclesPercentage; - bool8 DisableIRQ; - bool8 Paused; - bool8 ForcedPause; - bool8 StopEmulation; - bool8 FrameAdvance; - - /* Tracing options */ - bool8 TraceDMA; - bool8 TraceHDMA; - bool8 TraceVRAM; - bool8 TraceUnknownRegisters; - bool8 TraceDSP; - - /* Joystick options */ - bool8 SwapJoypads; - bool8 JoystickEnabled; - - /* ROM timing options (see also H_Max above) */ - bool8 ForcePAL; - bool8 ForceNTSC; - bool8 PAL; - uint32 FrameTimePAL; - uint32 FrameTimeNTSC; - uint32 FrameTime; - uint32 SkipFrames; - - /* ROM image options */ - bool8 ForceLoROM; - bool8 ForceHiROM; - bool8 ForceHeader; - bool8 ForceNoHeader; - bool8 ForceInterleaved; - bool8 ForceInterleaved2; - bool8 ForceNotInterleaved; - - /* Peripherial options */ - bool8 ForceSuperFX; - bool8 ForceNoSuperFX; - bool8 ForceDSP1; - bool8 ForceNoDSP1; - bool8 ForceSA1; - bool8 ForceNoSA1; - bool8 ForceC4; - bool8 ForceNoC4; - bool8 ForceSDD1; - bool8 ForceNoSDD1; - bool8 MultiPlayer5; - bool8 Mouse; - bool8 SuperScope; - bool8 SRTC; - uint32 ControllerOption; - - bool8 ShutdownMaster; - bool8 MultiPlayer5Master; - bool8 SuperScopeMaster; - bool8 MouseMaster; - bool8 SuperFX; - bool8 DSP1Master; - bool8 SA1; - bool8 C4; - bool8 SDD1; - bool8 SPC7110; - bool8 SPC7110RTC; - bool8 OBC1; - /* Sound options */ - uint32 SoundPlaybackRate; - bool8 TraceSoundDSP; - bool8 EightBitConsoleSound; // due to caching, this needs S9xSetEightBitConsoleSound() - int SoundBufferSize; - int SoundMixInterval; - bool8 SoundEnvelopeHeightReading; - bool8 DisableSoundEcho; - bool8 DisableMasterVolume; - bool8 SoundSync; - bool8 InterpolatedSound; - bool8 ThreadSound; - bool8 Mute; - bool8 NextAPUEnabled; - uint8 AltSampleDecode; - bool8 FixFrequency; - - /* Graphics options */ - bool8 Transparency; - bool8 SupportHiRes; - bool8 Mode7Interpolate; - - /* SNES graphics options */ - bool8 BGLayering; - bool8 DisableGraphicWindows; - bool8 ForceTransparency; - bool8 ForceNoTransparency; - bool8 DisableHDMA; - bool8 DisplayFrameRate; - bool8 DisableRangeTimeOver; /* XXX: unused */ - - /* Others */ - bool8 ApplyCheats; - -/* Fixes for individual games */ - bool8 StarfoxHack; - bool8 WinterGold; - bool8 BS; /* Japanese Satellite System games. */ - bool8 DaffyDuck; - uint8 APURAMInitialValue; - bool8 SampleCatchup; - bool8 JustifierMaster; - bool8 Justifier; - bool8 SecondJustifier; - int8 SETA; - bool8 TakeScreenshot; - int8 StretchScreenshots; - uint16 DisplayColor; - int SoundDriver; - int AIDOShmId; - bool8 SDD1Pack; - bool8 NoPatch; - bool8 ForceInterleaveGD24; +typedef struct +{ + /* CPU options */ + bool8 APUEnabled; + bool8 Shutdown; + uint8 SoundSkipMethod; + long H_Max; + long HBlankStart; + long CyclesPercentage; + bool8 DisableIRQ; + bool8 Paused; + bool8 ForcedPause; + bool8 StopEmulation; + bool8 FrameAdvance; + + /* Tracing options */ + bool8 TraceDMA; + bool8 TraceHDMA; + bool8 TraceVRAM; + bool8 TraceUnknownRegisters; + bool8 TraceDSP; + + /* Joystick options */ + bool8 SwapJoypads; + bool8 JoystickEnabled; + + /* ROM timing options (see also H_Max above) */ + bool8 ForcePAL; + bool8 ForceNTSC; + bool8 PAL; + uint32 FrameTimePAL; + uint32 FrameTimeNTSC; + uint32 FrameTime; + uint32 SkipFrames; + + /* ROM image options */ + bool8 ForceLoROM; + bool8 ForceHiROM; + bool8 ForceHeader; + bool8 ForceNoHeader; + bool8 ForceInterleaved; + bool8 ForceInterleaved2; + bool8 ForceNotInterleaved; + + /* Peripherial options */ + bool8 ForceSuperFX; + bool8 ForceNoSuperFX; + bool8 ForceDSP1; + bool8 ForceNoDSP1; + bool8 ForceSA1; + bool8 ForceNoSA1; + bool8 ForceC4; + bool8 ForceNoC4; + bool8 ForceSDD1; + bool8 ForceNoSDD1; + bool8 MultiPlayer5; + bool8 Mouse; + bool8 SuperScope; + bool8 SRTC; + uint32 ControllerOption; + + bool8 ShutdownMaster; + bool8 MultiPlayer5Master; + bool8 SuperScopeMaster; + bool8 MouseMaster; + bool8 SuperFX; + bool8 DSP1Master; + bool8 SA1; + bool8 C4; + bool8 SDD1; + bool8 SPC7110; + bool8 SPC7110RTC; + bool8 OBC1; + /* Sound options */ + uint32 SoundPlaybackRate; + bool8 TraceSoundDSP; + bool8 EightBitConsoleSound; // due to caching, this needs S9xSetEightBitConsoleSound() + int SoundBufferSize; + int SoundMixInterval; + bool8 SoundEnvelopeHeightReading; + bool8 DisableSoundEcho; + bool8 DisableMasterVolume; + bool8 SoundSync; + bool8 InterpolatedSound; + bool8 ThreadSound; + bool8 Mute; + bool8 NextAPUEnabled; + uint8 AltSampleDecode; + bool8 FixFrequency; + + /* Graphics options */ + bool8 Transparency; + bool8 SupportHiRes; + bool8 Mode7Interpolate; + + /* SNES graphics options */ + bool8 BGLayering; + bool8 DisableGraphicWindows; + bool8 ForceTransparency; + bool8 ForceNoTransparency; + bool8 DisableHDMA; + bool8 DisplayFrameRate; + bool8 DisableRangeTimeOver; /* XXX: unused */ + + /* Others */ + bool8 ApplyCheats; + + /* Fixes for individual games */ + bool8 StarfoxHack; + bool8 WinterGold; + bool8 BS; /* Japanese Satellite System games. */ + bool8 DaffyDuck; + uint8 APURAMInitialValue; + bool8 SampleCatchup; + bool8 JustifierMaster; + bool8 Justifier; + bool8 SecondJustifier; + int8 SETA; + bool8 TakeScreenshot; + int8 StretchScreenshots; + uint16 DisplayColor; + int SoundDriver; + int AIDOShmId; + bool8 SDD1Pack; + bool8 NoPatch; + bool8 ForceInterleaveGD24; #ifdef DEBUG_MAXCOUNT - unsigned int MaxCount; + unsigned int MaxCount; #endif -}SSettings; +} SSettings; typedef struct { - uint8 alienVSpredetorFix; - uint8 APU_OutPorts_ReturnValueFix; - uint8 SoundEnvelopeHeightReading2; - uint8 SRAMInitialValue; - uint8 Uniracers; - bool8 EchoOnlyOutput; -}SSNESGameFixes; + uint8 alienVSpredetorFix; + uint8 APU_OutPorts_ReturnValueFix; + uint8 SoundEnvelopeHeightReading2; + uint8 SRAMInitialValue; + uint8 Uniracers; + bool8 EchoOnlyOutput; +} SSNESGameFixes; extern SSettings Settings; extern SCPUState CPU; extern SSNESGameFixes SNESGameFixes; extern char String [513]; -void S9xExit (); -void S9xMessage (int type, int number, const char *message); -void S9xLoadSDD1Data (); +void S9xExit(); +void S9xMessage(int type, int number, const char* message); +void S9xLoadSDD1Data(); -void S9xSetPause (uint32 mask); -void S9xClearPause (uint32 mask); +void S9xSetPause(uint32 mask); +void S9xClearPause(uint32 mask); #endif diff --git a/source/soundux.c b/source/soundux.c index e021381..4e7fe57 100644 --- a/source/soundux.c +++ b/source/soundux.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -98,31 +98,31 @@ #include #define CLIP16(v) \ - if ((v) < -32768) \ + if ((v) < -32768) \ (v) = -32768; \ - else \ - if ((v) > 32767) \ + else \ + if ((v) > 32767) \ (v) = 32767 #define CLIP16_latch(v,l) \ - if ((v) < -32768) \ + if ((v) < -32768) \ { (v) = -32768; (l)++; }\ - else \ - if ((v) > 32767) \ + else \ + if ((v) > 32767) \ { (v) = 32767; (l)++; } #define CLIP24(v) \ - if ((v) < -8388608) \ + if ((v) < -8388608) \ (v) = -8388608; \ - else \ - if ((v) > 8388607) \ + else \ + if ((v) > 8388607) \ (v) = 8388607 #define CLIP8(v) \ - if ((v) < -128) \ + if ((v) < -128) \ (v) = -128; \ - else \ - if ((v) > 127) \ + else \ + if ((v) > 127) \ (v) = 127 #include "snes9x.h" @@ -157,8 +157,8 @@ static int32 noise_gen; #define VOL_DIV16 0x0080 #define ENVX_SHIFT 24 -void DecodeBlockAsm (int8 *, int16 *, int32 *, int32 *); -void DecodeBlockAsm2 (int8 *, int16 *, int32 *, int32 *); +void DecodeBlockAsm(int8*, int16*, int32*, int32*); +void DecodeBlockAsm2(int8*, int16*, int32*, int32*); // F is channel's current frequency and M is the 16-bit modulation waveform // from the previous channel multiplied by the current envelope volume level. @@ -168,1186 +168,1192 @@ void DecodeBlockAsm2 (int8 *, int16 *, int32 *, int32 *); #define LAST_SAMPLE 0xffffff #define JUST_PLAYED_LAST_SAMPLE(c) ((c)->sample_pointer >= LAST_SAMPLE) -void S9xSetEightBitConsoleSound (bool8 Enabled) +void S9xSetEightBitConsoleSound(bool8 Enabled) { - if (Settings.EightBitConsoleSound != Enabled) - { - Settings.EightBitConsoleSound = Enabled; - int i; - for (i = 0; i < 8; i++) - { - SoundData.channels[i].needs_decode = TRUE; - } - } + if (Settings.EightBitConsoleSound != Enabled) + { + Settings.EightBitConsoleSound = Enabled; + int i; + for (i = 0; i < 8; i++) + SoundData.channels[i].needs_decode = TRUE; + } } -STATIC inline uint8 *S9xGetSampleAddress (int sample_number) +STATIC inline uint8* S9xGetSampleAddress(int sample_number) { - uint32 addr = (((APU.DSP[APU_DIR] << 8) + (sample_number << 2)) & 0xffff); - return (IAPU.RAM + addr); + uint32 addr = (((APU.DSP[APU_DIR] << 8) + (sample_number << 2)) & 0xffff); + return (IAPU.RAM + addr); } -void S9xAPUSetEndOfSample (int i, Channel *ch) +void S9xAPUSetEndOfSample(int i, Channel* ch) { - ch->state = SOUND_SILENT; - ch->mode = MODE_NONE; - APU.DSP [APU_ENDX] |= 1 << i; - APU.DSP [APU_KON] &= ~(1 << i); - APU.DSP [APU_KOFF] &= ~(1 << i); - APU.KeyedChannels &= ~(1 << i); + ch->state = SOUND_SILENT; + ch->mode = MODE_NONE; + APU.DSP [APU_ENDX] |= 1 << i; + APU.DSP [APU_KON] &= ~(1 << i); + APU.DSP [APU_KOFF] &= ~(1 << i); + APU.KeyedChannels &= ~(1 << i); } #ifdef __DJGPP -END_OF_FUNCTION (S9xAPUSetEndOfSample) +END_OF_FUNCTION(S9xAPUSetEndOfSample) #endif -void S9xAPUSetEndX (int ch) +void S9xAPUSetEndX(int ch) { - APU.DSP [APU_ENDX] |= 1 << ch; + APU.DSP [APU_ENDX] |= 1 << ch; } #ifdef __DJGPP -END_OF_FUNCTION (S9xAPUSetEndX) +END_OF_FUNCTION(S9xAPUSetEndX) #endif -void S9xSetEnvRate (Channel *ch, unsigned long rate, int direction, int target) +void S9xSetEnvRate(Channel* ch, unsigned long rate, int direction, int target) { - ch->envx_target = target; - - if (rate == ~0UL) - { - ch->direction = 0; - rate = 0; - } - else - ch->direction = direction; - - static int64 steps [] = - { - // 0, 64, 1238, 1238, 256, 1, 64, 109, 64, 1238 - 0, - (int64) FIXED_POINT * 1000 * 64, - (int64) FIXED_POINT * 1000 * 619, - (int64) FIXED_POINT * 1000 * 619, - (int64) FIXED_POINT * 1000 * 128, - (int64) FIXED_POINT * 1000 * 1, - (int64) FIXED_POINT * 1000 * 64, - (int64) FIXED_POINT * 1000 * 55, - (int64) FIXED_POINT * 1000 * 64, - (int64) FIXED_POINT * 1000 * 619 - }; - - if (rate == 0 || so.playback_rate == 0) - ch->erate = 0; - else - { - ch->erate = (unsigned long) - (steps [ch->state] / (rate * so.playback_rate)); - } + ch->envx_target = target; + + if (rate == ~0UL) + { + ch->direction = 0; + rate = 0; + } + else + ch->direction = direction; + + static int64 steps [] = + { + // 0, 64, 1238, 1238, 256, 1, 64, 109, 64, 1238 + 0, + (int64) FIXED_POINT * 1000 * 64, + (int64) FIXED_POINT * 1000 * 619, + (int64) FIXED_POINT * 1000 * 619, + (int64) FIXED_POINT * 1000 * 128, + (int64) FIXED_POINT * 1000 * 1, + (int64) FIXED_POINT * 1000 * 64, + (int64) FIXED_POINT * 1000 * 55, + (int64) FIXED_POINT * 1000 * 64, + (int64) FIXED_POINT * 1000 * 619 + }; + + if (rate == 0 || so.playback_rate == 0) + ch->erate = 0; + else + { + ch->erate = (unsigned long) + (steps [ch->state] / (rate * so.playback_rate)); + } } #ifdef __DJGPP END_OF_FUNCTION(S9xSetEnvRate); #endif -void S9xSetEnvelopeRate (int channel, unsigned long rate, int direction, - int target) +void S9xSetEnvelopeRate(int channel, unsigned long rate, int direction, + int target) { - S9xSetEnvRate (&SoundData.channels [channel], rate, direction, target); + S9xSetEnvRate(&SoundData.channels [channel], rate, direction, target); } #ifdef __DJGPP END_OF_FUNCTION(S9xSetEnvelopeRate); #endif -void S9xSetSoundVolume (int channel, short volume_left, short volume_right) +void S9xSetSoundVolume(int channel, short volume_left, short volume_right) { - Channel *ch = &SoundData.channels[channel]; - ch->volume_left = volume_left; - ch->volume_right = volume_right; - ch-> left_vol_level = (ch->envx * volume_left) / 128; - ch->right_vol_level = (ch->envx * volume_right) / 128; + Channel* ch = &SoundData.channels[channel]; + ch->volume_left = volume_left; + ch->volume_right = volume_right; + ch-> left_vol_level = (ch->envx * volume_left) / 128; + ch->right_vol_level = (ch->envx * volume_right) / 128; } -void S9xSetMasterVolume (short volume_left, short volume_right) +void S9xSetMasterVolume(short volume_left, short volume_right) { - if (Settings.DisableMasterVolume || SNESGameFixes.EchoOnlyOutput) - { - SoundData.master_volume [0] = SoundData.master_volume [1] = 127; - } - else - { - SoundData.master_volume [0] = volume_left; - SoundData.master_volume [1] = volume_right; - } + if (Settings.DisableMasterVolume || SNESGameFixes.EchoOnlyOutput) + SoundData.master_volume [0] = SoundData.master_volume [1] = 127; + else + { + SoundData.master_volume [0] = volume_left; + SoundData.master_volume [1] = volume_right; + } } -void S9xSetEchoVolume (short volume_left, short volume_right) +void S9xSetEchoVolume(short volume_left, short volume_right) { - SoundData.echo_volume [0] = volume_left; - SoundData.echo_volume [1] = volume_right; + SoundData.echo_volume [0] = volume_left; + SoundData.echo_volume [1] = volume_right; } -void S9xSetEchoEnable (uint8 byte) +void S9xSetEchoEnable(uint8 byte) { - SoundData.echo_channel_enable = byte; - if (!SoundData.echo_write_enabled || Settings.DisableSoundEcho) - byte = 0; - if (byte && !SoundData.echo_enable) - { - memset (Echo, 0, sizeof (Echo)); - memset (Loop, 0, sizeof (Loop)); - } - - SoundData.echo_enable = byte; - int i; - for (i = 0; i < NUM_CHANNELS; i++) - { - if (byte & (1 << i)) - SoundData.channels [i].echo_buf_ptr = EchoBuffer; - else - SoundData.channels [i].echo_buf_ptr = DummyEchoBuffer; - } + SoundData.echo_channel_enable = byte; + if (!SoundData.echo_write_enabled || Settings.DisableSoundEcho) + byte = 0; + if (byte && !SoundData.echo_enable) + { + memset(Echo, 0, sizeof(Echo)); + memset(Loop, 0, sizeof(Loop)); + } + + SoundData.echo_enable = byte; + int i; + for (i = 0; i < NUM_CHANNELS; i++) + { + if (byte & (1 << i)) + SoundData.channels [i].echo_buf_ptr = EchoBuffer; + else + SoundData.channels [i].echo_buf_ptr = DummyEchoBuffer; + } } -void S9xSetEchoFeedback (int feedback) +void S9xSetEchoFeedback(int feedback) { - CLIP8(feedback); - SoundData.echo_feedback = feedback; + CLIP8(feedback); + SoundData.echo_feedback = feedback; } -void S9xSetEchoDelay (int delay) +void S9xSetEchoDelay(int delay) { - SoundData.echo_buffer_size = (512 * delay * so.playback_rate) / 32000; - SoundData.echo_buffer_size <<= 1; - if (SoundData.echo_buffer_size) - SoundData.echo_ptr %= SoundData.echo_buffer_size; - else - SoundData.echo_ptr = 0; - S9xSetEchoEnable (APU.DSP [APU_EON]); + SoundData.echo_buffer_size = (512 * delay * so.playback_rate) / 32000; + SoundData.echo_buffer_size <<= 1; + if (SoundData.echo_buffer_size) + SoundData.echo_ptr %= SoundData.echo_buffer_size; + else + SoundData.echo_ptr = 0; + S9xSetEchoEnable(APU.DSP [APU_EON]); } -void S9xSetEchoWriteEnable (uint8 byte) +void S9xSetEchoWriteEnable(uint8 byte) { - SoundData.echo_write_enabled = byte; - S9xSetEchoDelay (APU.DSP [APU_EDL] & 15); + SoundData.echo_write_enabled = byte; + S9xSetEchoDelay(APU.DSP [APU_EDL] & 15); } -void S9xSetFrequencyModulationEnable (uint8 byte) +void S9xSetFrequencyModulationEnable(uint8 byte) { - SoundData.pitch_mod = byte & ~1; + SoundData.pitch_mod = byte & ~1; } -void S9xSetSoundKeyOff (int channel) +void S9xSetSoundKeyOff(int channel) { - Channel *ch = &SoundData.channels[channel]; - - if (ch->state != SOUND_SILENT) - { - ch->state = SOUND_RELEASE; - ch->mode = MODE_RELEASE; - S9xSetEnvRate (ch, 8, -1, 0); - } + Channel* ch = &SoundData.channels[channel]; + + if (ch->state != SOUND_SILENT) + { + ch->state = SOUND_RELEASE; + ch->mode = MODE_RELEASE; + S9xSetEnvRate(ch, 8, -1, 0); + } } -void S9xFixSoundAfterSnapshotLoad () +void S9xFixSoundAfterSnapshotLoad() { - SoundData.echo_write_enabled = !(APU.DSP [APU_FLG] & 0x20); - SoundData.echo_channel_enable = APU.DSP [APU_EON]; - S9xSetEchoDelay (APU.DSP [APU_EDL] & 0xf); - S9xSetEchoFeedback ((signed char) APU.DSP [APU_EFB]); - - S9xSetFilterCoefficient (0, (signed char) APU.DSP [APU_C0]); - S9xSetFilterCoefficient (1, (signed char) APU.DSP [APU_C1]); - S9xSetFilterCoefficient (2, (signed char) APU.DSP [APU_C2]); - S9xSetFilterCoefficient (3, (signed char) APU.DSP [APU_C3]); - S9xSetFilterCoefficient (4, (signed char) APU.DSP [APU_C4]); - S9xSetFilterCoefficient (5, (signed char) APU.DSP [APU_C5]); - S9xSetFilterCoefficient (6, (signed char) APU.DSP [APU_C6]); - S9xSetFilterCoefficient (7, (signed char) APU.DSP [APU_C7]); - int i; - for (i = 0; i < 8; i++) - { - SoundData.channels[i].needs_decode = TRUE; - S9xSetSoundFrequency (i, SoundData.channels[i].hertz); - SoundData.channels [i].envxx = SoundData.channels [i].envx << ENVX_SHIFT; - SoundData.channels [i].next_sample = 0; - SoundData.channels [i].interpolate = 0; - SoundData.channels [i].previous [0] = (int32) SoundData.channels [i].previous16 [0]; - SoundData.channels [i].previous [1] = (int32) SoundData.channels [i].previous16 [1]; - } - IAPU.Scanline = 0; + SoundData.echo_write_enabled = !(APU.DSP [APU_FLG] & 0x20); + SoundData.echo_channel_enable = APU.DSP [APU_EON]; + S9xSetEchoDelay(APU.DSP [APU_EDL] & 0xf); + S9xSetEchoFeedback((signed char) APU.DSP [APU_EFB]); + + S9xSetFilterCoefficient(0, (signed char) APU.DSP [APU_C0]); + S9xSetFilterCoefficient(1, (signed char) APU.DSP [APU_C1]); + S9xSetFilterCoefficient(2, (signed char) APU.DSP [APU_C2]); + S9xSetFilterCoefficient(3, (signed char) APU.DSP [APU_C3]); + S9xSetFilterCoefficient(4, (signed char) APU.DSP [APU_C4]); + S9xSetFilterCoefficient(5, (signed char) APU.DSP [APU_C5]); + S9xSetFilterCoefficient(6, (signed char) APU.DSP [APU_C6]); + S9xSetFilterCoefficient(7, (signed char) APU.DSP [APU_C7]); + int i; + for (i = 0; i < 8; i++) + { + SoundData.channels[i].needs_decode = TRUE; + S9xSetSoundFrequency(i, SoundData.channels[i].hertz); + SoundData.channels [i].envxx = SoundData.channels [i].envx << ENVX_SHIFT; + SoundData.channels [i].next_sample = 0; + SoundData.channels [i].interpolate = 0; + SoundData.channels [i].previous [0] = (int32) + SoundData.channels [i].previous16 [0]; + SoundData.channels [i].previous [1] = (int32) + SoundData.channels [i].previous16 [1]; + } + IAPU.Scanline = 0; } -void S9xSetFilterCoefficient (int tap, int value) +void S9xSetFilterCoefficient(int tap, int value) { - FilterTaps [tap & 7] = value; - if (value == 0 || (tap == 0 && value == 127)) - FilterTapDefinitionBitfield &= ~(1 << (tap & 7)); - else - FilterTapDefinitionBitfield |= 1 << (tap & 7); + FilterTaps [tap & 7] = value; + if (value == 0 || (tap == 0 && value == 127)) + FilterTapDefinitionBitfield &= ~(1 << (tap & 7)); + else + FilterTapDefinitionBitfield |= 1 << (tap & 7); } -void S9xSetSoundADSR (int channel, int attack_rate, int decay_rate, - int sustain_rate, int sustain_level, int release_rate) +void S9xSetSoundADSR(int channel, int attack_rate, int decay_rate, + int sustain_rate, int sustain_level, int release_rate) { - Channel *ch = &SoundData.channels[channel]; - ch->attack_rate = attack_rate; - ch->decay_rate = decay_rate; - ch->sustain_rate = sustain_rate; - ch->release_rate = release_rate; - ch->sustain_level = sustain_level + 1; - - switch (SoundData.channels[channel].state) - { - case SOUND_ATTACK: - S9xSetEnvRate (ch, attack_rate, 1, 127); - break; - - case SOUND_DECAY: - S9xSetEnvRate (ch, decay_rate, -1, - (MAX_ENVELOPE_HEIGHT * (sustain_level + 1)) >> 3); - break; - case SOUND_SUSTAIN: - S9xSetEnvRate (ch, sustain_rate, -1, 0); - break; - } + Channel* ch = &SoundData.channels[channel]; + ch->attack_rate = attack_rate; + ch->decay_rate = decay_rate; + ch->sustain_rate = sustain_rate; + ch->release_rate = release_rate; + ch->sustain_level = sustain_level + 1; + + switch (SoundData.channels[channel].state) + { + case SOUND_ATTACK: + S9xSetEnvRate(ch, attack_rate, 1, 127); + break; + + case SOUND_DECAY: + S9xSetEnvRate(ch, decay_rate, -1, + (MAX_ENVELOPE_HEIGHT * (sustain_level + 1)) >> 3); + break; + case SOUND_SUSTAIN: + S9xSetEnvRate(ch, sustain_rate, -1, 0); + break; + } } -void S9xSetEnvelopeHeight (int channel, int level) +void S9xSetEnvelopeHeight(int channel, int level) { - Channel *ch = &SoundData.channels[channel]; - - ch->envx = level; - ch->envxx = level << ENVX_SHIFT; - - ch->left_vol_level = (level * ch->volume_left) / 128; - ch->right_vol_level = (level * ch->volume_right) / 128; - - if (ch->envx == 0 && ch->state != SOUND_SILENT && ch->state != SOUND_GAIN) - { - S9xAPUSetEndOfSample (channel, ch); - } + Channel* ch = &SoundData.channels[channel]; + + ch->envx = level; + ch->envxx = level << ENVX_SHIFT; + + ch->left_vol_level = (level * ch->volume_left) / 128; + ch->right_vol_level = (level * ch->volume_right) / 128; + + if (ch->envx == 0 && ch->state != SOUND_SILENT && ch->state != SOUND_GAIN) + S9xAPUSetEndOfSample(channel, ch); } -int S9xGetEnvelopeHeight (int channel) +int S9xGetEnvelopeHeight(int channel) { - if ((Settings.SoundEnvelopeHeightReading || - SNESGameFixes.SoundEnvelopeHeightReading2) && - SoundData.channels[channel].state != SOUND_SILENT && - SoundData.channels[channel].state != SOUND_GAIN) - { - return (SoundData.channels[channel].envx); - } - - //siren fix from XPP - if (SNESGameFixes.SoundEnvelopeHeightReading2 && - SoundData.channels[channel].state != SOUND_SILENT) - { - return (SoundData.channels[channel].envx); - } - - return (0); + if ((Settings.SoundEnvelopeHeightReading || + SNESGameFixes.SoundEnvelopeHeightReading2) && + SoundData.channels[channel].state != SOUND_SILENT && + SoundData.channels[channel].state != SOUND_GAIN) + return (SoundData.channels[channel].envx); + + //siren fix from XPP + if (SNESGameFixes.SoundEnvelopeHeightReading2 && + SoundData.channels[channel].state != SOUND_SILENT) + return (SoundData.channels[channel].envx); + + return (0); } #if 1 -void S9xSetSoundSample (int channel, uint16 sample_number) +void S9xSetSoundSample(int channel, uint16 sample_number) { } #else -void S9xSetSoundSample (int channel, uint16 sample_number) +void S9xSetSoundSample(int channel, uint16 sample_number) { - register Channel *ch = &SoundData.channels[channel]; - - if (ch->state != SOUND_SILENT && - sample_number != ch->sample_number) - { - int keep = ch->state; - ch->state = SOUND_SILENT; - ch->sample_number = sample_number; - ch->loop = FALSE; - ch->needs_decode = TRUE; - ch->last_block = FALSE; - ch->previous [0] = ch->previous[1] = 0; - uint8 *dir = S9xGetSampleAddress (sample_number); - ch->block_pointer = READ_WORD (dir); - ch->sample_pointer = 0; - ch->state = keep; - } + register Channel* ch = &SoundData.channels[channel]; + + if (ch->state != SOUND_SILENT && + sample_number != ch->sample_number) + { + int keep = ch->state; + ch->state = SOUND_SILENT; + ch->sample_number = sample_number; + ch->loop = FALSE; + ch->needs_decode = TRUE; + ch->last_block = FALSE; + ch->previous [0] = ch->previous[1] = 0; + uint8* dir = S9xGetSampleAddress(sample_number); + ch->block_pointer = READ_WORD(dir); + ch->sample_pointer = 0; + ch->state = keep; + } } #endif -void S9xSetSoundFrequency (int channel, int hertz) +void S9xSetSoundFrequency(int channel, int hertz) { - if (so.playback_rate) - { - if (SoundData.channels[channel].type == SOUND_NOISE) - hertz = NoiseFreq [APU.DSP [APU_FLG] & 0x1f]; - SoundData.channels[channel].frequency = (int) - (((int64) hertz * FIXED_POINT) / so.playback_rate); - if (Settings.FixFrequency) - { - SoundData.channels[channel].frequency = - (unsigned long) (SoundData.channels[channel].frequency * 49 / 50); - } - } + if (so.playback_rate) + { + if (SoundData.channels[channel].type == SOUND_NOISE) + hertz = NoiseFreq [APU.DSP [APU_FLG] & 0x1f]; + SoundData.channels[channel].frequency = (int) + (((int64) hertz * FIXED_POINT) / so.playback_rate); + if (Settings.FixFrequency) + { + SoundData.channels[channel].frequency = + (unsigned long)(SoundData.channels[channel].frequency * 49 / 50); + } + } } -void S9xSetSoundHertz (int channel, int hertz) +void S9xSetSoundHertz(int channel, int hertz) { - SoundData.channels[channel].hertz = hertz; - S9xSetSoundFrequency (channel, hertz); + SoundData.channels[channel].hertz = hertz; + S9xSetSoundFrequency(channel, hertz); } -void S9xSetSoundType (int channel, int type_of_sound) +void S9xSetSoundType(int channel, int type_of_sound) { - SoundData.channels[channel].type = type_of_sound; + SoundData.channels[channel].type = type_of_sound; } -bool8 S9xSetSoundMute (bool8 mute) +bool8 S9xSetSoundMute(bool8 mute) { - bool8 old = so.mute_sound; - so.mute_sound = mute; - return (old); + bool8 old = so.mute_sound; + so.mute_sound = mute; + return (old); } -void AltDecodeBlock (Channel *ch) +void AltDecodeBlock(Channel* ch) { - if (ch->block_pointer >= 0x10000 - 9) - { - ch->last_block = TRUE; - ch->loop = FALSE; - ch->block = ch->decoded; - memset ((void *) ch->decoded, 0, sizeof (int16) * 16); - return; - } - signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer]; - - unsigned char filter = *compressed; - if ((ch->last_block = filter & 1)) - ch->loop = (filter & 2) != 0; - + if (ch->block_pointer >= 0x10000 - 9) + { + ch->last_block = TRUE; + ch->loop = FALSE; + ch->block = ch->decoded; + memset((void*) ch->decoded, 0, sizeof(int16) * 16); + return; + } + signed char* compressed = (signed char*) &IAPU.RAM [ch->block_pointer]; + + unsigned char filter = *compressed; + if ((ch->last_block = filter & 1)) + ch->loop = (filter & 2) != 0; + #if (defined (USE_X86_ASM) && (defined (__i386__) || defined (__i486__) ||\ defined (__i586__) || defined (__WIN32__) || defined (__DJGPP))) - int16 *raw = ch->block = ch->decoded; - - if (Settings.AltSampleDecode == 1) - DecodeBlockAsm (compressed, raw, &ch->previous [0], &ch->previous [1]); - else - DecodeBlockAsm2 (compressed, raw, &ch->previous [0], &ch->previous [1]); + int16* raw = ch->block = ch->decoded; + + if (Settings.AltSampleDecode == 1) + DecodeBlockAsm(compressed, raw, &ch->previous [0], &ch->previous [1]); + else + DecodeBlockAsm2(compressed, raw, &ch->previous [0], &ch->previous [1]); #else - int32 out; - unsigned char shift; - signed char sample1, sample2; - unsigned int i; - - compressed++; - signed short *raw = ch->block = ch->decoded; - - int32 prev0 = ch->previous [0]; - int32 prev1 = ch->previous [1]; - shift = filter >> 4; - - switch ((filter >> 2) & 3) - { - case 0: - for (i = 8; i != 0; i--) - { - sample1 = *compressed++; - sample2 = sample1 << 4; - sample2 >>= 4; - sample1 >>= 4; - *raw++ = ((int32) sample1 << shift); - *raw++ = ((int32) sample2 << shift); - } - prev1 = *(raw - 2); - prev0 = *(raw - 1); - break; - case 1: - for (i = 8; i != 0; i--) - { - sample1 = *compressed++; - sample2 = sample1 << 4; - sample2 >>= 4; - sample1 >>= 4; - prev0 = (int16) prev0; - *raw++ = prev1 = ((int32) sample1 << shift) + prev0 - (prev0 >> 4); - prev1 = (int16) prev1; - *raw++ = prev0 = ((int32) sample2 << shift) + prev1 - (prev1 >> 4); - } - break; - case 2: - for (i = 8; i != 0; i--) - { - sample1 = *compressed++; - sample2 = sample1 << 4; - sample2 >>= 4; - sample1 >>= 4; - - out = (sample1 << shift) - prev1 + (prev1 >> 4); - prev1 = (int16) prev0; - prev0 &= ~3; - *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) - - (prev0 >> 4); - - out = (sample2 << shift) - prev1 + (prev1 >> 4); - prev1 = (int16) prev0; - prev0 &= ~3; - *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) - - (prev0 >> 4); - } - break; - case 3: - for (i = 8; i != 0; i--) - { - sample1 = *compressed++; - sample2 = sample1 << 4; - sample2 >>= 4; - sample1 >>= 4; - out = (sample1 << shift); - - out = out - prev1 + (prev1 >> 3) + (prev1 >> 4); - prev1 = (int16) prev0; - prev0 &= ~3; - *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) - - (prev0 >> 4) - (prev1 >> 6); - - out = (sample2 << shift); - out = out - prev1 + (prev1 >> 3) + (prev1 >> 4); - prev1 = (int16) prev0; - prev0 &= ~3; - *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) - - (prev0 >> 4) - (prev1 >> 6); - } - break; - } - ch->previous [0] = prev0; - ch->previous [1] = prev1; + int32 out; + unsigned char shift; + signed char sample1, sample2; + unsigned int i; + + compressed++; + signed short* raw = ch->block = ch->decoded; + + int32 prev0 = ch->previous [0]; + int32 prev1 = ch->previous [1]; + shift = filter >> 4; + + switch ((filter >> 2) & 3) + { + case 0: + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + sample2 >>= 4; + sample1 >>= 4; + *raw++ = ((int32) sample1 << shift); + *raw++ = ((int32) sample2 << shift); + } + prev1 = *(raw - 2); + prev0 = *(raw - 1); + break; + case 1: + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + sample2 >>= 4; + sample1 >>= 4; + prev0 = (int16) prev0; + *raw++ = prev1 = ((int32) sample1 << shift) + prev0 - (prev0 >> 4); + prev1 = (int16) prev1; + *raw++ = prev0 = ((int32) sample2 << shift) + prev1 - (prev1 >> 4); + } + break; + case 2: + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + sample2 >>= 4; + sample1 >>= 4; + + out = (sample1 << shift) - prev1 + (prev1 >> 4); + prev1 = (int16) prev0; + prev0 &= ~3; + *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) - + (prev0 >> 4); + + out = (sample2 << shift) - prev1 + (prev1 >> 4); + prev1 = (int16) prev0; + prev0 &= ~3; + *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) - + (prev0 >> 4); + } + break; + case 3: + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + sample2 >>= 4; + sample1 >>= 4; + out = (sample1 << shift); + + out = out - prev1 + (prev1 >> 3) + (prev1 >> 4); + prev1 = (int16) prev0; + prev0 &= ~3; + *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) - + (prev0 >> 4) - (prev1 >> 6); + + out = (sample2 << shift); + out = out - prev1 + (prev1 >> 3) + (prev1 >> 4); + prev1 = (int16) prev0; + prev0 &= ~3; + *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) - + (prev0 >> 4) - (prev1 >> 6); + } + break; + } + ch->previous [0] = prev0; + ch->previous [1] = prev1; #endif - - ch->block_pointer += 9; + + ch->block_pointer += 9; } -void AltDecodeBlock2 (Channel *ch) +void AltDecodeBlock2(Channel* ch) { - int32 out; - unsigned char filter; - unsigned char shift; - signed char sample1, sample2; - unsigned char i; - - if (ch->block_pointer > 0x10000 - 9) - { - ch->last_block = TRUE; - ch->loop = FALSE; - ch->block = ch->decoded; - memset ((void *) ch->decoded, 0, sizeof (int16) * 16); - return; - } - - signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer]; - - filter = *compressed; - if ((ch->last_block = filter & 1)) - ch->loop = (filter & 2) != 0; - - compressed++; - signed short *raw = ch->block = ch->decoded; - - shift = filter >> 4; - int32 prev0 = ch->previous [0]; - int32 prev1 = ch->previous [1]; - - if(shift > 12) - shift -= 4; - - switch ((filter >> 2) & 3) - { - case 0: - for (i = 8; i != 0; i--) - { - sample1 = *compressed++; - sample2 = sample1 << 4; - //Sample 2 = Bottom Nibble, Sign Extended. - sample2 >>= 4; - //Sample 1 = Top Nibble, shifted down and Sign Extended. - sample1 >>= 4; - - out = (int32)(sample1 << shift); - - prev1 = prev0; - prev0 = out; - CLIP16(out); - *raw++ = (int16)out; - - out = (int32)(sample2 << shift); - - prev1 = prev0; - prev0 = out; - CLIP16(out); - *raw++ = (int16)out; - } - break; - case 1: - for (i = 8; i != 0; i--) - { - sample1 = *compressed++; - sample2 = sample1 << 4; - //Sample 2 = Bottom Nibble, Sign Extended. - sample2 >>= 4; - //Sample 1 = Top Nibble, shifted down and Sign Extended. - sample1 >>= 4; - out = (int32)(sample1 << shift); - out += (int32)((double)prev0 * 15/16); - - prev1 = prev0; - prev0 = out; - CLIP16(out); - *raw++ = (int16)out; - - out = (int32)(sample2 << shift); - out += (int32)((double)prev0 * 15/16); - - prev1 = prev0; - prev0 = out; - CLIP16(out); - *raw++ = (int16)out; - } - break; - case 2: - for (i = 8; i != 0; i--) - { - sample1 = *compressed++; - sample2 = sample1 << 4; - //Sample 2 = Bottom Nibble, Sign Extended. - sample2 >>= 4; - //Sample 1 = Top Nibble, shifted down and Sign Extended. - sample1 >>= 4; - - out = ((sample1 << shift) * 256 + (prev0 & ~0x2) * 488 - prev1 * 240) >> 8; - - prev1 = prev0; - prev0 = (int16)out; - *raw++ = (int16)out; - - out = ((sample2 << shift) * 256 + (prev0 & ~0x2) * 488 - prev1 * 240) >> 8; - - prev1 = prev0; - prev0 = (int16)out; - *raw++ = (int16)out; - } - break; - - case 3: - for (i = 8; i != 0; i--) - { - sample1 = *compressed++; - sample2 = sample1 << 4; - //Sample 2 = Bottom Nibble, Sign Extended. - sample2 >>= 4; - //Sample 1 = Top Nibble, shifted down and Sign Extended. - sample1 >>= 4; - out = (int32)(sample1 << shift); - out += (int32)((double)prev0 * 115/64 - (double)prev1 * 13/16); - - prev1 = prev0; - prev0 = out; - - CLIP16(out); - *raw++ = (int16)out; - - out = (int32)(sample2 << shift); - out += (int32)((double)prev0 * 115/64 - (double)prev1 * 13/16); - - prev1 = prev0; - prev0 = out; - - CLIP16(out); - *raw++ = (int16)out; - } - break; - } - ch->previous [0] = prev0; - ch->previous [1] = prev1; - ch->block_pointer += 9; + int32 out; + unsigned char filter; + unsigned char shift; + signed char sample1, sample2; + unsigned char i; + + if (ch->block_pointer > 0x10000 - 9) + { + ch->last_block = TRUE; + ch->loop = FALSE; + ch->block = ch->decoded; + memset((void*) ch->decoded, 0, sizeof(int16) * 16); + return; + } + + signed char* compressed = (signed char*) &IAPU.RAM [ch->block_pointer]; + + filter = *compressed; + if ((ch->last_block = filter & 1)) + ch->loop = (filter & 2) != 0; + + compressed++; + signed short* raw = ch->block = ch->decoded; + + shift = filter >> 4; + int32 prev0 = ch->previous [0]; + int32 prev1 = ch->previous [1]; + + if (shift > 12) + shift -= 4; + + switch ((filter >> 2) & 3) + { + case 0: + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + //Sample 2 = Bottom Nibble, Sign Extended. + sample2 >>= 4; + //Sample 1 = Top Nibble, shifted down and Sign Extended. + sample1 >>= 4; + + out = (int32)(sample1 << shift); + + prev1 = prev0; + prev0 = out; + CLIP16(out); + *raw++ = (int16)out; + + out = (int32)(sample2 << shift); + + prev1 = prev0; + prev0 = out; + CLIP16(out); + *raw++ = (int16)out; + } + break; + case 1: + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + //Sample 2 = Bottom Nibble, Sign Extended. + sample2 >>= 4; + //Sample 1 = Top Nibble, shifted down and Sign Extended. + sample1 >>= 4; + out = (int32)(sample1 << shift); + out += (int32)((double)prev0 * 15 / 16); + + prev1 = prev0; + prev0 = out; + CLIP16(out); + *raw++ = (int16)out; + + out = (int32)(sample2 << shift); + out += (int32)((double)prev0 * 15 / 16); + + prev1 = prev0; + prev0 = out; + CLIP16(out); + *raw++ = (int16)out; + } + break; + case 2: + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + //Sample 2 = Bottom Nibble, Sign Extended. + sample2 >>= 4; + //Sample 1 = Top Nibble, shifted down and Sign Extended. + sample1 >>= 4; + + out = ((sample1 << shift) * 256 + (prev0 & ~0x2) * 488 - prev1 * 240) >> 8; + + prev1 = prev0; + prev0 = (int16)out; + *raw++ = (int16)out; + + out = ((sample2 << shift) * 256 + (prev0 & ~0x2) * 488 - prev1 * 240) >> 8; + + prev1 = prev0; + prev0 = (int16)out; + *raw++ = (int16)out; + } + break; + + case 3: + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + //Sample 2 = Bottom Nibble, Sign Extended. + sample2 >>= 4; + //Sample 1 = Top Nibble, shifted down and Sign Extended. + sample1 >>= 4; + out = (int32)(sample1 << shift); + out += (int32)((double)prev0 * 115 / 64 - (double)prev1 * 13 / 16); + + prev1 = prev0; + prev0 = out; + + CLIP16(out); + *raw++ = (int16)out; + + out = (int32)(sample2 << shift); + out += (int32)((double)prev0 * 115 / 64 - (double)prev1 * 13 / 16); + + prev1 = prev0; + prev0 = out; + + CLIP16(out); + *raw++ = (int16)out; + } + break; + } + ch->previous [0] = prev0; + ch->previous [1] = prev1; + ch->block_pointer += 9; } -void DecodeBlock (Channel *ch) +void DecodeBlock(Channel* ch) { - int32 out; - unsigned char filter; - unsigned char shift; - signed char sample1, sample2; - unsigned char i; - bool invalid_header; - - if (Settings.AltSampleDecode) - { - if (Settings.AltSampleDecode < 3) - AltDecodeBlock (ch); - else - AltDecodeBlock2 (ch); - return; - } - if (ch->block_pointer > 0x10000 - 9) - { - ch->last_block = TRUE; - ch->loop = FALSE; - ch->block = ch->decoded; - return; - } - - if (Settings.EightBitConsoleSound) - { - signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer]; - - filter = *compressed; - if ((ch->last_block = filter & 1)) - ch->loop = (filter & 2) != 0; - - int16 interim[16]; - uint8 interim_byte = 0; - - compressed++; - signed short *raw = ch->block = ch->decoded; - - // Seperate out the header parts used for decoding - - shift = filter >> 4; - - // Header validity check: if range(shift) is over 12, ignore - // all bits of the data for that block except for the sign bit of each - invalid_header = (shift >= 0xD); - - filter = filter&0x0c; - - int32 prev0 = ch->previous [0]; - int32 prev1 = ch->previous [1]; - - int16 amplitude = 0; - - for (i = 8; i != 0; i--) - { - sample1 = *compressed++; - sample2 = sample1 << 4; - //Sample 2 = Bottom Nibble, Sign Extended. - sample2 >>= 4; - //Sample 1 = Top Nibble, shifted down and Sign Extended. - sample1 >>= 4; - if (invalid_header) { sample1>>=3; sample2>>=3; } - - int nybblesmp; - for (nybblesmp = 0; nybblesmp<2; nybblesmp++){ - out=(((nybblesmp) ? sample2 : sample1) << shift); - out >>= 1; - - switch(filter) - { - case 0x00: - // Method0 - [Smp] - break; - - case 0x04: - // Method1 - [Delta]+[Smp-1](15/16) - out+=(prev0>>1)+((-prev0)>>5); - break; - - case 0x08: - // Method2 - [Delta]+[Smp-1](61/32)-[Smp-2](15/16) - out+=(prev0)+((-(prev0 +(prev0>>1)))>>5)-(prev1>>1)+(prev1>>5); - break; - - default: - // Method3 - [Delta]+[Smp-1](115/64)-[Smp-2](13/16) - out+=(prev0)+((-(prev0 + (prev0<<2) + (prev0<<3)))>>7)-(prev1>>1)+((prev1+(prev1>>1))>>4); - break; - - } - CLIP16(out); - int16 result = (signed short)(out<<1); - if (abs(result) > amplitude) - amplitude = abs(result); - interim[interim_byte++] = out; - prev1=(signed short)prev0; - prev0=(signed short)(out<<1); - } - } - ch->previous [0] = prev0; - ch->previous [1] = prev1; - - int32 total_deviation_from_previous = 0; - for (i = 1; i < 16; i++) - total_deviation_from_previous += abs(interim[i] - interim[i - 1]); - if (total_deviation_from_previous >= (int32) amplitude * 4) - { - /* Looks like noise. Generate noise. */ - for (i = 0; i < 16; i++) - { - int feedback = (noise_gen << 13) ^ (noise_gen << 14); - noise_gen = (feedback & 0x4000) ^ (noise_gen >> 1); - ch->decoded[i] = (noise_gen << 17) >> 17; - } - } - else if (interim[0] < interim[1] && interim[1] < interim[2] - && interim[2] < interim[3] - && interim[4] > interim[5] && interim[5] > interim[6] - && interim[6] > interim[7] && interim[7] > interim[8] - && interim[8] > interim[9] && interim[9] > interim[10] - && interim[10] > interim[11] - && interim[12] < interim[13] && interim[13] < interim[14] - && interim[14] < interim[15]) - { - /* Looks like a sine or triangle wave. Make it a - * triangle wave with an amplitude equivalent to that - * of the highest amplitude sample of the block. */ - ch->decoded[0] = ch->decoded[8] = 0; - ch->decoded[1] = ch->decoded[7] = amplitude / 4; - ch->decoded[2] = ch->decoded[6] = amplitude / 2; - ch->decoded[3] = ch->decoded[5] = amplitude * 3 / 4; - ch->decoded[4] = amplitude; - ch->decoded[9] = ch->decoded[15] = -(amplitude / 4); - ch->decoded[10] = ch->decoded[14] = -(amplitude / 2); - ch->decoded[11] = ch->decoded[13] = -(amplitude * 3 / 4); - ch->decoded[12] = -amplitude; - } - else if (interim[0] > interim[1] && interim[1] > interim[2] - && interim[2] > interim[3] - && interim[4] < interim[5] && interim[5] < interim[6] - && interim[6] < interim[7] && interim[7] < interim[8] - && interim[8] < interim[9] && interim[9] < interim[10] - && interim[10] < interim[11] - && interim[12] > interim[13] && interim[13] > interim[14] - && interim[14] > interim[15]) - { - /* Inverted triangle wave. */ - ch->decoded[0] = ch->decoded[8] = 0; - ch->decoded[1] = ch->decoded[7] = -(amplitude / 4); - ch->decoded[2] = ch->decoded[6] = -(amplitude / 2); - ch->decoded[3] = ch->decoded[5] = -(amplitude * 3 / 4); - ch->decoded[4] = -amplitude; - ch->decoded[9] = ch->decoded[15] = amplitude / 4; - ch->decoded[10] = ch->decoded[14] = amplitude / 2; - ch->decoded[11] = ch->decoded[13] = amplitude * 3 / 4; - ch->decoded[12] = amplitude; - } - else if (interim[0] < interim[1] && interim[1] < interim[2] - && interim[2] < interim[3] && interim[3] < interim[4] - && interim[4] < interim[5] && interim[5] < interim[6] - && interim[6] < interim[7] - && interim[8] > interim[9] && interim[9] > interim[10] - && interim[10] > interim[11] && interim[11] > interim[12] - && interim[12] > interim[13] && interim[13] > interim[14] - && interim[14] > interim[15]) - { - /* Looks like a V wave. Make it a half-triangle wave - * with an amplitude equivalent to that - * of the highest amplitude sample of the block. */ - ch->decoded[0] = 0; - ch->decoded[1] = ch->decoded[15] = amplitude / 8; - ch->decoded[2] = ch->decoded[14] = amplitude / 4; - ch->decoded[3] = ch->decoded[13] = amplitude * 3 / 8; - ch->decoded[4] = ch->decoded[12] = amplitude / 2; - ch->decoded[5] = ch->decoded[11] = amplitude * 5 / 8; - ch->decoded[6] = ch->decoded[10] = amplitude * 3 / 4; - ch->decoded[7] = ch->decoded[9] = amplitude * 7 / 8; - ch->decoded[8] = amplitude; - } - else if (interim[0] > interim[1] && interim[1] > interim[2] - && interim[2] > interim[3] && interim[3] > interim[4] - && interim[4] > interim[5] && interim[5] > interim[6] - && interim[6] > interim[7] - && interim[8] < interim[9] && interim[9] < interim[10] - && interim[10] < interim[11] && interim[11] < interim[12] - && interim[12] < interim[13] && interim[13] < interim[14] - && interim[14] < interim[15]) - { - /* Inverted V wave. */ - ch->decoded[0] = 0; - ch->decoded[1] = ch->decoded[15] = -(amplitude / 8); - ch->decoded[2] = ch->decoded[14] = -(amplitude / 4); - ch->decoded[3] = ch->decoded[13] = -(amplitude * 3 / 8); - ch->decoded[4] = ch->decoded[12] = -(amplitude / 2); - ch->decoded[5] = ch->decoded[11] = -(amplitude * 5 / 8); - ch->decoded[6] = ch->decoded[10] = -(amplitude * 3 / 4); - ch->decoded[7] = ch->decoded[9] = -(amplitude * 7 / 8); - ch->decoded[8] = -amplitude; - } - else - { - // Make it a square wave with an amplitude equivalent to that - // of the highest amplitude sample of the block. - // But actually put half of the amplitude, because - // square waves are just loud. - for (i = 0; i < 8; i++) - ch->decoded[i] = amplitude / 2; - for (i = 8; i < 16; i++) - ch->decoded[i] = -(amplitude / 2); - } - } - else - { - signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer]; - - filter = *compressed; - if ((ch->last_block = filter & 1)) - ch->loop = (filter & 2) != 0; - - compressed++; - signed short *raw = ch->block = ch->decoded; - - // Seperate out the header parts used for decoding - - shift = filter >> 4; - - // Header validity check: if range(shift) is over 12, ignore - // all bits of the data for that block except for the sign bit of each - invalid_header = (shift >= 0xD); - - filter = filter&0x0c; - - int32 prev0 = ch->previous [0]; - int32 prev1 = ch->previous [1]; - - for (i = 8; i != 0; i--) - { - sample1 = *compressed++; - sample2 = sample1 << 4; - //Sample 2 = Bottom Nibble, Sign Extended. - sample2 >>= 4; - //Sample 1 = Top Nibble, shifted down and Sign Extended. - sample1 >>= 4; - if (invalid_header) { sample1>>=3; sample2>>=3; } - + int32 out; + unsigned char filter; + unsigned char shift; + signed char sample1, sample2; + unsigned char i; + bool invalid_header; + + if (Settings.AltSampleDecode) + { + if (Settings.AltSampleDecode < 3) + AltDecodeBlock(ch); + else + AltDecodeBlock2(ch); + return; + } + if (ch->block_pointer > 0x10000 - 9) + { + ch->last_block = TRUE; + ch->loop = FALSE; + ch->block = ch->decoded; + return; + } + + if (Settings.EightBitConsoleSound) + { + signed char* compressed = (signed char*) &IAPU.RAM [ch->block_pointer]; + + filter = *compressed; + if ((ch->last_block = filter & 1)) + ch->loop = (filter & 2) != 0; + + int16 interim[16]; + uint8 interim_byte = 0; + + compressed++; + signed short* raw = ch->block = ch->decoded; + + // Seperate out the header parts used for decoding + + shift = filter >> 4; + + // Header validity check: if range(shift) is over 12, ignore + // all bits of the data for that block except for the sign bit of each + invalid_header = (shift >= 0xD); + + filter = filter & 0x0c; + + int32 prev0 = ch->previous [0]; + int32 prev1 = ch->previous [1]; + + int16 amplitude = 0; + + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + //Sample 2 = Bottom Nibble, Sign Extended. + sample2 >>= 4; + //Sample 1 = Top Nibble, shifted down and Sign Extended. + sample1 >>= 4; + if (invalid_header) + { + sample1 >>= 3; + sample2 >>= 3; + } + + int nybblesmp; + for (nybblesmp = 0; nybblesmp < 2; nybblesmp++) + { + out = (((nybblesmp) ? sample2 : sample1) << shift); + out >>= 1; + + switch (filter) + { + case 0x00: + // Method0 - [Smp] + break; + + case 0x04: + // Method1 - [Delta]+[Smp-1](15/16) + out += (prev0 >> 1) + ((-prev0) >> 5); + break; + + case 0x08: + // Method2 - [Delta]+[Smp-1](61/32)-[Smp-2](15/16) + out += (prev0) + ((-(prev0 + (prev0 >> 1))) >> 5) - (prev1 >> 1) + (prev1 >> 5); + break; + + default: + // Method3 - [Delta]+[Smp-1](115/64)-[Smp-2](13/16) + out += (prev0) + ((-(prev0 + (prev0 << 2) + (prev0 << 3))) >> 7) - + (prev1 >> 1) + ((prev1 + (prev1 >> 1)) >> 4); + break; + + } + CLIP16(out); + int16 result = (signed short)(out << 1); + if (abs(result) > amplitude) + amplitude = abs(result); + interim[interim_byte++] = out; + prev1 = (signed short)prev0; + prev0 = (signed short)(out << 1); + } + } + ch->previous [0] = prev0; + ch->previous [1] = prev1; + + int32 total_deviation_from_previous = 0; + for (i = 1; i < 16; i++) + total_deviation_from_previous += abs(interim[i] - interim[i - 1]); + if (total_deviation_from_previous >= (int32) amplitude * 4) + { + /* Looks like noise. Generate noise. */ + for (i = 0; i < 16; i++) + { + int feedback = (noise_gen << 13) ^ (noise_gen << 14); + noise_gen = (feedback & 0x4000) ^ (noise_gen >> 1); + ch->decoded[i] = (noise_gen << 17) >> 17; + } + } + else if (interim[0] < interim[1] && interim[1] < interim[2] + && interim[2] < interim[3] + && interim[4] > interim[5] && interim[5] > interim[6] + && interim[6] > interim[7] && interim[7] > interim[8] + && interim[8] > interim[9] && interim[9] > interim[10] + && interim[10] > interim[11] + && interim[12] < interim[13] && interim[13] < interim[14] + && interim[14] < interim[15]) + { + /* Looks like a sine or triangle wave. Make it a + * triangle wave with an amplitude equivalent to that + * of the highest amplitude sample of the block. */ + ch->decoded[0] = ch->decoded[8] = 0; + ch->decoded[1] = ch->decoded[7] = amplitude / 4; + ch->decoded[2] = ch->decoded[6] = amplitude / 2; + ch->decoded[3] = ch->decoded[5] = amplitude * 3 / 4; + ch->decoded[4] = amplitude; + ch->decoded[9] = ch->decoded[15] = -(amplitude / 4); + ch->decoded[10] = ch->decoded[14] = -(amplitude / 2); + ch->decoded[11] = ch->decoded[13] = -(amplitude * 3 / 4); + ch->decoded[12] = -amplitude; + } + else if (interim[0] > interim[1] && interim[1] > interim[2] + && interim[2] > interim[3] + && interim[4] < interim[5] && interim[5] < interim[6] + && interim[6] < interim[7] && interim[7] < interim[8] + && interim[8] < interim[9] && interim[9] < interim[10] + && interim[10] < interim[11] + && interim[12] > interim[13] && interim[13] > interim[14] + && interim[14] > interim[15]) + { + /* Inverted triangle wave. */ + ch->decoded[0] = ch->decoded[8] = 0; + ch->decoded[1] = ch->decoded[7] = -(amplitude / 4); + ch->decoded[2] = ch->decoded[6] = -(amplitude / 2); + ch->decoded[3] = ch->decoded[5] = -(amplitude * 3 / 4); + ch->decoded[4] = -amplitude; + ch->decoded[9] = ch->decoded[15] = amplitude / 4; + ch->decoded[10] = ch->decoded[14] = amplitude / 2; + ch->decoded[11] = ch->decoded[13] = amplitude * 3 / 4; + ch->decoded[12] = amplitude; + } + else if (interim[0] < interim[1] && interim[1] < interim[2] + && interim[2] < interim[3] && interim[3] < interim[4] + && interim[4] < interim[5] && interim[5] < interim[6] + && interim[6] < interim[7] + && interim[8] > interim[9] && interim[9] > interim[10] + && interim[10] > interim[11] && interim[11] > interim[12] + && interim[12] > interim[13] && interim[13] > interim[14] + && interim[14] > interim[15]) + { + /* Looks like a V wave. Make it a half-triangle wave + * with an amplitude equivalent to that + * of the highest amplitude sample of the block. */ + ch->decoded[0] = 0; + ch->decoded[1] = ch->decoded[15] = amplitude / 8; + ch->decoded[2] = ch->decoded[14] = amplitude / 4; + ch->decoded[3] = ch->decoded[13] = amplitude * 3 / 8; + ch->decoded[4] = ch->decoded[12] = amplitude / 2; + ch->decoded[5] = ch->decoded[11] = amplitude * 5 / 8; + ch->decoded[6] = ch->decoded[10] = amplitude * 3 / 4; + ch->decoded[7] = ch->decoded[9] = amplitude * 7 / 8; + ch->decoded[8] = amplitude; + } + else if (interim[0] > interim[1] && interim[1] > interim[2] + && interim[2] > interim[3] && interim[3] > interim[4] + && interim[4] > interim[5] && interim[5] > interim[6] + && interim[6] > interim[7] + && interim[8] < interim[9] && interim[9] < interim[10] + && interim[10] < interim[11] && interim[11] < interim[12] + && interim[12] < interim[13] && interim[13] < interim[14] + && interim[14] < interim[15]) + { + /* Inverted V wave. */ + ch->decoded[0] = 0; + ch->decoded[1] = ch->decoded[15] = -(amplitude / 8); + ch->decoded[2] = ch->decoded[14] = -(amplitude / 4); + ch->decoded[3] = ch->decoded[13] = -(amplitude * 3 / 8); + ch->decoded[4] = ch->decoded[12] = -(amplitude / 2); + ch->decoded[5] = ch->decoded[11] = -(amplitude * 5 / 8); + ch->decoded[6] = ch->decoded[10] = -(amplitude * 3 / 4); + ch->decoded[7] = ch->decoded[9] = -(amplitude * 7 / 8); + ch->decoded[8] = -amplitude; + } + else + { + // Make it a square wave with an amplitude equivalent to that + // of the highest amplitude sample of the block. + // But actually put half of the amplitude, because + // square waves are just loud. + for (i = 0; i < 8; i++) + ch->decoded[i] = amplitude / 2; + for (i = 8; i < 16; i++) + ch->decoded[i] = -(amplitude / 2); + } + } + else + { + signed char* compressed = (signed char*) &IAPU.RAM [ch->block_pointer]; + + filter = *compressed; + if ((ch->last_block = filter & 1)) + ch->loop = (filter & 2) != 0; + + compressed++; + signed short* raw = ch->block = ch->decoded; + + // Seperate out the header parts used for decoding + + shift = filter >> 4; + + // Header validity check: if range(shift) is over 12, ignore + // all bits of the data for that block except for the sign bit of each + invalid_header = (shift >= 0xD); + + filter = filter & 0x0c; + + int32 prev0 = ch->previous [0]; + int32 prev1 = ch->previous [1]; + + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + //Sample 2 = Bottom Nibble, Sign Extended. + sample2 >>= 4; + //Sample 1 = Top Nibble, shifted down and Sign Extended. + sample1 >>= 4; + if (invalid_header) + { + sample1 >>= 3; + sample2 >>= 3; + } + int nybblesmp; - for (nybblesmp = 0; nybblesmp<2; nybblesmp++){ - out=(((nybblesmp) ? sample2 : sample1) << shift); - out >>= 1; - - switch(filter) - { - case 0x00: - // Method0 - [Smp] - break; - - case 0x04: - // Method1 - [Delta]+[Smp-1](15/16) - out+=(prev0>>1)+((-prev0)>>5); - break; - - case 0x08: - // Method2 - [Delta]+[Smp-1](61/32)-[Smp-2](15/16) - out+=(prev0)+((-(prev0 +(prev0>>1)))>>5)-(prev1>>1)+(prev1>>5); - break; - - default: - // Method3 - [Delta]+[Smp-1](115/64)-[Smp-2](13/16) - out+=(prev0)+((-(prev0 + (prev0<<2) + (prev0<<3)))>>7)-(prev1>>1)+((prev1+(prev1>>1))>>4); - break; - - } - CLIP16(out); - *raw++ = (signed short)(out<<1); - prev1=(signed short)prev0; - prev0=(signed short)(out<<1); - } - } - ch->previous [0] = prev0; - ch->previous [1] = prev1; - } - ch->block_pointer += 9; + for (nybblesmp = 0; nybblesmp < 2; nybblesmp++) + { + out = (((nybblesmp) ? sample2 : sample1) << shift); + out >>= 1; + + switch (filter) + { + case 0x00: + // Method0 - [Smp] + break; + + case 0x04: + // Method1 - [Delta]+[Smp-1](15/16) + out += (prev0 >> 1) + ((-prev0) >> 5); + break; + + case 0x08: + // Method2 - [Delta]+[Smp-1](61/32)-[Smp-2](15/16) + out += (prev0) + ((-(prev0 + (prev0 >> 1))) >> 5) - (prev1 >> 1) + (prev1 >> 5); + break; + + default: + // Method3 - [Delta]+[Smp-1](115/64)-[Smp-2](13/16) + out += (prev0) + ((-(prev0 + (prev0 << 2) + (prev0 << 3))) >> 7) - + (prev1 >> 1) + ((prev1 + (prev1 >> 1)) >> 4); + break; + + } + CLIP16(out); + *raw++ = (signed short)(out << 1); + prev1 = (signed short)prev0; + prev0 = (signed short)(out << 1); + } + } + ch->previous [0] = prev0; + ch->previous [1] = prev1; + } + ch->block_pointer += 9; } -static inline void MixStereo (int sample_count) +static inline void MixStereo(int sample_count) { - static int32 wave[SOUND_BUFFER_SIZE]; + static int32 wave[SOUND_BUFFER_SIZE]; - int pitch_mod = SoundData.pitch_mod & ~APU.DSP[APU_NON]; + int pitch_mod = SoundData.pitch_mod & ~APU.DSP[APU_NON]; uint32 J; for (J = 0; J < NUM_CHANNELS; J++) - { - Channel *ch = &SoundData.channels[J]; + { + Channel* ch = &SoundData.channels[J]; - if (ch->state == SOUND_SILENT || !(so.sound_switch & (1 << J))) - continue; + if (ch->state == SOUND_SILENT || !(so.sound_switch & (1 << J))) + continue; - int32 VL, VR; - unsigned long freq0 = ch->frequency; + int32 VL, VR; + unsigned long freq0 = ch->frequency; - // freq0 = (unsigned long) ((double) freq0 * 0.985);//uncommented by jonathan gevaryahu, as it is necessary for most cards in linux - freq0 = freq0 * 985/1000; + // freq0 = (unsigned long) ((double) freq0 * 0.985);//uncommented by jonathan gevaryahu, as it is necessary for most cards in linux + freq0 = freq0 * 985 / 1000; - bool8 mod = pitch_mod & (1 << J); + bool8 mod = pitch_mod & (1 << J); - if (ch->needs_decode) - { - DecodeBlock(ch); - ch->needs_decode = FALSE; - ch->sample = ch->block[0]; - ch->sample_pointer = freq0 >> FIXED_POINT_SHIFT; - if (ch->sample_pointer == 0) - ch->sample_pointer = 1; - if (ch->sample_pointer > SOUND_DECODE_LENGTH) - ch->sample_pointer = SOUND_DECODE_LENGTH - 1; + if (ch->needs_decode) + { + DecodeBlock(ch); + ch->needs_decode = FALSE; + ch->sample = ch->block[0]; + ch->sample_pointer = freq0 >> FIXED_POINT_SHIFT; + if (ch->sample_pointer == 0) + ch->sample_pointer = 1; + if (ch->sample_pointer > SOUND_DECODE_LENGTH) + ch->sample_pointer = SOUND_DECODE_LENGTH - 1; - ch->next_sample=ch->block[ch->sample_pointer]; - ch->interpolate = 0; + ch->next_sample = ch->block[ch->sample_pointer]; + ch->interpolate = 0; - if (Settings.InterpolatedSound && freq0 < FIXED_POINT && !mod) - ch->interpolate = ((ch->next_sample - ch->sample) * - (long) freq0) / (long) FIXED_POINT; - } - VL = (ch->sample * ch-> left_vol_level) / 128; - VR = (ch->sample * ch->right_vol_level) / 128; + if (Settings.InterpolatedSound && freq0 < FIXED_POINT && !mod) + ch->interpolate = ((ch->next_sample - ch->sample) * + (long) freq0) / (long) FIXED_POINT; + } + VL = (ch->sample * ch-> left_vol_level) / 128; + VR = (ch->sample * ch->right_vol_level) / 128; uint32 I; for (I = 0; I < (uint32) sample_count; I += 2) - { - unsigned long freq = freq0; - - if (mod) - freq = PITCH_MOD(freq, wave [I / 2]); - - ch->env_error += ch->erate; - if (ch->env_error >= FIXED_POINT) - { - uint32 step = ch->env_error >> FIXED_POINT_SHIFT; - - switch (ch->state) - { - case SOUND_ATTACK: - ch->env_error &= FIXED_POINT_REMAINDER; - ch->envx += step << 1; - ch->envxx = ch->envx << ENVX_SHIFT; - - if (ch->envx >= 126) - { - ch->envx = 127; - ch->envxx = 127 << ENVX_SHIFT; - ch->state = SOUND_DECAY; - if (ch->sustain_level != 8) - { - S9xSetEnvRate (ch, ch->decay_rate, -1, - (MAX_ENVELOPE_HEIGHT * ch->sustain_level) - >> 3); - break; - } - ch->state = SOUND_SUSTAIN; - S9xSetEnvRate (ch, ch->sustain_rate, -1, 0); - } - break; - - case SOUND_DECAY: - while (ch->env_error >= FIXED_POINT) - { - ch->envxx = (ch->envxx >> 8) * 255; - ch->env_error -= FIXED_POINT; - } - ch->envx = ch->envxx >> ENVX_SHIFT; - if (ch->envx <= ch->envx_target) - { - if (ch->envx <= 0) - { - S9xAPUSetEndOfSample (J, ch); - goto stereo_exit; - } - ch->state = SOUND_SUSTAIN; - S9xSetEnvRate (ch, ch->sustain_rate, -1, 0); - } - break; - - case SOUND_SUSTAIN: - while (ch->env_error >= FIXED_POINT) - { - ch->envxx = (ch->envxx >> 8) * 255; - ch->env_error -= FIXED_POINT; - } - ch->envx = ch->envxx >> ENVX_SHIFT; - if (ch->envx <= 0) - { - S9xAPUSetEndOfSample (J, ch); - goto stereo_exit; - } - break; - - case SOUND_RELEASE: - while (ch->env_error >= FIXED_POINT) - { - ch->envxx -= (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256; - ch->env_error -= FIXED_POINT; - } - ch->envx = ch->envxx >> ENVX_SHIFT; - if (ch->envx <= 0) - { - S9xAPUSetEndOfSample (J, ch); - goto stereo_exit; - } - break; - - case SOUND_INCREASE_LINEAR: - ch->env_error &= FIXED_POINT_REMAINDER; - ch->envx += step << 1; - ch->envxx = ch->envx << ENVX_SHIFT; - - if (ch->envx >= 126) - { - ch->envx = 127; - ch->envxx = 127 << ENVX_SHIFT; - ch->state = SOUND_GAIN; - ch->mode = MODE_GAIN; - S9xSetEnvRate (ch, 0, -1, 0); - } - break; - - case SOUND_INCREASE_BENT_LINE: - if (ch->envx >= (MAX_ENVELOPE_HEIGHT * 3) / 4) - { - while (ch->env_error >= FIXED_POINT) - { - ch->envxx += (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256; - ch->env_error -= FIXED_POINT; - } - ch->envx = ch->envxx >> ENVX_SHIFT; - } - else - { - ch->env_error &= FIXED_POINT_REMAINDER; - ch->envx += step << 1; - ch->envxx = ch->envx << ENVX_SHIFT; - } - - if (ch->envx >= 126) - { - ch->envx = 127; - ch->envxx = 127 << ENVX_SHIFT; - ch->state = SOUND_GAIN; - ch->mode = MODE_GAIN; - S9xSetEnvRate (ch, 0, -1, 0); - } - break; - - case SOUND_DECREASE_LINEAR: - ch->env_error &= FIXED_POINT_REMAINDER; - ch->envx -= step << 1; - ch->envxx = ch->envx << ENVX_SHIFT; - if (ch->envx <= 0) - { - S9xAPUSetEndOfSample (J, ch); - goto stereo_exit; - } - break; - - case SOUND_DECREASE_EXPONENTIAL: - while (ch->env_error >= FIXED_POINT) - { - ch->envxx = (ch->envxx >> 8) * 255; - ch->env_error -= FIXED_POINT; - } - ch->envx = ch->envxx >> ENVX_SHIFT; - if (ch->envx <= 0) - { - S9xAPUSetEndOfSample (J, ch); - goto stereo_exit; - } - break; - - case SOUND_GAIN: - S9xSetEnvRate (ch, 0, -1, 0); - break; - } - ch-> left_vol_level = (ch->envx * ch->volume_left) / 128; - ch->right_vol_level = (ch->envx * ch->volume_right) / 128; - VL = (ch->sample * ch-> left_vol_level) / 128; - VR = (ch->sample * ch->right_vol_level) / 128; - } - - ch->count += freq; - if (ch->count >= FIXED_POINT) - { - VL = ch->count >> FIXED_POINT_SHIFT; - ch->sample_pointer += VL; - ch->count &= FIXED_POINT_REMAINDER; - - ch->sample = ch->next_sample; - if (ch->sample_pointer >= SOUND_DECODE_LENGTH) - { - if (JUST_PLAYED_LAST_SAMPLE(ch)) - { - S9xAPUSetEndOfSample (J, ch); - goto stereo_exit; - } - do - { - ch->sample_pointer -= SOUND_DECODE_LENGTH; - if (ch->last_block) - { - if (!ch->loop) - { - ch->sample_pointer = LAST_SAMPLE; - ch->next_sample = ch->sample; - break; - } - else - { - S9xAPUSetEndX (J); - ch->last_block = FALSE; - uint8 *dir = S9xGetSampleAddress (ch->sample_number); - ch->block_pointer = READ_WORD(dir + 2); - } - } - DecodeBlock (ch); - } while (ch->sample_pointer >= SOUND_DECODE_LENGTH); - if (!JUST_PLAYED_LAST_SAMPLE (ch)) - ch->next_sample = ch->block [ch->sample_pointer]; - } - else - ch->next_sample = ch->block [ch->sample_pointer]; - - if (ch->type == SOUND_SAMPLE) - { - if (Settings.InterpolatedSound && freq < FIXED_POINT && !mod) - { - ch->interpolate = ((ch->next_sample - ch->sample) * - (long) freq) / (long) FIXED_POINT; - ch->sample = (int16) (ch->sample + (((ch->next_sample - ch->sample) * - (long) (ch->count)) / (long) FIXED_POINT)); - } - else - ch->interpolate = 0; - } - else - { - // Snes9x 1.53's SPC_DSP.cpp, by blargg - int feedback = (noise_gen << 13) ^ (noise_gen << 14); - noise_gen = (feedback & 0x4000) ^ (noise_gen >> 1); - ch->sample = (noise_gen << 17) >> 17; - ch->interpolate = 0; - } - - VL = (ch->sample * ch-> left_vol_level) / 128; - VR = (ch->sample * ch->right_vol_level) / 128; - } - else - { - if (ch->interpolate) - { - int32 s = (int32) ch->sample + ch->interpolate; - - CLIP16(s); - ch->sample = (int16) s; - VL = (ch->sample * ch-> left_vol_level) / 128; - VR = (ch->sample * ch->right_vol_level) / 128; - } - } - - if (pitch_mod & (1 << (J + 1))) - wave [I / 2] = ch->sample * ch->envx; - - MixBuffer [I ] += VL; - MixBuffer [I + 1] += VR; - ch->echo_buf_ptr [I ] += VL; - ch->echo_buf_ptr [I + 1] += VR; - } -stereo_exit: ; - } + { + unsigned long freq = freq0; + + if (mod) + freq = PITCH_MOD(freq, wave [I / 2]); + + ch->env_error += ch->erate; + if (ch->env_error >= FIXED_POINT) + { + uint32 step = ch->env_error >> FIXED_POINT_SHIFT; + + switch (ch->state) + { + case SOUND_ATTACK: + ch->env_error &= FIXED_POINT_REMAINDER; + ch->envx += step << 1; + ch->envxx = ch->envx << ENVX_SHIFT; + + if (ch->envx >= 126) + { + ch->envx = 127; + ch->envxx = 127 << ENVX_SHIFT; + ch->state = SOUND_DECAY; + if (ch->sustain_level != 8) + { + S9xSetEnvRate(ch, ch->decay_rate, -1, + (MAX_ENVELOPE_HEIGHT * ch->sustain_level) + >> 3); + break; + } + ch->state = SOUND_SUSTAIN; + S9xSetEnvRate(ch, ch->sustain_rate, -1, 0); + } + break; + + case SOUND_DECAY: + while (ch->env_error >= FIXED_POINT) + { + ch->envxx = (ch->envxx >> 8) * 255; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + if (ch->envx <= ch->envx_target) + { + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample(J, ch); + goto stereo_exit; + } + ch->state = SOUND_SUSTAIN; + S9xSetEnvRate(ch, ch->sustain_rate, -1, 0); + } + break; + + case SOUND_SUSTAIN: + while (ch->env_error >= FIXED_POINT) + { + ch->envxx = (ch->envxx >> 8) * 255; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample(J, ch); + goto stereo_exit; + } + break; + + case SOUND_RELEASE: + while (ch->env_error >= FIXED_POINT) + { + ch->envxx -= (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample(J, ch); + goto stereo_exit; + } + break; + + case SOUND_INCREASE_LINEAR: + ch->env_error &= FIXED_POINT_REMAINDER; + ch->envx += step << 1; + ch->envxx = ch->envx << ENVX_SHIFT; + + if (ch->envx >= 126) + { + ch->envx = 127; + ch->envxx = 127 << ENVX_SHIFT; + ch->state = SOUND_GAIN; + ch->mode = MODE_GAIN; + S9xSetEnvRate(ch, 0, -1, 0); + } + break; + + case SOUND_INCREASE_BENT_LINE: + if (ch->envx >= (MAX_ENVELOPE_HEIGHT * 3) / 4) + { + while (ch->env_error >= FIXED_POINT) + { + ch->envxx += (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + } + else + { + ch->env_error &= FIXED_POINT_REMAINDER; + ch->envx += step << 1; + ch->envxx = ch->envx << ENVX_SHIFT; + } + + if (ch->envx >= 126) + { + ch->envx = 127; + ch->envxx = 127 << ENVX_SHIFT; + ch->state = SOUND_GAIN; + ch->mode = MODE_GAIN; + S9xSetEnvRate(ch, 0, -1, 0); + } + break; + + case SOUND_DECREASE_LINEAR: + ch->env_error &= FIXED_POINT_REMAINDER; + ch->envx -= step << 1; + ch->envxx = ch->envx << ENVX_SHIFT; + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample(J, ch); + goto stereo_exit; + } + break; + + case SOUND_DECREASE_EXPONENTIAL: + while (ch->env_error >= FIXED_POINT) + { + ch->envxx = (ch->envxx >> 8) * 255; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample(J, ch); + goto stereo_exit; + } + break; + + case SOUND_GAIN: + S9xSetEnvRate(ch, 0, -1, 0); + break; + } + ch-> left_vol_level = (ch->envx * ch->volume_left) / 128; + ch->right_vol_level = (ch->envx * ch->volume_right) / 128; + VL = (ch->sample * ch-> left_vol_level) / 128; + VR = (ch->sample * ch->right_vol_level) / 128; + } + + ch->count += freq; + if (ch->count >= FIXED_POINT) + { + VL = ch->count >> FIXED_POINT_SHIFT; + ch->sample_pointer += VL; + ch->count &= FIXED_POINT_REMAINDER; + + ch->sample = ch->next_sample; + if (ch->sample_pointer >= SOUND_DECODE_LENGTH) + { + if (JUST_PLAYED_LAST_SAMPLE(ch)) + { + S9xAPUSetEndOfSample(J, ch); + goto stereo_exit; + } + do + { + ch->sample_pointer -= SOUND_DECODE_LENGTH; + if (ch->last_block) + { + if (!ch->loop) + { + ch->sample_pointer = LAST_SAMPLE; + ch->next_sample = ch->sample; + break; + } + else + { + S9xAPUSetEndX(J); + ch->last_block = FALSE; + uint8* dir = S9xGetSampleAddress(ch->sample_number); + ch->block_pointer = READ_WORD(dir + 2); + } + } + DecodeBlock(ch); + } + while (ch->sample_pointer >= SOUND_DECODE_LENGTH); + if (!JUST_PLAYED_LAST_SAMPLE(ch)) + ch->next_sample = ch->block [ch->sample_pointer]; + } + else + ch->next_sample = ch->block [ch->sample_pointer]; + + if (ch->type == SOUND_SAMPLE) + { + if (Settings.InterpolatedSound && freq < FIXED_POINT && !mod) + { + ch->interpolate = ((ch->next_sample - ch->sample) * + (long) freq) / (long) FIXED_POINT; + ch->sample = (int16)(ch->sample + (((ch->next_sample - ch->sample) * + (long)(ch->count)) / (long) FIXED_POINT)); + } + else + ch->interpolate = 0; + } + else + { + // Snes9x 1.53's SPC_DSP.cpp, by blargg + int feedback = (noise_gen << 13) ^ (noise_gen << 14); + noise_gen = (feedback & 0x4000) ^ (noise_gen >> 1); + ch->sample = (noise_gen << 17) >> 17; + ch->interpolate = 0; + } + + VL = (ch->sample * ch-> left_vol_level) / 128; + VR = (ch->sample * ch->right_vol_level) / 128; + } + else + { + if (ch->interpolate) + { + int32 s = (int32) ch->sample + ch->interpolate; + + CLIP16(s); + ch->sample = (int16) s; + VL = (ch->sample * ch-> left_vol_level) / 128; + VR = (ch->sample * ch->right_vol_level) / 128; + } + } + + if (pitch_mod & (1 << (J + 1))) + wave [I / 2] = ch->sample * ch->envx; + + MixBuffer [I ] += VL; + MixBuffer [I + 1] += VR; + ch->echo_buf_ptr [I ] += VL; + ch->echo_buf_ptr [I + 1] += VR; + } +stereo_exit: + ; + } } #ifdef __DJGPP @@ -1355,368 +1361,375 @@ END_OF_FUNCTION(MixStereo); #endif #ifdef __sun -extern uint8 int2ulaw (int); +extern uint8 int2ulaw(int); #endif // For backwards compatibility with older port specific code -void S9xMixSamplesO (uint8 *buffer, int sample_count, int byte_offset) +void S9xMixSamplesO(uint8* buffer, int sample_count, int byte_offset) { - S9xMixSamples (buffer+byte_offset, sample_count); + S9xMixSamples(buffer + byte_offset, sample_count); } #ifdef __DJGPP END_OF_FUNCTION(S9xMixSamplesO); #endif -void S9xMixSamples (uint8 *buffer, int sample_count) +void S9xMixSamples(uint8* buffer, int sample_count) { - int J; - int I; - - if (!so.mute_sound) - { - if (SoundData.echo_enable) - memset (EchoBuffer, 0, sample_count * sizeof (EchoBuffer [0])); - memset (MixBuffer, 0, sample_count * sizeof (MixBuffer [0])); - MixStereo (sample_count); - } - - /* Mix and convert waveforms */ - int byte_count = sample_count << 1; - - // 16-bit sound - if (so.mute_sound) - { - memset (buffer, 0, byte_count); - } - else - { - if (SoundData.echo_enable && SoundData.echo_buffer_size) - { - // 16-bit stereo sound with echo enabled ... - if (FilterTapDefinitionBitfield == 0) - { - // ... but no filter defined. - for (J = 0; J < sample_count; J++) - { - int E = Echo [SoundData.echo_ptr]; - - Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 + - EchoBuffer [J]; - - if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size) - SoundData.echo_ptr = 0; - - I = (MixBuffer [J] * - SoundData.master_volume [J & 1] + - E * SoundData.echo_volume [J & 1]) / VOL_DIV16; - - CLIP16(I); - ((signed short *) buffer)[J] = I; - } - } - else - { - // ... with filter defined. - for (J = 0; J < sample_count; J++) - { - int E = Echo [SoundData.echo_ptr]; - - Loop [(Z - 0) & 15] = E; - E = E * FilterTaps [0]; - if (FilterTapDefinitionBitfield & 0x02) E += Loop [(Z - 2) & 15] * FilterTaps [1]; - if (FilterTapDefinitionBitfield & 0x04) E += Loop [(Z - 4) & 15] * FilterTaps [2]; - if (FilterTapDefinitionBitfield & 0x08) E += Loop [(Z - 6) & 15] * FilterTaps [3]; - if (FilterTapDefinitionBitfield & 0x10) E += Loop [(Z - 8) & 15] * FilterTaps [4]; - if (FilterTapDefinitionBitfield & 0x20) E += Loop [(Z - 10) & 15] * FilterTaps [5]; - if (FilterTapDefinitionBitfield & 0x40) E += Loop [(Z - 12) & 15] * FilterTaps [6]; - if (FilterTapDefinitionBitfield & 0x80) E += Loop [(Z - 14) & 15] * FilterTaps [7]; - E /= 128; - Z++; - - Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 + - EchoBuffer [J]; - - if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size) - SoundData.echo_ptr = 0; - - I = (MixBuffer [J] * - SoundData.master_volume [J & 1] + - E * SoundData.echo_volume [J & 1]) / VOL_DIV16; - - CLIP16(I); - ((signed short *) buffer)[J] = I; - } - } - } - else - { - // 16-bit mono or stereo sound, no echo - for (J = 0; J < sample_count; J++) - { - I = (MixBuffer [J] * - SoundData.master_volume [J & 1]) / VOL_DIV16; - - CLIP16(I); - ((signed short *) buffer)[J] = I; - } - } - } + int J; + int I; + + if (!so.mute_sound) + { + if (SoundData.echo_enable) + memset(EchoBuffer, 0, sample_count * sizeof(EchoBuffer [0])); + memset(MixBuffer, 0, sample_count * sizeof(MixBuffer [0])); + MixStereo(sample_count); + } + + /* Mix and convert waveforms */ + int byte_count = sample_count << 1; + + // 16-bit sound + if (so.mute_sound) + memset(buffer, 0, byte_count); + else + { + if (SoundData.echo_enable && SoundData.echo_buffer_size) + { + // 16-bit stereo sound with echo enabled ... + if (FilterTapDefinitionBitfield == 0) + { + // ... but no filter defined. + for (J = 0; J < sample_count; J++) + { + int E = Echo [SoundData.echo_ptr]; + + Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 + + EchoBuffer [J]; + + if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size) + SoundData.echo_ptr = 0; + + I = (MixBuffer [J] * + SoundData.master_volume [J & 1] + + E * SoundData.echo_volume [J & 1]) / VOL_DIV16; + + CLIP16(I); + ((signed short*) buffer)[J] = I; + } + } + else + { + // ... with filter defined. + for (J = 0; J < sample_count; J++) + { + int E = Echo [SoundData.echo_ptr]; + + Loop [(Z - 0) & 15] = E; + E = E * FilterTaps [0]; + if (FilterTapDefinitionBitfield & 0x02) E += Loop [(Z - 2) & 15] * + FilterTaps [1]; + if (FilterTapDefinitionBitfield & 0x04) E += Loop [(Z - 4) & 15] * + FilterTaps [2]; + if (FilterTapDefinitionBitfield & 0x08) E += Loop [(Z - 6) & 15] * + FilterTaps [3]; + if (FilterTapDefinitionBitfield & 0x10) E += Loop [(Z - 8) & 15] * + FilterTaps [4]; + if (FilterTapDefinitionBitfield & 0x20) E += Loop [(Z - 10) & 15] * + FilterTaps [5]; + if (FilterTapDefinitionBitfield & 0x40) E += Loop [(Z - 12) & 15] * + FilterTaps [6]; + if (FilterTapDefinitionBitfield & 0x80) E += Loop [(Z - 14) & 15] * + FilterTaps [7]; + E /= 128; + Z++; + + Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 + + EchoBuffer [J]; + + if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size) + SoundData.echo_ptr = 0; + + I = (MixBuffer [J] * + SoundData.master_volume [J & 1] + + E * SoundData.echo_volume [J & 1]) / VOL_DIV16; + + CLIP16(I); + ((signed short*) buffer)[J] = I; + } + } + } + else + { + // 16-bit mono or stereo sound, no echo + for (J = 0; J < sample_count; J++) + { + I = (MixBuffer [J] * + SoundData.master_volume [J & 1]) / VOL_DIV16; + + CLIP16(I); + ((signed short*) buffer)[J] = I; + } + } + } } #ifdef __DJGPP END_OF_FUNCTION(S9xMixSamples); #endif -void S9xResetSound (bool8 full) +void S9xResetSound(bool8 full) { int i; - for (i = 0; i < 8; i++) - { - SoundData.channels[i].state = SOUND_SILENT; - SoundData.channels[i].mode = MODE_NONE; - SoundData.channels[i].type = SOUND_SAMPLE; - SoundData.channels[i].volume_left = 0; - SoundData.channels[i].volume_right = 0; - SoundData.channels[i].hertz = 0; - SoundData.channels[i].count = 0; - SoundData.channels[i].loop = FALSE; - SoundData.channels[i].envx_target = 0; - SoundData.channels[i].env_error = 0; - SoundData.channels[i].erate = 0; - SoundData.channels[i].envx = 0; - SoundData.channels[i].envxx = 0; - SoundData.channels[i].left_vol_level = 0; - SoundData.channels[i].right_vol_level = 0; - SoundData.channels[i].direction = 0; - SoundData.channels[i].attack_rate = 0; - SoundData.channels[i].decay_rate = 0; - SoundData.channels[i].sustain_rate = 0; - SoundData.channels[i].release_rate = 0; - SoundData.channels[i].sustain_level = 0; - SoundData.echo_ptr = 0; - SoundData.echo_feedback = 0; - SoundData.echo_buffer_size = 1; - } - FilterTaps [0] = 127; - FilterTaps [1] = 0; - FilterTaps [2] = 0; - FilterTaps [3] = 0; - FilterTaps [4] = 0; - FilterTaps [5] = 0; - FilterTaps [6] = 0; - FilterTaps [7] = 0; - FilterTapDefinitionBitfield = 0; - so.mute_sound = TRUE; - noise_gen = 1; - so.sound_switch = 255; - so.samples_mixed_so_far = 0; - so.play_position = 0; - so.err_counter = 0; - - if (full) - { - SoundData.echo_enable = 0; - SoundData.echo_write_enabled = 0; - SoundData.echo_channel_enable = 0; - SoundData.pitch_mod = 0; - SoundData.dummy[0] = 0; - SoundData.dummy[1] = 0; - SoundData.dummy[2] = 0; - SoundData.master_volume[0] = 0; - SoundData.master_volume[1] = 0; - SoundData.echo_volume[0] = 0; - SoundData.echo_volume[1] = 0; - SoundData.noise_hertz = 0; - } - - SoundData.master_volume [0] = SoundData.master_volume [1] = 127; - if (so.playback_rate) - so.err_rate = (uint32) (FIXED_POINT * SNES_SCANLINE_TIME / (1.0 / so.playback_rate)); - else - so.err_rate = 0; + for (i = 0; i < 8; i++) + { + SoundData.channels[i].state = SOUND_SILENT; + SoundData.channels[i].mode = MODE_NONE; + SoundData.channels[i].type = SOUND_SAMPLE; + SoundData.channels[i].volume_left = 0; + SoundData.channels[i].volume_right = 0; + SoundData.channels[i].hertz = 0; + SoundData.channels[i].count = 0; + SoundData.channels[i].loop = FALSE; + SoundData.channels[i].envx_target = 0; + SoundData.channels[i].env_error = 0; + SoundData.channels[i].erate = 0; + SoundData.channels[i].envx = 0; + SoundData.channels[i].envxx = 0; + SoundData.channels[i].left_vol_level = 0; + SoundData.channels[i].right_vol_level = 0; + SoundData.channels[i].direction = 0; + SoundData.channels[i].attack_rate = 0; + SoundData.channels[i].decay_rate = 0; + SoundData.channels[i].sustain_rate = 0; + SoundData.channels[i].release_rate = 0; + SoundData.channels[i].sustain_level = 0; + SoundData.echo_ptr = 0; + SoundData.echo_feedback = 0; + SoundData.echo_buffer_size = 1; + } + FilterTaps [0] = 127; + FilterTaps [1] = 0; + FilterTaps [2] = 0; + FilterTaps [3] = 0; + FilterTaps [4] = 0; + FilterTaps [5] = 0; + FilterTaps [6] = 0; + FilterTaps [7] = 0; + FilterTapDefinitionBitfield = 0; + so.mute_sound = TRUE; + noise_gen = 1; + so.sound_switch = 255; + so.samples_mixed_so_far = 0; + so.play_position = 0; + so.err_counter = 0; + + if (full) + { + SoundData.echo_enable = 0; + SoundData.echo_write_enabled = 0; + SoundData.echo_channel_enable = 0; + SoundData.pitch_mod = 0; + SoundData.dummy[0] = 0; + SoundData.dummy[1] = 0; + SoundData.dummy[2] = 0; + SoundData.master_volume[0] = 0; + SoundData.master_volume[1] = 0; + SoundData.echo_volume[0] = 0; + SoundData.echo_volume[1] = 0; + SoundData.noise_hertz = 0; + } + + SoundData.master_volume [0] = SoundData.master_volume [1] = 127; + if (so.playback_rate) + so.err_rate = (uint32)(FIXED_POINT * SNES_SCANLINE_TIME / + (1.0 / so.playback_rate)); + else + so.err_rate = 0; } -void S9xSetPlaybackRate (uint32 playback_rate) +void S9xSetPlaybackRate(uint32 playback_rate) { - so.playback_rate = playback_rate; - so.err_rate = (uint32) (SNES_SCANLINE_TIME * FIXED_POINT / (1.0 / (double) so.playback_rate)); - S9xSetEchoDelay (APU.DSP [APU_EDL] & 0xf); - int i; - for (i = 0; i < 8; i++) - S9xSetSoundFrequency (i, SoundData.channels [i].hertz); + so.playback_rate = playback_rate; + so.err_rate = (uint32)(SNES_SCANLINE_TIME * FIXED_POINT / (1.0 / + (double) so.playback_rate)); + S9xSetEchoDelay(APU.DSP [APU_EDL] & 0xf); + int i; + for (i = 0; i < 8; i++) + S9xSetSoundFrequency(i, SoundData.channels [i].hertz); } -bool8 S9xInitSound (int mode, bool8 stereo, int buffer_size) +bool8 S9xInitSound(int mode, bool8 stereo, int buffer_size) { - so.sound_fd = -1; - so.sound_switch = 255; - - so.playback_rate = 0; - so.buffer_size = 0; - so.encoded = FALSE; - - S9xResetSound (TRUE); - - if (!(mode & 7)) - return (1); - - S9xSetSoundMute (TRUE); - if (!S9xOpenSoundDevice (mode, stereo, buffer_size)) - { - S9xMessage (S9X_ERROR, S9X_SOUND_DEVICE_OPEN_FAILED, - "Sound device open failed"); - return (0); - } - - return (1); + so.sound_fd = -1; + so.sound_switch = 255; + + so.playback_rate = 0; + so.buffer_size = 0; + so.encoded = FALSE; + + S9xResetSound(TRUE); + + if (!(mode & 7)) + return (1); + + S9xSetSoundMute(TRUE); + if (!S9xOpenSoundDevice(mode, stereo, buffer_size)) + { + S9xMessage(S9X_ERROR, S9X_SOUND_DEVICE_OPEN_FAILED, + "Sound device open failed"); + return (0); + } + + return (1); } -bool8 S9xSetSoundMode (int channel, int mode) +bool8 S9xSetSoundMode(int channel, int mode) { - Channel *ch = &SoundData.channels[channel]; - - switch (mode) - { - case MODE_RELEASE: - if (ch->mode != MODE_NONE) - { - ch->mode = MODE_RELEASE; - return (TRUE); - } - break; - - case MODE_DECREASE_LINEAR: - case MODE_DECREASE_EXPONENTIAL: - case MODE_GAIN: - if (ch->mode != MODE_RELEASE) - { - ch->mode = mode; - if (ch->state != SOUND_SILENT) - ch->state = mode; - - return (TRUE); - } - break; - - case MODE_INCREASE_LINEAR: - case MODE_INCREASE_BENT_LINE: - if (ch->mode != MODE_RELEASE) - { - ch->mode = mode; - if (ch->state != SOUND_SILENT) - ch->state = mode; - - return (TRUE); - } - break; - - case MODE_ADSR: - if (ch->mode == MODE_NONE || ch->mode == MODE_ADSR) - { - ch->mode = mode; - return (TRUE); - } - } - - return (FALSE); + Channel* ch = &SoundData.channels[channel]; + + switch (mode) + { + case MODE_RELEASE: + if (ch->mode != MODE_NONE) + { + ch->mode = MODE_RELEASE; + return (TRUE); + } + break; + + case MODE_DECREASE_LINEAR: + case MODE_DECREASE_EXPONENTIAL: + case MODE_GAIN: + if (ch->mode != MODE_RELEASE) + { + ch->mode = mode; + if (ch->state != SOUND_SILENT) + ch->state = mode; + + return (TRUE); + } + break; + + case MODE_INCREASE_LINEAR: + case MODE_INCREASE_BENT_LINE: + if (ch->mode != MODE_RELEASE) + { + ch->mode = mode; + if (ch->state != SOUND_SILENT) + ch->state = mode; + + return (TRUE); + } + break; + + case MODE_ADSR: + if (ch->mode == MODE_NONE || ch->mode == MODE_ADSR) + { + ch->mode = mode; + return (TRUE); + } + } + + return (FALSE); } -void S9xSetSoundControl (int sound_switch) +void S9xSetSoundControl(int sound_switch) { - so.sound_switch = sound_switch; + so.sound_switch = sound_switch; } -void S9xPlaySample (int channel) +void S9xPlaySample(int channel) { - Channel *ch = &SoundData.channels[channel]; - - ch->state = SOUND_SILENT; - ch->mode = MODE_NONE; - ch->envx = 0; - ch->envxx = 0; - - S9xFixEnvelope (channel, - APU.DSP [APU_GAIN + (channel << 4)], - APU.DSP [APU_ADSR1 + (channel << 4)], - APU.DSP [APU_ADSR2 + (channel << 4)]); - - ch->sample_number = APU.DSP [APU_SRCN + channel * 0x10]; - if (APU.DSP [APU_NON] & (1 << channel)) - ch->type = SOUND_NOISE; - else - ch->type = SOUND_SAMPLE; - - S9xSetSoundFrequency (channel, ch->hertz); - ch->loop = FALSE; - ch->needs_decode = TRUE; - ch->last_block = FALSE; - ch->previous [0] = ch->previous[1] = 0; - uint8 *dir = S9xGetSampleAddress (ch->sample_number); - ch->block_pointer = READ_WORD (dir); - ch->sample_pointer = 0; - ch->env_error = 0; - ch->next_sample = 0; - ch->interpolate = 0; - switch (ch->mode) - { - case MODE_ADSR: - if (ch->attack_rate == 0) - { - if (ch->decay_rate == 0 || ch->sustain_level == 8) - { - ch->state = SOUND_SUSTAIN; - ch->envx = (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3; - S9xSetEnvRate (ch, ch->sustain_rate, -1, 0); - } - else - { - ch->state = SOUND_DECAY; - ch->envx = MAX_ENVELOPE_HEIGHT; - S9xSetEnvRate (ch, ch->decay_rate, -1, - (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3); - } - ch-> left_vol_level = (ch->envx * ch->volume_left) / 128; - ch->right_vol_level = (ch->envx * ch->volume_right) / 128; - } - else - { - ch->state = SOUND_ATTACK; - ch->envx = 0; - ch->left_vol_level = 0; - ch->right_vol_level = 0; - S9xSetEnvRate (ch, ch->attack_rate, 1, MAX_ENVELOPE_HEIGHT); - } - ch->envxx = ch->envx << ENVX_SHIFT; - break; - - case MODE_GAIN: - ch->state = SOUND_GAIN; - break; - - case MODE_INCREASE_LINEAR: - ch->state = SOUND_INCREASE_LINEAR; - break; - - case MODE_INCREASE_BENT_LINE: - ch->state = SOUND_INCREASE_BENT_LINE; - break; - - case MODE_DECREASE_LINEAR: - ch->state = SOUND_DECREASE_LINEAR; - break; - - case MODE_DECREASE_EXPONENTIAL: - ch->state = SOUND_DECREASE_EXPONENTIAL; - break; - - default: - break; - } - - S9xFixEnvelope (channel, - APU.DSP [APU_GAIN + (channel << 4)], - APU.DSP [APU_ADSR1 + (channel << 4)], - APU.DSP [APU_ADSR2 + (channel << 4)]); + Channel* ch = &SoundData.channels[channel]; + + ch->state = SOUND_SILENT; + ch->mode = MODE_NONE; + ch->envx = 0; + ch->envxx = 0; + + S9xFixEnvelope(channel, + APU.DSP [APU_GAIN + (channel << 4)], + APU.DSP [APU_ADSR1 + (channel << 4)], + APU.DSP [APU_ADSR2 + (channel << 4)]); + + ch->sample_number = APU.DSP [APU_SRCN + channel * 0x10]; + if (APU.DSP [APU_NON] & (1 << channel)) + ch->type = SOUND_NOISE; + else + ch->type = SOUND_SAMPLE; + + S9xSetSoundFrequency(channel, ch->hertz); + ch->loop = FALSE; + ch->needs_decode = TRUE; + ch->last_block = FALSE; + ch->previous [0] = ch->previous[1] = 0; + uint8* dir = S9xGetSampleAddress(ch->sample_number); + ch->block_pointer = READ_WORD(dir); + ch->sample_pointer = 0; + ch->env_error = 0; + ch->next_sample = 0; + ch->interpolate = 0; + switch (ch->mode) + { + case MODE_ADSR: + if (ch->attack_rate == 0) + { + if (ch->decay_rate == 0 || ch->sustain_level == 8) + { + ch->state = SOUND_SUSTAIN; + ch->envx = (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3; + S9xSetEnvRate(ch, ch->sustain_rate, -1, 0); + } + else + { + ch->state = SOUND_DECAY; + ch->envx = MAX_ENVELOPE_HEIGHT; + S9xSetEnvRate(ch, ch->decay_rate, -1, + (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3); + } + ch-> left_vol_level = (ch->envx * ch->volume_left) / 128; + ch->right_vol_level = (ch->envx * ch->volume_right) / 128; + } + else + { + ch->state = SOUND_ATTACK; + ch->envx = 0; + ch->left_vol_level = 0; + ch->right_vol_level = 0; + S9xSetEnvRate(ch, ch->attack_rate, 1, MAX_ENVELOPE_HEIGHT); + } + ch->envxx = ch->envx << ENVX_SHIFT; + break; + + case MODE_GAIN: + ch->state = SOUND_GAIN; + break; + + case MODE_INCREASE_LINEAR: + ch->state = SOUND_INCREASE_LINEAR; + break; + + case MODE_INCREASE_BENT_LINE: + ch->state = SOUND_INCREASE_BENT_LINE; + break; + + case MODE_DECREASE_LINEAR: + ch->state = SOUND_DECREASE_LINEAR; + break; + + case MODE_DECREASE_EXPONENTIAL: + ch->state = SOUND_DECREASE_EXPONENTIAL; + break; + + default: + break; + } + + S9xFixEnvelope(channel, + APU.DSP [APU_GAIN + (channel << 4)], + APU.DSP [APU_ADSR1 + (channel << 4)], + APU.DSP [APU_ADSR2 + (channel << 4)]); } diff --git a/source/soundux.h b/source/soundux.h index 7e77d4f..ecccc53 100644 --- a/source/soundux.h +++ b/source/soundux.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -93,11 +93,13 @@ enum { SOUND_SAMPLE = 0, SOUND_NOISE, SOUND_EXTRA_NOISE, SOUND_MUTE }; enum { SOUND_SILENT, SOUND_ATTACK, SOUND_DECAY, SOUND_SUSTAIN, SOUND_RELEASE, SOUND_GAIN, SOUND_INCREASE_LINEAR, SOUND_INCREASE_BENT_LINE, SOUND_DECREASE_LINEAR, - SOUND_DECREASE_EXPONENTIAL}; + SOUND_DECREASE_EXPONENTIAL + }; enum { MODE_NONE = SOUND_SILENT, MODE_ADSR, MODE_RELEASE = SOUND_RELEASE, MODE_GAIN, MODE_INCREASE_LINEAR, MODE_INCREASE_BENT_LINE, - MODE_DECREASE_LINEAR, MODE_DECREASE_EXPONENTIAL}; + MODE_DECREASE_LINEAR, MODE_DECREASE_EXPONENTIAL + }; #define MAX_ENVELOPE_HEIGHT 127 #define ENVELOPE_SHIFT 7 @@ -117,129 +119,131 @@ enum { MODE_NONE = SOUND_SILENT, MODE_ADSR, MODE_RELEASE = SOUND_RELEASE, # include #endif /* __sgi */ -typedef struct { - int sound_fd; - int sound_switch; - int playback_rate; - int buffer_size; - // int noise_gen; - // Moved to soundux.cpp's noise_gen; this doesn't need volatility! [Neb] - bool8 mute_sound; - bool8 encoded; +typedef struct +{ + int sound_fd; + int sound_switch; + int playback_rate; + int buffer_size; + // int noise_gen; + // Moved to soundux.cpp's noise_gen; this doesn't need volatility! [Neb] + bool8 mute_sound; + bool8 encoded; #ifdef __sun - int last_eof; + int last_eof; #endif #ifdef __sgi - ALport al_port; + ALport al_port; #endif /* __sgi */ - int32 samples_mixed_so_far; - int32 play_position; - uint32 err_counter; - uint32 err_rate; + int32 samples_mixed_so_far; + int32 play_position; + uint32 err_counter; + uint32 err_rate; } SoundStatus; SoundStatus so; -typedef struct { - int state; - int type; - short volume_left; - short volume_right; - uint32 hertz; - uint32 frequency; - uint32 count; - bool8 loop; - int envx; - short left_vol_level; - short right_vol_level; - short envx_target; - unsigned long int env_error; - unsigned long erate; - int direction; - unsigned long attack_rate; - unsigned long decay_rate; - unsigned long sustain_rate; - unsigned long release_rate; - unsigned long sustain_level; - signed short sample; - signed short decoded [16]; - signed short previous16 [2]; - signed short *block; - uint16 sample_number; - bool8 last_block; - bool8 needs_decode; - uint32 block_pointer; - uint32 sample_pointer; - int *echo_buf_ptr; - int mode; - int32 envxx; - signed short next_sample; - int32 interpolate; - int32 previous [2]; - // Just incase they are needed in the future, for snapshot compatibility. - uint32 dummy [8]; -// unsigned short last_valid_header; +typedef struct +{ + int state; + int type; + short volume_left; + short volume_right; + uint32 hertz; + uint32 frequency; + uint32 count; + bool8 loop; + int envx; + short left_vol_level; + short right_vol_level; + short envx_target; + unsigned long int env_error; + unsigned long erate; + int direction; + unsigned long attack_rate; + unsigned long decay_rate; + unsigned long sustain_rate; + unsigned long release_rate; + unsigned long sustain_level; + signed short sample; + signed short decoded [16]; + signed short previous16 [2]; + signed short* block; + uint16 sample_number; + bool8 last_block; + bool8 needs_decode; + uint32 block_pointer; + uint32 sample_pointer; + int* echo_buf_ptr; + int mode; + int32 envxx; + signed short next_sample; + int32 interpolate; + int32 previous [2]; + // Just incase they are needed in the future, for snapshot compatibility. + uint32 dummy [8]; + // unsigned short last_valid_header; } Channel; typedef struct { - int echo_enable; - int echo_feedback; /* range is -128 .. 127 */ - int echo_ptr; - int echo_buffer_size; - int echo_write_enabled; - int echo_channel_enable; - int pitch_mod; - // Just incase they are needed in the future, for snapshot compatibility. - uint32 dummy [3]; - Channel channels [NUM_CHANNELS]; - // bool8 no_filter; - short master_volume [2]; /* range is -128 .. 127 */ - short echo_volume [2]; /* range is -128 .. 127 */ - int noise_hertz; + int echo_enable; + int echo_feedback; /* range is -128 .. 127 */ + int echo_ptr; + int echo_buffer_size; + int echo_write_enabled; + int echo_channel_enable; + int pitch_mod; + // Just incase they are needed in the future, for snapshot compatibility. + uint32 dummy [3]; + Channel channels [NUM_CHANNELS]; + // bool8 no_filter; + short master_volume [2]; /* range is -128 .. 127 */ + short echo_volume [2]; /* range is -128 .. 127 */ + int noise_hertz; } SSoundData; SSoundData SoundData; -void S9xSetEightBitConsoleSound (bool8 Enabled); - -void S9xSetSoundVolume (int channel, short volume_left, short volume_right); -void S9xSetSoundFrequency (int channel, int hertz); -void S9xSetSoundHertz (int channel, int hertz); -void S9xSetSoundType (int channel, int type_of_sound); -void S9xSetMasterVolume (short master_volume_left, short master_volume_right); -void S9xSetEchoVolume (short echo_volume_left, short echo_volume_right); -void S9xSetSoundControl (int sound_switch); -bool8 S9xSetSoundMute (bool8 mute); -void S9xSetEnvelopeHeight (int channel, int height); -void S9xSetSoundADSR (int channel, int attack, int decay, int sustain, - int sustain_level, int release); -void S9xSetSoundKeyOff (int channel); -void S9xSetSoundDecayMode (int channel); -void S9xSetSoundAttachMode (int channel); -void S9xSoundStartEnvelope (Channel *); -void S9xSetSoundSample (int channel, uint16 sample_number); -void S9xSetEchoFeedback (int echo_feedback); -void S9xSetEchoEnable (uint8 byte); -void S9xSetEchoDelay (int byte); -void S9xSetEchoWriteEnable (uint8 byte); -void S9xSetFilterCoefficient (int tap, int value); -void S9xSetFrequencyModulationEnable (uint8 byte); -void S9xSetEnvelopeRate (int channel, unsigned long rate, int direction, - int target); -bool8 S9xSetSoundMode (int channel, int mode); -int S9xGetEnvelopeHeight (int channel); -void S9xResetSound (bool8 full); -void S9xFixSoundAfterSnapshotLoad (); -void S9xPlaybackSoundSetting (int channel); -void S9xPlaySample (int channel); -void S9xFixEnvelope (int channel, uint8 gain, uint8 adsr1, uint8 adsr2); -void S9xStartSample (int channel); - -void S9xMixSamples (uint8 *buffer, int sample_count); -void S9xMixSamplesO (uint8 *buffer, int sample_count, int byte_offset); -bool8 S9xOpenSoundDevice (int, bool8, int); -void S9xSetPlaybackRate (uint32 rate); +void S9xSetEightBitConsoleSound(bool8 Enabled); + +void S9xSetSoundVolume(int channel, short volume_left, short volume_right); +void S9xSetSoundFrequency(int channel, int hertz); +void S9xSetSoundHertz(int channel, int hertz); +void S9xSetSoundType(int channel, int type_of_sound); +void S9xSetMasterVolume(short master_volume_left, short master_volume_right); +void S9xSetEchoVolume(short echo_volume_left, short echo_volume_right); +void S9xSetSoundControl(int sound_switch); +bool8 S9xSetSoundMute(bool8 mute); +void S9xSetEnvelopeHeight(int channel, int height); +void S9xSetSoundADSR(int channel, int attack, int decay, int sustain, + int sustain_level, int release); +void S9xSetSoundKeyOff(int channel); +void S9xSetSoundDecayMode(int channel); +void S9xSetSoundAttachMode(int channel); +void S9xSoundStartEnvelope(Channel*); +void S9xSetSoundSample(int channel, uint16 sample_number); +void S9xSetEchoFeedback(int echo_feedback); +void S9xSetEchoEnable(uint8 byte); +void S9xSetEchoDelay(int byte); +void S9xSetEchoWriteEnable(uint8 byte); +void S9xSetFilterCoefficient(int tap, int value); +void S9xSetFrequencyModulationEnable(uint8 byte); +void S9xSetEnvelopeRate(int channel, unsigned long rate, int direction, + int target); +bool8 S9xSetSoundMode(int channel, int mode); +int S9xGetEnvelopeHeight(int channel); +void S9xResetSound(bool8 full); +void S9xFixSoundAfterSnapshotLoad(); +void S9xPlaybackSoundSetting(int channel); +void S9xPlaySample(int channel); +void S9xFixEnvelope(int channel, uint8 gain, uint8 adsr1, uint8 adsr2); +void S9xStartSample(int channel); + +void S9xMixSamples(uint8* buffer, int sample_count); +void S9xMixSamplesO(uint8* buffer, int sample_count, int byte_offset); +bool8 S9xOpenSoundDevice(int, bool8, int); +void S9xSetPlaybackRate(uint32 rate); #endif diff --git a/source/spc700.c b/source/spc700.c index 3bfeeac..2607e1a 100644 --- a/source/spc700.c +++ b/source/spc700.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -96,10 +96,10 @@ // SPC700/Sound DSP chips have a 24.57MHz crystal on their PCB. #ifdef NO_INLINE_SET_GET -uint8 S9xAPUGetByteZ (uint8 address); -uint8 S9xAPUGetByte (uint32 address); -void S9xAPUSetByteZ (uint8, uint8 address); -void S9xAPUSetByte (uint8, uint32 address); +uint8 S9xAPUGetByteZ(uint8 address); +uint8 S9xAPUGetByte(uint32 address); +void S9xAPUSetByteZ(uint8, uint8 address); +void S9xAPUSetByte(uint8, uint32 address); #else #undef INLINE @@ -114,18 +114,18 @@ void S9xAPUSetByte (uint8, uint32 address); #define APUShutdown() \ if (Settings.Shutdown && (IAPU.PC == IAPU.WaitAddress1 || IAPU.PC == IAPU.WaitAddress2)) \ { \ - if (IAPU.WaitCounter == 0) \ - { \ - if (!ICPU.CPUExecuting) \ - APU.Cycles = CPU.Cycles = CPU.NextEvent; \ - else \ - IAPU.APUExecuting = FALSE; \ - } \ - else \ - if (IAPU.WaitCounter >= 2) \ - IAPU.WaitCounter = 1; \ - else \ - IAPU.WaitCounter--; \ + if (IAPU.WaitCounter == 0) \ + { \ + if (!ICPU.CPUExecuting) \ + APU.Cycles = CPU.Cycles = CPU.NextEvent; \ + else \ + IAPU.APUExecuting = FALSE; \ + } \ + else \ + if (IAPU.WaitCounter >= 2) \ + IAPU.WaitCounter = 1; \ + else \ + IAPU.WaitCounter--; \ } #else #define APUShutdown() @@ -137,25 +137,26 @@ void S9xAPUSetByte (uint8, uint32 address); #define APUSetZN16(w)\ IAPU._Zero = ((w) != 0) | ((w) >> 8); -void STOP (char *s) +void STOP(char* s) { - char buffer[100]; + char buffer[100]; - buffer[0] = '\0'; + buffer[0] = '\0'; - sprintf (String, "Sound CPU in unknown state executing %s at %04X\n%s\n", s, IAPU.PC - IAPU.RAM, buffer); - S9xMessage (S9X_ERROR, S9X_APU_STOPPED, String); - APU.TimerEnabled[0] = APU.TimerEnabled[1] = APU.TimerEnabled[2] = FALSE; - IAPU.APUExecuting = FALSE; + sprintf(String, "Sound CPU in unknown state executing %s at %04X\n%s\n", s, + IAPU.PC - IAPU.RAM, buffer); + S9xMessage(S9X_ERROR, S9X_APU_STOPPED, String); + APU.TimerEnabled[0] = APU.TimerEnabled[1] = APU.TimerEnabled[2] = FALSE; + IAPU.APUExecuting = FALSE; - S9xExit (); + S9xExit(); } #define TCALL(n)\ {\ PushW (IAPU.PC - IAPU.RAM + 1); \ IAPU.PC = IAPU.RAM + (APU.ExtraRAM [((15 - n) << 1)] + \ - (APU.ExtraRAM [((15 - n) << 1) + 1] << 8)); \ + (APU.ExtraRAM [((15 - n) << 1) + 1] << 8)); \ } // XXX: HalfCarry - BJ fixed? @@ -268,7 +269,7 @@ APUSetZN8 ((uint8) Int16); #else #define IndexedXIndirect()\ IAPU.Address = *(IAPU.DirectPage + ((OP1 + IAPU.Registers.X) & 0xff)) + \ - (*(IAPU.DirectPage + ((OP1 + IAPU.Registers.X + 1) & 0xff)) << 8); + (*(IAPU.DirectPage + ((OP1 + IAPU.Registers.X + 1) & 0xff)) << 8); #define Absolute()\ IAPU.Address = OP1 + (OP2 << 8); @@ -285,149 +286,197 @@ APUSetZN8 ((uint8) Int16); #define IndirectIndexedY()\ IAPU.Address = *(IAPU.DirectPage + OP1) + \ - (*(IAPU.DirectPage + OP1 + 1) << 8) + \ - IAPU.Registers.YA.B.Y; + (*(IAPU.DirectPage + OP1 + 1) << 8) + \ + IAPU.Registers.YA.B.Y; #endif -void Apu00 () +void Apu00() { -// NOP - IAPU.PC++; + // NOP + IAPU.PC++; } -void Apu01 () { TCALL (0) } +void Apu01() +{ + TCALL(0) +} -void Apu11 () { TCALL (1) } +void Apu11() +{ + TCALL(1) +} -void Apu21 () { TCALL (2) } +void Apu21() +{ + TCALL(2) +} -void Apu31 () { TCALL (3) } +void Apu31() +{ + TCALL(3) +} -void Apu41 () { TCALL (4) } +void Apu41() +{ + TCALL(4) +} -void Apu51 () { TCALL (5) } +void Apu51() +{ + TCALL(5) +} -void Apu61 () { TCALL (6) } +void Apu61() +{ + TCALL(6) +} -void Apu71 () { TCALL (7) } +void Apu71() +{ + TCALL(7) +} -void Apu81 () { TCALL (8) } +void Apu81() +{ + TCALL(8) +} -void Apu91 () { TCALL (9) } +void Apu91() +{ + TCALL(9) +} -void ApuA1 () { TCALL (10) } +void ApuA1() +{ + TCALL(10) +} -void ApuB1 () { TCALL (11) } +void ApuB1() +{ + TCALL(11) +} -void ApuC1 () { TCALL (12) } +void ApuC1() +{ + TCALL(12) +} -void ApuD1 () { TCALL (13) } +void ApuD1() +{ + TCALL(13) +} -void ApuE1 () { TCALL (14) } +void ApuE1() +{ + TCALL(14) +} -void ApuF1 () { TCALL (15) } +void ApuF1() +{ + TCALL(15) +} -void Apu3F () // CALL absolute +void Apu3F() // CALL absolute { - Absolute (); - // 0xB6f for Star Fox 2 - PushW (IAPU.PC + 3 - IAPU.RAM); - IAPU.PC = IAPU.RAM + IAPU.Address; + Absolute(); + // 0xB6f for Star Fox 2 + PushW(IAPU.PC + 3 - IAPU.RAM); + IAPU.PC = IAPU.RAM + IAPU.Address; } -void Apu4F () // PCALL $XX +void Apu4F() // PCALL $XX { - uint8 Work8 = OP1; - PushW (IAPU.PC + 2 - IAPU.RAM); - IAPU.PC = IAPU.RAM + 0xff00 + Work8; + uint8 Work8 = OP1; + PushW(IAPU.PC + 2 - IAPU.RAM); + IAPU.PC = IAPU.RAM + 0xff00 + Work8; } #define SET(b) \ S9xAPUSetByteZ ((uint8) (S9xAPUGetByteZ (OP1 ) | (1 << (b))), OP1); \ IAPU.PC += 2 -void Apu02 () +void Apu02() { - SET (0); + SET(0); } -void Apu22 () +void Apu22() { - SET (1); + SET(1); } -void Apu42 () +void Apu42() { - SET (2); + SET(2); } -void Apu62 () +void Apu62() { - SET (3); + SET(3); } -void Apu82 () +void Apu82() { - SET (4); + SET(4); } -void ApuA2 () +void ApuA2() { - SET (5); + SET(5); } -void ApuC2 () +void ApuC2() { - SET (6); + SET(6); } -void ApuE2 () +void ApuE2() { - SET (7); + SET(7); } #define CLR(b) \ S9xAPUSetByteZ ((uint8) (S9xAPUGetByteZ (OP1) & ~(1 << (b))), OP1); \ IAPU.PC += 2; -void Apu12 () +void Apu12() { - CLR (0); + CLR(0); } -void Apu32 () +void Apu32() { - CLR (1); + CLR(1); } -void Apu52 () +void Apu52() { - CLR (2); + CLR(2); } -void Apu72 () +void Apu72() { - CLR (3); + CLR(3); } -void Apu92 () +void Apu92() { - CLR (4); + CLR(4); } -void ApuB2 () +void ApuB2() { - CLR (5); + CLR(5); } -void ApuD2 () +void ApuD2() { - CLR (6); + CLR(6); } -void ApuF2 () +void ApuF2() { - CLR (7); + CLR(7); } #define BBS(b) \ @@ -441,44 +490,44 @@ if (S9xAPUGetByteZ (Work8) & (1 << (b))) \ else \ IAPU.PC += 3 -void Apu03 () +void Apu03() { - BBS (0); + BBS(0); } -void Apu23 () +void Apu23() { - BBS (1); + BBS(1); } -void Apu43 () +void Apu43() { - BBS (2); + BBS(2); } -void Apu63 () +void Apu63() { - BBS (3); + BBS(3); } -void Apu83 () +void Apu83() { - BBS (4); + BBS(4); } -void ApuA3 () +void ApuA3() { - BBS (5); + BBS(5); } -void ApuC3 () +void ApuC3() { - BBS (6); + BBS(6); } -void ApuE3 () +void ApuE3() { - BBS (7); + BBS(7); } #define BBC(b) \ @@ -492,2016 +541,2016 @@ if (!(S9xAPUGetByteZ (Work8) & (1 << (b)))) \ else \ IAPU.PC += 3 -void Apu13 () +void Apu13() { - BBC (0); + BBC(0); } -void Apu33 () +void Apu33() { - BBC (1); + BBC(1); } -void Apu53 () +void Apu53() { - BBC (2); + BBC(2); } -void Apu73 () +void Apu73() { - BBC (3); + BBC(3); } -void Apu93 () +void Apu93() { - BBC (4); + BBC(4); } -void ApuB3 () +void ApuB3() { - BBC (5); + BBC(5); } -void ApuD3 () +void ApuD3() { - BBC (6); + BBC(6); } -void ApuF3 () +void ApuF3() { - BBC (7); + BBC(7); } -void Apu04 () +void Apu04() { -// OR A,dp - IAPU.Registers.YA.B.A |= S9xAPUGetByteZ (OP1); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 2; + // OR A,dp + IAPU.Registers.YA.B.A |= S9xAPUGetByteZ(OP1); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 2; } -void Apu05 () +void Apu05() { -// OR A,abs - Absolute (); - IAPU.Registers.YA.B.A |= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 3; + // OR A,abs + Absolute(); + IAPU.Registers.YA.B.A |= S9xAPUGetByte(IAPU.Address); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 3; } -void Apu06 () +void Apu06() { -// OR A,(X) - IAPU.Registers.YA.B.A |= S9xAPUGetByteZ (IAPU.Registers.X); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC++; + // OR A,(X) + IAPU.Registers.YA.B.A |= S9xAPUGetByteZ(IAPU.Registers.X); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC++; } -void Apu07 () +void Apu07() { -// OR A,(dp+X) - IndexedXIndirect (); - IAPU.Registers.YA.B.A |= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 2; + // OR A,(dp+X) + IndexedXIndirect(); + IAPU.Registers.YA.B.A |= S9xAPUGetByte(IAPU.Address); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 2; } -void Apu08 () +void Apu08() { -// OR A,#00 - IAPU.Registers.YA.B.A |= OP1; - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 2; + // OR A,#00 + IAPU.Registers.YA.B.A |= OP1; + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 2; } -void Apu09 () +void Apu09() { -// OR dp(dest),dp(src) - uint8 Work8 = S9xAPUGetByteZ (OP1); - Work8 |= S9xAPUGetByteZ (OP2); - S9xAPUSetByteZ (Work8, OP2); - APUSetZN8 (Work8); - IAPU.PC += 3; + // OR dp(dest),dp(src) + uint8 Work8 = S9xAPUGetByteZ(OP1); + Work8 |= S9xAPUGetByteZ(OP2); + S9xAPUSetByteZ(Work8, OP2); + APUSetZN8(Work8); + IAPU.PC += 3; } -void Apu14 () +void Apu14() { -// OR A,dp+X - IAPU.Registers.YA.B.A |= S9xAPUGetByteZ (OP1 + IAPU.Registers.X); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 2; + // OR A,dp+X + IAPU.Registers.YA.B.A |= S9xAPUGetByteZ(OP1 + IAPU.Registers.X); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 2; } -void Apu15 () +void Apu15() { -// OR A,abs+X - AbsoluteX (); - IAPU.Registers.YA.B.A |= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 3; + // OR A,abs+X + AbsoluteX(); + IAPU.Registers.YA.B.A |= S9xAPUGetByte(IAPU.Address); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 3; } -void Apu16 () +void Apu16() { -// OR A,abs+Y - AbsoluteY (); - IAPU.Registers.YA.B.A |= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 3; + // OR A,abs+Y + AbsoluteY(); + IAPU.Registers.YA.B.A |= S9xAPUGetByte(IAPU.Address); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 3; } -void Apu17 () +void Apu17() { -// OR A,(dp)+Y - IndirectIndexedY (); - IAPU.Registers.YA.B.A |= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 2; + // OR A,(dp)+Y + IndirectIndexedY(); + IAPU.Registers.YA.B.A |= S9xAPUGetByte(IAPU.Address); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 2; } -void Apu18 () +void Apu18() { -// OR dp,#00 - uint8 Work8 = OP1; - Work8 |= S9xAPUGetByteZ (OP2); - S9xAPUSetByteZ (Work8, OP2); - APUSetZN8 (Work8); - IAPU.PC += 3; + // OR dp,#00 + uint8 Work8 = OP1; + Work8 |= S9xAPUGetByteZ(OP2); + S9xAPUSetByteZ(Work8, OP2); + APUSetZN8(Work8); + IAPU.PC += 3; } -void Apu19 () +void Apu19() { -// OR (X),(Y) - uint8 Work8 = S9xAPUGetByteZ (IAPU.Registers.X) | S9xAPUGetByteZ (IAPU.Registers.YA.B.Y); - APUSetZN8 (Work8); - S9xAPUSetByteZ (Work8, IAPU.Registers.X); - IAPU.PC++; + // OR (X),(Y) + uint8 Work8 = S9xAPUGetByteZ(IAPU.Registers.X) | S9xAPUGetByteZ( + IAPU.Registers.YA.B.Y); + APUSetZN8(Work8); + S9xAPUSetByteZ(Work8, IAPU.Registers.X); + IAPU.PC++; } -void Apu0A () +void Apu0A() { -// OR1 C,membit - MemBit (); - if (!APUCheckCarry ()) - { - if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit)) - APUSetCarry (); - } - IAPU.PC += 3; + // OR1 C,membit + MemBit(); + if (!APUCheckCarry()) + { + if (S9xAPUGetByte(IAPU.Address) & (1 << IAPU.Bit)) + APUSetCarry(); + } + IAPU.PC += 3; } -void Apu2A () +void Apu2A() { -// OR1 C,not membit - MemBit (); - if (!APUCheckCarry ()) - { - if (!(S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))) - APUSetCarry (); - } - IAPU.PC += 3; + // OR1 C,not membit + MemBit(); + if (!APUCheckCarry()) + { + if (!(S9xAPUGetByte(IAPU.Address) & (1 << IAPU.Bit))) + APUSetCarry(); + } + IAPU.PC += 3; } -void Apu4A () +void Apu4A() { -// AND1 C,membit - MemBit (); - if (APUCheckCarry ()) - { - if (!(S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))) - APUClearCarry (); - } - IAPU.PC += 3; + // AND1 C,membit + MemBit(); + if (APUCheckCarry()) + { + if (!(S9xAPUGetByte(IAPU.Address) & (1 << IAPU.Bit))) + APUClearCarry(); + } + IAPU.PC += 3; } -void Apu6A () +void Apu6A() { -// AND1 C, not membit - MemBit (); - if (APUCheckCarry ()) - { - if ((S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))) - APUClearCarry (); - } - IAPU.PC += 3; + // AND1 C, not membit + MemBit(); + if (APUCheckCarry()) + { + if ((S9xAPUGetByte(IAPU.Address) & (1 << IAPU.Bit))) + APUClearCarry(); + } + IAPU.PC += 3; } -void Apu8A () +void Apu8A() { -// EOR1 C, membit - MemBit (); - if (APUCheckCarry ()) - { - if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit)) - APUClearCarry (); - } - else - { - if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit)) - APUSetCarry (); - } - IAPU.PC += 3; + // EOR1 C, membit + MemBit(); + if (APUCheckCarry()) + { + if (S9xAPUGetByte(IAPU.Address) & (1 << IAPU.Bit)) + APUClearCarry(); + } + else + { + if (S9xAPUGetByte(IAPU.Address) & (1 << IAPU.Bit)) + APUSetCarry(); + } + IAPU.PC += 3; } -void ApuAA () +void ApuAA() { -// MOV1 C,membit - MemBit (); - if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit)) - APUSetCarry (); - else - APUClearCarry (); - IAPU.PC += 3; + // MOV1 C,membit + MemBit(); + if (S9xAPUGetByte(IAPU.Address) & (1 << IAPU.Bit)) + APUSetCarry(); + else + APUClearCarry(); + IAPU.PC += 3; } -void ApuCA () +void ApuCA() { -// MOV1 membit,C - MemBit (); - if (APUCheckCarry ()) - { - S9xAPUSetByte (S9xAPUGetByte (IAPU.Address) | (1 << IAPU.Bit), IAPU.Address); - } - else - { - S9xAPUSetByte (S9xAPUGetByte (IAPU.Address) & ~(1 << IAPU.Bit), IAPU.Address); - } - IAPU.PC += 3; + // MOV1 membit,C + MemBit(); + if (APUCheckCarry()) + S9xAPUSetByte(S9xAPUGetByte(IAPU.Address) | (1 << IAPU.Bit), IAPU.Address); + else + S9xAPUSetByte(S9xAPUGetByte(IAPU.Address) & ~(1 << IAPU.Bit), IAPU.Address); + IAPU.PC += 3; } -void ApuEA () +void ApuEA() { -// NOT1 membit - MemBit (); - S9xAPUSetByte (S9xAPUGetByte (IAPU.Address) ^ (1 << IAPU.Bit), IAPU.Address); - IAPU.PC += 3; + // NOT1 membit + MemBit(); + S9xAPUSetByte(S9xAPUGetByte(IAPU.Address) ^ (1 << IAPU.Bit), IAPU.Address); + IAPU.PC += 3; } -void Apu0B () +void Apu0B() { -// ASL dp - uint8 Work8 = S9xAPUGetByteZ (OP1); - ASL (Work8); - S9xAPUSetByteZ (Work8, OP1); - IAPU.PC += 2; + // ASL dp + uint8 Work8 = S9xAPUGetByteZ(OP1); + ASL(Work8); + S9xAPUSetByteZ(Work8, OP1); + IAPU.PC += 2; } -void Apu0C () +void Apu0C() { -// ASL abs - Absolute (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address); - ASL (Work8); - S9xAPUSetByte (Work8, IAPU.Address); - IAPU.PC += 3; + // ASL abs + Absolute(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address); + ASL(Work8); + S9xAPUSetByte(Work8, IAPU.Address); + IAPU.PC += 3; } -void Apu1B () +void Apu1B() { -// ASL dp+X - uint8 Work8 = S9xAPUGetByteZ (OP1 + IAPU.Registers.X); - ASL (Work8); - S9xAPUSetByteZ (Work8, OP1 + IAPU.Registers.X); - IAPU.PC += 2; + // ASL dp+X + uint8 Work8 = S9xAPUGetByteZ(OP1 + IAPU.Registers.X); + ASL(Work8); + S9xAPUSetByteZ(Work8, OP1 + IAPU.Registers.X); + IAPU.PC += 2; } -void Apu1C () +void Apu1C() { -// ASL A - ASL (IAPU.Registers.YA.B.A); - IAPU.PC++; + // ASL A + ASL(IAPU.Registers.YA.B.A); + IAPU.PC++; } -void Apu0D () +void Apu0D() { -// PUSH PSW - S9xAPUPackStatus (); - Push (IAPU.Registers.P); - IAPU.PC++; + // PUSH PSW + S9xAPUPackStatus(); + Push(IAPU.Registers.P); + IAPU.PC++; } -void Apu2D () +void Apu2D() { -// PUSH A - Push (IAPU.Registers.YA.B.A); - IAPU.PC++; + // PUSH A + Push(IAPU.Registers.YA.B.A); + IAPU.PC++; } -void Apu4D () +void Apu4D() { -// PUSH X - Push (IAPU.Registers.X); - IAPU.PC++; + // PUSH X + Push(IAPU.Registers.X); + IAPU.PC++; } -void Apu6D () +void Apu6D() { -// PUSH Y - Push (IAPU.Registers.YA.B.Y); - IAPU.PC++; + // PUSH Y + Push(IAPU.Registers.YA.B.Y); + IAPU.PC++; } -void Apu8E () +void Apu8E() { -// POP PSW - Pop (IAPU.Registers.P); - S9xAPUUnpackStatus (); - if (APUCheckDirectPage ()) - IAPU.DirectPage = IAPU.RAM + 0x100; - else - IAPU.DirectPage = IAPU.RAM; - IAPU.PC++; + // POP PSW + Pop(IAPU.Registers.P); + S9xAPUUnpackStatus(); + if (APUCheckDirectPage()) + IAPU.DirectPage = IAPU.RAM + 0x100; + else + IAPU.DirectPage = IAPU.RAM; + IAPU.PC++; } -void ApuAE () +void ApuAE() { -// POP A - Pop (IAPU.Registers.YA.B.A); - IAPU.PC++; + // POP A + Pop(IAPU.Registers.YA.B.A); + IAPU.PC++; } -void ApuCE () +void ApuCE() { -// POP X - Pop (IAPU.Registers.X); - IAPU.PC++; + // POP X + Pop(IAPU.Registers.X); + IAPU.PC++; } -void ApuEE () +void ApuEE() { -// POP Y - Pop (IAPU.Registers.YA.B.Y); - IAPU.PC++; + // POP Y + Pop(IAPU.Registers.YA.B.Y); + IAPU.PC++; } -void Apu0E () +void Apu0E() { -// TSET1 abs - Absolute (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address); - S9xAPUSetByte (Work8 | IAPU.Registers.YA.B.A, IAPU.Address); - Work8 &= IAPU.Registers.YA.B.A; - APUSetZN8 (Work8); - IAPU.PC += 3; + // TSET1 abs + Absolute(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address); + S9xAPUSetByte(Work8 | IAPU.Registers.YA.B.A, IAPU.Address); + Work8 &= IAPU.Registers.YA.B.A; + APUSetZN8(Work8); + IAPU.PC += 3; } -void Apu4E () +void Apu4E() { -// TCLR1 abs - Absolute (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address); - S9xAPUSetByte (Work8 & ~IAPU.Registers.YA.B.A, IAPU.Address); - Work8 &= IAPU.Registers.YA.B.A; - APUSetZN8 (Work8); - IAPU.PC += 3; + // TCLR1 abs + Absolute(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address); + S9xAPUSetByte(Work8 & ~IAPU.Registers.YA.B.A, IAPU.Address); + Work8 &= IAPU.Registers.YA.B.A; + APUSetZN8(Work8); + IAPU.PC += 3; } -void Apu0F () +void Apu0F() { -// BRK + // BRK #if 0 - STOP ("BRK"); + STOP("BRK"); #else - PushW (IAPU.PC + 1 - IAPU.RAM); - S9xAPUPackStatus (); - Push (IAPU.Registers.P); - APUSetBreak (); - APUClearInterrupt (); -// XXX:Where is the BRK vector ??? - IAPU.PC = IAPU.RAM + APU.ExtraRAM[0x20] + (APU.ExtraRAM[0x21] << 8); + PushW(IAPU.PC + 1 - IAPU.RAM); + S9xAPUPackStatus(); + Push(IAPU.Registers.P); + APUSetBreak(); + APUClearInterrupt(); + // XXX:Where is the BRK vector ??? + IAPU.PC = IAPU.RAM + APU.ExtraRAM[0x20] + (APU.ExtraRAM[0x21] << 8); #endif } -void ApuEF () +void ApuEF() { -// SLEEP - // XXX: sleep - // STOP ("SLEEP"); - IAPU.APUExecuting = FALSE; - IAPU.PC++; + // SLEEP + // XXX: sleep + // STOP ("SLEEP"); + IAPU.APUExecuting = FALSE; + IAPU.PC++; } -void ApuFF () -{ -// STOP - // STOP ("STOP"); - IAPU.APUExecuting = FALSE; - IAPU.PC++; +void ApuFF() +{ + // STOP + // STOP ("STOP"); + IAPU.APUExecuting = FALSE; + IAPU.PC++; } -void Apu10 () +void Apu10() { -// BPL - Relative (); - if (!APUCheckNegative ()) - { - IAPU.PC = IAPU.RAM + (uint16) Int16; - APU.Cycles += IAPU.TwoCycles; - APUShutdown (); - } - else - IAPU.PC += 2; + // BPL + Relative(); + if (!APUCheckNegative()) + { + IAPU.PC = IAPU.RAM + (uint16) Int16; + APU.Cycles += IAPU.TwoCycles; + APUShutdown(); + } + else + IAPU.PC += 2; } -void Apu30 () +void Apu30() { -// BMI - Relative (); - if (APUCheckNegative ()) - { - IAPU.PC = IAPU.RAM + (uint16) Int16; - APU.Cycles += IAPU.TwoCycles; - APUShutdown (); - } - else - IAPU.PC += 2; + // BMI + Relative(); + if (APUCheckNegative()) + { + IAPU.PC = IAPU.RAM + (uint16) Int16; + APU.Cycles += IAPU.TwoCycles; + APUShutdown(); + } + else + IAPU.PC += 2; } -void Apu90 () +void Apu90() { -// BCC - Relative (); - if (!APUCheckCarry ()) - { - IAPU.PC = IAPU.RAM + (uint16) Int16; - APU.Cycles += IAPU.TwoCycles; - APUShutdown (); - } - else - IAPU.PC += 2; + // BCC + Relative(); + if (!APUCheckCarry()) + { + IAPU.PC = IAPU.RAM + (uint16) Int16; + APU.Cycles += IAPU.TwoCycles; + APUShutdown(); + } + else + IAPU.PC += 2; } -void ApuB0 () +void ApuB0() { -// BCS - Relative (); - if (APUCheckCarry ()) - { - IAPU.PC = IAPU.RAM + (uint16) Int16; - APU.Cycles += IAPU.TwoCycles; - APUShutdown (); - } - else - IAPU.PC += 2; + // BCS + Relative(); + if (APUCheckCarry()) + { + IAPU.PC = IAPU.RAM + (uint16) Int16; + APU.Cycles += IAPU.TwoCycles; + APUShutdown(); + } + else + IAPU.PC += 2; } -void ApuD0 () +void ApuD0() { -// BNE - Relative (); - if (!APUCheckZero ()) - { - IAPU.PC = IAPU.RAM + (uint16) Int16; - APU.Cycles += IAPU.TwoCycles; - APUShutdown (); - } - else - IAPU.PC += 2; + // BNE + Relative(); + if (!APUCheckZero()) + { + IAPU.PC = IAPU.RAM + (uint16) Int16; + APU.Cycles += IAPU.TwoCycles; + APUShutdown(); + } + else + IAPU.PC += 2; } -void ApuF0 () +void ApuF0() { -// BEQ - Relative (); - if (APUCheckZero ()) - { - IAPU.PC = IAPU.RAM + (uint16) Int16; - APU.Cycles += IAPU.TwoCycles; - APUShutdown (); - } - else - IAPU.PC += 2; + // BEQ + Relative(); + if (APUCheckZero()) + { + IAPU.PC = IAPU.RAM + (uint16) Int16; + APU.Cycles += IAPU.TwoCycles; + APUShutdown(); + } + else + IAPU.PC += 2; } -void Apu50 () +void Apu50() { -// BVC - Relative (); - if (!APUCheckOverflow ()) - { - IAPU.PC = IAPU.RAM + (uint16) Int16; - APU.Cycles += IAPU.TwoCycles; - } - else - IAPU.PC += 2; + // BVC + Relative(); + if (!APUCheckOverflow()) + { + IAPU.PC = IAPU.RAM + (uint16) Int16; + APU.Cycles += IAPU.TwoCycles; + } + else + IAPU.PC += 2; } -void Apu70 () +void Apu70() { -// BVS - Relative (); - if (APUCheckOverflow ()) - { - IAPU.PC = IAPU.RAM + (uint16) Int16; - APU.Cycles += IAPU.TwoCycles; - } - else - IAPU.PC += 2; + // BVS + Relative(); + if (APUCheckOverflow()) + { + IAPU.PC = IAPU.RAM + (uint16) Int16; + APU.Cycles += IAPU.TwoCycles; + } + else + IAPU.PC += 2; } -void Apu2F () +void Apu2F() { -// BRA - Relative (); - IAPU.PC = IAPU.RAM + (uint16) Int16; + // BRA + Relative(); + IAPU.PC = IAPU.RAM + (uint16) Int16; } -void Apu80 () +void Apu80() { -// SETC - APUSetCarry (); - IAPU.PC++; + // SETC + APUSetCarry(); + IAPU.PC++; } -void ApuED () +void ApuED() { -// NOTC - IAPU._Carry ^= 1; - IAPU.PC++; + // NOTC + IAPU._Carry ^= 1; + IAPU.PC++; } -void Apu40 () +void Apu40() { -// SETP - APUSetDirectPage (); - IAPU.DirectPage = IAPU.RAM + 0x100; - IAPU.PC++; + // SETP + APUSetDirectPage(); + IAPU.DirectPage = IAPU.RAM + 0x100; + IAPU.PC++; } -void Apu1A () +void Apu1A() { -// DECW dp - uint16 Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); - Work16--; - S9xAPUSetByteZ ((uint8) Work16, OP1); - S9xAPUSetByteZ (Work16 >> 8, OP1 + 1); - APUSetZN16 (Work16); - IAPU.PC += 2; + // DECW dp + uint16 Work16 = S9xAPUGetByteZ(OP1) + (S9xAPUGetByteZ(OP1 + 1) << 8); + Work16--; + S9xAPUSetByteZ((uint8) Work16, OP1); + S9xAPUSetByteZ(Work16 >> 8, OP1 + 1); + APUSetZN16(Work16); + IAPU.PC += 2; } -void Apu5A () +void Apu5A() { -// CMPW YA,dp - uint16 Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); - int32 Int32 = (long) IAPU.Registers.YA.W - (long) Work16; - IAPU._Carry = Int32 >= 0; - APUSetZN16 ((uint16) Int32); - IAPU.PC += 2; + // CMPW YA,dp + uint16 Work16 = S9xAPUGetByteZ(OP1) + (S9xAPUGetByteZ(OP1 + 1) << 8); + int32 Int32 = (long) IAPU.Registers.YA.W - (long) Work16; + IAPU._Carry = Int32 >= 0; + APUSetZN16((uint16) Int32); + IAPU.PC += 2; } -void Apu3A () +void Apu3A() { -// INCW dp - uint16 Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); - Work16++; - S9xAPUSetByteZ ((uint8) Work16, OP1); - S9xAPUSetByteZ (Work16 >> 8, OP1 + 1); - APUSetZN16 (Work16); - IAPU.PC += 2; + // INCW dp + uint16 Work16 = S9xAPUGetByteZ(OP1) + (S9xAPUGetByteZ(OP1 + 1) << 8); + Work16++; + S9xAPUSetByteZ((uint8) Work16, OP1); + S9xAPUSetByteZ(Work16 >> 8, OP1 + 1); + APUSetZN16(Work16); + IAPU.PC += 2; } // XXX: HalfCarry - BJ Fixed? Or is it between bits 7 and 8 for ADDW/SUBW? -void Apu7A () -{ -// ADDW YA,dp - uint16 Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); - uint32 Work32 = (uint32) IAPU.Registers.YA.W + Work16; - IAPU._Carry = Work32 >= 0x10000; - if (~(IAPU.Registers.YA.W ^ Work16) & (Work16 ^ (uint16) Work32) & 0x8000) - APUSetOverflow (); - else - APUClearOverflow (); - APUClearHalfCarry (); - if((IAPU.Registers.YA.W ^ Work16 ^ (uint16) Work32) & 0x10) - APUSetHalfCarry (); - IAPU.Registers.YA.W = (uint16) Work32; - APUSetZN16 (IAPU.Registers.YA.W); - IAPU.PC += 2; +void Apu7A() +{ + // ADDW YA,dp + uint16 Work16 = S9xAPUGetByteZ(OP1) + (S9xAPUGetByteZ(OP1 + 1) << 8); + uint32 Work32 = (uint32) IAPU.Registers.YA.W + Work16; + IAPU._Carry = Work32 >= 0x10000; + if (~(IAPU.Registers.YA.W ^ Work16) & (Work16 ^ (uint16) Work32) & 0x8000) + APUSetOverflow(); + else + APUClearOverflow(); + APUClearHalfCarry(); + if ((IAPU.Registers.YA.W ^ Work16 ^ (uint16) Work32) & 0x10) + APUSetHalfCarry(); + IAPU.Registers.YA.W = (uint16) Work32; + APUSetZN16(IAPU.Registers.YA.W); + IAPU.PC += 2; } // XXX: BJ: i think the old HalfCarry behavior was wrong... // XXX: Or is it between bits 7 and 8 for ADDW/SUBW? // XXX: Used Work32 instead of Int32 before. Fixed? [Neb] -void Apu9A () +void Apu9A() { -// SUBW YA,dp - uint16 Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); - int32 Int32 = (long) IAPU.Registers.YA.W - (long) Work16; - APUClearHalfCarry (); - IAPU._Carry = Int32 >= 0; - if (((IAPU.Registers.YA.W ^ Work16) & 0x8000) && - ((IAPU.Registers.YA.W ^ (uint16) Int32) & 0x8000)) - APUSetOverflow (); - else - APUClearOverflow (); - if (((IAPU.Registers.YA.W ^ Work16) & 0x0080) && - ((IAPU.Registers.YA.W ^ (uint16) Int32) & 0x0080)) - APUSetHalfCarry (); - APUSetHalfCarry (); - if((IAPU.Registers.YA.W ^ Work16 ^ (uint16) Int32) & 0x10) - APUClearHalfCarry (); - IAPU.Registers.YA.W = (uint16) Int32; - APUSetZN16 (IAPU.Registers.YA.W); - IAPU.PC += 2; + // SUBW YA,dp + uint16 Work16 = S9xAPUGetByteZ(OP1) + (S9xAPUGetByteZ(OP1 + 1) << 8); + int32 Int32 = (long) IAPU.Registers.YA.W - (long) Work16; + APUClearHalfCarry(); + IAPU._Carry = Int32 >= 0; + if (((IAPU.Registers.YA.W ^ Work16) & 0x8000) && + ((IAPU.Registers.YA.W ^ (uint16) Int32) & 0x8000)) + APUSetOverflow(); + else + APUClearOverflow(); + if (((IAPU.Registers.YA.W ^ Work16) & 0x0080) && + ((IAPU.Registers.YA.W ^ (uint16) Int32) & 0x0080)) + APUSetHalfCarry(); + APUSetHalfCarry(); + if ((IAPU.Registers.YA.W ^ Work16 ^ (uint16) Int32) & 0x10) + APUClearHalfCarry(); + IAPU.Registers.YA.W = (uint16) Int32; + APUSetZN16(IAPU.Registers.YA.W); + IAPU.PC += 2; } -void ApuBA () +void ApuBA() { -// MOVW YA,dp - IAPU.Registers.YA.B.A = S9xAPUGetByteZ (OP1); - IAPU.Registers.YA.B.Y = S9xAPUGetByteZ (OP1 + 1); - APUSetZN16 (IAPU.Registers.YA.W); - IAPU.PC += 2; + // MOVW YA,dp + IAPU.Registers.YA.B.A = S9xAPUGetByteZ(OP1); + IAPU.Registers.YA.B.Y = S9xAPUGetByteZ(OP1 + 1); + APUSetZN16(IAPU.Registers.YA.W); + IAPU.PC += 2; } -void ApuDA () +void ApuDA() { -// MOVW dp,YA - S9xAPUSetByteZ (IAPU.Registers.YA.B.A, OP1); - S9xAPUSetByteZ (IAPU.Registers.YA.B.Y, OP1 + 1); - IAPU.PC += 2; + // MOVW dp,YA + S9xAPUSetByteZ(IAPU.Registers.YA.B.A, OP1); + S9xAPUSetByteZ(IAPU.Registers.YA.B.Y, OP1 + 1); + IAPU.PC += 2; } -void Apu64 () +void Apu64() { -// CMP A,dp - uint8 Work8 = S9xAPUGetByteZ (OP1); - CMP (IAPU.Registers.YA.B.A, Work8); - IAPU.PC += 2; + // CMP A,dp + uint8 Work8 = S9xAPUGetByteZ(OP1); + CMP(IAPU.Registers.YA.B.A, Work8); + IAPU.PC += 2; } -void Apu65 () +void Apu65() { -// CMP A,abs - Absolute (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address); - CMP (IAPU.Registers.YA.B.A, Work8); - IAPU.PC += 3; + // CMP A,abs + Absolute(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address); + CMP(IAPU.Registers.YA.B.A, Work8); + IAPU.PC += 3; } -void Apu66 () +void Apu66() { -// CMP A,(X) - uint8 Work8 = S9xAPUGetByteZ (IAPU.Registers.X); - CMP (IAPU.Registers.YA.B.A, Work8); - IAPU.PC++; + // CMP A,(X) + uint8 Work8 = S9xAPUGetByteZ(IAPU.Registers.X); + CMP(IAPU.Registers.YA.B.A, Work8); + IAPU.PC++; } -void Apu67 () +void Apu67() { -// CMP A,(dp+X) - IndexedXIndirect (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address); - CMP (IAPU.Registers.YA.B.A, Work8); - IAPU.PC += 2; + // CMP A,(dp+X) + IndexedXIndirect(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address); + CMP(IAPU.Registers.YA.B.A, Work8); + IAPU.PC += 2; } -void Apu68 () +void Apu68() { -// CMP A,#00 - uint8 Work8 = OP1; - CMP (IAPU.Registers.YA.B.A, Work8); - IAPU.PC += 2; + // CMP A,#00 + uint8 Work8 = OP1; + CMP(IAPU.Registers.YA.B.A, Work8); + IAPU.PC += 2; } -void Apu69 () +void Apu69() { -// CMP dp(dest), dp(src) - uint8 W1 = S9xAPUGetByteZ (OP1); - uint8 Work8 = S9xAPUGetByteZ (OP2); - CMP (Work8, W1); - IAPU.PC += 3; + // CMP dp(dest), dp(src) + uint8 W1 = S9xAPUGetByteZ(OP1); + uint8 Work8 = S9xAPUGetByteZ(OP2); + CMP(Work8, W1); + IAPU.PC += 3; } -void Apu74 () +void Apu74() { -// CMP A, dp+X - uint8 Work8 = S9xAPUGetByteZ (OP1 + IAPU.Registers.X); - CMP (IAPU.Registers.YA.B.A, Work8); - IAPU.PC += 2; + // CMP A, dp+X + uint8 Work8 = S9xAPUGetByteZ(OP1 + IAPU.Registers.X); + CMP(IAPU.Registers.YA.B.A, Work8); + IAPU.PC += 2; } -void Apu75 () +void Apu75() { -// CMP A,abs+X - AbsoluteX (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address); - CMP (IAPU.Registers.YA.B.A, Work8); - IAPU.PC += 3; + // CMP A,abs+X + AbsoluteX(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address); + CMP(IAPU.Registers.YA.B.A, Work8); + IAPU.PC += 3; } -void Apu76 () +void Apu76() { -// CMP A, abs+Y - AbsoluteY (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address); - CMP (IAPU.Registers.YA.B.A, Work8); - IAPU.PC += 3; + // CMP A, abs+Y + AbsoluteY(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address); + CMP(IAPU.Registers.YA.B.A, Work8); + IAPU.PC += 3; } -void Apu77 () +void Apu77() { -// CMP A,(dp)+Y - IndirectIndexedY (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address); - CMP (IAPU.Registers.YA.B.A, Work8); - IAPU.PC += 2; + // CMP A,(dp)+Y + IndirectIndexedY(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address); + CMP(IAPU.Registers.YA.B.A, Work8); + IAPU.PC += 2; } -void Apu78 () +void Apu78() { -// CMP dp,#00 - uint8 Work8 = OP1; - uint8 W1 = S9xAPUGetByteZ (OP2); - CMP (W1, Work8); - IAPU.PC += 3; + // CMP dp,#00 + uint8 Work8 = OP1; + uint8 W1 = S9xAPUGetByteZ(OP2); + CMP(W1, Work8); + IAPU.PC += 3; } -void Apu79 () +void Apu79() { -// CMP (X),(Y) - uint8 W1 = S9xAPUGetByteZ (IAPU.Registers.X); - uint8 Work8 = S9xAPUGetByteZ (IAPU.Registers.YA.B.Y); - CMP (W1, Work8); - IAPU.PC++; + // CMP (X),(Y) + uint8 W1 = S9xAPUGetByteZ(IAPU.Registers.X); + uint8 Work8 = S9xAPUGetByteZ(IAPU.Registers.YA.B.Y); + CMP(W1, Work8); + IAPU.PC++; } -void Apu1E () +void Apu1E() { -// CMP X,abs - Absolute (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address); - CMP (IAPU.Registers.X, Work8); - IAPU.PC += 3; + // CMP X,abs + Absolute(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address); + CMP(IAPU.Registers.X, Work8); + IAPU.PC += 3; } -void Apu3E () +void Apu3E() { -// CMP X,dp - uint8 Work8 = S9xAPUGetByteZ (OP1); - CMP (IAPU.Registers.X, Work8); - IAPU.PC += 2; + // CMP X,dp + uint8 Work8 = S9xAPUGetByteZ(OP1); + CMP(IAPU.Registers.X, Work8); + IAPU.PC += 2; } -void ApuC8 () +void ApuC8() { -// CMP X,#00 - CMP (IAPU.Registers.X, OP1); - IAPU.PC += 2; + // CMP X,#00 + CMP(IAPU.Registers.X, OP1); + IAPU.PC += 2; } -void Apu5E () +void Apu5E() { -// CMP Y,abs - Absolute (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address); - CMP (IAPU.Registers.YA.B.Y, Work8); - IAPU.PC += 3; + // CMP Y,abs + Absolute(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address); + CMP(IAPU.Registers.YA.B.Y, Work8); + IAPU.PC += 3; } -void Apu7E () +void Apu7E() { -// CMP Y,dp - uint8 Work8 = S9xAPUGetByteZ (OP1); - CMP (IAPU.Registers.YA.B.Y, Work8); - IAPU.PC += 2; + // CMP Y,dp + uint8 Work8 = S9xAPUGetByteZ(OP1); + CMP(IAPU.Registers.YA.B.Y, Work8); + IAPU.PC += 2; } -void ApuAD () +void ApuAD() { -// CMP Y,#00 - uint8 Work8 = OP1; - CMP (IAPU.Registers.YA.B.Y, Work8); - IAPU.PC += 2; + // CMP Y,#00 + uint8 Work8 = OP1; + CMP(IAPU.Registers.YA.B.Y, Work8); + IAPU.PC += 2; } -void Apu1F () +void Apu1F() { -// JMP (abs+X) - Absolute (); - IAPU.PC = IAPU.RAM + S9xAPUGetByte (IAPU.Address + IAPU.Registers.X) + - (S9xAPUGetByte (IAPU.Address + IAPU.Registers.X + 1) << 8); -// XXX: HERE: - // APU.Flags |= TRACE_FLAG; + // JMP (abs+X) + Absolute(); + IAPU.PC = IAPU.RAM + S9xAPUGetByte(IAPU.Address + IAPU.Registers.X) + + (S9xAPUGetByte(IAPU.Address + IAPU.Registers.X + 1) << 8); + // XXX: HERE: + // APU.Flags |= TRACE_FLAG; } -void Apu5F () +void Apu5F() { -// JMP abs - Absolute (); - IAPU.PC = IAPU.RAM + IAPU.Address; + // JMP abs + Absolute(); + IAPU.PC = IAPU.RAM + IAPU.Address; } -void Apu20 () +void Apu20() { -// CLRP - APUClearDirectPage (); - IAPU.DirectPage = IAPU.RAM; - IAPU.PC++; + // CLRP + APUClearDirectPage(); + IAPU.DirectPage = IAPU.RAM; + IAPU.PC++; } -void Apu60 () +void Apu60() { -// CLRC - APUClearCarry (); - IAPU.PC++; + // CLRC + APUClearCarry(); + IAPU.PC++; } -void ApuE0 () +void ApuE0() { -// CLRV - APUClearHalfCarry (); - APUClearOverflow (); - IAPU.PC++; + // CLRV + APUClearHalfCarry(); + APUClearOverflow(); + IAPU.PC++; } -void Apu24 () +void Apu24() { -// AND A,dp - IAPU.Registers.YA.B.A &= S9xAPUGetByteZ (OP1); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 2; + // AND A,dp + IAPU.Registers.YA.B.A &= S9xAPUGetByteZ(OP1); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 2; } -void Apu25 () +void Apu25() { -// AND A,abs - Absolute (); - IAPU.Registers.YA.B.A &= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 3; + // AND A,abs + Absolute(); + IAPU.Registers.YA.B.A &= S9xAPUGetByte(IAPU.Address); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 3; } -void Apu26 () +void Apu26() { -// AND A,(X) - IAPU.Registers.YA.B.A &= S9xAPUGetByteZ (IAPU.Registers.X); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC++; + // AND A,(X) + IAPU.Registers.YA.B.A &= S9xAPUGetByteZ(IAPU.Registers.X); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC++; } -void Apu27 () +void Apu27() { -// AND A,(dp+X) - IndexedXIndirect (); - IAPU.Registers.YA.B.A &= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 2; + // AND A,(dp+X) + IndexedXIndirect(); + IAPU.Registers.YA.B.A &= S9xAPUGetByte(IAPU.Address); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 2; } -void Apu28 () +void Apu28() { -// AND A,#00 - IAPU.Registers.YA.B.A &= OP1; - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 2; + // AND A,#00 + IAPU.Registers.YA.B.A &= OP1; + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 2; } -void Apu29 () +void Apu29() { -// AND dp(dest),dp(src) - uint8 Work8 = S9xAPUGetByteZ (OP1); - Work8 &= S9xAPUGetByteZ (OP2); - S9xAPUSetByteZ (Work8, OP2); - APUSetZN8 (Work8); - IAPU.PC += 3; + // AND dp(dest),dp(src) + uint8 Work8 = S9xAPUGetByteZ(OP1); + Work8 &= S9xAPUGetByteZ(OP2); + S9xAPUSetByteZ(Work8, OP2); + APUSetZN8(Work8); + IAPU.PC += 3; } -void Apu34 () +void Apu34() { -// AND A,dp+X - IAPU.Registers.YA.B.A &= S9xAPUGetByteZ (OP1 + IAPU.Registers.X); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 2; + // AND A,dp+X + IAPU.Registers.YA.B.A &= S9xAPUGetByteZ(OP1 + IAPU.Registers.X); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 2; } -void Apu35 () +void Apu35() { -// AND A,abs+X - AbsoluteX (); - IAPU.Registers.YA.B.A &= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 3; + // AND A,abs+X + AbsoluteX(); + IAPU.Registers.YA.B.A &= S9xAPUGetByte(IAPU.Address); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 3; } -void Apu36 () +void Apu36() { -// AND A,abs+Y - AbsoluteY (); - IAPU.Registers.YA.B.A &= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 3; + // AND A,abs+Y + AbsoluteY(); + IAPU.Registers.YA.B.A &= S9xAPUGetByte(IAPU.Address); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 3; } -void Apu37 () +void Apu37() { -// AND A,(dp)+Y - IndirectIndexedY (); - IAPU.Registers.YA.B.A &= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 2; + // AND A,(dp)+Y + IndirectIndexedY(); + IAPU.Registers.YA.B.A &= S9xAPUGetByte(IAPU.Address); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 2; } -void Apu38 () +void Apu38() { -// AND dp,#00 - uint8 Work8 = OP1; - Work8 &= S9xAPUGetByteZ (OP2); - S9xAPUSetByteZ (Work8, OP2); - APUSetZN8 (Work8); - IAPU.PC += 3; + // AND dp,#00 + uint8 Work8 = OP1; + Work8 &= S9xAPUGetByteZ(OP2); + S9xAPUSetByteZ(Work8, OP2); + APUSetZN8(Work8); + IAPU.PC += 3; } -void Apu39 () +void Apu39() { -// AND (X),(Y) - uint8 Work8 = S9xAPUGetByteZ (IAPU.Registers.X) & S9xAPUGetByteZ (IAPU.Registers.YA.B.Y); - APUSetZN8 (Work8); - S9xAPUSetByteZ (Work8, IAPU.Registers.X); - IAPU.PC++; + // AND (X),(Y) + uint8 Work8 = S9xAPUGetByteZ(IAPU.Registers.X) & S9xAPUGetByteZ( + IAPU.Registers.YA.B.Y); + APUSetZN8(Work8); + S9xAPUSetByteZ(Work8, IAPU.Registers.X); + IAPU.PC++; } -void Apu2B () +void Apu2B() { -// ROL dp - uint8 Work8 = S9xAPUGetByteZ (OP1); - ROL (Work8); - S9xAPUSetByteZ (Work8, OP1); - IAPU.PC += 2; + // ROL dp + uint8 Work8 = S9xAPUGetByteZ(OP1); + ROL(Work8); + S9xAPUSetByteZ(Work8, OP1); + IAPU.PC += 2; } -void Apu2C () +void Apu2C() { -// ROL abs - Absolute (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address); - ROL (Work8); - S9xAPUSetByte (Work8, IAPU.Address); - IAPU.PC += 3; + // ROL abs + Absolute(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address); + ROL(Work8); + S9xAPUSetByte(Work8, IAPU.Address); + IAPU.PC += 3; } -void Apu3B () +void Apu3B() { -// ROL dp+X - uint8 Work8 = S9xAPUGetByteZ (OP1 + IAPU.Registers.X); - ROL (Work8); - S9xAPUSetByteZ (Work8, OP1 + IAPU.Registers.X); - IAPU.PC += 2; + // ROL dp+X + uint8 Work8 = S9xAPUGetByteZ(OP1 + IAPU.Registers.X); + ROL(Work8); + S9xAPUSetByteZ(Work8, OP1 + IAPU.Registers.X); + IAPU.PC += 2; } -void Apu3C () +void Apu3C() { -// ROL A - ROL (IAPU.Registers.YA.B.A); - IAPU.PC++; + // ROL A + ROL(IAPU.Registers.YA.B.A); + IAPU.PC++; } -void Apu2E () +void Apu2E() { -// CBNE dp,rel - uint8 Work8 = OP1; - Relative2 (); - - if (S9xAPUGetByteZ (Work8) != IAPU.Registers.YA.B.A) - { - IAPU.PC = IAPU.RAM + (uint16) Int16; - APU.Cycles += IAPU.TwoCycles; - APUShutdown (); - } - else - IAPU.PC += 3; + // CBNE dp,rel + uint8 Work8 = OP1; + Relative2(); + + if (S9xAPUGetByteZ(Work8) != IAPU.Registers.YA.B.A) + { + IAPU.PC = IAPU.RAM + (uint16) Int16; + APU.Cycles += IAPU.TwoCycles; + APUShutdown(); + } + else + IAPU.PC += 3; } -void ApuDE () +void ApuDE() { -// CBNE dp+X,rel - uint8 Work8 = OP1 + IAPU.Registers.X; - Relative2 (); + // CBNE dp+X,rel + uint8 Work8 = OP1 + IAPU.Registers.X; + Relative2(); - if (S9xAPUGetByteZ (Work8) != IAPU.Registers.YA.B.A) - { - IAPU.PC = IAPU.RAM + (uint16) Int16; - APU.Cycles += IAPU.TwoCycles; - APUShutdown (); - } - else - IAPU.PC += 3; + if (S9xAPUGetByteZ(Work8) != IAPU.Registers.YA.B.A) + { + IAPU.PC = IAPU.RAM + (uint16) Int16; + APU.Cycles += IAPU.TwoCycles; + APUShutdown(); + } + else + IAPU.PC += 3; } -void Apu3D () +void Apu3D() { -// INC X - IAPU.Registers.X++; - APUSetZN8 (IAPU.Registers.X); + // INC X + IAPU.Registers.X++; + APUSetZN8(IAPU.Registers.X); #ifdef SPC700_SHUTDOWN - IAPU.WaitCounter++; + IAPU.WaitCounter++; #endif - IAPU.PC++; + IAPU.PC++; } -void ApuFC () +void ApuFC() { -// INC Y - IAPU.Registers.YA.B.Y++; - APUSetZN8 (IAPU.Registers.YA.B.Y); + // INC Y + IAPU.Registers.YA.B.Y++; + APUSetZN8(IAPU.Registers.YA.B.Y); #ifdef SPC700_SHUTDOWN - IAPU.WaitCounter++; + IAPU.WaitCounter++; #endif - IAPU.PC++; + IAPU.PC++; } -void Apu1D () +void Apu1D() { -// DEC X - IAPU.Registers.X--; - APUSetZN8 (IAPU.Registers.X); + // DEC X + IAPU.Registers.X--; + APUSetZN8(IAPU.Registers.X); #ifdef SPC700_SHUTDOWN - IAPU.WaitCounter++; + IAPU.WaitCounter++; #endif - IAPU.PC++; + IAPU.PC++; } -void ApuDC () +void ApuDC() { -// DEC Y - IAPU.Registers.YA.B.Y--; - APUSetZN8 (IAPU.Registers.YA.B.Y); + // DEC Y + IAPU.Registers.YA.B.Y--; + APUSetZN8(IAPU.Registers.YA.B.Y); #ifdef SPC700_SHUTDOWN - IAPU.WaitCounter++; + IAPU.WaitCounter++; #endif - IAPU.PC++; + IAPU.PC++; } -void ApuAB () +void ApuAB() { -// INC dp - uint8 Work8 = S9xAPUGetByteZ (OP1) + 1; - S9xAPUSetByteZ (Work8, OP1); - APUSetZN8 (Work8); + // INC dp + uint8 Work8 = S9xAPUGetByteZ(OP1) + 1; + S9xAPUSetByteZ(Work8, OP1); + APUSetZN8(Work8); #ifdef SPC700_SHUTDOWN - IAPU.WaitCounter++; + IAPU.WaitCounter++; #endif - IAPU.PC += 2; + IAPU.PC += 2; } -void ApuAC () +void ApuAC() { -// INC abs - Absolute (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address) + 1; - S9xAPUSetByte (Work8, IAPU.Address); - APUSetZN8 (Work8); + // INC abs + Absolute(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address) + 1; + S9xAPUSetByte(Work8, IAPU.Address); + APUSetZN8(Work8); #ifdef SPC700_SHUTDOWN - IAPU.WaitCounter++; + IAPU.WaitCounter++; #endif - IAPU.PC += 3; + IAPU.PC += 3; } -void ApuBB () +void ApuBB() { -// INC dp+X - uint8 Work8 = S9xAPUGetByteZ (OP1 + IAPU.Registers.X) + 1; - S9xAPUSetByteZ (Work8, OP1 + IAPU.Registers.X); - APUSetZN8 (Work8); + // INC dp+X + uint8 Work8 = S9xAPUGetByteZ(OP1 + IAPU.Registers.X) + 1; + S9xAPUSetByteZ(Work8, OP1 + IAPU.Registers.X); + APUSetZN8(Work8); #ifdef SPC700_SHUTDOWN - IAPU.WaitCounter++; + IAPU.WaitCounter++; #endif - IAPU.PC += 2; + IAPU.PC += 2; } -void ApuBC () +void ApuBC() { -// INC A - IAPU.Registers.YA.B.A++; - APUSetZN8 (IAPU.Registers.YA.B.A); + // INC A + IAPU.Registers.YA.B.A++; + APUSetZN8(IAPU.Registers.YA.B.A); #ifdef SPC700_SHUTDOWN - IAPU.WaitCounter++; + IAPU.WaitCounter++; #endif - IAPU.PC++; + IAPU.PC++; } -void Apu8B () +void Apu8B() { -// DEC dp - uint8 Work8 = S9xAPUGetByteZ (OP1) - 1; - S9xAPUSetByteZ (Work8, OP1); - APUSetZN8 (Work8); + // DEC dp + uint8 Work8 = S9xAPUGetByteZ(OP1) - 1; + S9xAPUSetByteZ(Work8, OP1); + APUSetZN8(Work8); #ifdef SPC700_SHUTDOWN - IAPU.WaitCounter++; + IAPU.WaitCounter++; #endif - IAPU.PC += 2; + IAPU.PC += 2; } -void Apu8C () +void Apu8C() { -// DEC abs - Absolute (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address) - 1; - S9xAPUSetByte (Work8, IAPU.Address); - APUSetZN8 (Work8); + // DEC abs + Absolute(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address) - 1; + S9xAPUSetByte(Work8, IAPU.Address); + APUSetZN8(Work8); #ifdef SPC700_SHUTDOWN - IAPU.WaitCounter++; + IAPU.WaitCounter++; #endif - IAPU.PC += 3; + IAPU.PC += 3; } -void Apu9B () +void Apu9B() { -// DEC dp+X - uint8 Work8 = S9xAPUGetByteZ (OP1 + IAPU.Registers.X) - 1; - S9xAPUSetByteZ (Work8, OP1 + IAPU.Registers.X); - APUSetZN8 (Work8); + // DEC dp+X + uint8 Work8 = S9xAPUGetByteZ(OP1 + IAPU.Registers.X) - 1; + S9xAPUSetByteZ(Work8, OP1 + IAPU.Registers.X); + APUSetZN8(Work8); #ifdef SPC700_SHUTDOWN - IAPU.WaitCounter++; + IAPU.WaitCounter++; #endif - IAPU.PC += 2; + IAPU.PC += 2; } -void Apu9C () +void Apu9C() { -// DEC A - IAPU.Registers.YA.B.A--; - APUSetZN8 (IAPU.Registers.YA.B.A); + // DEC A + IAPU.Registers.YA.B.A--; + APUSetZN8(IAPU.Registers.YA.B.A); #ifdef SPC700_SHUTDOWN - IAPU.WaitCounter++; + IAPU.WaitCounter++; #endif - IAPU.PC++; + IAPU.PC++; } -void Apu44 () +void Apu44() { -// EOR A,dp - IAPU.Registers.YA.B.A ^= S9xAPUGetByteZ (OP1); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 2; + // EOR A,dp + IAPU.Registers.YA.B.A ^= S9xAPUGetByteZ(OP1); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 2; } -void Apu45 () +void Apu45() { -// EOR A,abs - Absolute (); - IAPU.Registers.YA.B.A ^= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 3; + // EOR A,abs + Absolute(); + IAPU.Registers.YA.B.A ^= S9xAPUGetByte(IAPU.Address); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 3; } -void Apu46 () +void Apu46() { -// EOR A,(X) - IAPU.Registers.YA.B.A ^= S9xAPUGetByteZ (IAPU.Registers.X); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC++; + // EOR A,(X) + IAPU.Registers.YA.B.A ^= S9xAPUGetByteZ(IAPU.Registers.X); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC++; } -void Apu47 () +void Apu47() { -// EOR A,(dp+X) - IndexedXIndirect (); - IAPU.Registers.YA.B.A ^= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 2; + // EOR A,(dp+X) + IndexedXIndirect(); + IAPU.Registers.YA.B.A ^= S9xAPUGetByte(IAPU.Address); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 2; } -void Apu48 () +void Apu48() { -// EOR A,#00 - IAPU.Registers.YA.B.A ^= OP1; - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 2; + // EOR A,#00 + IAPU.Registers.YA.B.A ^= OP1; + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 2; } -void Apu49 () +void Apu49() { -// EOR dp(dest),dp(src) - uint8 Work8 = S9xAPUGetByteZ (OP1); - Work8 ^= S9xAPUGetByteZ (OP2); - S9xAPUSetByteZ (Work8, OP2); - APUSetZN8 (Work8); - IAPU.PC += 3; + // EOR dp(dest),dp(src) + uint8 Work8 = S9xAPUGetByteZ(OP1); + Work8 ^= S9xAPUGetByteZ(OP2); + S9xAPUSetByteZ(Work8, OP2); + APUSetZN8(Work8); + IAPU.PC += 3; } -void Apu54 () +void Apu54() { -// EOR A,dp+X - IAPU.Registers.YA.B.A ^= S9xAPUGetByteZ (OP1 + IAPU.Registers.X); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 2; + // EOR A,dp+X + IAPU.Registers.YA.B.A ^= S9xAPUGetByteZ(OP1 + IAPU.Registers.X); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 2; } -void Apu55 () +void Apu55() { -// EOR A,abs+X - AbsoluteX (); - IAPU.Registers.YA.B.A ^= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 3; + // EOR A,abs+X + AbsoluteX(); + IAPU.Registers.YA.B.A ^= S9xAPUGetByte(IAPU.Address); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 3; } -void Apu56 () +void Apu56() { -// EOR A,abs+Y - AbsoluteY (); - IAPU.Registers.YA.B.A ^= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 3; + // EOR A,abs+Y + AbsoluteY(); + IAPU.Registers.YA.B.A ^= S9xAPUGetByte(IAPU.Address); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 3; } -void Apu57 () +void Apu57() { -// EOR A,(dp)+Y - IndirectIndexedY (); - IAPU.Registers.YA.B.A ^= S9xAPUGetByte (IAPU.Address); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 2; + // EOR A,(dp)+Y + IndirectIndexedY(); + IAPU.Registers.YA.B.A ^= S9xAPUGetByte(IAPU.Address); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 2; } -void Apu58 () +void Apu58() { -// EOR dp,#00 - uint8 Work8 = OP1; - Work8 ^= S9xAPUGetByteZ (OP2); - S9xAPUSetByteZ (Work8, OP2); - APUSetZN8 (Work8); - IAPU.PC += 3; + // EOR dp,#00 + uint8 Work8 = OP1; + Work8 ^= S9xAPUGetByteZ(OP2); + S9xAPUSetByteZ(Work8, OP2); + APUSetZN8(Work8); + IAPU.PC += 3; } -void Apu59 () +void Apu59() { -// EOR (X),(Y) - uint8 Work8 = S9xAPUGetByteZ (IAPU.Registers.X) ^ S9xAPUGetByteZ (IAPU.Registers.YA.B.Y); - APUSetZN8 (Work8); - S9xAPUSetByteZ (Work8, IAPU.Registers.X); - IAPU.PC++; + // EOR (X),(Y) + uint8 Work8 = S9xAPUGetByteZ(IAPU.Registers.X) ^ S9xAPUGetByteZ( + IAPU.Registers.YA.B.Y); + APUSetZN8(Work8); + S9xAPUSetByteZ(Work8, IAPU.Registers.X); + IAPU.PC++; } -void Apu4B () +void Apu4B() { -// LSR dp - uint8 Work8 = S9xAPUGetByteZ (OP1); - LSR (Work8); - S9xAPUSetByteZ (Work8, OP1); - IAPU.PC += 2; + // LSR dp + uint8 Work8 = S9xAPUGetByteZ(OP1); + LSR(Work8); + S9xAPUSetByteZ(Work8, OP1); + IAPU.PC += 2; } -void Apu4C () +void Apu4C() { -// LSR abs - Absolute (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address); - LSR (Work8); - S9xAPUSetByte (Work8, IAPU.Address); - IAPU.PC += 3; + // LSR abs + Absolute(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address); + LSR(Work8); + S9xAPUSetByte(Work8, IAPU.Address); + IAPU.PC += 3; } -void Apu5B () +void Apu5B() { -// LSR dp+X - uint8 Work8 = S9xAPUGetByteZ (OP1 + IAPU.Registers.X); - LSR (Work8); - S9xAPUSetByteZ (Work8, OP1 + IAPU.Registers.X); - IAPU.PC += 2; + // LSR dp+X + uint8 Work8 = S9xAPUGetByteZ(OP1 + IAPU.Registers.X); + LSR(Work8); + S9xAPUSetByteZ(Work8, OP1 + IAPU.Registers.X); + IAPU.PC += 2; } -void Apu5C () +void Apu5C() { -// LSR A - LSR (IAPU.Registers.YA.B.A); - IAPU.PC++; + // LSR A + LSR(IAPU.Registers.YA.B.A); + IAPU.PC++; } -void Apu7D () +void Apu7D() { -// MOV A,X - IAPU.Registers.YA.B.A = IAPU.Registers.X; - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC++; + // MOV A,X + IAPU.Registers.YA.B.A = IAPU.Registers.X; + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC++; } -void ApuDD () +void ApuDD() { -// MOV A,Y - IAPU.Registers.YA.B.A = IAPU.Registers.YA.B.Y; - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC++; + // MOV A,Y + IAPU.Registers.YA.B.A = IAPU.Registers.YA.B.Y; + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC++; } -void Apu5D () +void Apu5D() { -// MOV X,A - IAPU.Registers.X = IAPU.Registers.YA.B.A; - APUSetZN8 (IAPU.Registers.X); - IAPU.PC++; + // MOV X,A + IAPU.Registers.X = IAPU.Registers.YA.B.A; + APUSetZN8(IAPU.Registers.X); + IAPU.PC++; } -void ApuFD () +void ApuFD() { -// MOV Y,A - IAPU.Registers.YA.B.Y = IAPU.Registers.YA.B.A; - APUSetZN8 (IAPU.Registers.YA.B.Y); - IAPU.PC++; + // MOV Y,A + IAPU.Registers.YA.B.Y = IAPU.Registers.YA.B.A; + APUSetZN8(IAPU.Registers.YA.B.Y); + IAPU.PC++; } -void Apu9D () +void Apu9D() { -//MOV X,SP - IAPU.Registers.X = IAPU.Registers.S; - APUSetZN8 (IAPU.Registers.X); - IAPU.PC++; + //MOV X,SP + IAPU.Registers.X = IAPU.Registers.S; + APUSetZN8(IAPU.Registers.X); + IAPU.PC++; } -void ApuBD () +void ApuBD() { -// MOV SP,X - IAPU.Registers.S = IAPU.Registers.X; - IAPU.PC++; + // MOV SP,X + IAPU.Registers.S = IAPU.Registers.X; + IAPU.PC++; } -void Apu6B () +void Apu6B() { -// ROR dp - uint8 Work8 = S9xAPUGetByteZ (OP1); - ROR (Work8); - S9xAPUSetByteZ (Work8, OP1); - IAPU.PC += 2; + // ROR dp + uint8 Work8 = S9xAPUGetByteZ(OP1); + ROR(Work8); + S9xAPUSetByteZ(Work8, OP1); + IAPU.PC += 2; } -void Apu6C () +void Apu6C() { -// ROR abs - Absolute (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address); - ROR (Work8); - S9xAPUSetByte (Work8, IAPU.Address); - IAPU.PC += 3; + // ROR abs + Absolute(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address); + ROR(Work8); + S9xAPUSetByte(Work8, IAPU.Address); + IAPU.PC += 3; } -void Apu7B () +void Apu7B() { -// ROR dp+X - uint8 Work8 = S9xAPUGetByteZ (OP1 + IAPU.Registers.X); - ROR (Work8); - S9xAPUSetByteZ (Work8, OP1 + IAPU.Registers.X); - IAPU.PC += 2; + // ROR dp+X + uint8 Work8 = S9xAPUGetByteZ(OP1 + IAPU.Registers.X); + ROR(Work8); + S9xAPUSetByteZ(Work8, OP1 + IAPU.Registers.X); + IAPU.PC += 2; } -void Apu7C () +void Apu7C() { -// ROR A - ROR (IAPU.Registers.YA.B.A); - IAPU.PC++; + // ROR A + ROR(IAPU.Registers.YA.B.A); + IAPU.PC++; } -void Apu6E () +void Apu6E() { -// DBNZ dp,rel - uint8 Work8 = OP1; - Relative2 (); - uint8 W1 = S9xAPUGetByteZ (Work8) - 1; - S9xAPUSetByteZ (W1, Work8); - if (W1 != 0) - { - IAPU.PC = IAPU.RAM + (uint16) Int16; - APU.Cycles += IAPU.TwoCycles; - } - else - IAPU.PC += 3; + // DBNZ dp,rel + uint8 Work8 = OP1; + Relative2(); + uint8 W1 = S9xAPUGetByteZ(Work8) - 1; + S9xAPUSetByteZ(W1, Work8); + if (W1 != 0) + { + IAPU.PC = IAPU.RAM + (uint16) Int16; + APU.Cycles += IAPU.TwoCycles; + } + else + IAPU.PC += 3; } -void ApuFE () +void ApuFE() { -// DBNZ Y,rel - Relative (); - IAPU.Registers.YA.B.Y--; - if (IAPU.Registers.YA.B.Y != 0) - { - IAPU.PC = IAPU.RAM + (uint16) Int16; - APU.Cycles += IAPU.TwoCycles; - } - else - IAPU.PC += 2; + // DBNZ Y,rel + Relative(); + IAPU.Registers.YA.B.Y--; + if (IAPU.Registers.YA.B.Y != 0) + { + IAPU.PC = IAPU.RAM + (uint16) Int16; + APU.Cycles += IAPU.TwoCycles; + } + else + IAPU.PC += 2; } -void Apu6F () +void Apu6F() { -// RET - PopW (IAPU.Registers.PC); - IAPU.PC = IAPU.RAM + IAPU.Registers.PC; + // RET + PopW(IAPU.Registers.PC); + IAPU.PC = IAPU.RAM + IAPU.Registers.PC; } -void Apu7F () +void Apu7F() { -// RETI - // STOP ("RETI"); - Pop (IAPU.Registers.P); - S9xAPUUnpackStatus (); - PopW (IAPU.Registers.PC); - IAPU.PC = IAPU.RAM + IAPU.Registers.PC; + // RETI + // STOP ("RETI"); + Pop(IAPU.Registers.P); + S9xAPUUnpackStatus(); + PopW(IAPU.Registers.PC); + IAPU.PC = IAPU.RAM + IAPU.Registers.PC; } -void Apu84 () +void Apu84() { -// ADC A,dp - uint8 Work8 = S9xAPUGetByteZ (OP1); - ADC (IAPU.Registers.YA.B.A, Work8); - IAPU.PC += 2; + // ADC A,dp + uint8 Work8 = S9xAPUGetByteZ(OP1); + ADC(IAPU.Registers.YA.B.A, Work8); + IAPU.PC += 2; } -void Apu85 () +void Apu85() { -// ADC A, abs - Absolute (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address); - ADC (IAPU.Registers.YA.B.A, Work8); - IAPU.PC += 3; + // ADC A, abs + Absolute(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address); + ADC(IAPU.Registers.YA.B.A, Work8); + IAPU.PC += 3; } -void Apu86 () +void Apu86() { -// ADC A,(X) - uint8 Work8 = S9xAPUGetByteZ (IAPU.Registers.X); - ADC (IAPU.Registers.YA.B.A, Work8); - IAPU.PC++; + // ADC A,(X) + uint8 Work8 = S9xAPUGetByteZ(IAPU.Registers.X); + ADC(IAPU.Registers.YA.B.A, Work8); + IAPU.PC++; } -void Apu87 () +void Apu87() { -// ADC A,(dp+X) - IndexedXIndirect (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address); - ADC (IAPU.Registers.YA.B.A, Work8); - IAPU.PC += 2; + // ADC A,(dp+X) + IndexedXIndirect(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address); + ADC(IAPU.Registers.YA.B.A, Work8); + IAPU.PC += 2; } -void Apu88 () +void Apu88() { -// ADC A,#00 - uint8 Work8 = OP1; - ADC (IAPU.Registers.YA.B.A, Work8); - IAPU.PC += 2; + // ADC A,#00 + uint8 Work8 = OP1; + ADC(IAPU.Registers.YA.B.A, Work8); + IAPU.PC += 2; } -void Apu89 () +void Apu89() { -// ADC dp(dest),dp(src) - uint8 Work8 = S9xAPUGetByteZ (OP1); - uint8 W1 = S9xAPUGetByteZ (OP2); - ADC (W1, Work8); - S9xAPUSetByteZ (W1, OP2); - IAPU.PC += 3; + // ADC dp(dest),dp(src) + uint8 Work8 = S9xAPUGetByteZ(OP1); + uint8 W1 = S9xAPUGetByteZ(OP2); + ADC(W1, Work8); + S9xAPUSetByteZ(W1, OP2); + IAPU.PC += 3; } -void Apu94 () +void Apu94() { -// ADC A,dp+X - uint8 Work8 = S9xAPUGetByteZ (OP1 + IAPU.Registers.X); - ADC (IAPU.Registers.YA.B.A, Work8); - IAPU.PC += 2; + // ADC A,dp+X + uint8 Work8 = S9xAPUGetByteZ(OP1 + IAPU.Registers.X); + ADC(IAPU.Registers.YA.B.A, Work8); + IAPU.PC += 2; } -void Apu95 () +void Apu95() { -// ADC A, abs+X - AbsoluteX (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address); - ADC (IAPU.Registers.YA.B.A, Work8); - IAPU.PC += 3; + // ADC A, abs+X + AbsoluteX(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address); + ADC(IAPU.Registers.YA.B.A, Work8); + IAPU.PC += 3; } -void Apu96 () +void Apu96() { -// ADC A, abs+Y - AbsoluteY (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address); - ADC (IAPU.Registers.YA.B.A, Work8); - IAPU.PC += 3; + // ADC A, abs+Y + AbsoluteY(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address); + ADC(IAPU.Registers.YA.B.A, Work8); + IAPU.PC += 3; } -void Apu97 () +void Apu97() { -// ADC A, (dp)+Y - IndirectIndexedY (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address); - ADC (IAPU.Registers.YA.B.A, Work8); - IAPU.PC += 2; + // ADC A, (dp)+Y + IndirectIndexedY(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address); + ADC(IAPU.Registers.YA.B.A, Work8); + IAPU.PC += 2; } -void Apu98 () +void Apu98() { -// ADC dp,#00 - uint8 Work8 = OP1; - uint8 W1 = S9xAPUGetByteZ (OP2); - ADC (W1, Work8); - S9xAPUSetByteZ (W1, OP2); - IAPU.PC += 3; + // ADC dp,#00 + uint8 Work8 = OP1; + uint8 W1 = S9xAPUGetByteZ(OP2); + ADC(W1, Work8); + S9xAPUSetByteZ(W1, OP2); + IAPU.PC += 3; } -void Apu99 () +void Apu99() { -// ADC (X),(Y) - uint8 W1 = S9xAPUGetByteZ (IAPU.Registers.X); - uint8 Work8 = S9xAPUGetByteZ (IAPU.Registers.YA.B.Y); - ADC (W1, Work8); - S9xAPUSetByteZ (W1, IAPU.Registers.X); - IAPU.PC++; + // ADC (X),(Y) + uint8 W1 = S9xAPUGetByteZ(IAPU.Registers.X); + uint8 Work8 = S9xAPUGetByteZ(IAPU.Registers.YA.B.Y); + ADC(W1, Work8); + S9xAPUSetByteZ(W1, IAPU.Registers.X); + IAPU.PC++; } -void Apu8D () +void Apu8D() { -// MOV Y,#00 - IAPU.Registers.YA.B.Y = OP1; - APUSetZN8 (IAPU.Registers.YA.B.Y); - IAPU.PC += 2; + // MOV Y,#00 + IAPU.Registers.YA.B.Y = OP1; + APUSetZN8(IAPU.Registers.YA.B.Y); + IAPU.PC += 2; } -void Apu8F () +void Apu8F() { -// MOV dp,#00 - uint8 Work8 = OP1; - S9xAPUSetByteZ (Work8, OP2); - IAPU.PC += 3; + // MOV dp,#00 + uint8 Work8 = OP1; + S9xAPUSetByteZ(Work8, OP2); + IAPU.PC += 3; } -void Apu9E () +void Apu9E() { -// DIV YA,X - if (IAPU.Registers.X == 0) - { - APUSetOverflow (); - IAPU.Registers.YA.B.Y = 0xff; - IAPU.Registers.YA.B.A = 0xff; - } - else - { - APUClearOverflow (); - uint8 Work8 = IAPU.Registers.YA.W / IAPU.Registers.X; - IAPU.Registers.YA.B.Y = IAPU.Registers.YA.W % IAPU.Registers.X; - IAPU.Registers.YA.B.A = Work8; - } -// XXX How should Overflow, Half Carry, Zero and Negative flags be set?? - // APUSetZN16 (IAPU.Registers.YA.W); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC++; + // DIV YA,X + if (IAPU.Registers.X == 0) + { + APUSetOverflow(); + IAPU.Registers.YA.B.Y = 0xff; + IAPU.Registers.YA.B.A = 0xff; + } + else + { + APUClearOverflow(); + uint8 Work8 = IAPU.Registers.YA.W / IAPU.Registers.X; + IAPU.Registers.YA.B.Y = IAPU.Registers.YA.W % IAPU.Registers.X; + IAPU.Registers.YA.B.A = Work8; + } + // XXX How should Overflow, Half Carry, Zero and Negative flags be set?? + // APUSetZN16 (IAPU.Registers.YA.W); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC++; } -void Apu9F () +void Apu9F() { -// XCN A - IAPU.Registers.YA.B.A = (IAPU.Registers.YA.B.A >> 4) | (IAPU.Registers.YA.B.A << 4); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC++; + // XCN A + IAPU.Registers.YA.B.A = (IAPU.Registers.YA.B.A >> 4) | (IAPU.Registers.YA.B.A << + 4); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC++; } -void ApuA4 () +void ApuA4() { -// SBC A, dp - uint8 Work8 = S9xAPUGetByteZ (OP1); - SBC (IAPU.Registers.YA.B.A, Work8); - IAPU.PC += 2; + // SBC A, dp + uint8 Work8 = S9xAPUGetByteZ(OP1); + SBC(IAPU.Registers.YA.B.A, Work8); + IAPU.PC += 2; } -void ApuA5 () +void ApuA5() { -// SBC A, abs - Absolute (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address); - SBC (IAPU.Registers.YA.B.A, Work8); - IAPU.PC += 3; + // SBC A, abs + Absolute(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address); + SBC(IAPU.Registers.YA.B.A, Work8); + IAPU.PC += 3; } -void ApuA6 () +void ApuA6() { -// SBC A, (X) - uint8 Work8 = S9xAPUGetByteZ (IAPU.Registers.X); - SBC (IAPU.Registers.YA.B.A, Work8); - IAPU.PC++; + // SBC A, (X) + uint8 Work8 = S9xAPUGetByteZ(IAPU.Registers.X); + SBC(IAPU.Registers.YA.B.A, Work8); + IAPU.PC++; } -void ApuA7 () +void ApuA7() { -// SBC A,(dp+X) - IndexedXIndirect (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address); - SBC (IAPU.Registers.YA.B.A, Work8); - IAPU.PC += 2; + // SBC A,(dp+X) + IndexedXIndirect(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address); + SBC(IAPU.Registers.YA.B.A, Work8); + IAPU.PC += 2; } -void ApuA8 () +void ApuA8() { -// SBC A,#00 - uint8 Work8 = OP1; - SBC (IAPU.Registers.YA.B.A, Work8); - IAPU.PC += 2; + // SBC A,#00 + uint8 Work8 = OP1; + SBC(IAPU.Registers.YA.B.A, Work8); + IAPU.PC += 2; } -void ApuA9 () +void ApuA9() { -// SBC dp(dest), dp(src) - uint8 Work8 = S9xAPUGetByteZ (OP1); - uint8 W1 = S9xAPUGetByteZ (OP2); - SBC (W1, Work8); - S9xAPUSetByteZ (W1, OP2); - IAPU.PC += 3; + // SBC dp(dest), dp(src) + uint8 Work8 = S9xAPUGetByteZ(OP1); + uint8 W1 = S9xAPUGetByteZ(OP2); + SBC(W1, Work8); + S9xAPUSetByteZ(W1, OP2); + IAPU.PC += 3; } -void ApuB4 () +void ApuB4() { -// SBC A, dp+X - uint8 Work8 = S9xAPUGetByteZ (OP1 + IAPU.Registers.X); - SBC (IAPU.Registers.YA.B.A, Work8); - IAPU.PC += 2; + // SBC A, dp+X + uint8 Work8 = S9xAPUGetByteZ(OP1 + IAPU.Registers.X); + SBC(IAPU.Registers.YA.B.A, Work8); + IAPU.PC += 2; } -void ApuB5 () +void ApuB5() { -// SBC A,abs+X - AbsoluteX (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address); - SBC (IAPU.Registers.YA.B.A, Work8); - IAPU.PC += 3; + // SBC A,abs+X + AbsoluteX(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address); + SBC(IAPU.Registers.YA.B.A, Work8); + IAPU.PC += 3; } -void ApuB6 () +void ApuB6() { -// SBC A,abs+Y - AbsoluteY (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address); - SBC (IAPU.Registers.YA.B.A, Work8); - IAPU.PC += 3; + // SBC A,abs+Y + AbsoluteY(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address); + SBC(IAPU.Registers.YA.B.A, Work8); + IAPU.PC += 3; } -void ApuB7 () +void ApuB7() { -// SBC A,(dp)+Y - IndirectIndexedY (); - uint8 Work8 = S9xAPUGetByte (IAPU.Address); - SBC (IAPU.Registers.YA.B.A, Work8); - IAPU.PC += 2; + // SBC A,(dp)+Y + IndirectIndexedY(); + uint8 Work8 = S9xAPUGetByte(IAPU.Address); + SBC(IAPU.Registers.YA.B.A, Work8); + IAPU.PC += 2; } -void ApuB8 () +void ApuB8() { -// SBC dp,#00 - uint8 Work8 = OP1; - uint8 W1 = S9xAPUGetByteZ (OP2); - SBC (W1, Work8); - S9xAPUSetByteZ (W1, OP2); - IAPU.PC += 3; + // SBC dp,#00 + uint8 Work8 = OP1; + uint8 W1 = S9xAPUGetByteZ(OP2); + SBC(W1, Work8); + S9xAPUSetByteZ(W1, OP2); + IAPU.PC += 3; } -void ApuB9 () +void ApuB9() { -// SBC (X),(Y) - uint8 W1 = S9xAPUGetByteZ (IAPU.Registers.X); - uint8 Work8 = S9xAPUGetByteZ (IAPU.Registers.YA.B.Y); - SBC (W1, Work8); - S9xAPUSetByteZ (W1, IAPU.Registers.X); - IAPU.PC++; + // SBC (X),(Y) + uint8 W1 = S9xAPUGetByteZ(IAPU.Registers.X); + uint8 Work8 = S9xAPUGetByteZ(IAPU.Registers.YA.B.Y); + SBC(W1, Work8); + S9xAPUSetByteZ(W1, IAPU.Registers.X); + IAPU.PC++; } -void ApuAF () +void ApuAF() { -// MOV (X)+, A - S9xAPUSetByteZ (IAPU.Registers.YA.B.A, IAPU.Registers.X++); - IAPU.PC++; + // MOV (X)+, A + S9xAPUSetByteZ(IAPU.Registers.YA.B.A, IAPU.Registers.X++); + IAPU.PC++; } -void ApuBE () +void ApuBE() { -// DAS - if ((IAPU.Registers.YA.B.A & 0x0f) > 9 || !APUCheckHalfCarry()) - { - IAPU.Registers.YA.B.A -= 6; - } - if (IAPU.Registers.YA.B.A > 0x9f || !IAPU._Carry) - { - IAPU.Registers.YA.B.A -= 0x60; - APUClearCarry (); - } - else { APUSetCarry (); } - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC++; + // DAS + if ((IAPU.Registers.YA.B.A & 0x0f) > 9 || !APUCheckHalfCarry()) + IAPU.Registers.YA.B.A -= 6; + if (IAPU.Registers.YA.B.A > 0x9f || !IAPU._Carry) + { + IAPU.Registers.YA.B.A -= 0x60; + APUClearCarry(); + } + else + APUSetCarry(); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC++; } -void ApuBF () +void ApuBF() { -// MOV A,(X)+ - IAPU.Registers.YA.B.A = S9xAPUGetByteZ (IAPU.Registers.X++); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC++; + // MOV A,(X)+ + IAPU.Registers.YA.B.A = S9xAPUGetByteZ(IAPU.Registers.X++); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC++; } -void ApuC0 () +void ApuC0() { -// DI - APUClearInterrupt (); - IAPU.PC++; + // DI + APUClearInterrupt(); + IAPU.PC++; } -void ApuA0 () +void ApuA0() { -// EI - APUSetInterrupt (); - IAPU.PC++; + // EI + APUSetInterrupt(); + IAPU.PC++; } -void ApuC4 () +void ApuC4() { -// MOV dp,A - S9xAPUSetByteZ (IAPU.Registers.YA.B.A, OP1); - IAPU.PC += 2; + // MOV dp,A + S9xAPUSetByteZ(IAPU.Registers.YA.B.A, OP1); + IAPU.PC += 2; } -void ApuC5 () +void ApuC5() { -// MOV abs,A - Absolute (); - S9xAPUSetByte (IAPU.Registers.YA.B.A, IAPU.Address); - IAPU.PC += 3; + // MOV abs,A + Absolute(); + S9xAPUSetByte(IAPU.Registers.YA.B.A, IAPU.Address); + IAPU.PC += 3; } -void ApuC6 () +void ApuC6() { -// MOV (X), A - S9xAPUSetByteZ (IAPU.Registers.YA.B.A, IAPU.Registers.X); - IAPU.PC++; + // MOV (X), A + S9xAPUSetByteZ(IAPU.Registers.YA.B.A, IAPU.Registers.X); + IAPU.PC++; } -void ApuC7 () +void ApuC7() { -// MOV (dp+X),A - IndexedXIndirect (); - S9xAPUSetByte (IAPU.Registers.YA.B.A, IAPU.Address); - IAPU.PC += 2; + // MOV (dp+X),A + IndexedXIndirect(); + S9xAPUSetByte(IAPU.Registers.YA.B.A, IAPU.Address); + IAPU.PC += 2; } -void ApuC9 () +void ApuC9() { -// MOV abs,X - Absolute (); - S9xAPUSetByte (IAPU.Registers.X, IAPU.Address); - IAPU.PC += 3; + // MOV abs,X + Absolute(); + S9xAPUSetByte(IAPU.Registers.X, IAPU.Address); + IAPU.PC += 3; } -void ApuCB () +void ApuCB() { -// MOV dp,Y - S9xAPUSetByteZ (IAPU.Registers.YA.B.Y, OP1); - IAPU.PC += 2; + // MOV dp,Y + S9xAPUSetByteZ(IAPU.Registers.YA.B.Y, OP1); + IAPU.PC += 2; } -void ApuCC () +void ApuCC() { -// MOV abs,Y - Absolute (); - S9xAPUSetByte (IAPU.Registers.YA.B.Y, IAPU.Address); - IAPU.PC += 3; + // MOV abs,Y + Absolute(); + S9xAPUSetByte(IAPU.Registers.YA.B.Y, IAPU.Address); + IAPU.PC += 3; } -void ApuCD () +void ApuCD() { -// MOV X,#00 - IAPU.Registers.X = OP1; - APUSetZN8 (IAPU.Registers.X); - IAPU.PC += 2; + // MOV X,#00 + IAPU.Registers.X = OP1; + APUSetZN8(IAPU.Registers.X); + IAPU.PC += 2; } -void ApuCF () +void ApuCF() { -// MUL YA - IAPU.Registers.YA.W = (uint16) IAPU.Registers.YA.B.A * IAPU.Registers.YA.B.Y; - APUSetZN16 (IAPU.Registers.YA.W); - IAPU.PC++; + // MUL YA + IAPU.Registers.YA.W = (uint16) IAPU.Registers.YA.B.A * IAPU.Registers.YA.B.Y; + APUSetZN16(IAPU.Registers.YA.W); + IAPU.PC++; } -void ApuD4 () +void ApuD4() { -// MOV dp+X, A - S9xAPUSetByteZ (IAPU.Registers.YA.B.A, OP1 + IAPU.Registers.X); - IAPU.PC += 2; + // MOV dp+X, A + S9xAPUSetByteZ(IAPU.Registers.YA.B.A, OP1 + IAPU.Registers.X); + IAPU.PC += 2; } -void ApuD5 () +void ApuD5() { -// MOV abs+X,A - AbsoluteX (); - S9xAPUSetByte (IAPU.Registers.YA.B.A, IAPU.Address); - IAPU.PC += 3; + // MOV abs+X,A + AbsoluteX(); + S9xAPUSetByte(IAPU.Registers.YA.B.A, IAPU.Address); + IAPU.PC += 3; } -void ApuD6 () +void ApuD6() { -// MOV abs+Y,A - AbsoluteY (); - S9xAPUSetByte (IAPU.Registers.YA.B.A, IAPU.Address); - IAPU.PC += 3; + // MOV abs+Y,A + AbsoluteY(); + S9xAPUSetByte(IAPU.Registers.YA.B.A, IAPU.Address); + IAPU.PC += 3; } -void ApuD7 () +void ApuD7() { -// MOV (dp)+Y,A - IndirectIndexedY (); - S9xAPUSetByte (IAPU.Registers.YA.B.A, IAPU.Address); - IAPU.PC += 2; + // MOV (dp)+Y,A + IndirectIndexedY(); + S9xAPUSetByte(IAPU.Registers.YA.B.A, IAPU.Address); + IAPU.PC += 2; } -void ApuD8 () +void ApuD8() { -// MOV dp,X - S9xAPUSetByteZ (IAPU.Registers.X, OP1); - IAPU.PC += 2; + // MOV dp,X + S9xAPUSetByteZ(IAPU.Registers.X, OP1); + IAPU.PC += 2; } -void ApuD9 () +void ApuD9() { -// MOV dp+Y,X - S9xAPUSetByteZ (IAPU.Registers.X, OP1 + IAPU.Registers.YA.B.Y); - IAPU.PC += 2; + // MOV dp+Y,X + S9xAPUSetByteZ(IAPU.Registers.X, OP1 + IAPU.Registers.YA.B.Y); + IAPU.PC += 2; } -void ApuDB () +void ApuDB() { -// MOV dp+X,Y - S9xAPUSetByteZ (IAPU.Registers.YA.B.Y, OP1 + IAPU.Registers.X); - IAPU.PC += 2; + // MOV dp+X,Y + S9xAPUSetByteZ(IAPU.Registers.YA.B.Y, OP1 + IAPU.Registers.X); + IAPU.PC += 2; } -void ApuDF () +void ApuDF() { -// DAA - if ((IAPU.Registers.YA.B.A & 0x0f) > 9 || APUCheckHalfCarry()) - { - if(IAPU.Registers.YA.B.A > 0xf0) APUSetCarry (); - IAPU.Registers.YA.B.A += 6; - //APUSetHalfCarry (); Intel procs do this, but this is a Sony proc... - } - //else { APUClearHalfCarry (); } ditto as above - if (IAPU.Registers.YA.B.A > 0x9f || IAPU._Carry) - { - IAPU.Registers.YA.B.A += 0x60; - APUSetCarry (); - } - else { APUClearCarry (); } - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC++; + // DAA + if ((IAPU.Registers.YA.B.A & 0x0f) > 9 || APUCheckHalfCarry()) + { + if (IAPU.Registers.YA.B.A > 0xf0) APUSetCarry(); + IAPU.Registers.YA.B.A += 6; + //APUSetHalfCarry (); Intel procs do this, but this is a Sony proc... + } + //else { APUClearHalfCarry (); } ditto as above + if (IAPU.Registers.YA.B.A > 0x9f || IAPU._Carry) + { + IAPU.Registers.YA.B.A += 0x60; + APUSetCarry(); + } + else + APUClearCarry(); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC++; } -void ApuE4 () +void ApuE4() { -// MOV A, dp - IAPU.Registers.YA.B.A = S9xAPUGetByteZ (OP1); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 2; + // MOV A, dp + IAPU.Registers.YA.B.A = S9xAPUGetByteZ(OP1); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 2; } -void ApuE5 () +void ApuE5() { -// MOV A,abs - Absolute (); - IAPU.Registers.YA.B.A = S9xAPUGetByte (IAPU.Address); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 3; + // MOV A,abs + Absolute(); + IAPU.Registers.YA.B.A = S9xAPUGetByte(IAPU.Address); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 3; } -void ApuE6 () +void ApuE6() { -// MOV A,(X) - IAPU.Registers.YA.B.A = S9xAPUGetByteZ (IAPU.Registers.X); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC++; + // MOV A,(X) + IAPU.Registers.YA.B.A = S9xAPUGetByteZ(IAPU.Registers.X); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC++; } -void ApuE7 () +void ApuE7() { -// MOV A,(dp+X) - IndexedXIndirect (); - IAPU.Registers.YA.B.A = S9xAPUGetByte (IAPU.Address); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 2; + // MOV A,(dp+X) + IndexedXIndirect(); + IAPU.Registers.YA.B.A = S9xAPUGetByte(IAPU.Address); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 2; } -void ApuE8 () +void ApuE8() { -// MOV A,#00 - IAPU.Registers.YA.B.A = OP1; - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 2; + // MOV A,#00 + IAPU.Registers.YA.B.A = OP1; + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 2; } -void ApuE9 () +void ApuE9() { -// MOV X, abs - Absolute (); - IAPU.Registers.X = S9xAPUGetByte (IAPU.Address); - APUSetZN8 (IAPU.Registers.X); - IAPU.PC += 3; + // MOV X, abs + Absolute(); + IAPU.Registers.X = S9xAPUGetByte(IAPU.Address); + APUSetZN8(IAPU.Registers.X); + IAPU.PC += 3; } -void ApuEB () +void ApuEB() { -// MOV Y,dp - IAPU.Registers.YA.B.Y = S9xAPUGetByteZ (OP1); - APUSetZN8 (IAPU.Registers.YA.B.Y); - IAPU.PC += 2; + // MOV Y,dp + IAPU.Registers.YA.B.Y = S9xAPUGetByteZ(OP1); + APUSetZN8(IAPU.Registers.YA.B.Y); + IAPU.PC += 2; } -void ApuEC () +void ApuEC() { -// MOV Y,abs - Absolute (); - IAPU.Registers.YA.B.Y = S9xAPUGetByte (IAPU.Address); - APUSetZN8 (IAPU.Registers.YA.B.Y); - IAPU.PC += 3; + // MOV Y,abs + Absolute(); + IAPU.Registers.YA.B.Y = S9xAPUGetByte(IAPU.Address); + APUSetZN8(IAPU.Registers.YA.B.Y); + IAPU.PC += 3; } -void ApuF4 () +void ApuF4() { -// MOV A, dp+X - IAPU.Registers.YA.B.A = S9xAPUGetByteZ (OP1 + IAPU.Registers.X); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 2; + // MOV A, dp+X + IAPU.Registers.YA.B.A = S9xAPUGetByteZ(OP1 + IAPU.Registers.X); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 2; } -void ApuF5 () +void ApuF5() { -// MOV A, abs+X - AbsoluteX (); - IAPU.Registers.YA.B.A = S9xAPUGetByte (IAPU.Address); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 3; + // MOV A, abs+X + AbsoluteX(); + IAPU.Registers.YA.B.A = S9xAPUGetByte(IAPU.Address); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 3; } -void ApuF6 () +void ApuF6() { -// MOV A, abs+Y - AbsoluteY (); - IAPU.Registers.YA.B.A = S9xAPUGetByte (IAPU.Address); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 3; + // MOV A, abs+Y + AbsoluteY(); + IAPU.Registers.YA.B.A = S9xAPUGetByte(IAPU.Address); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 3; } -void ApuF7 () +void ApuF7() { -// MOV A, (dp)+Y - IndirectIndexedY (); - IAPU.Registers.YA.B.A = S9xAPUGetByte (IAPU.Address); - APUSetZN8 (IAPU.Registers.YA.B.A); - IAPU.PC += 2; + // MOV A, (dp)+Y + IndirectIndexedY(); + IAPU.Registers.YA.B.A = S9xAPUGetByte(IAPU.Address); + APUSetZN8(IAPU.Registers.YA.B.A); + IAPU.PC += 2; } -void ApuF8 () +void ApuF8() { -// MOV X,dp - IAPU.Registers.X = S9xAPUGetByteZ (OP1); - APUSetZN8 (IAPU.Registers.X); - IAPU.PC += 2; + // MOV X,dp + IAPU.Registers.X = S9xAPUGetByteZ(OP1); + APUSetZN8(IAPU.Registers.X); + IAPU.PC += 2; } -void ApuF9 () +void ApuF9() { -// MOV X,dp+Y - IAPU.Registers.X = S9xAPUGetByteZ (OP1 + IAPU.Registers.YA.B.Y); - APUSetZN8 (IAPU.Registers.X); - IAPU.PC += 2; + // MOV X,dp+Y + IAPU.Registers.X = S9xAPUGetByteZ(OP1 + IAPU.Registers.YA.B.Y); + APUSetZN8(IAPU.Registers.X); + IAPU.PC += 2; } -void ApuFA () +void ApuFA() { -// MOV dp(dest),dp(src) - S9xAPUSetByteZ (S9xAPUGetByteZ (OP1), OP2); - IAPU.PC += 3; + // MOV dp(dest),dp(src) + S9xAPUSetByteZ(S9xAPUGetByteZ(OP1), OP2); + IAPU.PC += 3; } -void ApuFB () +void ApuFB() { -// MOV Y,dp+X - IAPU.Registers.YA.B.Y = S9xAPUGetByteZ (OP1 + IAPU.Registers.X); - APUSetZN8 (IAPU.Registers.YA.B.Y); - IAPU.PC += 2; + // MOV Y,dp+X + IAPU.Registers.YA.B.Y = S9xAPUGetByteZ(OP1 + IAPU.Registers.X); + APUSetZN8(IAPU.Registers.YA.B.Y); + IAPU.PC += 2; } #ifdef NO_INLINE_SET_GET @@ -2510,39 +2559,39 @@ void ApuFB () #include "apumem.h" #endif -void (*S9xApuOpcodes[256]) (void) = -{ - Apu00, Apu01, Apu02, Apu03, Apu04, Apu05, Apu06, Apu07, - Apu08, Apu09, Apu0A, Apu0B, Apu0C, Apu0D, Apu0E, Apu0F, - Apu10, Apu11, Apu12, Apu13, Apu14, Apu15, Apu16, Apu17, - Apu18, Apu19, Apu1A, Apu1B, Apu1C, Apu1D, Apu1E, Apu1F, - Apu20, Apu21, Apu22, Apu23, Apu24, Apu25, Apu26, Apu27, - Apu28, Apu29, Apu2A, Apu2B, Apu2C, Apu2D, Apu2E, Apu2F, - Apu30, Apu31, Apu32, Apu33, Apu34, Apu35, Apu36, Apu37, - Apu38, Apu39, Apu3A, Apu3B, Apu3C, Apu3D, Apu3E, Apu3F, - Apu40, Apu41, Apu42, Apu43, Apu44, Apu45, Apu46, Apu47, - Apu48, Apu49, Apu4A, Apu4B, Apu4C, Apu4D, Apu4E, Apu4F, - Apu50, Apu51, Apu52, Apu53, Apu54, Apu55, Apu56, Apu57, - Apu58, Apu59, Apu5A, Apu5B, Apu5C, Apu5D, Apu5E, Apu5F, - Apu60, Apu61, Apu62, Apu63, Apu64, Apu65, Apu66, Apu67, - Apu68, Apu69, Apu6A, Apu6B, Apu6C, Apu6D, Apu6E, Apu6F, - Apu70, Apu71, Apu72, Apu73, Apu74, Apu75, Apu76, Apu77, - Apu78, Apu79, Apu7A, Apu7B, Apu7C, Apu7D, Apu7E, Apu7F, - Apu80, Apu81, Apu82, Apu83, Apu84, Apu85, Apu86, Apu87, - Apu88, Apu89, Apu8A, Apu8B, Apu8C, Apu8D, Apu8E, Apu8F, - Apu90, Apu91, Apu92, Apu93, Apu94, Apu95, Apu96, Apu97, - Apu98, Apu99, Apu9A, Apu9B, Apu9C, Apu9D, Apu9E, Apu9F, - ApuA0, ApuA1, ApuA2, ApuA3, ApuA4, ApuA5, ApuA6, ApuA7, - ApuA8, ApuA9, ApuAA, ApuAB, ApuAC, ApuAD, ApuAE, ApuAF, - ApuB0, ApuB1, ApuB2, ApuB3, ApuB4, ApuB5, ApuB6, ApuB7, - ApuB8, ApuB9, ApuBA, ApuBB, ApuBC, ApuBD, ApuBE, ApuBF, - ApuC0, ApuC1, ApuC2, ApuC3, ApuC4, ApuC5, ApuC6, ApuC7, - ApuC8, ApuC9, ApuCA, ApuCB, ApuCC, ApuCD, ApuCE, ApuCF, - ApuD0, ApuD1, ApuD2, ApuD3, ApuD4, ApuD5, ApuD6, ApuD7, - ApuD8, ApuD9, ApuDA, ApuDB, ApuDC, ApuDD, ApuDE, ApuDF, - ApuE0, ApuE1, ApuE2, ApuE3, ApuE4, ApuE5, ApuE6, ApuE7, - ApuE8, ApuE9, ApuEA, ApuEB, ApuEC, ApuED, ApuEE, ApuEF, - ApuF0, ApuF1, ApuF2, ApuF3, ApuF4, ApuF5, ApuF6, ApuF7, - ApuF8, ApuF9, ApuFA, ApuFB, ApuFC, ApuFD, ApuFE, ApuFF +void (*S9xApuOpcodes[256])(void) = +{ + Apu00, Apu01, Apu02, Apu03, Apu04, Apu05, Apu06, Apu07, + Apu08, Apu09, Apu0A, Apu0B, Apu0C, Apu0D, Apu0E, Apu0F, + Apu10, Apu11, Apu12, Apu13, Apu14, Apu15, Apu16, Apu17, + Apu18, Apu19, Apu1A, Apu1B, Apu1C, Apu1D, Apu1E, Apu1F, + Apu20, Apu21, Apu22, Apu23, Apu24, Apu25, Apu26, Apu27, + Apu28, Apu29, Apu2A, Apu2B, Apu2C, Apu2D, Apu2E, Apu2F, + Apu30, Apu31, Apu32, Apu33, Apu34, Apu35, Apu36, Apu37, + Apu38, Apu39, Apu3A, Apu3B, Apu3C, Apu3D, Apu3E, Apu3F, + Apu40, Apu41, Apu42, Apu43, Apu44, Apu45, Apu46, Apu47, + Apu48, Apu49, Apu4A, Apu4B, Apu4C, Apu4D, Apu4E, Apu4F, + Apu50, Apu51, Apu52, Apu53, Apu54, Apu55, Apu56, Apu57, + Apu58, Apu59, Apu5A, Apu5B, Apu5C, Apu5D, Apu5E, Apu5F, + Apu60, Apu61, Apu62, Apu63, Apu64, Apu65, Apu66, Apu67, + Apu68, Apu69, Apu6A, Apu6B, Apu6C, Apu6D, Apu6E, Apu6F, + Apu70, Apu71, Apu72, Apu73, Apu74, Apu75, Apu76, Apu77, + Apu78, Apu79, Apu7A, Apu7B, Apu7C, Apu7D, Apu7E, Apu7F, + Apu80, Apu81, Apu82, Apu83, Apu84, Apu85, Apu86, Apu87, + Apu88, Apu89, Apu8A, Apu8B, Apu8C, Apu8D, Apu8E, Apu8F, + Apu90, Apu91, Apu92, Apu93, Apu94, Apu95, Apu96, Apu97, + Apu98, Apu99, Apu9A, Apu9B, Apu9C, Apu9D, Apu9E, Apu9F, + ApuA0, ApuA1, ApuA2, ApuA3, ApuA4, ApuA5, ApuA6, ApuA7, + ApuA8, ApuA9, ApuAA, ApuAB, ApuAC, ApuAD, ApuAE, ApuAF, + ApuB0, ApuB1, ApuB2, ApuB3, ApuB4, ApuB5, ApuB6, ApuB7, + ApuB8, ApuB9, ApuBA, ApuBB, ApuBC, ApuBD, ApuBE, ApuBF, + ApuC0, ApuC1, ApuC2, ApuC3, ApuC4, ApuC5, ApuC6, ApuC7, + ApuC8, ApuC9, ApuCA, ApuCB, ApuCC, ApuCD, ApuCE, ApuCF, + ApuD0, ApuD1, ApuD2, ApuD3, ApuD4, ApuD5, ApuD6, ApuD7, + ApuD8, ApuD9, ApuDA, ApuDB, ApuDC, ApuDD, ApuDE, ApuDF, + ApuE0, ApuE1, ApuE2, ApuE3, ApuE4, ApuE5, ApuE6, ApuE7, + ApuE8, ApuE9, ApuEA, ApuEB, ApuEC, ApuED, ApuEE, ApuEF, + ApuF0, ApuF1, ApuF2, ApuF3, ApuF4, ApuF5, ApuF6, ApuF7, + ApuF8, ApuF9, ApuFA, ApuFB, ApuFC, ApuFD, ApuFE, ApuFF }; diff --git a/source/spc700.h b/source/spc700.h index 9500183..1b4ac03 100644 --- a/source/spc700.h +++ b/source/spc700.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -134,20 +134,27 @@ typedef union { #ifdef LSB_FIRST - struct { uint8 A, Y; } B; + struct + { + uint8 A, Y; + } B; #else - struct { uint8 Y, A; } B; + struct + { + uint8 Y, A; + } B; #endif - uint16 W; + uint16 W; } YAndA; -typedef struct{ - uint8 P; - YAndA YA; - uint8 X; - uint8 S; - uint16 PC; -}SAPURegisters; +typedef struct +{ + uint8 P; + YAndA YA; + uint8 X; + uint8 S; + uint16 PC; +} SAPURegisters; // Needed by ILLUSION OF GAIA //#define ONE_APU_CYCLE 14 @@ -160,7 +167,7 @@ typedef struct{ // 1.953us := 1.024065.54MHz #ifdef SPCTOOL -int32 ESPC (int32); +int32 ESPC(int32); #define APU_EXECUTE() \ { \ @@ -184,7 +191,7 @@ int32 ESPC (int32); if (IAPU.APUExecuting) \ {\ while (APU.Cycles <= CPU.Cycles) \ - APU_EXECUTE1(); \ + APU_EXECUTE1(); \ } #endif diff --git a/source/spc7110.c b/source/spc7110.c index b9fa722..fdd625c 100644 --- a/source/spc7110.c +++ b/source/spc7110.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -94,14 +94,14 @@ //Windows includes #ifdef __WIN32__ -#ifndef _XBOX // chdir and getcwd not supported on Xbox hardware +#ifndef _XBOX // chdir and getcwd not supported on Xbox hardware #include #define chdir _chdir #define getcwd _getcwd #endif -#define FREEZEFOLDER GUI.FreezeFileDir +#define FREEZEFOLDER GUI.FreezeFileDir //zinx suggested this, for *nix compatibility -#define PATH_MAX MAX_PATH +#define PATH_MAX MAX_PATH #else // Unix #include "display.h" #include @@ -109,8 +109,8 @@ #define FREEZEFOLDER S9xGetSnapshotDirectory () #endif -const char *S9xGetFilename (const char *); -char *osd_GetPackDir(); +const char* S9xGetFilename(const char*); +char* osd_GetPackDir(); //really not needed, but usually MS adds the _ to POSIX functions, //while *nix doesn't, so this was to "un-M$" the function. #define splitpath _splitpath @@ -119,189 +119,192 @@ char *osd_GetPackDir(); #define MAX_TABLES 48 //default to using 5 megs of RAM for method 3 caching. -uint16 cacheMegs=5; +uint16 cacheMegs = 5; //using function pointers to initialize cache management -void (*CleanUp7110)(void)=NULL; -void (*LoadUp7110)(char*)=&SPC7110Load; -void (*Copy7110)(void)=NULL; +void (*CleanUp7110)(void) = NULL; +void (*LoadUp7110)(char*) = &SPC7110Load; +void (*Copy7110)(void) = NULL; //size and offset of the pack data //offset and size of reads from pack typedef struct SPC7110DecompressionLocationStruct { - uint32 offset; - uint32 size; - uint16 used_offset; - uint16 used_len; + uint32 offset; + uint32 size; + uint16 used_offset; + uint16 used_len; } Data7110; //this maps an index.bin table to the decompression pack typedef struct SPC7110DecompressionIndexStruct { - int table; - bool is_file; - Data7110 location[256]; + int table; + bool is_file; + Data7110 location[256]; } Index7110; //this contains all the data for the decompression pack. typedef struct SPC7110DecompressionPackStructure { - uint8* binfiles[MAX_TABLES]; - Index7110 tableEnts[MAX_TABLES]; - int last_table; - int idx; - uint8 last_idx; - uint16 last_offset; + uint8* binfiles[MAX_TABLES]; + Index7110 tableEnts[MAX_TABLES]; + int last_table; + int idx; + uint8 last_idx; + uint16 last_offset; } Pack7110; -char pfold[9]; //hack variable for log naming (each game makes a different log) -Pack7110* decompack=NULL; //decompression pack uses a fair chunk of RAM, so dynalloc it. -SPC7110Regs s7r; //SPC7110 registers, about 33KB -S7RTC rtc_f9; //FEOEZ (and Shounen Jump no SHou) RTC -void S9xUpdateRTC (); //S-RTC function hacked to work with the RTC +char pfold[9]; //hack variable for log naming (each game makes a different log) +Pack7110* decompack = + NULL; //decompression pack uses a fair chunk of RAM, so dynalloc it. +SPC7110Regs s7r; //SPC7110 registers, about 33KB +S7RTC rtc_f9; //FEOEZ (and Shounen Jump no SHou) RTC +void S9xUpdateRTC(); //S-RTC function hacked to work with the RTC //Emulate power on state void S9xSpc7110Init() { - s7r.DataRomOffset=0x00100000;//handy constant! - s7r.DataRomSize=Memory.CalculatedSize-s7r.DataRomOffset; - s7r.reg4800=0; - s7r.reg4801=0; - s7r.reg4802=0; - s7r.reg4803=0; - s7r.reg4804=0; - s7r.reg4805=0; - s7r.reg4806=0; - s7r.reg4807=0; - s7r.reg4808=0; - s7r.reg4809=0; - s7r.reg480A=0; - s7r.reg480B=0; - s7r.reg480C=0; - s7r.reg4811=0; - s7r.reg4812=0; - s7r.reg4813=0; - s7r.reg4814=0; - s7r.reg4815=0; - s7r.reg4816=0; - s7r.reg4817=0; - s7r.reg4818=0; - s7r.reg4820=0; - s7r.reg4821=0; - s7r.reg4822=0; - s7r.reg4823=0; - s7r.reg4824=0; - s7r.reg4825=0; - s7r.reg4826=0; - s7r.reg4827=0; - s7r.reg4828=0; - s7r.reg4829=0; - s7r.reg482A=0; - s7r.reg482B=0; - s7r.reg482C=0; - s7r.reg482D=0; - s7r.reg482E=0; - s7r.reg482F=0; - s7r.reg4830=0; - s7r.reg4831=0; - s7r.reg4832=1; - s7r.reg4833=2; - s7r.reg4834=0; - s7r.reg4840=0; - s7r.reg4841=0; - s7r.reg4842=0; - s7r.written=0; - s7r.offset_add=0; - s7r.AlignBy=1; - - (*LoadUp7110)(osd_GetPackDir()); - - s7r.bank50Internal=0; - memset(s7r.bank50,0x00,DECOMP_BUFFER_SIZE); + s7r.DataRomOffset = 0x00100000; //handy constant! + s7r.DataRomSize = Memory.CalculatedSize - s7r.DataRomOffset; + s7r.reg4800 = 0; + s7r.reg4801 = 0; + s7r.reg4802 = 0; + s7r.reg4803 = 0; + s7r.reg4804 = 0; + s7r.reg4805 = 0; + s7r.reg4806 = 0; + s7r.reg4807 = 0; + s7r.reg4808 = 0; + s7r.reg4809 = 0; + s7r.reg480A = 0; + s7r.reg480B = 0; + s7r.reg480C = 0; + s7r.reg4811 = 0; + s7r.reg4812 = 0; + s7r.reg4813 = 0; + s7r.reg4814 = 0; + s7r.reg4815 = 0; + s7r.reg4816 = 0; + s7r.reg4817 = 0; + s7r.reg4818 = 0; + s7r.reg4820 = 0; + s7r.reg4821 = 0; + s7r.reg4822 = 0; + s7r.reg4823 = 0; + s7r.reg4824 = 0; + s7r.reg4825 = 0; + s7r.reg4826 = 0; + s7r.reg4827 = 0; + s7r.reg4828 = 0; + s7r.reg4829 = 0; + s7r.reg482A = 0; + s7r.reg482B = 0; + s7r.reg482C = 0; + s7r.reg482D = 0; + s7r.reg482E = 0; + s7r.reg482F = 0; + s7r.reg4830 = 0; + s7r.reg4831 = 0; + s7r.reg4832 = 1; + s7r.reg4833 = 2; + s7r.reg4834 = 0; + s7r.reg4840 = 0; + s7r.reg4841 = 0; + s7r.reg4842 = 0; + s7r.written = 0; + s7r.offset_add = 0; + s7r.AlignBy = 1; + + (*LoadUp7110)(osd_GetPackDir()); + + s7r.bank50Internal = 0; + memset(s7r.bank50, 0x00, DECOMP_BUFFER_SIZE); } //full cache decompression routine (memcpy) Method 1 void MovePackData() { - //log the last entry - Data7110* log=&(decompack->tableEnts[decompack->idx].location[decompack->last_idx]); - if((log->used_len+log->used_offset)<(decompack->last_offset+(unsigned short)s7r.bank50Internal)) - { - log->used_len=s7r.bank50Internal; - log->used_offset=decompack->last_offset; - } - - //set up for next logging - decompack->last_offset=(s7r.reg4805)|(s7r.reg4806<<8); - - decompack->last_idx=s7r.reg4804; - - //start decompression - int table=(s7r.reg4803<<16)|(s7r.reg4802<<8)|s7r.reg4801; - - //the table is a offset multiplier byte and a big-endian pointer - int j= 4*s7r.reg4804; - j+=s7r.DataRomOffset; - j+=table; - - //set proper offsetting. - if(s7r.reg480B==0) - s7r.AlignBy=0; - else - { - switch(Memory.ROM[j]) - { - case 0x03: - s7r.AlignBy=8; - break; - case 0x01: - s7r.AlignBy=2; - break; - case 0x02: - s7r.AlignBy=4; - break; - case 0x00: - default: - s7r.AlignBy=1; - break; - } - } - //note that we are still setting up for the next log. - decompack->last_offset*=s7r.AlignBy; - decompack->last_offset%=DECOMP_BUFFER_SIZE; - - //find the table - if(table!=decompack->last_table) - { - int i=0; - while(itableEnts[i].table!=table) - i++; - if(i==MAX_TABLES) - { + //log the last entry + Data7110* log = & + (decompack->tableEnts[decompack->idx].location[decompack->last_idx]); + if ((log->used_len + log->used_offset) < (decompack->last_offset + + (unsigned short)s7r.bank50Internal)) + { + log->used_len = s7r.bank50Internal; + log->used_offset = decompack->last_offset; + } + + //set up for next logging + decompack->last_offset = (s7r.reg4805) | (s7r.reg4806 << 8); + + decompack->last_idx = s7r.reg4804; + + //start decompression + int table = (s7r.reg4803 << 16) | (s7r.reg4802 << 8) | s7r.reg4801; + + //the table is a offset multiplier byte and a big-endian pointer + int j = 4 * s7r.reg4804; + j += s7r.DataRomOffset; + j += table; + + //set proper offsetting. + if (s7r.reg480B == 0) + s7r.AlignBy = 0; + else + { + switch (Memory.ROM[j]) + { + case 0x03: + s7r.AlignBy = 8; + break; + case 0x01: + s7r.AlignBy = 2; + break; + case 0x02: + s7r.AlignBy = 4; + break; + case 0x00: + default: + s7r.AlignBy = 1; + break; + } + } + //note that we are still setting up for the next log. + decompack->last_offset *= s7r.AlignBy; + decompack->last_offset %= DECOMP_BUFFER_SIZE; + + //find the table + if (table != decompack->last_table) + { + int i = 0; + while (i < MAX_TABLES && decompack->tableEnts[i].table != table) + i++; + if (i == MAX_TABLES) + { #ifdef _XBOX - FILE* fp=fopen("T:\\sp7err.out","a"); + FILE* fp = fopen("T:\\sp7err.out", "a"); #else - FILE* fp=fopen("sp7err.out","a"); + FILE* fp = fopen("sp7err.out", "a"); #endif -// fprintf(fp, "Table Entry %06X:%02X not found\n", table, s7r.reg4804); - fclose(fp); - return; - } - decompack->idx=i; - decompack->last_table=table; - } - - //copy data - if(decompack->binfiles[decompack->idx]) - { - memcpy(s7r.bank50, - &(decompack->binfiles[decompack->idx][decompack->tableEnts[decompack->idx].location[s7r.reg4804].offset]), - decompack->tableEnts[decompack->idx].location[s7r.reg4804].size); - } + // fprintf(fp, "Table Entry %06X:%02X not found\n", table, s7r.reg4804); + fclose(fp); + return; + } + decompack->idx = i; + decompack->last_table = table; + } + + //copy data + if (decompack->binfiles[decompack->idx]) + { + memcpy(s7r.bank50, + &(decompack->binfiles[decompack->idx][decompack->tableEnts[decompack->idx].location[s7r.reg4804].offset]), + decompack->tableEnts[decompack->idx].location[s7r.reg4804].size); + } } @@ -309,1149 +312,1185 @@ void MovePackData() // and reads the data directly. Method 2 void ReadPackData() { - static int table_age_2; - static int table_age_3; - static int table_age_4; - static int table_age_5; - - int table=(s7r.reg4803<<16)|(s7r.reg4802<<8)|s7r.reg4801; - - if(table==0) - { - table_age_2=table_age_3=table_age_4=table_age_5=MAX_TABLES; - return; - } - - if(table_age_2==0&&table_age_3==0&&table_age_4==0&&table_age_5==0) - table_age_2=table_age_3=table_age_4=table_age_5=MAX_TABLES; - Data7110* log=&(decompack->tableEnts[decompack->idx].location[decompack->last_idx]); - if((log->used_len+log->used_offset)<(decompack->last_offset+(unsigned short)s7r.bank50Internal)) - { - log->used_len=s7r.bank50Internal; - log->used_offset=decompack->last_offset; - } - - decompack->last_offset=(s7r.reg4805)|(s7r.reg4806<<8); - - decompack->last_idx=s7r.reg4804; - - int j= 4*s7r.reg4804; - j+=s7r.DataRomOffset; - j+=table; - - if(s7r.reg480B==0) - s7r.AlignBy=0; - else - { - switch(Memory.ROM[j]) - { - case 0x03: - s7r.AlignBy=8; - break; - case 0x01: - s7r.AlignBy=2; - break; - case 0x02: - s7r.AlignBy=4; - break; - case 0x00: - default: - s7r.AlignBy=1; - break; - } - } - decompack->last_offset*=s7r.AlignBy; - decompack->last_offset%=DECOMP_BUFFER_SIZE; - if(table!=decompack->last_table) - { - int i=0; - while(itableEnts[i].table!=table) - i++; - if(i==MAX_TABLES) - { - FILE* fp=fopen("sp7err.out","a"); -// fprintf(fp, "Table Entry %06X:%02X not found\n", table, s7r.reg4804); - fclose(fp); - return; - } - if(i!= table_age_2 && i!= table_age_3 && i!= table_age_4 && i!= table_age_5) - { - if(table_age_5!=MAX_TABLES&&decompack->binfiles[table_age_5]) - { - fclose((FILE*)(decompack->binfiles[table_age_5])); - (decompack->binfiles[table_age_5])=NULL; - } - table_age_5=table_age_4; - table_age_4=table_age_3; - table_age_3=table_age_2; - table_age_2=decompack->idx; - char name[PATH_MAX]; - //open file - char drive [_MAX_DRIVE + 1]; - char dir [_MAX_DIR + 1]; - char fname [_MAX_FNAME + 1]; - char ext [_MAX_EXT + 1]; - if (strlen (FREEZEFOLDER)) - { - //splitpath (Memory.ROMFilename, drive, dir, fname, ext); - strcpy (name, FREEZEFOLDER); - strcat (name, "/"); - } - else - { - splitpath (Memory.ROMFilename, drive, dir, fname, ext); - strcpy(name, drive); - //strcat(filename, "\\"); - strcat(name, dir); - } - strcat(name, pfold); - char bfname[11]; - sprintf(bfname, "%06X.bin", table); - strcat(name, "/"); - strcat(name, bfname); - decompack->binfiles[i]=(uint8*)fopen(name, "rb"); - } - else - { - //fix tables in this case - if(table_age_5==i) - { - table_age_5=table_age_4; - table_age_4=table_age_3; - table_age_3=table_age_2; - table_age_2=decompack->idx; - } - if(table_age_4==i) - { - table_age_4=table_age_3; - table_age_3=table_age_2; - table_age_2=decompack->idx; - } - if(table_age_3==i) - { - table_age_3=table_age_2; - table_age_2=decompack->idx; - } - if(table_age_2==i) - { - table_age_2=decompack->idx; - } - } - decompack->idx=i; - decompack->last_table=table; - } - //do read here. - if(decompack->binfiles[decompack->idx]) - { - fseek((FILE*)(decompack->binfiles[decompack->idx]), decompack->tableEnts[decompack->idx].location[s7r.reg4804].offset, 0); - fread(s7r.bank50,1, (decompack->tableEnts[decompack->idx].location[s7r.reg4804].size), (FILE*)(decompack->binfiles[decompack->idx])); - } + static int table_age_2; + static int table_age_3; + static int table_age_4; + static int table_age_5; + + int table = (s7r.reg4803 << 16) | (s7r.reg4802 << 8) | s7r.reg4801; + + if (table == 0) + { + table_age_2 = table_age_3 = table_age_4 = table_age_5 = MAX_TABLES; + return; + } + + if (table_age_2 == 0 && table_age_3 == 0 && table_age_4 == 0 + && table_age_5 == 0) + table_age_2 = table_age_3 = table_age_4 = table_age_5 = MAX_TABLES; + Data7110* log = & + (decompack->tableEnts[decompack->idx].location[decompack->last_idx]); + if ((log->used_len + log->used_offset) < (decompack->last_offset + + (unsigned short)s7r.bank50Internal)) + { + log->used_len = s7r.bank50Internal; + log->used_offset = decompack->last_offset; + } + + decompack->last_offset = (s7r.reg4805) | (s7r.reg4806 << 8); + + decompack->last_idx = s7r.reg4804; + + int j = 4 * s7r.reg4804; + j += s7r.DataRomOffset; + j += table; + + if (s7r.reg480B == 0) + s7r.AlignBy = 0; + else + { + switch (Memory.ROM[j]) + { + case 0x03: + s7r.AlignBy = 8; + break; + case 0x01: + s7r.AlignBy = 2; + break; + case 0x02: + s7r.AlignBy = 4; + break; + case 0x00: + default: + s7r.AlignBy = 1; + break; + } + } + decompack->last_offset *= s7r.AlignBy; + decompack->last_offset %= DECOMP_BUFFER_SIZE; + if (table != decompack->last_table) + { + int i = 0; + while (i < MAX_TABLES && decompack->tableEnts[i].table != table) + i++; + if (i == MAX_TABLES) + { + FILE* fp = fopen("sp7err.out", "a"); + // fprintf(fp, "Table Entry %06X:%02X not found\n", table, s7r.reg4804); + fclose(fp); + return; + } + if (i != table_age_2 && i != table_age_3 && i != table_age_4 + && i != table_age_5) + { + if (table_age_5 != MAX_TABLES && decompack->binfiles[table_age_5]) + { + fclose((FILE*)(decompack->binfiles[table_age_5])); + (decompack->binfiles[table_age_5]) = NULL; + } + table_age_5 = table_age_4; + table_age_4 = table_age_3; + table_age_3 = table_age_2; + table_age_2 = decompack->idx; + char name[PATH_MAX]; + //open file + char drive [_MAX_DRIVE + 1]; + char dir [_MAX_DIR + 1]; + char fname [_MAX_FNAME + 1]; + char ext [_MAX_EXT + 1]; + if (strlen(FREEZEFOLDER)) + { + //splitpath (Memory.ROMFilename, drive, dir, fname, ext); + strcpy(name, FREEZEFOLDER); + strcat(name, "/"); + } + else + { + splitpath(Memory.ROMFilename, drive, dir, fname, ext); + strcpy(name, drive); + //strcat(filename, "\\"); + strcat(name, dir); + } + strcat(name, pfold); + char bfname[11]; + sprintf(bfname, "%06X.bin", table); + strcat(name, "/"); + strcat(name, bfname); + decompack->binfiles[i] = (uint8*)fopen(name, "rb"); + } + else + { + //fix tables in this case + if (table_age_5 == i) + { + table_age_5 = table_age_4; + table_age_4 = table_age_3; + table_age_3 = table_age_2; + table_age_2 = decompack->idx; + } + if (table_age_4 == i) + { + table_age_4 = table_age_3; + table_age_3 = table_age_2; + table_age_2 = decompack->idx; + } + if (table_age_3 == i) + { + table_age_3 = table_age_2; + table_age_2 = decompack->idx; + } + if (table_age_2 == i) + table_age_2 = decompack->idx; + } + decompack->idx = i; + decompack->last_table = table; + } + //do read here. + if (decompack->binfiles[decompack->idx]) + { + fseek((FILE*)(decompack->binfiles[decompack->idx]), + decompack->tableEnts[decompack->idx].location[s7r.reg4804].offset, 0); + fread(s7r.bank50, 1, ( + decompack->tableEnts[decompack->idx].location[s7r.reg4804].size), + (FILE*)(decompack->binfiles[decompack->idx])); + } } //Cache Method 3: some entries are cached, others are file handles. //use is_file to distinguish. void GetPackData() { - Data7110* log=&(decompack->tableEnts[decompack->idx].location[decompack->last_idx]); - if((log->used_len+log->used_offset)<(decompack->last_offset+(unsigned short)s7r.bank50Internal)) - { - log->used_len=s7r.bank50Internal; - log->used_offset=decompack->last_offset; - } - - decompack->last_offset=(s7r.reg4805)|(s7r.reg4806<<8); - - decompack->last_idx=s7r.reg4804; - int table=(s7r.reg4803<<16)|(s7r.reg4802<<8)|s7r.reg4801; - - int j= 4*s7r.reg4804; - j+=s7r.DataRomOffset; - j+=table; - - if(s7r.reg480B==0) - s7r.AlignBy=0; - else - { - switch(Memory.ROM[j]) - { - case 0x03: - s7r.AlignBy=8; - break; - case 0x01: - s7r.AlignBy=2; - break; - case 0x02: - s7r.AlignBy=4; - break; - case 0x00: - default: - s7r.AlignBy=1; - break; - } - } - decompack->last_offset*=s7r.AlignBy; - decompack->last_offset%=DECOMP_BUFFER_SIZE; - if(table!=decompack->last_table) - { - int i=0; - while(itableEnts[i].table!=table) - i++; - if(i==MAX_TABLES) - { - FILE* fp=fopen("sp7err.out","a"); -// fprintf(fp, "Table Entry %06X:%02X not found\n", table, s7r.reg4804); - fclose(fp); - return; - } - decompack->idx=i; - decompack->last_table=table; - } - if(decompack->binfiles[decompack->idx]) - { - if(decompack->tableEnts[decompack->idx].is_file) - { - fseek((FILE*)decompack->binfiles[decompack->idx], decompack->tableEnts[decompack->idx].location[s7r.reg4804].offset, 0); - fread(s7r.bank50,1, (decompack->tableEnts[decompack->idx].location[s7r.reg4804].size), (FILE*)(decompack->binfiles[decompack->idx])); - } - else - { - memcpy(s7r.bank50, - &(decompack->binfiles[decompack->idx][decompack->tableEnts[decompack->idx].location[s7r.reg4804].offset]), - decompack->tableEnts[decompack->idx].location[s7r.reg4804].size); - } - } + Data7110* log = & + (decompack->tableEnts[decompack->idx].location[decompack->last_idx]); + if ((log->used_len + log->used_offset) < (decompack->last_offset + + (unsigned short)s7r.bank50Internal)) + { + log->used_len = s7r.bank50Internal; + log->used_offset = decompack->last_offset; + } + + decompack->last_offset = (s7r.reg4805) | (s7r.reg4806 << 8); + + decompack->last_idx = s7r.reg4804; + int table = (s7r.reg4803 << 16) | (s7r.reg4802 << 8) | s7r.reg4801; + + int j = 4 * s7r.reg4804; + j += s7r.DataRomOffset; + j += table; + + if (s7r.reg480B == 0) + s7r.AlignBy = 0; + else + { + switch (Memory.ROM[j]) + { + case 0x03: + s7r.AlignBy = 8; + break; + case 0x01: + s7r.AlignBy = 2; + break; + case 0x02: + s7r.AlignBy = 4; + break; + case 0x00: + default: + s7r.AlignBy = 1; + break; + } + } + decompack->last_offset *= s7r.AlignBy; + decompack->last_offset %= DECOMP_BUFFER_SIZE; + if (table != decompack->last_table) + { + int i = 0; + while (i < MAX_TABLES && decompack->tableEnts[i].table != table) + i++; + if (i == MAX_TABLES) + { + FILE* fp = fopen("sp7err.out", "a"); + // fprintf(fp, "Table Entry %06X:%02X not found\n", table, s7r.reg4804); + fclose(fp); + return; + } + decompack->idx = i; + decompack->last_table = table; + } + if (decompack->binfiles[decompack->idx]) + { + if (decompack->tableEnts[decompack->idx].is_file) + { + fseek((FILE*)decompack->binfiles[decompack->idx], + decompack->tableEnts[decompack->idx].location[s7r.reg4804].offset, 0); + fread(s7r.bank50, 1, ( + decompack->tableEnts[decompack->idx].location[s7r.reg4804].size), + (FILE*)(decompack->binfiles[decompack->idx])); + } + else + { + memcpy(s7r.bank50, + &(decompack->binfiles[decompack->idx][decompack->tableEnts[decompack->idx].location[s7r.reg4804].offset]), + decompack->tableEnts[decompack->idx].location[s7r.reg4804].size); + } + } } //reads SPC7110 and RTC registers. uint8 S9xGetSPC7110(uint16 Address) { - switch (Address) - { - //decompressed data read port. decrements 4809-A (with wrap) - //4805-6 is the offset into the bank - //AlignBy is set (afaik) at decompression time, and is the offset multiplier - //bank50internal is an internal pointer to the actual byte to read. - //so you read from offset*multiplier + bank50internal - //the offset registers cannot be incremented due to the offset multiplier. - case 0x4800: - { - unsigned short count=s7r.reg4809|(s7r.reg480A<<8); - uint32 i, j; - j=(s7r.reg4805|(s7r.reg4806<<8)); - j*=s7r.AlignBy; - i=j; - if(count >0) - count--; - else count = 0xFFFF; - s7r.reg4809=0x00ff&count; - s7r.reg480A=(0xff00&count)>>8; - i+=s7r.bank50Internal; - i%=DECOMP_BUFFER_SIZE; - s7r.reg4800=s7r.bank50[i]; - - s7r.bank50Internal++; - s7r.bank50Internal%=DECOMP_BUFFER_SIZE; - } - return s7r.reg4800; - //table register low - case 0x4801: return s7r.reg4801; - //table register middle - case 0x4802: return s7r.reg4802; - //table register high - case 0x4803: return s7r.reg4803; - //index of pointer in table (each entry is 4 bytes) - case 0x4804: return s7r.reg4804; - //offset register low - case 0x4805: return s7r.reg4805; - //offset register high - case 0x4806: return s7r.reg4806; - //DMA channel (not that I see this usually set, - //regardless of what channel DMA is on) - case 0x4807: return s7r.reg4807; - //C r/w option, unknown, defval:00 is what Dark Force says - //afaict, Snes9x doesn't use this at all. - case 0x4808: return s7r.reg4808; - //C-Length low - //counts down the number of bytes left to read from the decompression buffer. - //this is set by the ROM, and wraps on bounds. - case 0x4809: return s7r.reg4809; - //C Length high - case 0x480A: return s7r.reg480A; - //Offset enable. - //if this is zero, 4805-6 are useless. Emulated by setting AlignBy to 0 - case 0x480B: - return s7r.reg480B; - //decompression finished: just emulated by switching each read. - case 0x480C: - s7r.reg480C^=0x80; - return s7r.reg480C^0x80; - - //Data access port - //reads from the data ROM (anywhere over the first 8 mbits - //behavior is complex, will document later, - //possibly missing cases, because of the number of switches in play - case 0x4810: - if(s7r.written==0) - return 0; - if((s7r.written&0x07)==0x07) - { - uint32 i=(s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811; - i%=s7r.DataRomSize; - if(s7r.reg4818&0x02) - { - if(s7r.reg4818&0x08) - { - signed short r4814; - r4814=(s7r.reg4815<<8)|s7r.reg4814; - i+=r4814; - r4814++; - s7r.reg4815=(uint8)(r4814>>8); - s7r.reg4814=(uint8)(r4814&0x00FF); - } - else - { - unsigned short r4814; - r4814=(s7r.reg4815<<8)|s7r.reg4814; - i+=r4814; - if(r4814!=0xFFFF) - r4814++; - else r4814=0; - s7r.reg4815=(uint8)(r4814>>8); - s7r.reg4814=(uint8)(r4814&0x00FF); - - } - } - i+=s7r.DataRomOffset; - uint8 tmp=Memory.ROM[i]; - i=(s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811; - - if(s7r.reg4818&0x02) - { - } - else if(s7r.reg4818&0x01) - { - if(s7r.reg4818&0x04) - { - signed short inc; - inc=(s7r.reg4817<<8)|s7r.reg4816; - - if(!(s7r.reg4818&0x10)) - i+=inc; - else - { - if(s7r.reg4818&0x08) - { - signed short r4814; - r4814=(s7r.reg4815<<8)|s7r.reg4814; - r4814+=inc; - s7r.reg4815=(r4814&0xFF00)>>8; - s7r.reg4814=r4814&0xFF; - } - else - { - unsigned short r4814; - r4814=(s7r.reg4815<<8)|s7r.reg4814; - r4814+=inc; - s7r.reg4815=(r4814&0xFF00)>>8; - s7r.reg4814=r4814&0xFF; - - } - } - //is signed - } - else - { - uint16 inc; - inc=(s7r.reg4817<<8)|s7r.reg4816; - if(!(s7r.reg4818&0x10)) - i+=inc; - else - { - if(s7r.reg4818&0x08) - { - signed short r4814; - r4814=(s7r.reg4815<<8)|s7r.reg4814; - r4814+=inc; - s7r.reg4815=(r4814&0xFF00)>>8; - s7r.reg4814=r4814&0xFF; - } - else - { - unsigned short r4814; - r4814=(s7r.reg4815<<8)|s7r.reg4814; - r4814+=inc; - s7r.reg4815=(r4814&0xFF00)>>8; - s7r.reg4814=r4814&0xFF; - - } - } - } - } - else - { - if(!(s7r.reg4818&0x10)) - i+=1; - else - { - if(s7r.reg4818&0x08) - { - signed short r4814; - r4814=(s7r.reg4815<<8)|s7r.reg4814; - r4814+=1; - s7r.reg4815=(r4814&0xFF00)>>8; - s7r.reg4814=r4814&0xFF; - } - else - { - unsigned short r4814; - r4814=(s7r.reg4815<<8)|s7r.reg4814; - r4814+=1; - s7r.reg4815=(r4814&0xFF00)>>8; - s7r.reg4814=r4814&0xFF; - - } - } - } - - i%=s7r.DataRomSize; - s7r.reg4811=i&0x00FF; - s7r.reg4812=(i&0x00FF00)>>8; - s7r.reg4813=((i&0xFF0000)>>16); - return tmp; - } - else return 0; - //direct read address low - case 0x4811: return s7r.reg4811; - //direct read address middle - case 0x4812: return s7r.reg4812; - //direct read access high - case 0x4813: return s7r.reg4813; - //read adjust low - case 0x4814: return s7r.reg4814; - //read adjust high - case 0x4815: return s7r.reg4815; - //read increment low - case 0x4816: return s7r.reg4816; - //read increment high - case 0x4817: return s7r.reg4817; - //Data ROM command mode - //essentially, this controls the insane code of $4810 and $481A - case 0x4818: return s7r.reg4818; - //read after adjust port - //what this does, besides more nasty stuff like 4810, - //I don't know. Just assume it is a different implementation of $4810, - //if it helps your sanity - case 0x481A: - if(s7r.written==0x1F) - { - uint32 i=((s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811); - if(s7r.reg4818&0x08) - { - short adj; - adj=((short)(s7r.reg4815<<8))|s7r.reg4814; - i+=adj; - } - else - { - uint16 adj; - adj=(s7r.reg4815<<8)|s7r.reg4814; - i+=adj; - } - - i%=s7r.DataRomSize; - i+=s7r.DataRomOffset; - uint8 tmp=Memory.ROM[i]; - i=((s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811); - if(0x60==(s7r.reg4818&0x60)) - { - i=((s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811); - - if(!(s7r.reg4818&0x10)) - { - if(s7r.reg4818&0x08) - { - short adj; - adj=((short)(s7r.reg4815<<8))|s7r.reg4814; - i+=adj; - } - else - { - uint16 adj; - adj=(s7r.reg4815<<8)|s7r.reg4814; - i+=adj; - } - i%=s7r.DataRomSize; - s7r.reg4811=i&0x00FF; - s7r.reg4812=(i&0x00FF00)>>8; - s7r.reg4813=((i&0xFF0000)>>16); - } - else - { - if(s7r.reg4818&0x08) - { - short adj; - adj=((short)(s7r.reg4815<<8))|s7r.reg4814; - adj+=adj; - s7r.reg4815=(adj&0xFF00)>>8; - s7r.reg4814=adj&0xFF; - } - else - { - uint16 adj; - adj=(s7r.reg4815<<8)|s7r.reg4814; - adj+=adj; - s7r.reg4815=(adj&0xFF00)>>8; - s7r.reg4814=adj&0xFF; - } - } - } - return tmp; - } - else return 0; - - //multiplicand low or dividend lowest - case 0x4820: return s7r.reg4820; - //multiplicand high or divdend lower - case 0x4821: return s7r.reg4821; - //dividend higher - case 0x4822: return s7r.reg4822; - //dividend highest - case 0x4823: return s7r.reg4823; - //multiplier low - case 0x4824: return s7r.reg4824; - //multiplier high - case 0x4825: return s7r.reg4825; - //divisor low - case 0x4826: return s7r.reg4826; - //divisor high - case 0x4827: return s7r.reg4827; - - //result lowest - case 0x4828: - return s7r.reg4828; - //result lower - case 0x4829: - return s7r.reg4829; - //result higher - case 0x482A: - return s7r.reg482A; - //result highest - case 0x482B: - return s7r.reg482B; - //remainder (division) low - case 0x482C: return s7r.reg482C; - //remainder (division) high - case 0x482D: return s7r.reg482D; - //signed/unsigned - case 0x482E: return s7r.reg482E; - //finished flag, emulated as an on-read toggle. - case 0x482F: - if(s7r.reg482F) - { - s7r.reg482F=0; - return 0x80; - } - return 0; - break; - - //SRAM toggle - case 0x4830: - return s7r.reg4830; - //DX bank mapping - case 0x4831: - return s7r.reg4831; - //EX bank mapping - case 0x4832: - return s7r.reg4832; - //FX bank mapping - case 0x4833: - return s7r.reg4833; - //SRAM mapping? We have no clue! - case 0x4834: - return s7r.reg4834; -//RTC enable - case 0x4840: - if(!Settings.SPC7110RTC) - return Address>>8; - return s7r.reg4840; -//command/index/value of RTC (essentially, zero unless we're in read mode - case 0x4841: - if(!Settings.SPC7110RTC) - return Address>>8; - if(rtc_f9.init) - { - S9xUpdateRTC(); - uint8 tmp=rtc_f9.reg[rtc_f9.index]; - rtc_f9.index++; - rtc_f9.index%=0x10; - return tmp; - } - else return 0; -//RTC done flag - case 0x4842: - if(!Settings.SPC7110RTC) - return Address>>8; - s7r.reg4842^=0x80; - return s7r.reg4842^0x80; - default: - return 0x00; - } + switch (Address) + { + //decompressed data read port. decrements 4809-A (with wrap) + //4805-6 is the offset into the bank + //AlignBy is set (afaik) at decompression time, and is the offset multiplier + //bank50internal is an internal pointer to the actual byte to read. + //so you read from offset*multiplier + bank50internal + //the offset registers cannot be incremented due to the offset multiplier. + case 0x4800: + { + unsigned short count = s7r.reg4809 | (s7r.reg480A << 8); + uint32 i, j; + j = (s7r.reg4805 | (s7r.reg4806 << 8)); + j *= s7r.AlignBy; + i = j; + if (count > 0) + count--; + else count = 0xFFFF; + s7r.reg4809 = 0x00ff & count; + s7r.reg480A = (0xff00 & count) >> 8; + i += s7r.bank50Internal; + i %= DECOMP_BUFFER_SIZE; + s7r.reg4800 = s7r.bank50[i]; + + s7r.bank50Internal++; + s7r.bank50Internal %= DECOMP_BUFFER_SIZE; + } + return s7r.reg4800; + //table register low + case 0x4801: + return s7r.reg4801; + //table register middle + case 0x4802: + return s7r.reg4802; + //table register high + case 0x4803: + return s7r.reg4803; + //index of pointer in table (each entry is 4 bytes) + case 0x4804: + return s7r.reg4804; + //offset register low + case 0x4805: + return s7r.reg4805; + //offset register high + case 0x4806: + return s7r.reg4806; + //DMA channel (not that I see this usually set, + //regardless of what channel DMA is on) + case 0x4807: + return s7r.reg4807; + //C r/w option, unknown, defval:00 is what Dark Force says + //afaict, Snes9x doesn't use this at all. + case 0x4808: + return s7r.reg4808; + //C-Length low + //counts down the number of bytes left to read from the decompression buffer. + //this is set by the ROM, and wraps on bounds. + case 0x4809: + return s7r.reg4809; + //C Length high + case 0x480A: + return s7r.reg480A; + //Offset enable. + //if this is zero, 4805-6 are useless. Emulated by setting AlignBy to 0 + case 0x480B: + return s7r.reg480B; + //decompression finished: just emulated by switching each read. + case 0x480C: + s7r.reg480C ^= 0x80; + return s7r.reg480C ^ 0x80; + + //Data access port + //reads from the data ROM (anywhere over the first 8 mbits + //behavior is complex, will document later, + //possibly missing cases, because of the number of switches in play + case 0x4810: + if (s7r.written == 0) + return 0; + if ((s7r.written & 0x07) == 0x07) + { + uint32 i = (s7r.reg4813 << 16) | (s7r.reg4812 << 8) | s7r.reg4811; + i %= s7r.DataRomSize; + if (s7r.reg4818 & 0x02) + { + if (s7r.reg4818 & 0x08) + { + signed short r4814; + r4814 = (s7r.reg4815 << 8) | s7r.reg4814; + i += r4814; + r4814++; + s7r.reg4815 = (uint8)(r4814 >> 8); + s7r.reg4814 = (uint8)(r4814 & 0x00FF); + } + else + { + unsigned short r4814; + r4814 = (s7r.reg4815 << 8) | s7r.reg4814; + i += r4814; + if (r4814 != 0xFFFF) + r4814++; + else r4814 = 0; + s7r.reg4815 = (uint8)(r4814 >> 8); + s7r.reg4814 = (uint8)(r4814 & 0x00FF); + + } + } + i += s7r.DataRomOffset; + uint8 tmp = Memory.ROM[i]; + i = (s7r.reg4813 << 16) | (s7r.reg4812 << 8) | s7r.reg4811; + + if (s7r.reg4818 & 0x02) + { + } + else if (s7r.reg4818 & 0x01) + { + if (s7r.reg4818 & 0x04) + { + signed short inc; + inc = (s7r.reg4817 << 8) | s7r.reg4816; + + if (!(s7r.reg4818 & 0x10)) + i += inc; + else + { + if (s7r.reg4818 & 0x08) + { + signed short r4814; + r4814 = (s7r.reg4815 << 8) | s7r.reg4814; + r4814 += inc; + s7r.reg4815 = (r4814 & 0xFF00) >> 8; + s7r.reg4814 = r4814 & 0xFF; + } + else + { + unsigned short r4814; + r4814 = (s7r.reg4815 << 8) | s7r.reg4814; + r4814 += inc; + s7r.reg4815 = (r4814 & 0xFF00) >> 8; + s7r.reg4814 = r4814 & 0xFF; + + } + } + //is signed + } + else + { + uint16 inc; + inc = (s7r.reg4817 << 8) | s7r.reg4816; + if (!(s7r.reg4818 & 0x10)) + i += inc; + else + { + if (s7r.reg4818 & 0x08) + { + signed short r4814; + r4814 = (s7r.reg4815 << 8) | s7r.reg4814; + r4814 += inc; + s7r.reg4815 = (r4814 & 0xFF00) >> 8; + s7r.reg4814 = r4814 & 0xFF; + } + else + { + unsigned short r4814; + r4814 = (s7r.reg4815 << 8) | s7r.reg4814; + r4814 += inc; + s7r.reg4815 = (r4814 & 0xFF00) >> 8; + s7r.reg4814 = r4814 & 0xFF; + + } + } + } + } + else + { + if (!(s7r.reg4818 & 0x10)) + i += 1; + else + { + if (s7r.reg4818 & 0x08) + { + signed short r4814; + r4814 = (s7r.reg4815 << 8) | s7r.reg4814; + r4814 += 1; + s7r.reg4815 = (r4814 & 0xFF00) >> 8; + s7r.reg4814 = r4814 & 0xFF; + } + else + { + unsigned short r4814; + r4814 = (s7r.reg4815 << 8) | s7r.reg4814; + r4814 += 1; + s7r.reg4815 = (r4814 & 0xFF00) >> 8; + s7r.reg4814 = r4814 & 0xFF; + + } + } + } + + i %= s7r.DataRomSize; + s7r.reg4811 = i & 0x00FF; + s7r.reg4812 = (i & 0x00FF00) >> 8; + s7r.reg4813 = ((i & 0xFF0000) >> 16); + return tmp; + } + else return 0; + //direct read address low + case 0x4811: + return s7r.reg4811; + //direct read address middle + case 0x4812: + return s7r.reg4812; + //direct read access high + case 0x4813: + return s7r.reg4813; + //read adjust low + case 0x4814: + return s7r.reg4814; + //read adjust high + case 0x4815: + return s7r.reg4815; + //read increment low + case 0x4816: + return s7r.reg4816; + //read increment high + case 0x4817: + return s7r.reg4817; + //Data ROM command mode + //essentially, this controls the insane code of $4810 and $481A + case 0x4818: + return s7r.reg4818; + //read after adjust port + //what this does, besides more nasty stuff like 4810, + //I don't know. Just assume it is a different implementation of $4810, + //if it helps your sanity + case 0x481A: + if (s7r.written == 0x1F) + { + uint32 i = ((s7r.reg4813 << 16) | (s7r.reg4812 << 8) | s7r.reg4811); + if (s7r.reg4818 & 0x08) + { + short adj; + adj = ((short)(s7r.reg4815 << 8)) | s7r.reg4814; + i += adj; + } + else + { + uint16 adj; + adj = (s7r.reg4815 << 8) | s7r.reg4814; + i += adj; + } + + i %= s7r.DataRomSize; + i += s7r.DataRomOffset; + uint8 tmp = Memory.ROM[i]; + i = ((s7r.reg4813 << 16) | (s7r.reg4812 << 8) | s7r.reg4811); + if (0x60 == (s7r.reg4818 & 0x60)) + { + i = ((s7r.reg4813 << 16) | (s7r.reg4812 << 8) | s7r.reg4811); + + if (!(s7r.reg4818 & 0x10)) + { + if (s7r.reg4818 & 0x08) + { + short adj; + adj = ((short)(s7r.reg4815 << 8)) | s7r.reg4814; + i += adj; + } + else + { + uint16 adj; + adj = (s7r.reg4815 << 8) | s7r.reg4814; + i += adj; + } + i %= s7r.DataRomSize; + s7r.reg4811 = i & 0x00FF; + s7r.reg4812 = (i & 0x00FF00) >> 8; + s7r.reg4813 = ((i & 0xFF0000) >> 16); + } + else + { + if (s7r.reg4818 & 0x08) + { + short adj; + adj = ((short)(s7r.reg4815 << 8)) | s7r.reg4814; + adj += adj; + s7r.reg4815 = (adj & 0xFF00) >> 8; + s7r.reg4814 = adj & 0xFF; + } + else + { + uint16 adj; + adj = (s7r.reg4815 << 8) | s7r.reg4814; + adj += adj; + s7r.reg4815 = (adj & 0xFF00) >> 8; + s7r.reg4814 = adj & 0xFF; + } + } + } + return tmp; + } + else return 0; + + //multiplicand low or dividend lowest + case 0x4820: + return s7r.reg4820; + //multiplicand high or divdend lower + case 0x4821: + return s7r.reg4821; + //dividend higher + case 0x4822: + return s7r.reg4822; + //dividend highest + case 0x4823: + return s7r.reg4823; + //multiplier low + case 0x4824: + return s7r.reg4824; + //multiplier high + case 0x4825: + return s7r.reg4825; + //divisor low + case 0x4826: + return s7r.reg4826; + //divisor high + case 0x4827: + return s7r.reg4827; + + //result lowest + case 0x4828: + return s7r.reg4828; + //result lower + case 0x4829: + return s7r.reg4829; + //result higher + case 0x482A: + return s7r.reg482A; + //result highest + case 0x482B: + return s7r.reg482B; + //remainder (division) low + case 0x482C: + return s7r.reg482C; + //remainder (division) high + case 0x482D: + return s7r.reg482D; + //signed/unsigned + case 0x482E: + return s7r.reg482E; + //finished flag, emulated as an on-read toggle. + case 0x482F: + if (s7r.reg482F) + { + s7r.reg482F = 0; + return 0x80; + } + return 0; + break; + + //SRAM toggle + case 0x4830: + return s7r.reg4830; + //DX bank mapping + case 0x4831: + return s7r.reg4831; + //EX bank mapping + case 0x4832: + return s7r.reg4832; + //FX bank mapping + case 0x4833: + return s7r.reg4833; + //SRAM mapping? We have no clue! + case 0x4834: + return s7r.reg4834; + //RTC enable + case 0x4840: + if (!Settings.SPC7110RTC) + return Address >> 8; + return s7r.reg4840; + //command/index/value of RTC (essentially, zero unless we're in read mode + case 0x4841: + if (!Settings.SPC7110RTC) + return Address >> 8; + if (rtc_f9.init) + { + S9xUpdateRTC(); + uint8 tmp = rtc_f9.reg[rtc_f9.index]; + rtc_f9.index++; + rtc_f9.index %= 0x10; + return tmp; + } + else return 0; + //RTC done flag + case 0x4842: + if (!Settings.SPC7110RTC) + return Address >> 8; + s7r.reg4842 ^= 0x80; + return s7r.reg4842 ^ 0x80; + default: + return 0x00; + } } -void S9xSetSPC7110 (uint8 data, uint16 Address) +void S9xSetSPC7110(uint8 data, uint16 Address) { - switch(Address) - { -//Writes to $4800 are undefined. - - //table low, middle, and high. - case 0x4801: - s7r.reg4801=data; - break; - case 0x4802: - s7r.reg4802=data; - break; - case 0x4803: - s7r.reg4803=data; - break; - - //table index (4 byte entries, bigendian with a multiplier byte) - case 0x4804: - s7r.reg4804=data; - break; - - //offset low - case 0x4805: - s7r.reg4805=data; - break; - - //offset high, starts decompression - case 0x4806: - s7r.reg4806=data; - (*Copy7110)(); - s7r.bank50Internal=0; - s7r.reg480C&=0x7F; - break; - - //DMA channel register (Is it used??) - case 0x4807: - s7r.reg4807=data; - break; - - //C r/w? I have no idea. If you get weird values written here before a bug, - //The Dumper should probably be contacted about running a test. - case 0x4808: - s7r.reg4808=data; - break; - - //C-Length low - case 0x4809: - s7r.reg4809=data; - break; - //C-Length high - case 0x480A: - s7r.reg480A=data; - break; - - //Offset enable - case 0x480B: - { - s7r.reg480B=data; - int table=(s7r.reg4803<<16)|(s7r.reg4802<<8)|s7r.reg4801; - - int j= 4*s7r.reg4804; - j+=s7r.DataRomOffset; - j+=table; - - if(s7r.reg480B==0) - s7r.AlignBy=0; - else - { - switch(Memory.ROM[j]) - { - case 0x03: - s7r.AlignBy=8; - break; - case 0x01: - s7r.AlignBy=2; - break; - case 0x02: - s7r.AlignBy=4; - break; - case 0x00: - default: - s7r.AlignBy=1; - break; - } - } -// s7r.decomp_set=true; - } - break; -//$4810 is probably read only. - - //Data port address low - case 0x4811: - s7r.reg4811=data; - s7r.written|=0x01; - break; - - //data port address middle - case 0x4812: - s7r.reg4812=data; - s7r.written|=0x02; - break; - - //data port address high - case 0x4813: - s7r.reg4813=data; - s7r.written|=0x04; - break; - - //data port adjust low (has a funky immediate increment mode) - case 0x4814: - s7r.reg4814=data; - if(s7r.reg4818&0x02) - { - if((s7r.reg4818&0x20)&&!(s7r.reg4818&0x40)) - { - s7r.offset_add|=0x01; - if(s7r.offset_add==3) - { - if(s7r.reg4818&0x10) - { - } - else - { - uint32 i=(s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811; - if(s7r.reg4818&0x08) - { - i+=(signed char)s7r.reg4814; - } - else - { - i+=s7r.reg4814; - } - i%=s7r.DataRomSize; - s7r.reg4811=i&0x00FF; - s7r.reg4812=(i&0x00FF00)>>8; - s7r.reg4813=((i&0xFF0000)>>16); - } - } - } - else if((s7r.reg4818&0x40)&&!(s7r.reg4818&0x20)) - { - s7r.offset_add|=0x01; - if(s7r.offset_add==3) - { - if(s7r.reg4818&0x10) - { - } - else - { - uint32 i=(s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811; - if(s7r.reg4818&0x08) - { - short adj; - adj=((short)(s7r.reg4815<<8))|s7r.reg4814; - i+=adj; - } - else - { - uint16 adj; - adj=(s7r.reg4815<<8)|s7r.reg4814; - i+=adj; - } - i%=s7r.DataRomSize; - s7r.reg4811=i&0x00FF; - s7r.reg4812=(i&0x00FF00)>>8; - s7r.reg4813=((i&0xFF0000)>>16); - } - } - - } - } - - s7r.written|=0x08; - break; - - //data port adjust high (has a funky immediate increment mode) - case 0x4815: - s7r.reg4815=data; - if(s7r.reg4818&0x02) - { - if(s7r.reg4818&0x20&&!(s7r.reg4818&0x40)) - { - s7r.offset_add|=0x02; - if(s7r.offset_add==3) - { - if(s7r.reg4818&0x10) - { - } - else - { - uint32 i=(s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811; - - if(s7r.reg4818&0x08) - { - i+=(signed char)s7r.reg4814; - } - else - { - i+=s7r.reg4814; - } - i%=s7r.DataRomSize; - s7r.reg4811=i&0x00FF; - s7r.reg4812=(i&0x00FF00)>>8; - s7r.reg4813=((i&0xFF0000)>>16); - } - } - } - else if(s7r.reg4818&0x40&&!(s7r.reg4818&0x20)) - { - s7r.offset_add|=0x02; - if(s7r.offset_add==3) - { - if(s7r.reg4818&0x10) - { - } - else - { - uint32 i=(s7r.reg4813<<16)|(s7r.reg4812<<8)|s7r.reg4811; - if(s7r.reg4818&0x08) - { - short adj; - adj=((short)(s7r.reg4815<<8))|s7r.reg4814; - i+=adj; - } - else - { - uint16 adj; - adj=(s7r.reg4815<<8)|s7r.reg4814; - i+=adj; - } - i%=s7r.DataRomSize; - s7r.reg4811=i&0x00FF; - s7r.reg4812=(i&0x00FF00)>>8; - s7r.reg4813=((i&0xFF0000)>>16); - } - } - } - } - s7r.written|=0x10; - break; - //data port increment low - case 0x4816: - s7r.reg4816=data; - break; - //data port increment high - case 0x4817: - s7r.reg4817=data; - break; - - //data port mode switches - //note that it starts inactive. - case 0x4818: - if((s7r.written&0x18)!=0x18) - break; - s7r.offset_add=0; - s7r.reg4818=data; - break; - - //multiplicand low or dividend lowest - case 0x4820: - s7r.reg4820=data; - break; - //multiplicand high or dividend lower - case 0x4821: - s7r.reg4821=data; - break; - //dividend higher - case 0x4822: - s7r.reg4822=data; - break; - //dividend highest - case 0x4823: - s7r.reg4823=data; - break; - //multiplier low - case 0x4824: - s7r.reg4824=data; - break; - //multiplier high (triggers operation) - case 0x4825: - s7r.reg4825=data; - if(s7r.reg482E&0x01) - { - int mul; - short m1=(short)((s7r.reg4824)|(s7r.reg4825<<8)); - short m2=(short)((s7r.reg4820)|(s7r.reg4821<<8)); - - mul=m1*m2; - s7r.reg4828=(uint8)(mul&0x000000FF); - s7r.reg4829=(uint8)((mul&0x0000FF00)>>8); - s7r.reg482A=(uint8)((mul&0x00FF0000)>>16); - s7r.reg482B=(uint8)((mul&0xFF000000)>>24); - } - else - { - uint32 mul; - uint16 m1=(uint16)((s7r.reg4824)|(s7r.reg4825<<8)); - uint16 m2=(uint16)((s7r.reg4820)|(s7r.reg4821<<8)); - - mul=m1*m2; - s7r.reg4828=(uint8)(mul&0x000000FF); - s7r.reg4829=(uint8)((mul&0x0000FF00)>>8); - s7r.reg482A=(uint8)((mul&0x00FF0000)>>16); - s7r.reg482B=(uint8)((mul&0xFF000000)>>24); - } - s7r.reg482F=0x80; - break; - //divisor low - case 0x4826: - s7r.reg4826=data; - break; - //divisor high (triggers operation) - case 0x4827: - s7r.reg4827=data; - if(s7r.reg482E&0x01) - { - int quotient; - short remainder; - int dividend=(int)(s7r.reg4820|(s7r.reg4821<<8)|(s7r.reg4822<<16)|(s7r.reg4823<<24)); - short divisor=(short)(s7r.reg4826|(s7r.reg4827<<8)); - if(divisor != 0) - { - quotient=(int)(dividend/divisor); - remainder=(short)(dividend%divisor); - } - else - { - quotient=0; - remainder=dividend&0x0000FFFF; - } - s7r.reg4828=(uint8)(quotient&0x000000FF); - s7r.reg4829=(uint8)((quotient&0x0000FF00)>>8); - s7r.reg482A=(uint8)((quotient&0x00FF0000)>>16); - s7r.reg482B=(uint8)((quotient&0xFF000000)>>24); - s7r.reg482C=(uint8)remainder&0x00FF; - s7r.reg482D=(uint8)((remainder&0xFF00)>>8); - } - else - { - uint32 quotient; - uint16 remainder; - uint32 dividend=(uint32)(s7r.reg4820|(s7r.reg4821<<8)|(s7r.reg4822<<16)|(s7r.reg4823<<24)); - uint16 divisor=(uint16)(s7r.reg4826|(s7r.reg4827<<8)); - if(divisor != 0) - { - quotient=(uint32)(dividend/divisor); - remainder=(uint16)(dividend%divisor); - } - else - { - quotient=0; - remainder=dividend&0x0000FFFF; - } - s7r.reg4828=(uint8)(quotient&0x000000FF); - s7r.reg4829=(uint8)((quotient&0x0000FF00)>>8); - s7r.reg482A=(uint8)((quotient&0x00FF0000)>>16); - s7r.reg482B=(uint8)((quotient&0xFF000000)>>24); - s7r.reg482C=(uint8)remainder&0x00FF; - s7r.reg482D=(uint8)((remainder&0xFF00)>>8); - } - s7r.reg482F=0x80; - break; - //result registers are possibly read-only - - //reset: writes here nuke the whole math unit - //Zero indicates unsigned math, resets with non-zero values turn on signed math - case 0x482E: - s7r.reg4820=s7r.reg4821=s7r.reg4822=s7r.reg4823=s7r.reg4824=s7r.reg4825=s7r.reg4826=s7r.reg4827=s7r.reg4828=s7r.reg4829=s7r.reg482A=s7r.reg482B=s7r.reg482C=s7r.reg482D=0; - s7r.reg482E=data; - break; - - //math status register possibly read only - - //SRAM toggle - case 0x4830: + switch (Address) + { + //Writes to $4800 are undefined. + + //table low, middle, and high. + case 0x4801: + s7r.reg4801 = data; + break; + case 0x4802: + s7r.reg4802 = data; + break; + case 0x4803: + s7r.reg4803 = data; + break; + + //table index (4 byte entries, bigendian with a multiplier byte) + case 0x4804: + s7r.reg4804 = data; + break; + + //offset low + case 0x4805: + s7r.reg4805 = data; + break; + + //offset high, starts decompression + case 0x4806: + s7r.reg4806 = data; + (*Copy7110)(); + s7r.bank50Internal = 0; + s7r.reg480C &= 0x7F; + break; + + //DMA channel register (Is it used??) + case 0x4807: + s7r.reg4807 = data; + break; + + //C r/w? I have no idea. If you get weird values written here before a bug, + //The Dumper should probably be contacted about running a test. + case 0x4808: + s7r.reg4808 = data; + break; + + //C-Length low + case 0x4809: + s7r.reg4809 = data; + break; + //C-Length high + case 0x480A: + s7r.reg480A = data; + break; + + //Offset enable + case 0x480B: + { + s7r.reg480B = data; + int table = (s7r.reg4803 << 16) | (s7r.reg4802 << 8) | s7r.reg4801; + + int j = 4 * s7r.reg4804; + j += s7r.DataRomOffset; + j += table; + + if (s7r.reg480B == 0) + s7r.AlignBy = 0; + else + { + switch (Memory.ROM[j]) + { + case 0x03: + s7r.AlignBy = 8; + break; + case 0x01: + s7r.AlignBy = 2; + break; + case 0x02: + s7r.AlignBy = 4; + break; + case 0x00: + default: + s7r.AlignBy = 1; + break; + } + } + // s7r.decomp_set=true; + } + break; + //$4810 is probably read only. + + //Data port address low + case 0x4811: + s7r.reg4811 = data; + s7r.written |= 0x01; + break; + + //data port address middle + case 0x4812: + s7r.reg4812 = data; + s7r.written |= 0x02; + break; + + //data port address high + case 0x4813: + s7r.reg4813 = data; + s7r.written |= 0x04; + break; + + //data port adjust low (has a funky immediate increment mode) + case 0x4814: + s7r.reg4814 = data; + if (s7r.reg4818 & 0x02) + { + if ((s7r.reg4818 & 0x20) && !(s7r.reg4818 & 0x40)) + { + s7r.offset_add |= 0x01; + if (s7r.offset_add == 3) + { + if (s7r.reg4818 & 0x10) + { + } + else + { + uint32 i = (s7r.reg4813 << 16) | (s7r.reg4812 << 8) | s7r.reg4811; + if (s7r.reg4818 & 0x08) + i += (signed char)s7r.reg4814; + else + i += s7r.reg4814; + i %= s7r.DataRomSize; + s7r.reg4811 = i & 0x00FF; + s7r.reg4812 = (i & 0x00FF00) >> 8; + s7r.reg4813 = ((i & 0xFF0000) >> 16); + } + } + } + else if ((s7r.reg4818 & 0x40) && !(s7r.reg4818 & 0x20)) + { + s7r.offset_add |= 0x01; + if (s7r.offset_add == 3) + { + if (s7r.reg4818 & 0x10) + { + } + else + { + uint32 i = (s7r.reg4813 << 16) | (s7r.reg4812 << 8) | s7r.reg4811; + if (s7r.reg4818 & 0x08) + { + short adj; + adj = ((short)(s7r.reg4815 << 8)) | s7r.reg4814; + i += adj; + } + else + { + uint16 adj; + adj = (s7r.reg4815 << 8) | s7r.reg4814; + i += adj; + } + i %= s7r.DataRomSize; + s7r.reg4811 = i & 0x00FF; + s7r.reg4812 = (i & 0x00FF00) >> 8; + s7r.reg4813 = ((i & 0xFF0000) >> 16); + } + } + + } + } + + s7r.written |= 0x08; + break; + + //data port adjust high (has a funky immediate increment mode) + case 0x4815: + s7r.reg4815 = data; + if (s7r.reg4818 & 0x02) + { + if (s7r.reg4818 & 0x20 && !(s7r.reg4818 & 0x40)) + { + s7r.offset_add |= 0x02; + if (s7r.offset_add == 3) + { + if (s7r.reg4818 & 0x10) + { + } + else + { + uint32 i = (s7r.reg4813 << 16) | (s7r.reg4812 << 8) | s7r.reg4811; + + if (s7r.reg4818 & 0x08) + i += (signed char)s7r.reg4814; + else + i += s7r.reg4814; + i %= s7r.DataRomSize; + s7r.reg4811 = i & 0x00FF; + s7r.reg4812 = (i & 0x00FF00) >> 8; + s7r.reg4813 = ((i & 0xFF0000) >> 16); + } + } + } + else if (s7r.reg4818 & 0x40 && !(s7r.reg4818 & 0x20)) + { + s7r.offset_add |= 0x02; + if (s7r.offset_add == 3) + { + if (s7r.reg4818 & 0x10) + { + } + else + { + uint32 i = (s7r.reg4813 << 16) | (s7r.reg4812 << 8) | s7r.reg4811; + if (s7r.reg4818 & 0x08) + { + short adj; + adj = ((short)(s7r.reg4815 << 8)) | s7r.reg4814; + i += adj; + } + else + { + uint16 adj; + adj = (s7r.reg4815 << 8) | s7r.reg4814; + i += adj; + } + i %= s7r.DataRomSize; + s7r.reg4811 = i & 0x00FF; + s7r.reg4812 = (i & 0x00FF00) >> 8; + s7r.reg4813 = ((i & 0xFF0000) >> 16); + } + } + } + } + s7r.written |= 0x10; + break; + //data port increment low + case 0x4816: + s7r.reg4816 = data; + break; + //data port increment high + case 0x4817: + s7r.reg4817 = data; + break; + + //data port mode switches + //note that it starts inactive. + case 0x4818: + if ((s7r.written & 0x18) != 0x18) + break; + s7r.offset_add = 0; + s7r.reg4818 = data; + break; + + //multiplicand low or dividend lowest + case 0x4820: + s7r.reg4820 = data; + break; + //multiplicand high or dividend lower + case 0x4821: + s7r.reg4821 = data; + break; + //dividend higher + case 0x4822: + s7r.reg4822 = data; + break; + //dividend highest + case 0x4823: + s7r.reg4823 = data; + break; + //multiplier low + case 0x4824: + s7r.reg4824 = data; + break; + //multiplier high (triggers operation) + case 0x4825: + s7r.reg4825 = data; + if (s7r.reg482E & 0x01) + { + int mul; + short m1 = (short)((s7r.reg4824) | (s7r.reg4825 << 8)); + short m2 = (short)((s7r.reg4820) | (s7r.reg4821 << 8)); + + mul = m1 * m2; + s7r.reg4828 = (uint8)(mul & 0x000000FF); + s7r.reg4829 = (uint8)((mul & 0x0000FF00) >> 8); + s7r.reg482A = (uint8)((mul & 0x00FF0000) >> 16); + s7r.reg482B = (uint8)((mul & 0xFF000000) >> 24); + } + else + { + uint32 mul; + uint16 m1 = (uint16)((s7r.reg4824) | (s7r.reg4825 << 8)); + uint16 m2 = (uint16)((s7r.reg4820) | (s7r.reg4821 << 8)); + + mul = m1 * m2; + s7r.reg4828 = (uint8)(mul & 0x000000FF); + s7r.reg4829 = (uint8)((mul & 0x0000FF00) >> 8); + s7r.reg482A = (uint8)((mul & 0x00FF0000) >> 16); + s7r.reg482B = (uint8)((mul & 0xFF000000) >> 24); + } + s7r.reg482F = 0x80; + break; + //divisor low + case 0x4826: + s7r.reg4826 = data; + break; + //divisor high (triggers operation) + case 0x4827: + s7r.reg4827 = data; + if (s7r.reg482E & 0x01) + { + int quotient; + short remainder; + int dividend = (int)(s7r.reg4820 | (s7r.reg4821 << 8) | (s7r.reg4822 << 16) | + (s7r.reg4823 << 24)); + short divisor = (short)(s7r.reg4826 | (s7r.reg4827 << 8)); + if (divisor != 0) + { + quotient = (int)(dividend / divisor); + remainder = (short)(dividend % divisor); + } + else + { + quotient = 0; + remainder = dividend & 0x0000FFFF; + } + s7r.reg4828 = (uint8)(quotient & 0x000000FF); + s7r.reg4829 = (uint8)((quotient & 0x0000FF00) >> 8); + s7r.reg482A = (uint8)((quotient & 0x00FF0000) >> 16); + s7r.reg482B = (uint8)((quotient & 0xFF000000) >> 24); + s7r.reg482C = (uint8)remainder & 0x00FF; + s7r.reg482D = (uint8)((remainder & 0xFF00) >> 8); + } + else + { + uint32 quotient; + uint16 remainder; + uint32 dividend = (uint32)(s7r.reg4820 | (s7r.reg4821 << 8) | + (s7r.reg4822 << 16) | (s7r.reg4823 << 24)); + uint16 divisor = (uint16)(s7r.reg4826 | (s7r.reg4827 << 8)); + if (divisor != 0) + { + quotient = (uint32)(dividend / divisor); + remainder = (uint16)(dividend % divisor); + } + else + { + quotient = 0; + remainder = dividend & 0x0000FFFF; + } + s7r.reg4828 = (uint8)(quotient & 0x000000FF); + s7r.reg4829 = (uint8)((quotient & 0x0000FF00) >> 8); + s7r.reg482A = (uint8)((quotient & 0x00FF0000) >> 16); + s7r.reg482B = (uint8)((quotient & 0xFF000000) >> 24); + s7r.reg482C = (uint8)remainder & 0x00FF; + s7r.reg482D = (uint8)((remainder & 0xFF00) >> 8); + } + s7r.reg482F = 0x80; + break; + //result registers are possibly read-only + + //reset: writes here nuke the whole math unit + //Zero indicates unsigned math, resets with non-zero values turn on signed math + case 0x482E: + s7r.reg4820 = s7r.reg4821 = s7r.reg4822 = s7r.reg4823 = s7r.reg4824 = + s7r.reg4825 = s7r.reg4826 = s7r.reg4827 = s7r.reg4828 = s7r.reg4829 = + s7r.reg482A = s7r.reg482B = s7r.reg482C = s7r.reg482D = 0; + s7r.reg482E = data; + break; + + //math status register possibly read only + + //SRAM toggle + case 0x4830: SPC7110Sram(data); - s7r.reg4830=data; - break; - //Bank DX mapping - case 0x4831: - s7r.reg4831=data; - break; - //Bank EX mapping - case 0x4832: - s7r.reg4832=data; - break; - //Bank FX mapping - case 0x4833: - s7r.reg4833=data; - break; - //S-RAM mapping? who knows? - case 0x4834: - s7r.reg4834=data; - break; - //RTC Toggle - case 0x4840: - if(0==data) - { - S9xUpdateRTC(); - // rtc_f9.init=false; - // rtc_f9.index=-1; - } - if(data&0x01) - { - s7r.reg4842=0x80; - //rtc_f9.last_used=time(NULL);//???? - rtc_f9.init=false; - rtc_f9.index=-1; - } - s7r.reg4840=data; - break; - //RTC init/command/index register - case 0x4841: - if(rtc_f9.init) - { - if(-1==rtc_f9.index) - { - rtc_f9.index=data&0x0F; - break; - } - if(rtc_f9.control==0x0C) - { - rtc_f9.index=data&0x0F; - s7r.reg4842=0x80; - rtc_f9.last_used=time(NULL); - } - else - { - - if(0x0D==rtc_f9.index) - { - if(data&0x08) - { - if(rtc_f9.reg[1]<3) - { - S9xUpdateRTC(); - rtc_f9.reg[0]=0; - rtc_f9.reg[1]=0; - rtc_f9.last_used=time(NULL); - } - else - { - S9xUpdateRTC(); - rtc_f9.reg[0]=0; - rtc_f9.reg[1]=0; - rtc_f9.last_used=time(NULL)-60; - S9xUpdateRTC(); - rtc_f9.last_used=time(NULL); - } - data&=0x07; - } - if(rtc_f9.reg[0x0D]&0x01) - { - if(!(data%2)) - { - rtc_f9.reg[rtc_f9.index&0x0F]=data; - rtc_f9.last_used=time(NULL)-1; - S9xUpdateRTC(); - rtc_f9.last_used=time(NULL); - } - } - } - if(0x0F==rtc_f9.index) - { - if(data&0x01&&!(rtc_f9.reg[0x0F]&0x01)) - { - S9xUpdateRTC(); - rtc_f9.reg[0]=0; - rtc_f9.reg[1]=0; - rtc_f9.last_used=time(NULL); - } - if(data&0x02&&!(rtc_f9.reg[0x0F]&0x02)) - { - S9xUpdateRTC(); - rtc_f9.last_used=time(NULL); - } - } - rtc_f9.reg[rtc_f9.index&0x0F]=data; - s7r.reg4842=0x80; - rtc_f9.index=(rtc_f9.index+1)%0x10; - } - } - else - { - if(data==0x03||data==0x0C) - { - rtc_f9.init=true; - rtc_f9.control=data; - rtc_f9.index=-1; - } - } - break; - //writes to RTC status register aren't expected to be meaningful - default: - Address-=0x4800; - break; - //16 BIT MULTIPLIER: ($FF00) high byte, defval:00 - } + s7r.reg4830 = data; + break; + //Bank DX mapping + case 0x4831: + s7r.reg4831 = data; + break; + //Bank EX mapping + case 0x4832: + s7r.reg4832 = data; + break; + //Bank FX mapping + case 0x4833: + s7r.reg4833 = data; + break; + //S-RAM mapping? who knows? + case 0x4834: + s7r.reg4834 = data; + break; + //RTC Toggle + case 0x4840: + if (0 == data) + { + S9xUpdateRTC(); + // rtc_f9.init=false; + // rtc_f9.index=-1; + } + if (data & 0x01) + { + s7r.reg4842 = 0x80; + //rtc_f9.last_used=time(NULL);//???? + rtc_f9.init = false; + rtc_f9.index = -1; + } + s7r.reg4840 = data; + break; + //RTC init/command/index register + case 0x4841: + if (rtc_f9.init) + { + if (-1 == rtc_f9.index) + { + rtc_f9.index = data & 0x0F; + break; + } + if (rtc_f9.control == 0x0C) + { + rtc_f9.index = data & 0x0F; + s7r.reg4842 = 0x80; + rtc_f9.last_used = time(NULL); + } + else + { + + if (0x0D == rtc_f9.index) + { + if (data & 0x08) + { + if (rtc_f9.reg[1] < 3) + { + S9xUpdateRTC(); + rtc_f9.reg[0] = 0; + rtc_f9.reg[1] = 0; + rtc_f9.last_used = time(NULL); + } + else + { + S9xUpdateRTC(); + rtc_f9.reg[0] = 0; + rtc_f9.reg[1] = 0; + rtc_f9.last_used = time(NULL) - 60; + S9xUpdateRTC(); + rtc_f9.last_used = time(NULL); + } + data &= 0x07; + } + if (rtc_f9.reg[0x0D] & 0x01) + { + if (!(data % 2)) + { + rtc_f9.reg[rtc_f9.index & 0x0F] = data; + rtc_f9.last_used = time(NULL) - 1; + S9xUpdateRTC(); + rtc_f9.last_used = time(NULL); + } + } + } + if (0x0F == rtc_f9.index) + { + if (data & 0x01 && !(rtc_f9.reg[0x0F] & 0x01)) + { + S9xUpdateRTC(); + rtc_f9.reg[0] = 0; + rtc_f9.reg[1] = 0; + rtc_f9.last_used = time(NULL); + } + if (data & 0x02 && !(rtc_f9.reg[0x0F] & 0x02)) + { + S9xUpdateRTC(); + rtc_f9.last_used = time(NULL); + } + } + rtc_f9.reg[rtc_f9.index & 0x0F] = data; + s7r.reg4842 = 0x80; + rtc_f9.index = (rtc_f9.index + 1) % 0x10; + } + } + else + { + if (data == 0x03 || data == 0x0C) + { + rtc_f9.init = true; + rtc_f9.control = data; + rtc_f9.index = -1; + } + } + break; + //writes to RTC status register aren't expected to be meaningful + default: + Address -= 0x4800; + break; + //16 BIT MULTIPLIER: ($FF00) high byte, defval:00 + } } //emulate the SPC7110's ability to remap banks Dx, Ex, and Fx. uint8 S9xGetSPC7110Byte(uint32 Address) { - uint32 i; - switch((Address&0x00F00000)>>16) - { - case 0xD0: - i=s7r.reg4831*0x00100000; - break; - case 0xE0: - i=s7r.reg4832*0x00100000; - break; - case 0xF0: - i=s7r.reg4833*0x00100000; - break; - default:i=0; - } - i+=Address&0x000FFFFF; - i+=s7r.DataRomOffset; + uint32 i; + switch ((Address & 0x00F00000) >> 16) + { + case 0xD0: + i = s7r.reg4831 * 0x00100000; + break; + case 0xE0: + i = s7r.reg4832 * 0x00100000; + break; + case 0xF0: + i = s7r.reg4833 * 0x00100000; + break; + default: + i = 0; + } + i += Address & 0x000FFFFF; + i += s7r.DataRomOffset; return Memory.ROM[i]; } /**********************************************************************************************/ /* S9xSRTCDaysInMonth() */ /* Return the number of days in a specific month for a certain year */ -/* copied directly for RTC functionality, separated in case of incompatibilities */ +/* copied directly for RTC functionality, separated in case of incompatibilities */ /**********************************************************************************************/ -int S9xRTCDaysInMonth( int month, int year ) +int S9xRTCDaysInMonth(int month, int year) { - int mdays; - - switch ( month ) - { - case 2: - if ( ( year % 4 == 0 ) ) // DKJM2 only uses 199x - 22xx - mdays = 29; - else - mdays = 28; - break; - - case 4: - case 6: - case 9: - case 11: - mdays = 30; - break; - - default: // months 1,3,5,7,8,10,12 - mdays = 31; - break; - } - - return mdays; + int mdays; + + switch (month) + { + case 2: + if ((year % 4 == 0)) // DKJM2 only uses 199x - 22xx + mdays = 29; + else + mdays = 28; + break; + + case 4: + case 6: + case 9: + case 11: + mdays = 30; + break; + + default: // months 1,3,5,7,8,10,12 + mdays = 31; + break; + } + + return mdays; } @@ -1461,166 +1500,158 @@ int S9xRTCDaysInMonth( int month, int year ) /**********************************************************************************************/ -/* S9xUpdateRTC() */ -/* Advance the RTC time */ +/* S9xUpdateRTC() */ +/* Advance the RTC time */ /**********************************************************************************************/ -void S9xUpdateRTC () +void S9xUpdateRTC() { - time_t cur_systime; - long time_diff; - - // Keep track of game time by computing the number of seconds that pass on the system - // clock and adding the same number of seconds to the RTC clock structure. - - if (rtc_f9.init && 0==(rtc_f9.reg[0x0D]&0x01) && 0==(rtc_f9.reg[0x0F]&0x03)) - { - cur_systime = time (NULL); - - // This method assumes one time_t clock tick is one second - // which should work on PCs and GNU systems. - // If your tick interval is different adjust the - // DAYTICK, HOURTICK, and MINUTETICK defines - - time_diff = (long) (cur_systime - rtc_f9.last_used); - rtc_f9.last_used = cur_systime; - - if ( time_diff > 0 ) - { - int seconds; - int minutes; - int hours; - int days; - int month; - int year; - int temp_days; - - int year_hundreds; - int year_tens; - int year_ones; - - - if ( time_diff > DAYTICKS ) - { - days = time_diff / DAYTICKS; - time_diff = time_diff - days * DAYTICKS; - } - else - { - days = 0; - } - - if ( time_diff > HOURTICKS ) - { - hours = time_diff / HOURTICKS; - time_diff = time_diff - hours * HOURTICKS; - } - else - { - hours = 0; - } - - if ( time_diff > MINUTETICKS ) - { - minutes = time_diff / MINUTETICKS; - time_diff = time_diff - minutes * MINUTETICKS; - } - else - { - minutes = 0; - } - - if ( time_diff > 0 ) - { - seconds = time_diff; - } - else - { - seconds = 0; - } - - - seconds += (rtc_f9.reg[1]*10 + rtc_f9.reg[0]); - if ( seconds >= 60 ) - { - seconds -= 60; - minutes += 1; - } - - minutes += (rtc_f9.reg[3]*10 + rtc_f9.reg[2]); - if ( minutes >= 60 ) - { - minutes -= 60; - hours += 1; - } - - hours += (rtc_f9.reg[5]*10 + rtc_f9.reg[4]); - if ( hours >= 24 ) - { - hours -= 24; - days += 1; - } - - year = rtc_f9.reg[11]*10 + rtc_f9.reg[10]; - year += ( 1900 ); - month = rtc_f9.reg[8]+10*rtc_f9.reg[9]; - rtc_f9.reg[12]+=days; - days += (rtc_f9.reg[7]*10 + rtc_f9.reg[6]); - if ( days > 0 ) - { - while ( days > (temp_days = S9xRTCDaysInMonth( month, year )) ) - { - days -= temp_days; - month += 1; - if ( month > 12 ) - { - year += 1; - month = 1; - } - } - } - - year_tens = year % 100; - year_ones = year_tens % 10; - year_tens /= 10; - year_hundreds = (year - 1000) / 100; - - rtc_f9.reg[0] = seconds % 10; - rtc_f9.reg[1] = seconds / 10; - rtc_f9.reg[2] = minutes % 10; - rtc_f9.reg[3] = minutes / 10; - rtc_f9.reg[4] = hours % 10; - rtc_f9.reg[5] = hours / 10; - rtc_f9.reg[6] = days % 10; - rtc_f9.reg[7] = days / 10; - rtc_f9.reg[8] = month%10; - rtc_f9.reg[9] = month /10; - rtc_f9.reg[10] = year_ones; - rtc_f9.reg[11] = year_tens; - rtc_f9.reg[12] %= 7; - return; - } - } + time_t cur_systime; + long time_diff; + + // Keep track of game time by computing the number of seconds that pass on the system + // clock and adding the same number of seconds to the RTC clock structure. + + if (rtc_f9.init && 0 == (rtc_f9.reg[0x0D] & 0x01) + && 0 == (rtc_f9.reg[0x0F] & 0x03)) + { + cur_systime = time(NULL); + + // This method assumes one time_t clock tick is one second + // which should work on PCs and GNU systems. + // If your tick interval is different adjust the + // DAYTICK, HOURTICK, and MINUTETICK defines + + time_diff = (long)(cur_systime - rtc_f9.last_used); + rtc_f9.last_used = cur_systime; + + if (time_diff > 0) + { + int seconds; + int minutes; + int hours; + int days; + int month; + int year; + int temp_days; + + int year_hundreds; + int year_tens; + int year_ones; + + + if (time_diff > DAYTICKS) + { + days = time_diff / DAYTICKS; + time_diff = time_diff - days * DAYTICKS; + } + else + days = 0; + + if (time_diff > HOURTICKS) + { + hours = time_diff / HOURTICKS; + time_diff = time_diff - hours * HOURTICKS; + } + else + hours = 0; + + if (time_diff > MINUTETICKS) + { + minutes = time_diff / MINUTETICKS; + time_diff = time_diff - minutes * MINUTETICKS; + } + else + minutes = 0; + + if (time_diff > 0) + seconds = time_diff; + else + seconds = 0; + + + seconds += (rtc_f9.reg[1] * 10 + rtc_f9.reg[0]); + if (seconds >= 60) + { + seconds -= 60; + minutes += 1; + } + + minutes += (rtc_f9.reg[3] * 10 + rtc_f9.reg[2]); + if (minutes >= 60) + { + minutes -= 60; + hours += 1; + } + + hours += (rtc_f9.reg[5] * 10 + rtc_f9.reg[4]); + if (hours >= 24) + { + hours -= 24; + days += 1; + } + + year = rtc_f9.reg[11] * 10 + rtc_f9.reg[10]; + year += (1900); + month = rtc_f9.reg[8] + 10 * rtc_f9.reg[9]; + rtc_f9.reg[12] += days; + days += (rtc_f9.reg[7] * 10 + rtc_f9.reg[6]); + if (days > 0) + { + while (days > (temp_days = S9xRTCDaysInMonth(month, year))) + { + days -= temp_days; + month += 1; + if (month > 12) + { + year += 1; + month = 1; + } + } + } + + year_tens = year % 100; + year_ones = year_tens % 10; + year_tens /= 10; + year_hundreds = (year - 1000) / 100; + + rtc_f9.reg[0] = seconds % 10; + rtc_f9.reg[1] = seconds / 10; + rtc_f9.reg[2] = minutes % 10; + rtc_f9.reg[3] = minutes / 10; + rtc_f9.reg[4] = hours % 10; + rtc_f9.reg[5] = hours / 10; + rtc_f9.reg[6] = days % 10; + rtc_f9.reg[7] = days / 10; + rtc_f9.reg[8] = month % 10; + rtc_f9.reg[9] = month / 10; + rtc_f9.reg[10] = year_ones; + rtc_f9.reg[11] = year_tens; + rtc_f9.reg[12] %= 7; + return; + } + } } //allows DMA from the ROM (is this even possible on the SPC7110? uint8* Get7110BasePtr(uint32 Address) { - uint32 i; - switch((Address&0x00F00000)>>16) - { - case 0xD0: - i=s7r.reg4831*0x100000; - break; - case 0xE0: - i=s7r.reg4832*0x100000; - break; - case 0xF0: - i=s7r.reg4833*0x100000; - break; - default:i=0; - } - i+=Address&0x000F0000; + uint32 i; + switch ((Address & 0x00F00000) >> 16) + { + case 0xD0: + i = s7r.reg4831 * 0x100000; + break; + case 0xE0: + i = s7r.reg4832 * 0x100000; + break; + case 0xF0: + i = s7r.reg4833 * 0x100000; + break; + default: + i = 0; + } + i += Address & 0x000F0000; return &Memory.ROM[i]; } @@ -1629,391 +1660,386 @@ uint8* Get7110BasePtr(uint32 Address) //format index (1)-table(3)-file offset(4)-length(4) bool Load7110Index(char* filename) { - FILE* fp; - uint8 buffer[12]; - int table=0; - uint8 index=0; - uint32 offset=0; - uint32 size=0; - int i=0; - fp=fopen(filename, "rb"); - if(NULL==fp) - return false; - - int f_len; - //do - while(1) - { - i=0; - f_len= fread(buffer, 1, 12,fp); - if(f_len < 12) break; - - table=(buffer[3]<<16)|(buffer[2]<<8)|buffer[1]; - index=buffer[0]; - offset=(buffer[7]<<24)|(buffer[6]<<16)|(buffer[5]<<8)|buffer[4]; - size=(buffer[11]<<24)|(buffer[10]<<16)|(buffer[9]<<8)|buffer[8]; - while(itableEnts[i].table!=table&&decompack->tableEnts[i].table!=0) - i++; - if(i==MAX_TABLES) - return false; - //added - decompack->tableEnts[i].table=table; - //----- - decompack->tableEnts[i].location[index].offset=offset; - decompack->tableEnts[i].location[index].size=size; - decompack->tableEnts[i].location[index].used_len=0; - decompack->tableEnts[i].location[index].used_offset=0; - - } - //while(!feof(fp)); - fclose(fp); - return true; + FILE* fp; + uint8 buffer[12]; + int table = 0; + uint8 index = 0; + uint32 offset = 0; + uint32 size = 0; + int i = 0; + fp = fopen(filename, "rb"); + if (NULL == fp) + return false; + + int f_len; + //do + while (1) + { + i = 0; + f_len = fread(buffer, 1, 12, fp); + if (f_len < 12) break; + + table = (buffer[3] << 16) | (buffer[2] << 8) | buffer[1]; + index = buffer[0]; + offset = (buffer[7] << 24) | (buffer[6] << 16) | (buffer[5] << 8) | buffer[4]; + size = (buffer[11] << 24) | (buffer[10] << 16) | (buffer[9] << 8) | buffer[8]; + while (i < MAX_TABLES && decompack->tableEnts[i].table != table + && decompack->tableEnts[i].table != 0) + i++; + if (i == MAX_TABLES) + return false; + //added + decompack->tableEnts[i].table = table; + //----- + decompack->tableEnts[i].location[index].offset = offset; + decompack->tableEnts[i].location[index].size = size; + decompack->tableEnts[i].location[index].used_len = 0; + decompack->tableEnts[i].location[index].used_offset = 0; + + } + //while(!feof(fp)); + fclose(fp); + return true; } //Cache 1 load function void SPC7110Load(char* dirname) { - char temp_path[PATH_MAX]; - int i=0; + char temp_path[PATH_MAX]; + int i = 0; - decompack=(Pack7110*)malloc(sizeof(Pack7110)); + decompack = (Pack7110*)malloc(sizeof(Pack7110)); #ifndef _XBOX - getcwd(temp_path,PATH_MAX); + getcwd(temp_path, PATH_MAX); #endif - ZeroMemory(decompack, sizeof(Pack7110)); - + ZeroMemory(decompack, sizeof(Pack7110)); + #ifndef _XBOX - if(-1==chdir(dirname)) - { - S9xMessage(0,0,"Graphics Pack not found!"); - } + if (-1 == chdir(dirname)) + S9xMessage(0, 0, "Graphics Pack not found!"); #endif #ifndef _XBOX - Load7110Index("index.bin"); + Load7110Index("index.bin"); #else - // D:\\ is always app.path in Xbox - Load7110Index("d:\\index.bin"); + // D:\\ is always app.path in Xbox + Load7110Index("d:\\index.bin"); #endif - for(i=0;itableEnts[i].table!=0) - { - char binname[PATH_MAX]; + for (i = 0; i < MAX_TABLES; i++) + { + if (decompack->tableEnts[i].table != 0) + { + char binname[PATH_MAX]; #ifndef _XBOX - sprintf(binname,"%06X.bin",decompack->tableEnts[i].table); + sprintf(binname, "%06X.bin", decompack->tableEnts[i].table); #else - sprintf(binname,"%s%06X.bin",filename,decompack->tableEnts[i].table); + sprintf(binname, "%s%06X.bin", filename, decompack->tableEnts[i].table); #endif - struct stat buf; - if(-1!=stat(binname, &buf)) - decompack->binfiles[i]=(uint8*)malloc(buf.st_size); - FILE* fp=fopen(binname, "rb"); - if(fp) - { - fread(decompack->binfiles[i],buf.st_size,1,fp); - fclose(fp); - } - } - } - -#ifndef _XBOX - chdir(temp_path); + struct stat buf; + if (-1 != stat(binname, &buf)) + decompack->binfiles[i] = (uint8*)malloc(buf.st_size); + FILE* fp = fopen(binname, "rb"); + if (fp) + { + fread(decompack->binfiles[i], buf.st_size, 1, fp); + fclose(fp); + } + } + } + +#ifndef _XBOX + chdir(temp_path); #endif - Copy7110=&MovePackData; - CleanUp7110=&Del7110Gfx; + Copy7110 = &MovePackData; + CleanUp7110 = &Del7110Gfx; #ifdef __WIN32__ - #ifndef _XBOX - EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_ENABLED); - #endif +#ifndef _XBOX + EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_ENABLED); +#endif #endif } //Cache 2 load function void SPC7110Open(char* dirname) { - char temp_path[PATH_MAX]; - int i=0; + char temp_path[PATH_MAX]; + int i = 0; - decompack=(Pack7110*)malloc(sizeof(Pack7110)); + decompack = (Pack7110*)malloc(sizeof(Pack7110)); #ifndef _XBOX - getcwd(temp_path,PATH_MAX); + getcwd(temp_path, PATH_MAX); #endif - ZeroMemory(decompack, sizeof(Pack7110)); - + ZeroMemory(decompack, sizeof(Pack7110)); + #ifndef _XBOX - if(-1==chdir(dirname)) - { - S9xMessage(0,0,"Graphics Pack not found!"); - } + if (-1 == chdir(dirname)) + S9xMessage(0, 0, "Graphics Pack not found!"); #endif #ifndef _XBOX - Load7110Index("index.bin"); + Load7110Index("index.bin"); #else - // D:\\ is always app.path in Xbox - Load7110Index("d:\\index.bin"); + // D:\\ is always app.path in Xbox + Load7110Index("d:\\index.bin"); #endif - for (i=0; ibinfiles[i]=NULL; + for (i = 0; i < MAX_TABLES; i++) + decompack->binfiles[i] = NULL; - ReadPackData(); + ReadPackData(); #ifndef _XBOX - chdir(temp_path); + chdir(temp_path); #endif - Copy7110=&ReadPackData; - CleanUp7110=&Close7110Gfx; + Copy7110 = &ReadPackData; + CleanUp7110 = &Close7110Gfx; #ifdef __WIN32__ - #ifndef _XBOX - EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_ENABLED); - #endif +#ifndef _XBOX + EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_ENABLED); +#endif #endif } //Cache 3's load function void SPC7110Grab(char* dirname) { - char temp_path[PATH_MAX]; - int i=0; + char temp_path[PATH_MAX]; + int i = 0; - decompack=(Pack7110*)malloc(sizeof(Pack7110)); + decompack = (Pack7110*)malloc(sizeof(Pack7110)); #ifndef _XBOX - getcwd(temp_path,PATH_MAX); + getcwd(temp_path, PATH_MAX); #endif - int32 buffer_size=1024*1024*cacheMegs;//*some setting + int32 buffer_size = 1024 * 1024 * cacheMegs; //*some setting - ZeroMemory(decompack, sizeof(Pack7110)); + ZeroMemory(decompack, sizeof(Pack7110)); #ifndef _XBOX - - if(-1==chdir(dirname)) - { - S9xMessage(0,0,"Graphics Pack not found!"); - } + + if (-1 == chdir(dirname)) + S9xMessage(0, 0, "Graphics Pack not found!"); #endif #ifndef _XBOX - Load7110Index("index.bin"); + Load7110Index("index.bin"); #else - // D:\\ is always app.path in Xbox - Load7110Index("d:\\index.bin"); + // D:\\ is always app.path in Xbox + Load7110Index("d:\\index.bin"); #endif - for(i=0;itableEnts[i].table!=0) - { - char binname[PATH_MAX]; + for (i = 0; i < MAX_TABLES; i++) + { + if (decompack->tableEnts[i].table != 0) + { + char binname[PATH_MAX]; #ifndef _XBOX - sprintf(binname,"%06X.bin",decompack->tableEnts[i].table); + sprintf(binname, "%06X.bin", decompack->tableEnts[i].table); #else - sprintf(binname,"%s%06X.bin",filename,decompack->tableEnts[i].table); + sprintf(binname, "%s%06X.bin", filename, decompack->tableEnts[i].table); #endif - struct stat buf; -//add load/no load calculations here - if(-1!=stat(binname, &buf)) - { - if(buf.st_sizebinfiles[i]=(uint8*)malloc(buf.st_size); - FILE* fp=fopen(binname, "rb"); - //use them here - if(fp) - { - if(buf.st_sizebinfiles[i],buf.st_size,1,fp); - fclose(fp); - buffer_size-=buf.st_size; - decompack->tableEnts[i].is_file=false; - } - else - { - decompack->binfiles[i]=(uint8*)fp; - decompack->tableEnts[i].is_file=true; - } - } - } - } - } + struct stat buf; + //add load/no load calculations here + if (-1 != stat(binname, &buf)) + { + if (buf.st_size < buffer_size) + decompack->binfiles[i] = (uint8*)malloc(buf.st_size); + FILE* fp = fopen(binname, "rb"); + //use them here + if (fp) + { + if (buf.st_size < buffer_size) + { + fread(decompack->binfiles[i], buf.st_size, 1, fp); + fclose(fp); + buffer_size -= buf.st_size; + decompack->tableEnts[i].is_file = false; + } + else + { + decompack->binfiles[i] = (uint8*)fp; + decompack->tableEnts[i].is_file = true; + } + } + } + } + } #ifndef _XBOX - chdir(temp_path); + chdir(temp_path); #endif - Copy7110=&GetPackData; - CleanUp7110=&Drop7110Gfx; + Copy7110 = &GetPackData; + CleanUp7110 = &Drop7110Gfx; #ifdef __WIN32__ - #ifndef _XBOX - EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_ENABLED); - #endif +#ifndef _XBOX + EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_ENABLED); +#endif #endif } //Cache 1 clean up function void Del7110Gfx() { - int i; - if(Settings.SPC7110) - { + int i; + if (Settings.SPC7110) + { #ifdef __WIN32__ - #ifndef _XBOX - EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_GRAYED); - #endif +#ifndef _XBOX + EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_GRAYED); #endif - Do7110Logging(); - } - for(i=0;ibinfiles[i]!=NULL) - { +#endif + Do7110Logging(); + } + for (i = 0; i < MAX_TABLES; i++) + { + if (decompack->binfiles[i] != NULL) + { free(decompack->binfiles[i]); - decompack->binfiles[i]=NULL; - } - } - Settings.SPC7110=false; - Settings.SPC7110RTC=false; - if(NULL!=decompack) + decompack->binfiles[i] = NULL; + } + } + Settings.SPC7110 = false; + Settings.SPC7110RTC = false; + if (NULL != decompack) free(decompack); - decompack=NULL; - CleanUp7110=NULL; - Copy7110=NULL; + decompack = NULL; + CleanUp7110 = NULL; + Copy7110 = NULL; } //Cache2 cleanup function void Close7110Gfx() { - int i; - if(Settings.SPC7110) - { + int i; + if (Settings.SPC7110) + { #ifdef __WIN32__ - #ifndef _XBOX - EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_GRAYED); - #endif +#ifndef _XBOX + EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_GRAYED); #endif - Do7110Logging(); - } - for(i=0;ibinfiles[i]!=NULL) - { - fclose((FILE*)decompack->binfiles[i]); - decompack->binfiles[i]=NULL; - } - } - Settings.SPC7110=false; - Settings.SPC7110RTC=false; - if(NULL!=decompack) +#endif + Do7110Logging(); + } + for (i = 0; i < MAX_TABLES; i++) + { + if (decompack->binfiles[i] != NULL) + { + fclose((FILE*)decompack->binfiles[i]); + decompack->binfiles[i] = NULL; + } + } + Settings.SPC7110 = false; + Settings.SPC7110RTC = false; + if (NULL != decompack) free(decompack); - decompack=NULL; - CleanUp7110=NULL; - Copy7110=NULL; + decompack = NULL; + CleanUp7110 = NULL; + Copy7110 = NULL; } //cache 3's clean-up code void Drop7110Gfx() { - int i; - if(Settings.SPC7110) - { + int i; + if (Settings.SPC7110) + { #ifdef __WIN32__ - #ifndef _XBOX - EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_GRAYED); - #endif +#ifndef _XBOX + EnableMenuItem(GUI.hMenu, IDM_LOG_7110, MF_GRAYED); #endif - Do7110Logging(); - } - for(i=0;ibinfiles[i]!=NULL) - { - if(decompack->tableEnts[i].is_file) - { - fclose((FILE*)decompack->binfiles[i]); - decompack->binfiles[i]=NULL; - } - else - { +#endif + Do7110Logging(); + } + for (i = 0; i < MAX_TABLES; i++) + { + if (decompack->binfiles[i] != NULL) + { + if (decompack->tableEnts[i].is_file) + { + fclose((FILE*)decompack->binfiles[i]); + decompack->binfiles[i] = NULL; + } + else + { free(decompack->binfiles[i]); - decompack->binfiles[i]=NULL; - } - } - } - Settings.SPC7110=false; - Settings.SPC7110RTC=false; - if(NULL!=decompack) + decompack->binfiles[i] = NULL; + } + } + } + Settings.SPC7110 = false; + Settings.SPC7110RTC = false; + if (NULL != decompack) free(decompack); - decompack=NULL; - CleanUp7110=NULL; - Copy7110=NULL; + decompack = NULL; + CleanUp7110 = NULL; + Copy7110 = NULL; } //emulate a reset. void S9xSpc7110Reset() { - s7r.reg4800=0; - s7r.reg4801=0; - s7r.reg4802=0; - s7r.reg4803=0; - s7r.reg4804=0; - s7r.reg4805=0; - s7r.reg4806=0; - s7r.reg4807=0; - s7r.reg4808=0; - s7r.reg4809=0; - s7r.reg480A=0; - s7r.reg480B=0; - s7r.reg480C=0; - s7r.reg4811=0; - s7r.reg4812=0; - s7r.reg4813=0; - s7r.reg4814=0; - s7r.reg4815=0; - s7r.reg4816=0; - s7r.reg4817=0; - s7r.reg4818=0; - s7r.reg4820=0; - s7r.reg4821=0; - s7r.reg4822=0; - s7r.reg4823=0; - s7r.reg4824=0; - s7r.reg4825=0; - s7r.reg4826=0; - s7r.reg4827=0; - s7r.reg4828=0; - s7r.reg4829=0; - s7r.reg482A=0; - s7r.reg482B=0; - s7r.reg482C=0; - s7r.reg482D=0; - s7r.reg482E=0; - s7r.reg482F=0; - s7r.reg4830=0; - s7r.reg4831=0; - s7r.reg4832=1; - s7r.reg4833=2; - s7r.reg4834=0; - s7r.reg4840=0; - s7r.reg4841=0; - s7r.reg4842=0; - s7r.written=0; - s7r.offset_add=0; - s7r.AlignBy=1; - s7r.bank50Internal=0; - memset(s7r.bank50,0x00,DECOMP_BUFFER_SIZE); + s7r.reg4800 = 0; + s7r.reg4801 = 0; + s7r.reg4802 = 0; + s7r.reg4803 = 0; + s7r.reg4804 = 0; + s7r.reg4805 = 0; + s7r.reg4806 = 0; + s7r.reg4807 = 0; + s7r.reg4808 = 0; + s7r.reg4809 = 0; + s7r.reg480A = 0; + s7r.reg480B = 0; + s7r.reg480C = 0; + s7r.reg4811 = 0; + s7r.reg4812 = 0; + s7r.reg4813 = 0; + s7r.reg4814 = 0; + s7r.reg4815 = 0; + s7r.reg4816 = 0; + s7r.reg4817 = 0; + s7r.reg4818 = 0; + s7r.reg4820 = 0; + s7r.reg4821 = 0; + s7r.reg4822 = 0; + s7r.reg4823 = 0; + s7r.reg4824 = 0; + s7r.reg4825 = 0; + s7r.reg4826 = 0; + s7r.reg4827 = 0; + s7r.reg4828 = 0; + s7r.reg4829 = 0; + s7r.reg482A = 0; + s7r.reg482B = 0; + s7r.reg482C = 0; + s7r.reg482D = 0; + s7r.reg482E = 0; + s7r.reg482F = 0; + s7r.reg4830 = 0; + s7r.reg4831 = 0; + s7r.reg4832 = 1; + s7r.reg4833 = 2; + s7r.reg4834 = 0; + s7r.reg4840 = 0; + s7r.reg4841 = 0; + s7r.reg4842 = 0; + s7r.written = 0; + s7r.offset_add = 0; + s7r.AlignBy = 1; + s7r.bank50Internal = 0; + memset(s7r.bank50, 0x00, DECOMP_BUFFER_SIZE); } @@ -2023,262 +2049,260 @@ void S9xSpc7110Reset() //note the logs are explicitly little-endian, not host byte order. void Do7110Logging() { - uint8 ent_temp; - FILE* flog; - int entries=0; - - if(Settings.SPC7110) - { - //flush last read into logging - (*Copy7110)(); - - if(!strncmp((char*)&Memory.ROM [0xffc0], "SUPER POWER LEAG 4 ", 21)) - { + uint8 ent_temp; + FILE* flog; + int entries = 0; + + if (Settings.SPC7110) + { + //flush last read into logging + (*Copy7110)(); + + if (!strncmp((char*)&Memory.ROM [0xffc0], "SUPER POWER LEAG 4 ", 21)) + { #ifdef _XBOX - flog=fopen("T:\\spl4-sp7.dat","rb"); + flog = fopen("T:\\spl4-sp7.dat", "rb"); #else - flog=fopen("spl4-sp7.dat","rb"); + flog = fopen("spl4-sp7.dat", "rb"); #endif - } - else if(!strncmp((char*)&Memory.ROM [0xffc0], "MOMOTETSU HAPPY ",21)) - { + } + else if (!strncmp((char*)&Memory.ROM [0xffc0], "MOMOTETSU HAPPY ", 21)) + { #ifdef _XBOX - flog=fopen("T:\\smht-sp7.dat","rb"); + flog = fopen("T:\\smht-sp7.dat", "rb"); #else - flog=fopen("smht-sp7.dat","rb"); + flog = fopen("smht-sp7.dat", "rb"); #endif - } - else if(!strncmp((char*)&Memory.ROM [0xffc0], "HU TENGAI MAKYO ZERO ", 21)) - { + } + else if (!strncmp((char*)&Memory.ROM [0xffc0], "HU TENGAI MAKYO ZERO ", 21)) + { #ifdef _XBOX - flog=fopen("T:\\feoezsp7.dat","rb"); + flog = fopen("T:\\feoezsp7.dat", "rb"); #else - flog=fopen("feoezsp7.dat","rb"); + flog = fopen("feoezsp7.dat", "rb"); #endif - } - else if(!strncmp((char*)&Memory.ROM [0xffc0], "JUMP TENGAIMAKYO ZERO",21)) - { + } + else if (!strncmp((char*)&Memory.ROM [0xffc0], "JUMP TENGAIMAKYO ZERO", 21)) + { #ifdef _XBOX - flog=fopen("T:\\sjumpsp7.dat","rb"); + flog = fopen("T:\\sjumpsp7.dat", "rb"); #else - flog=fopen("sjumpsp7.dat","rb"); + flog = fopen("sjumpsp7.dat", "rb"); #endif - } - else - { + } + else + { #ifdef _XBOX - flog=fopen("T:\\misc-sp7.dat","rb"); + flog = fopen("T:\\misc-sp7.dat", "rb"); #else - flog=fopen("misc-sp7.dat","rb"); + flog = fopen("misc-sp7.dat", "rb"); #endif - } - - if(flog) - { - uint8 buffer[8]; - int table=0; - uint16 offset=0; - uint16 length=0; - fseek(flog, 35,0); - - int f_len; - //do - while(1) - { - int i=0; - Data7110 *log=NULL; - f_len= fread(buffer, 1, 8, flog); - if(f_len < 8) break; - - table=buffer[0]|(buffer[1]<<8)|(buffer[2]<<16); - offset=buffer[6]|(buffer[7]<<8); - length=buffer[4]|(buffer[5]<<8); - while(itableEnts[i].table==table) - { - log=&(decompack->tableEnts[i].location[(buffer[3])]); - if((log->used_offset+log->used_len)<(offset+length)) - { - log->used_offset=offset; - log->used_len=length; - } - } - i++; - } - } - //while(!feof(flog)); - fclose(flog); - } - - - if(!strncmp((char*)&Memory.ROM [0xffc0], "SUPER POWER LEAG 4 ", 21)) - { -#ifdef _XBOX // cwd could be the dvd-rom, so write to T:\\ which is storage region for each title - flog=fopen("T:\\spl4-sp7.dat","wb"); + } + + if (flog) + { + uint8 buffer[8]; + int table = 0; + uint16 offset = 0; + uint16 length = 0; + fseek(flog, 35, 0); + + int f_len; + //do + while (1) + { + int i = 0; + Data7110* log = NULL; + f_len = fread(buffer, 1, 8, flog); + if (f_len < 8) break; + + table = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16); + offset = buffer[6] | (buffer[7] << 8); + length = buffer[4] | (buffer[5] << 8); + while (i < MAX_TABLES && log == NULL) + { + if (decompack->tableEnts[i].table == table) + { + log = &(decompack->tableEnts[i].location[(buffer[3])]); + if ((log->used_offset + log->used_len) < (offset + length)) + { + log->used_offset = offset; + log->used_len = length; + } + } + i++; + } + } + //while(!feof(flog)); + fclose(flog); + } + + + if (!strncmp((char*)&Memory.ROM [0xffc0], "SUPER POWER LEAG 4 ", 21)) + { +#ifdef _XBOX // cwd could be the dvd-rom, so write to T:\\ which is storage region for each title + flog = fopen("T:\\spl4-sp7.dat", "wb"); #else - flog=fopen("spl4-sp7.dat","wb"); + flog = fopen("spl4-sp7.dat", "wb"); #endif - } - else if(!strncmp((char*)&Memory.ROM [0xffc0], "MOMOTETSU HAPPY ",21)) - { + } + else if (!strncmp((char*)&Memory.ROM [0xffc0], "MOMOTETSU HAPPY ", 21)) + { #ifdef _XBOX - flog=fopen("T:\\smht-sp7.dat","wb"); + flog = fopen("T:\\smht-sp7.dat", "wb"); #else - flog=fopen("smht-sp7.dat","wb"); + flog = fopen("smht-sp7.dat", "wb"); #endif - } - else if(!strncmp((char*)&Memory.ROM [0xffc0], "HU TENGAI MAKYO ZERO ", 21)) - { + } + else if (!strncmp((char*)&Memory.ROM [0xffc0], "HU TENGAI MAKYO ZERO ", 21)) + { #ifdef _XBOX - flog=fopen("T:\\feoezsp7.dat","wb"); + flog = fopen("T:\\feoezsp7.dat", "wb"); #else - flog=fopen("feoezsp7.dat","wb"); + flog = fopen("feoezsp7.dat", "wb"); #endif - } - else if(!strncmp((char*)&Memory.ROM [0xffc0], "JUMP TENGAIMAKYO ZERO",21)) - { + } + else if (!strncmp((char*)&Memory.ROM [0xffc0], "JUMP TENGAIMAKYO ZERO", 21)) + { #ifdef _XBOX - flog=fopen("T:\\sjumpsp7.dat","wb"); + flog = fopen("T:\\sjumpsp7.dat", "wb"); #else - flog=fopen("sjumpsp7.dat","wb"); + flog = fopen("sjumpsp7.dat", "wb"); #endif - } - else - { + } + else + { #ifdef _XBOX - flog=fopen("T:\\misc-sp7.dat","wb"); + flog = fopen("T:\\misc-sp7.dat", "wb"); #else - flog=fopen("misc-sp7.dat","wb"); + flog = fopen("misc-sp7.dat", "wb"); #endif - } - //count entries - if(flog) - { - int j=0; - int temp=0; - for(j=0;jtableEnts[j].location[k].used_len!=0) - entries++; - } - } - ent_temp=entries&0xFF; - fwrite(&ent_temp,1,1,flog); - ent_temp=(entries>>8)&0xFF; - fwrite(&ent_temp,1,1,flog); - ent_temp=(entries>>16)&0xFF; - fwrite(&ent_temp,1,1,flog); - ent_temp=(entries>>24)&0xFF; - fwrite(&ent_temp,1,1,flog); - fwrite(&temp,1,4,flog); - fwrite(&temp,1,4,flog); - fwrite(&temp,1,4,flog); - fwrite(&temp,1,4,flog); - fwrite(&temp,1,4,flog); - fwrite(&temp,1,4,flog); - fwrite(&temp,1,4,flog); - - ent_temp=0; - fwrite(&ent_temp,1,1,flog); - ent_temp=0; - fwrite(&ent_temp,1,1,flog); - ent_temp=0; - fwrite(&ent_temp,1,1,flog); - - for(j=0;jtableEnts[j].location[k].used_len != 0) + entries++; + } + } + ent_temp = entries & 0xFF; + fwrite(&ent_temp, 1, 1, flog); + ent_temp = (entries >> 8) & 0xFF; + fwrite(&ent_temp, 1, 1, flog); + ent_temp = (entries >> 16) & 0xFF; + fwrite(&ent_temp, 1, 1, flog); + ent_temp = (entries >> 24) & 0xFF; + fwrite(&ent_temp, 1, 1, flog); + fwrite(&temp, 1, 4, flog); + fwrite(&temp, 1, 4, flog); + fwrite(&temp, 1, 4, flog); + fwrite(&temp, 1, 4, flog); + fwrite(&temp, 1, 4, flog); + fwrite(&temp, 1, 4, flog); + fwrite(&temp, 1, 4, flog); + + ent_temp = 0; + fwrite(&ent_temp, 1, 1, flog); + ent_temp = 0; + fwrite(&ent_temp, 1, 1, flog); + ent_temp = 0; + fwrite(&ent_temp, 1, 1, flog); + + for (j = 0; j < MAX_TABLES; j++) + { int k; - for(k=0;k<256;k++) - { - if(decompack->tableEnts[j].location[k].used_len!=0) - { - ent_temp=decompack->tableEnts[j].table&0xFF; - fwrite(&ent_temp,1,1,flog);//801 - ent_temp=(decompack->tableEnts[j].table>>8)&0xFF;; - fwrite(&ent_temp,1,1,flog);//802 - ent_temp=(decompack->tableEnts[j].table>>16)&0xFF;; - fwrite(&ent_temp,1,1,flog);//803 - ent_temp=k&0xFF; - fwrite(&ent_temp,1,1,flog);//804 - ent_temp=decompack->tableEnts[j].location[k].used_len&0xFF; - fwrite(&ent_temp,1,1,flog);//lsb of - ent_temp=(decompack->tableEnts[j].location[k].used_len>>8)&0xFF; - fwrite(&ent_temp,1,1,flog);//msb of - ent_temp=(decompack->tableEnts[j].location[k].used_offset)&0xFF; - fwrite(&ent_temp,1,1,flog);//lsb of - ent_temp=(decompack->tableEnts[j].location[k].used_offset>>8)&0xFF; - fwrite(&ent_temp,1,1,flog);//msb of - } - } - } - fwrite(&temp,1,4,flog); - fwrite(&temp,1,4,flog); - fclose(flog); - } - } + for (k = 0; k < 256; k++) + { + if (decompack->tableEnts[j].location[k].used_len != 0) + { + ent_temp = decompack->tableEnts[j].table & 0xFF; + fwrite(&ent_temp, 1, 1, flog); //801 + ent_temp = (decompack->tableEnts[j].table >> 8) & 0xFF;; + fwrite(&ent_temp, 1, 1, flog); //802 + ent_temp = (decompack->tableEnts[j].table >> 16) & 0xFF;; + fwrite(&ent_temp, 1, 1, flog); //803 + ent_temp = k & 0xFF; + fwrite(&ent_temp, 1, 1, flog); //804 + ent_temp = decompack->tableEnts[j].location[k].used_len & 0xFF; + fwrite(&ent_temp, 1, 1, flog); //lsb of + ent_temp = (decompack->tableEnts[j].location[k].used_len >> 8) & 0xFF; + fwrite(&ent_temp, 1, 1, flog); //msb of + ent_temp = (decompack->tableEnts[j].location[k].used_offset) & 0xFF; + fwrite(&ent_temp, 1, 1, flog); //lsb of + ent_temp = (decompack->tableEnts[j].location[k].used_offset >> 8) & 0xFF; + fwrite(&ent_temp, 1, 1, flog); //msb of + } + } + } + fwrite(&temp, 1, 4, flog); + fwrite(&temp, 1, 4, flog); + fclose(flog); + } + } } -bool8 S9xSaveSPC7110RTC (S7RTC *rtc_f9) +bool8 S9xSaveSPC7110RTC(S7RTC* rtc_f9) { - FILE* fp; - - if((fp=fopen(S9xGetFilename(".rtc"), "wb"))==NULL) - return (FALSE); - int i=0; - uint8 temp=0; - for (i=0;i<16;i++) - fwrite(&rtc_f9->reg[i],1,1,fp); - temp=rtc_f9->index&0x00FF; - fwrite(&temp,1,1,fp); - temp=(rtc_f9->index)>>8; - fwrite(&temp,1,1,fp); - temp=(uint8)rtc_f9->control; - fwrite(&temp,1,1,fp); - temp=(uint8)rtc_f9->init; - fwrite(&temp,1,1,fp); - temp=rtc_f9->last_used&0x00FF; - fwrite(&temp,1,1,fp); - temp=(rtc_f9->last_used>>8)&0x00FF; - fwrite(&temp,1,1,fp); - temp=(rtc_f9->last_used>>16)&0x00FF; - fwrite(&temp,1,1,fp); - temp=(rtc_f9->last_used>>24)&0x00FF;; - fwrite(&temp,1,1,fp); - fclose(fp); - return (TRUE); + FILE* fp; + + if ((fp = fopen(S9xGetFilename(".rtc"), "wb")) == NULL) + return (FALSE); + int i = 0; + uint8 temp = 0; + for (i = 0; i < 16; i++) + fwrite(&rtc_f9->reg[i], 1, 1, fp); + temp = rtc_f9->index & 0x00FF; + fwrite(&temp, 1, 1, fp); + temp = (rtc_f9->index) >> 8; + fwrite(&temp, 1, 1, fp); + temp = (uint8)rtc_f9->control; + fwrite(&temp, 1, 1, fp); + temp = (uint8)rtc_f9->init; + fwrite(&temp, 1, 1, fp); + temp = rtc_f9->last_used & 0x00FF; + fwrite(&temp, 1, 1, fp); + temp = (rtc_f9->last_used >> 8) & 0x00FF; + fwrite(&temp, 1, 1, fp); + temp = (rtc_f9->last_used >> 16) & 0x00FF; + fwrite(&temp, 1, 1, fp); + temp = (rtc_f9->last_used >> 24) & 0x00FF;; + fwrite(&temp, 1, 1, fp); + fclose(fp); + return (TRUE); } -bool8 S9xLoadSPC7110RTC (S7RTC *rtc_f9) +bool8 S9xLoadSPC7110RTC(S7RTC* rtc_f9) { - FILE* fp; - - if((fp=fopen(S9xGetFilename(".rtc"), "rb"))==NULL) - return (FALSE); - int i; - for (i=0; i<16;i++) - { - fread(&(rtc_f9->reg[i]),1,1,fp); - } - uint8 temp=0; - fread(&temp,1,1,fp); - rtc_f9->index=temp; - fread(&temp,1,1,fp); - rtc_f9->index|=(temp<<8); - fread(&rtc_f9->control,1,1,fp); - fread(&rtc_f9->init,1,1,fp); - - fread(&temp,1,1,fp); - rtc_f9->last_used=temp; - fread(&temp,1,1,fp); - rtc_f9->last_used|=(temp<<8); - fread(&temp,1,1,fp); - rtc_f9->last_used|=(temp<<16); - fread(&temp,1,1,fp); - rtc_f9->last_used|=(temp<<24); - fclose(fp); - return (TRUE); + FILE* fp; + + if ((fp = fopen(S9xGetFilename(".rtc"), "rb")) == NULL) + return (FALSE); + int i; + for (i = 0; i < 16; i++) + fread(&(rtc_f9->reg[i]), 1, 1, fp); + uint8 temp = 0; + fread(&temp, 1, 1, fp); + rtc_f9->index = temp; + fread(&temp, 1, 1, fp); + rtc_f9->index |= (temp << 8); + fread(&rtc_f9->control, 1, 1, fp); + fread(&rtc_f9->init, 1, 1, fp); + + fread(&temp, 1, 1, fp); + rtc_f9->last_used = temp; + fread(&temp, 1, 1, fp); + rtc_f9->last_used |= (temp << 8); + fread(&temp, 1, 1, fp); + rtc_f9->last_used |= (temp << 16); + fread(&temp, 1, 1, fp); + rtc_f9->last_used |= (temp << 24); + fclose(fp); + return (TRUE); } diff --git a/source/spc7110.h b/source/spc7110.h index 7fd1602..12078d3 100644 --- a/source/spc7110.h +++ b/source/spc7110.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -90,7 +90,7 @@ #define _spc7110_h #include "port.h" -#define DECOMP_BUFFER_SIZE 0x10000 +#define DECOMP_BUFFER_SIZE 0x10000 extern void (*LoadUp7110)(char*); extern void (*CleanUp7110)(void); @@ -104,13 +104,13 @@ void Drop7110Gfx(void); uint8 S9xGetSPC7110(uint16 Address); uint8 S9xGetSPC7110Byte(uint32 Address); uint8* Get7110BasePtr(uint32); -void S9xSetSPC7110 (uint8 data, uint16 Address); +void S9xSetSPC7110(uint8 data, uint16 Address); void S9xSpc7110Init(); uint8* Get7110BasePtr(uint32); void S9xSpc7110Reset(); -void S9xUpdateRTC (); +void S9xUpdateRTC(); void Do7110Logging(); -int S9xRTCDaysInMonth( int month, int year ); +int S9xRTCDaysInMonth(int month, int year); //These are platform-dependant functions, but should work on //most systems that use GNU compilers, and on Win32. @@ -120,74 +120,74 @@ void SPC7110Grab(char*); typedef struct SPC7110RTC { - unsigned char reg[16]; - short index; - uint8 control; - bool init; - time_t last_used; + unsigned char reg[16]; + short index; + uint8 control; + bool init; + time_t last_used; } S7RTC; typedef struct SPC7110EmuVars { - unsigned char reg4800; - unsigned char reg4801; - unsigned char reg4802; - unsigned char reg4803; - unsigned char reg4804; - unsigned char reg4805; - unsigned char reg4806; - unsigned char reg4807; - unsigned char reg4808; - unsigned char reg4809; - unsigned char reg480A; - unsigned char reg480B; - unsigned char reg480C; - unsigned char reg4811; - unsigned char reg4812; - unsigned char reg4813; - unsigned char reg4814; - unsigned char reg4815; - unsigned char reg4816; - unsigned char reg4817; - unsigned char reg4818; - unsigned char reg4820; - unsigned char reg4821; - unsigned char reg4822; - unsigned char reg4823; - unsigned char reg4824; - unsigned char reg4825; - unsigned char reg4826; - unsigned char reg4827; - unsigned char reg4828; - unsigned char reg4829; - unsigned char reg482A; - unsigned char reg482B; - unsigned char reg482C; - unsigned char reg482D; - unsigned char reg482E; - unsigned char reg482F; - unsigned char reg4830; - unsigned char reg4831; - unsigned char reg4832; - unsigned char reg4833; - unsigned char reg4834; - unsigned char reg4840; - unsigned char reg4841; - unsigned char reg4842; - uint8 AlignBy; - uint8 written; - uint8 offset_add; - uint32 DataRomOffset; - uint32 DataRomSize; - uint32 bank50Internal; - uint8 bank50[DECOMP_BUFFER_SIZE]; + unsigned char reg4800; + unsigned char reg4801; + unsigned char reg4802; + unsigned char reg4803; + unsigned char reg4804; + unsigned char reg4805; + unsigned char reg4806; + unsigned char reg4807; + unsigned char reg4808; + unsigned char reg4809; + unsigned char reg480A; + unsigned char reg480B; + unsigned char reg480C; + unsigned char reg4811; + unsigned char reg4812; + unsigned char reg4813; + unsigned char reg4814; + unsigned char reg4815; + unsigned char reg4816; + unsigned char reg4817; + unsigned char reg4818; + unsigned char reg4820; + unsigned char reg4821; + unsigned char reg4822; + unsigned char reg4823; + unsigned char reg4824; + unsigned char reg4825; + unsigned char reg4826; + unsigned char reg4827; + unsigned char reg4828; + unsigned char reg4829; + unsigned char reg482A; + unsigned char reg482B; + unsigned char reg482C; + unsigned char reg482D; + unsigned char reg482E; + unsigned char reg482F; + unsigned char reg4830; + unsigned char reg4831; + unsigned char reg4832; + unsigned char reg4833; + unsigned char reg4834; + unsigned char reg4840; + unsigned char reg4841; + unsigned char reg4842; + uint8 AlignBy; + uint8 written; + uint8 offset_add; + uint32 DataRomOffset; + uint32 DataRomSize; + uint32 bank50Internal; + uint8 bank50[DECOMP_BUFFER_SIZE]; } SPC7110Regs; extern SPC7110Regs s7r; extern S7RTC rtc_f9; // These are defined in spc7110.cpp -bool8 S9xSaveSPC7110RTC (S7RTC *rtc_f9); -bool8 S9xLoadSPC7110RTC (S7RTC *rtc_f9); +bool8 S9xSaveSPC7110RTC(S7RTC* rtc_f9); +bool8 S9xLoadSPC7110RTC(S7RTC* rtc_f9); #endif diff --git a/source/srtc.c b/source/srtc.c index 482ce7b..ba221d4 100644 --- a/source/srtc.c +++ b/source/srtc.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -130,60 +130,60 @@ static int month_keys[12] = { 1, 4, 4, 0, 2, 5, 0, 3, 6, 1, 4, 6 }; * * On save: * - * Call S9xUpdateSrtcTime and save the rtc data structure. + * Call S9xUpdateSrtcTime and save the rtc data structure. * * On load: * - * restore the rtc data structure + * restore the rtc data structure * rtc.system_timestamp = time (NULL); - * + * * *********************************************************************************************/ -void S9xResetSRTC () +void S9xResetSRTC() { - rtc.index = -1; - rtc.mode = MODE_READ; + rtc.index = -1; + rtc.mode = MODE_READ; } -void S9xHardResetSRTC () +void S9xHardResetSRTC() { - ZeroMemory (&rtc, sizeof (rtc)); - rtc.index = -1; - rtc.mode = MODE_READ; - rtc.count_enable = FALSE; - rtc.needs_init = TRUE; - - // Get system timestamp - rtc.system_timestamp = time (NULL); + ZeroMemory(&rtc, sizeof(rtc)); + rtc.index = -1; + rtc.mode = MODE_READ; + rtc.count_enable = FALSE; + rtc.needs_init = TRUE; + + // Get system timestamp + rtc.system_timestamp = time(NULL); } /**********************************************************************************************/ /* S9xSRTCComputeDayOfWeek() */ /* Return 0-6 for Sunday-Saturday */ /**********************************************************************************************/ -unsigned int S9xSRTCComputeDayOfWeek () +unsigned int S9xSRTCComputeDayOfWeek() { - unsigned year = rtc.data[10]*10 + rtc.data[9]; - unsigned month = rtc.data[8]; - unsigned day = rtc.data[7]*10 + rtc.data[6]; - unsigned day_of_week; + unsigned year = rtc.data[10] * 10 + rtc.data[9]; + unsigned month = rtc.data[8]; + unsigned day = rtc.data[7] * 10 + rtc.data[6]; + unsigned day_of_week; - year += (rtc.data[11] - 9) * 100; + year += (rtc.data[11] - 9) * 100; - // Range check the month for valid array indicies - if ( month > 12 ) - month = 1; + // Range check the month for valid array indicies + if (month > 12) + month = 1; - day_of_week = year + (year / 4) + month_keys[month-1] + day - 1; + day_of_week = year + (year / 4) + month_keys[month - 1] + day - 1; - if(( year % 4 == 0 ) && ( month <= 2 ) ) - day_of_week--; + if ((year % 4 == 0) && (month <= 2)) + day_of_week--; - day_of_week %= 7; + day_of_week %= 7; - return day_of_week; + return day_of_week; } @@ -191,32 +191,32 @@ unsigned int S9xSRTCComputeDayOfWeek () /* S9xSRTCDaysInMonth() */ /* Return the number of days in a specific month for a certain year */ /**********************************************************************************************/ -int S9xSRTCDaysInMmonth( int month, int year ) +int S9xSRTCDaysInMmonth(int month, int year) { - int mdays; - - switch ( month ) - { - case 2: - if ( ( year % 4 == 0 ) ) // DKJM2 only uses 199x - 22xx - mdays = 29; - else - mdays = 28; - break; - - case 4: - case 6: - case 9: - case 11: - mdays = 30; - break; - - default: // months 1,3,5,7,8,10,12 - mdays = 31; - break; - } - - return mdays; + int mdays; + + switch (month) + { + case 2: + if ((year % 4 == 0)) // DKJM2 only uses 199x - 22xx + mdays = 29; + else + mdays = 28; + break; + + case 4: + case 6: + case 9: + case 11: + mdays = 30; + break; + + default: // months 1,3,5,7,8,10,12 + mdays = 31; + break; + } + + return mdays; } @@ -229,150 +229,140 @@ int S9xSRTCDaysInMmonth( int month, int year ) /* S9xUpdateSrtcTime() */ /* Advance the S-RTC time if counting is enabled */ /**********************************************************************************************/ -void S9xUpdateSrtcTime () +void S9xUpdateSrtcTime() { - time_t cur_systime; - long time_diff; - - // Keep track of game time by computing the number of seconds that pass on the system - // clock and adding the same number of seconds to the S-RTC clock structure. - // I originally tried using mktime and localtime library functions to keep track - // of time but some of the GNU time functions fail when the year goes to 2099 - // (and maybe less) and this would have caused a bug with DKJM2 so I'm doing - // it this way to get around that problem. - - // Note: Dai Kaijyu Monogatari II only allows dates in the range 1996-21xx. - - if (rtc.count_enable && !rtc.needs_init) - { - cur_systime = time (NULL); - - // This method assumes one time_t clock tick is one second - // which should work on PCs and GNU systems. - // If your tick interval is different adjust the - // DAYTICK, HOURTICK, and MINUTETICK defines - - time_diff = (long) (cur_systime - rtc.system_timestamp); - rtc.system_timestamp = cur_systime; - - if ( time_diff > 0 ) - { - int seconds; - int minutes; - int hours; - int days; - int month; - int year; - int temp_days; - - int year_hundreds; - int year_tens; - int year_ones; - - - if ( time_diff > DAYTICKS ) - { - days = time_diff / DAYTICKS; - time_diff = time_diff - days * DAYTICKS; - } - else - { - days = 0; - } - - if ( time_diff > HOURTICKS ) - { - hours = time_diff / HOURTICKS; - time_diff = time_diff - hours * HOURTICKS; - } - else - { - hours = 0; - } - - if ( time_diff > MINUTETICKS ) - { - minutes = time_diff / MINUTETICKS; - time_diff = time_diff - minutes * MINUTETICKS; - } - else - { - minutes = 0; - } - - if ( time_diff > 0 ) - { - seconds = time_diff; - } - else - { - seconds = 0; - } - - - seconds += (rtc.data[1]*10 + rtc.data[0]); - if ( seconds >= 60 ) - { - seconds -= 60; - minutes += 1; - } - - minutes += (rtc.data[3]*10 + rtc.data[2]); - if ( minutes >= 60 ) - { - minutes -= 60; - hours += 1; - } - - hours += (rtc.data[5]*10 + rtc.data[4]); - if ( hours >= 24 ) - { - hours -= 24; - days += 1; - } - - if ( days > 0 ) - { - year = rtc.data[10]*10 + rtc.data[9]; - year += ( 1000 + rtc.data[11] * 100 ); - - month = rtc.data[8]; - days += (rtc.data[7]*10 + rtc.data[6]); - while ( days > (temp_days = S9xSRTCDaysInMmonth( month, year )) ) + time_t cur_systime; + long time_diff; + + // Keep track of game time by computing the number of seconds that pass on the system + // clock and adding the same number of seconds to the S-RTC clock structure. + // I originally tried using mktime and localtime library functions to keep track + // of time but some of the GNU time functions fail when the year goes to 2099 + // (and maybe less) and this would have caused a bug with DKJM2 so I'm doing + // it this way to get around that problem. + + // Note: Dai Kaijyu Monogatari II only allows dates in the range 1996-21xx. + + if (rtc.count_enable && !rtc.needs_init) + { + cur_systime = time(NULL); + + // This method assumes one time_t clock tick is one second + // which should work on PCs and GNU systems. + // If your tick interval is different adjust the + // DAYTICK, HOURTICK, and MINUTETICK defines + + time_diff = (long)(cur_systime - rtc.system_timestamp); + rtc.system_timestamp = cur_systime; + + if (time_diff > 0) + { + int seconds; + int minutes; + int hours; + int days; + int month; + int year; + int temp_days; + + int year_hundreds; + int year_tens; + int year_ones; + + + if (time_diff > DAYTICKS) + { + days = time_diff / DAYTICKS; + time_diff = time_diff - days * DAYTICKS; + } + else + days = 0; + + if (time_diff > HOURTICKS) + { + hours = time_diff / HOURTICKS; + time_diff = time_diff - hours * HOURTICKS; + } + else + hours = 0; + + if (time_diff > MINUTETICKS) + { + minutes = time_diff / MINUTETICKS; + time_diff = time_diff - minutes * MINUTETICKS; + } + else + minutes = 0; + + if (time_diff > 0) + seconds = time_diff; + else + seconds = 0; + + + seconds += (rtc.data[1] * 10 + rtc.data[0]); + if (seconds >= 60) + { + seconds -= 60; + minutes += 1; + } + + minutes += (rtc.data[3] * 10 + rtc.data[2]); + if (minutes >= 60) + { + minutes -= 60; + hours += 1; + } + + hours += (rtc.data[5] * 10 + rtc.data[4]); + if (hours >= 24) + { + hours -= 24; + days += 1; + } + + if (days > 0) + { + year = rtc.data[10] * 10 + rtc.data[9]; + year += (1000 + rtc.data[11] * 100); + + month = rtc.data[8]; + days += (rtc.data[7] * 10 + rtc.data[6]); + while (days > (temp_days = S9xSRTCDaysInMmonth(month, year))) + { + days -= temp_days; + month += 1; + if (month > 12) { - days -= temp_days; - month += 1; - if ( month > 12 ) - { - year += 1; - month = 1; - } - } - - year_tens = year % 100; - year_ones = year_tens % 10; - year_tens /= 10; - year_hundreds = (year - 1000) / 100; - - rtc.data[6] = days % 10; - rtc.data[7] = days / 10; - rtc.data[8] = month; - rtc.data[9] = year_ones; - rtc.data[10] = year_tens; - rtc.data[11] = year_hundreds; - rtc.data[12] = S9xSRTCComputeDayOfWeek (); - } - - rtc.data[0] = seconds % 10; - rtc.data[1] = seconds / 10; - rtc.data[2] = minutes % 10; - rtc.data[3] = minutes / 10; - rtc.data[4] = hours % 10; - rtc.data[5] = hours / 10; - - return; - } - } + year += 1; + month = 1; + } + } + + year_tens = year % 100; + year_ones = year_tens % 10; + year_tens /= 10; + year_hundreds = (year - 1000) / 100; + + rtc.data[6] = days % 10; + rtc.data[7] = days / 10; + rtc.data[8] = month; + rtc.data[9] = year_ones; + rtc.data[10] = year_tens; + rtc.data[11] = year_hundreds; + rtc.data[12] = S9xSRTCComputeDayOfWeek(); + } + + rtc.data[0] = seconds % 10; + rtc.data[1] = seconds / 10; + rtc.data[2] = minutes % 10; + rtc.data[3] = minutes / 10; + rtc.data[4] = hours % 10; + rtc.data[5] = hours / 10; + + return; + } + } } @@ -380,202 +370,200 @@ void S9xUpdateSrtcTime () /* S9xSetSRTC() */ /* This function sends data to the S-RTC used in Dai Kaijyu Monogatari II */ /**********************************************************************************************/ -void S9xSetSRTC (uint8 data, uint16 Address) +void S9xSetSRTC(uint8 data, uint16 Address) { - data &= 0x0F; // Data is only 4-bits, mask out unused bits. - - if( data >= 0xD ) - { - // It's an RTC command - - switch ( data ) - { - case 0xD: - rtc.mode = MODE_READ; - rtc.index = -1; - break; - - case 0xE: - rtc.mode = MODE_COMMAND; - break; - - default: - // Ignore the write if it's an 0xF ??? - // Probably should switch back to read mode -- but this - // sequence never occurs in DKJM2 - break; - } - - return; - } - - if ( rtc.mode == MODE_LOAD_RTC ) - { - if ( (rtc.index >= 0) || (rtc.index < MAX_RTC_INDEX) ) - { - rtc.data[rtc.index++] = data; - - if ( rtc.index == MAX_RTC_INDEX ) - { - // We have all the data for the RTC load - - rtc.system_timestamp = time (NULL); // Get local system time - - // Get the day of the week - rtc.data[rtc.index++] = S9xSRTCComputeDayOfWeek (); - - // Start RTC counting again - rtc.count_enable = TRUE; - rtc.needs_init = FALSE; - } - - return; - } - else - { - // Attempting to write too much data - // error(); // ignore?? - } - } - else if ( rtc.mode == MODE_COMMAND ) - { - switch( data ) - { - case COMMAND_CLEAR_RTC: - // Disable RTC counter - rtc.count_enable = FALSE; - - ZeroMemory (rtc.data, MAX_RTC_INDEX+1); - rtc.index = -1; - rtc.mode = MODE_COMMAND_DONE; - break; - - case COMMAND_LOAD_RTC: - // Disable RTC counter - rtc.count_enable = FALSE; - - rtc.index = 0; // Setup for writing - rtc.mode = MODE_LOAD_RTC; - break; - - default: - rtc.mode = MODE_COMMAND_DONE; - // unrecognized command - need to implement. - } - - return; - } - else - { - if ( rtc.mode == MODE_READ ) - { - // Attempting to write while in read mode. Ignore. - } - - if ( rtc.mode == MODE_COMMAND_DONE ) - { - // Maybe this isn't an error. Maybe we should kick off - // a new E command. But is this valid? - } - } + data &= 0x0F; // Data is only 4-bits, mask out unused bits. + + if (data >= 0xD) + { + // It's an RTC command + + switch (data) + { + case 0xD: + rtc.mode = MODE_READ; + rtc.index = -1; + break; + + case 0xE: + rtc.mode = MODE_COMMAND; + break; + + default: + // Ignore the write if it's an 0xF ??? + // Probably should switch back to read mode -- but this + // sequence never occurs in DKJM2 + break; + } + + return; + } + + if (rtc.mode == MODE_LOAD_RTC) + { + if ((rtc.index >= 0) || (rtc.index < MAX_RTC_INDEX)) + { + rtc.data[rtc.index++] = data; + + if (rtc.index == MAX_RTC_INDEX) + { + // We have all the data for the RTC load + + rtc.system_timestamp = time(NULL); // Get local system time + + // Get the day of the week + rtc.data[rtc.index++] = S9xSRTCComputeDayOfWeek(); + + // Start RTC counting again + rtc.count_enable = TRUE; + rtc.needs_init = FALSE; + } + + return; + } + else + { + // Attempting to write too much data + // error(); // ignore?? + } + } + else if (rtc.mode == MODE_COMMAND) + { + switch (data) + { + case COMMAND_CLEAR_RTC: + // Disable RTC counter + rtc.count_enable = FALSE; + + ZeroMemory(rtc.data, MAX_RTC_INDEX + 1); + rtc.index = -1; + rtc.mode = MODE_COMMAND_DONE; + break; + + case COMMAND_LOAD_RTC: + // Disable RTC counter + rtc.count_enable = FALSE; + + rtc.index = 0; // Setup for writing + rtc.mode = MODE_LOAD_RTC; + break; + + default: + rtc.mode = MODE_COMMAND_DONE; + // unrecognized command - need to implement. + } + + return; + } + else + { + if (rtc.mode == MODE_READ) + { + // Attempting to write while in read mode. Ignore. + } + + if (rtc.mode == MODE_COMMAND_DONE) + { + // Maybe this isn't an error. Maybe we should kick off + // a new E command. But is this valid? + } + } } /**********************************************************************************************/ /* S9xGetSRTC() */ /* This function retrieves data from the S-RTC */ /**********************************************************************************************/ -uint8 S9xGetSRTC (uint16 Address) +uint8 S9xGetSRTC(uint16 Address) { - if ( rtc.mode == MODE_READ ) - { - if ( rtc.index < 0 ) - { - S9xUpdateSrtcTime (); // Only update it if the game reads it - rtc.index++; - return ( 0x0f ); // Send start marker. - } - else if (rtc.index > MAX_RTC_INDEX) - { - rtc.index = -1; // Setup for next set of reads - return ( 0x0f ); // Data done marker. - } - else - { - // Feed out the data - return rtc.data[rtc.index++]; - } - } - else - { - return 0x0; - } + if (rtc.mode == MODE_READ) + { + if (rtc.index < 0) + { + S9xUpdateSrtcTime(); // Only update it if the game reads it + rtc.index++; + return (0x0f); // Send start marker. + } + else if (rtc.index > MAX_RTC_INDEX) + { + rtc.index = -1; // Setup for next set of reads + return (0x0f); // Data done marker. + } + else + { + // Feed out the data + return rtc.data[rtc.index++]; + } + } + else + return 0x0; } -void S9xSRTCPreSaveState () +void S9xSRTCPreSaveState() { - if (Settings.SRTC) - { - S9xUpdateSrtcTime (); - - int s = Memory.SRAMSize ? - (1 << (Memory.SRAMSize + 3)) * 128 : 0; - if (s > 0x20000) - s = 0x20000; - - Memory.SRAM [s + 0] = rtc.needs_init; - Memory.SRAM [s + 1] = rtc.count_enable; - // memmove converted: Different mallocs [Neb] - memcpy (&Memory.SRAM [s + 2], rtc.data, MAX_RTC_INDEX + 1); - Memory.SRAM [s + 3 + MAX_RTC_INDEX] = rtc.index; - Memory.SRAM [s + 4 + MAX_RTC_INDEX] = rtc.mode; + if (Settings.SRTC) + { + S9xUpdateSrtcTime(); + + int s = Memory.SRAMSize ? + (1 << (Memory.SRAMSize + 3)) * 128 : 0; + if (s > 0x20000) + s = 0x20000; + + Memory.SRAM [s + 0] = rtc.needs_init; + Memory.SRAM [s + 1] = rtc.count_enable; + // memmove converted: Different mallocs [Neb] + memcpy(&Memory.SRAM [s + 2], rtc.data, MAX_RTC_INDEX + 1); + Memory.SRAM [s + 3 + MAX_RTC_INDEX] = rtc.index; + Memory.SRAM [s + 4 + MAX_RTC_INDEX] = rtc.mode; #ifdef LSB_FIRST - // memmove converted: Different mallocs [Neb] - memcpy (&Memory.SRAM [s + 5 + MAX_RTC_INDEX], &rtc.system_timestamp, 8); + // memmove converted: Different mallocs [Neb] + memcpy(&Memory.SRAM [s + 5 + MAX_RTC_INDEX], &rtc.system_timestamp, 8); #else - SRAM [s + 5 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 0); - SRAM [s + 6 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 8); - SRAM [s + 7 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 16); - SRAM [s + 8 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 24); - SRAM [s + 9 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 32); - SRAM [s + 10 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 40); - SRAM [s + 11 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 48); - SRAM [s + 12 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 56); + SRAM [s + 5 + MAX_RTC_INDEX] = (uint8)(rtc.system_timestamp >> 0); + SRAM [s + 6 + MAX_RTC_INDEX] = (uint8)(rtc.system_timestamp >> 8); + SRAM [s + 7 + MAX_RTC_INDEX] = (uint8)(rtc.system_timestamp >> 16); + SRAM [s + 8 + MAX_RTC_INDEX] = (uint8)(rtc.system_timestamp >> 24); + SRAM [s + 9 + MAX_RTC_INDEX] = (uint8)(rtc.system_timestamp >> 32); + SRAM [s + 10 + MAX_RTC_INDEX] = (uint8)(rtc.system_timestamp >> 40); + SRAM [s + 11 + MAX_RTC_INDEX] = (uint8)(rtc.system_timestamp >> 48); + SRAM [s + 12 + MAX_RTC_INDEX] = (uint8)(rtc.system_timestamp >> 56); #endif - } + } } -void S9xSRTCPostLoadState () +void S9xSRTCPostLoadState() { - if (Settings.SRTC) - { - int s = Memory.SRAMSize ? - (1 << (Memory.SRAMSize + 3)) * 128 : 0; - if (s > 0x20000) - s = 0x20000; - - rtc.needs_init = Memory.SRAM [s + 0]; - rtc.count_enable = Memory.SRAM [s + 1]; - // memmove converted: Different mallocs [Neb] - memcpy (rtc.data, &Memory.SRAM [s + 2], MAX_RTC_INDEX + 1); - rtc.index = Memory.SRAM [s + 3 + MAX_RTC_INDEX]; - rtc.mode = Memory.SRAM [s + 4 + MAX_RTC_INDEX]; + if (Settings.SRTC) + { + int s = Memory.SRAMSize ? + (1 << (Memory.SRAMSize + 3)) * 128 : 0; + if (s > 0x20000) + s = 0x20000; + + rtc.needs_init = Memory.SRAM [s + 0]; + rtc.count_enable = Memory.SRAM [s + 1]; + // memmove converted: Different mallocs [Neb] + memcpy(rtc.data, &Memory.SRAM [s + 2], MAX_RTC_INDEX + 1); + rtc.index = Memory.SRAM [s + 3 + MAX_RTC_INDEX]; + rtc.mode = Memory.SRAM [s + 4 + MAX_RTC_INDEX]; #ifdef LSB_FIRST - // memmove converted: Different mallocs [Neb] - memcpy (&rtc.system_timestamp, &Memory.SRAM [s + 5 + MAX_RTC_INDEX], 8); + // memmove converted: Different mallocs [Neb] + memcpy(&rtc.system_timestamp, &Memory.SRAM [s + 5 + MAX_RTC_INDEX], 8); #else - rtc.system_timestamp |= (SRAM [s + 5 + MAX_RTC_INDEX] << 0); - rtc.system_timestamp |= (SRAM [s + 6 + MAX_RTC_INDEX] << 8); - rtc.system_timestamp |= (SRAM [s + 7 + MAX_RTC_INDEX] << 16); - rtc.system_timestamp |= (SRAM [s + 8 + MAX_RTC_INDEX] << 24); - rtc.system_timestamp |= (SRAM [s + 9 + MAX_RTC_INDEX] << 32); - rtc.system_timestamp |= (SRAM [s + 10 + MAX_RTC_INDEX] << 40); - rtc.system_timestamp |= (SRAM [s + 11 + MAX_RTC_INDEX] << 48); - rtc.system_timestamp |= (SRAM [s + 12 + MAX_RTC_INDEX] << 56); + rtc.system_timestamp |= (SRAM [s + 5 + MAX_RTC_INDEX] << 0); + rtc.system_timestamp |= (SRAM [s + 6 + MAX_RTC_INDEX] << 8); + rtc.system_timestamp |= (SRAM [s + 7 + MAX_RTC_INDEX] << 16); + rtc.system_timestamp |= (SRAM [s + 8 + MAX_RTC_INDEX] << 24); + rtc.system_timestamp |= (SRAM [s + 9 + MAX_RTC_INDEX] << 32); + rtc.system_timestamp |= (SRAM [s + 10 + MAX_RTC_INDEX] << 40); + rtc.system_timestamp |= (SRAM [s + 11 + MAX_RTC_INDEX] << 48); + rtc.system_timestamp |= (SRAM [s + 12 + MAX_RTC_INDEX] << 56); #endif - S9xUpdateSrtcTime (); - } + S9xUpdateSrtcTime(); + } } diff --git a/source/srtc.h b/source/srtc.h index 4ee24b0..2158207 100644 --- a/source/srtc.h +++ b/source/srtc.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -131,27 +131,27 @@ Index Description Range (nibble) typedef struct { - bool8 needs_init; - bool8 count_enable; // Does RTC mark time or is it frozen - uint8 data [MAX_RTC_INDEX+1]; - int8 index; - uint8 mode; - - time_t system_timestamp; // Of latest RTC load time - uint32 pad; + bool8 needs_init; + bool8 count_enable; // Does RTC mark time or is it frozen + uint8 data [MAX_RTC_INDEX + 1]; + int8 index; + uint8 mode; + + time_t system_timestamp; // Of latest RTC load time + uint32 pad; } SRTC_DATA; extern SRTC_DATA rtc; -void S9xUpdateSrtcTime (); -void S9xSetSRTC (uint8 data, uint16 Address); -uint8 S9xGetSRTC (uint16 Address); -void S9xSRTCPreSaveState (); -void S9xSRTCPostLoadState (); -void S9xResetSRTC (); -void S9xHardResetSRTC (); +void S9xUpdateSrtcTime(); +void S9xSetSRTC(uint8 data, uint16 Address); +uint8 S9xGetSRTC(uint16 Address); +void S9xSRTCPreSaveState(); +void S9xSRTCPostLoadState(); +void S9xResetSRTC(); +void S9xHardResetSRTC(); #define SRTC_SRAM_PAD (4 + 8 + 1 + MAX_RTC_INDEX) -#endif // _srtc_h +#endif // _srtc_h diff --git a/source/tile.c b/source/tile.c index ae9edfd..38ac831 100644 --- a/source/tile.c +++ b/source/tile.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -97,973 +97,1004 @@ extern uint32 HeadMask [4]; extern uint32 TailMask [5]; -static uint8 ConvertTile (uint8 *pCache, uint32 TileAddr) +static uint8 ConvertTile(uint8* pCache, uint32 TileAddr) { - register uint8 *tp = &Memory.VRAM[TileAddr]; - uint32 *p = (uint32 *) pCache; - uint32 non_zero = 0; - uint8 line; - - switch (BG.BitShift) - { - case 8: - for (line = 8; line != 0; line--, tp += 2) - { - uint32 p1 = 0; - uint32 p2 = 0; - register uint8 pix; - - if ((pix = *(tp + 0))) - { - p1 |= odd_high[0][pix >> 4]; - p2 |= odd_low[0][pix & 0xf]; - } - if ((pix = *(tp + 1))) - { - p1 |= even_high[0][pix >> 4]; - p2 |= even_low[0][pix & 0xf]; - } - if ((pix = *(tp + 16))) - { - p1 |= odd_high[1][pix >> 4]; - p2 |= odd_low[1][pix & 0xf]; - } - if ((pix = *(tp + 17))) - { - p1 |= even_high[1][pix >> 4]; - p2 |= even_low[1][pix & 0xf]; - } - if ((pix = *(tp + 32))) - { - p1 |= odd_high[2][pix >> 4]; - p2 |= odd_low[2][pix & 0xf]; - } - if ((pix = *(tp + 33))) - { - p1 |= even_high[2][pix >> 4]; - p2 |= even_low[2][pix & 0xf]; - } - if ((pix = *(tp + 48))) - { - p1 |= odd_high[3][pix >> 4]; - p2 |= odd_low[3][pix & 0xf]; - } - if ((pix = *(tp + 49))) - { - p1 |= even_high[3][pix >> 4]; - p2 |= even_low[3][pix & 0xf]; - } - *p++ = p1; - *p++ = p2; - non_zero |= p1 | p2; - } - break; - - case 4: - for (line = 8; line != 0; line--, tp += 2) - { - uint32 p1 = 0; - uint32 p2 = 0; - register uint8 pix; - if ((pix = *(tp + 0))) - { - p1 |= odd_high[0][pix >> 4]; - p2 |= odd_low[0][pix & 0xf]; - } - if ((pix = *(tp + 1))) - { - p1 |= even_high[0][pix >> 4]; - p2 |= even_low[0][pix & 0xf]; - } - if ((pix = *(tp + 16))) - { - p1 |= odd_high[1][pix >> 4]; - p2 |= odd_low[1][pix & 0xf]; - } - if ((pix = *(tp + 17))) - { - p1 |= even_high[1][pix >> 4]; - p2 |= even_low[1][pix & 0xf]; - } - *p++ = p1; - *p++ = p2; - non_zero |= p1 | p2; - } - break; - - case 2: - for (line = 8; line != 0; line--, tp += 2) - { - uint32 p1 = 0; - uint32 p2 = 0; - register uint8 pix; - if ((pix = *(tp + 0))) - { - p1 |= odd_high[0][pix >> 4]; - p2 |= odd_low[0][pix & 0xf]; - } - if ((pix = *(tp + 1))) - { - p1 |= even_high[0][pix >> 4]; - p2 |= even_low[0][pix & 0xf]; - } - *p++ = p1; - *p++ = p2; - non_zero |= p1 | p2; - } - break; - } - return (non_zero ? TRUE : BLANK_TILE); + register uint8* tp = &Memory.VRAM[TileAddr]; + uint32* p = (uint32*) pCache; + uint32 non_zero = 0; + uint8 line; + + switch (BG.BitShift) + { + case 8: + for (line = 8; line != 0; line--, tp += 2) + { + uint32 p1 = 0; + uint32 p2 = 0; + register uint8 pix; + + if ((pix = *(tp + 0))) + { + p1 |= odd_high[0][pix >> 4]; + p2 |= odd_low[0][pix & 0xf]; + } + if ((pix = *(tp + 1))) + { + p1 |= even_high[0][pix >> 4]; + p2 |= even_low[0][pix & 0xf]; + } + if ((pix = *(tp + 16))) + { + p1 |= odd_high[1][pix >> 4]; + p2 |= odd_low[1][pix & 0xf]; + } + if ((pix = *(tp + 17))) + { + p1 |= even_high[1][pix >> 4]; + p2 |= even_low[1][pix & 0xf]; + } + if ((pix = *(tp + 32))) + { + p1 |= odd_high[2][pix >> 4]; + p2 |= odd_low[2][pix & 0xf]; + } + if ((pix = *(tp + 33))) + { + p1 |= even_high[2][pix >> 4]; + p2 |= even_low[2][pix & 0xf]; + } + if ((pix = *(tp + 48))) + { + p1 |= odd_high[3][pix >> 4]; + p2 |= odd_low[3][pix & 0xf]; + } + if ((pix = *(tp + 49))) + { + p1 |= even_high[3][pix >> 4]; + p2 |= even_low[3][pix & 0xf]; + } + *p++ = p1; + *p++ = p2; + non_zero |= p1 | p2; + } + break; + + case 4: + for (line = 8; line != 0; line--, tp += 2) + { + uint32 p1 = 0; + uint32 p2 = 0; + register uint8 pix; + if ((pix = *(tp + 0))) + { + p1 |= odd_high[0][pix >> 4]; + p2 |= odd_low[0][pix & 0xf]; + } + if ((pix = *(tp + 1))) + { + p1 |= even_high[0][pix >> 4]; + p2 |= even_low[0][pix & 0xf]; + } + if ((pix = *(tp + 16))) + { + p1 |= odd_high[1][pix >> 4]; + p2 |= odd_low[1][pix & 0xf]; + } + if ((pix = *(tp + 17))) + { + p1 |= even_high[1][pix >> 4]; + p2 |= even_low[1][pix & 0xf]; + } + *p++ = p1; + *p++ = p2; + non_zero |= p1 | p2; + } + break; + + case 2: + for (line = 8; line != 0; line--, tp += 2) + { + uint32 p1 = 0; + uint32 p2 = 0; + register uint8 pix; + if ((pix = *(tp + 0))) + { + p1 |= odd_high[0][pix >> 4]; + p2 |= odd_low[0][pix & 0xf]; + } + if ((pix = *(tp + 1))) + { + p1 |= even_high[0][pix >> 4]; + p2 |= even_low[0][pix & 0xf]; + } + *p++ = p1; + *p++ = p2; + non_zero |= p1 | p2; + } + break; + } + return (non_zero ? TRUE : BLANK_TILE); } #define PLOT_PIXEL(screen, pixel) (pixel) -static void WRITE_4PIXELS16 (int32 Offset, uint8 *Pixels, uint16 *ScreenColors) +static void WRITE_4PIXELS16(int32 Offset, uint8* Pixels, uint16* ScreenColors) { - uint8 Pixel,N; - uint16 *Screen = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.DB + Offset; + uint8 Pixel, N; + uint16* Screen = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.DB + Offset; for (N = 0; N < 4; N++) - { - if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) - { - Screen [N] = ScreenColors [Pixel]; - Depth [N] = GFX.Z2; - } - } + { + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) + { + Screen [N] = ScreenColors [Pixel]; + Depth [N] = GFX.Z2; + } + } } -static void WRITE_4PIXELS16_FLIPPED (int32 Offset, uint8 *Pixels, uint16 *ScreenColors) +static void WRITE_4PIXELS16_FLIPPED(int32 Offset, uint8* Pixels, + uint16* ScreenColors) { - uint8 Pixel,N; - uint16 *Screen = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.DB + Offset; + uint8 Pixel, N; + uint16* Screen = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.DB + Offset; for (N = 0; N < 4; N++) - { - if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) - { - Screen [N] = ScreenColors [Pixel]; - Depth [N] = GFX.Z2; - } - } + { + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) + { + Screen [N] = ScreenColors [Pixel]; + Depth [N] = GFX.Z2; + } + } } -static void WRITE_4PIXELS16_HALFWIDTH (int32 Offset, uint8 *Pixels, uint16 *ScreenColors) +static void WRITE_4PIXELS16_HALFWIDTH(int32 Offset, uint8* Pixels, + uint16* ScreenColors) { - uint8 Pixel,N; - uint16 *Screen = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.DB + Offset; + uint8 Pixel, N; + uint16* Screen = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.DB + Offset; for (N = 0; N < 4; N += 2) - { - if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) - { - Screen [N >> 1] = ScreenColors [Pixel]; - Depth [N >> 1] = GFX.Z2; - } - } + { + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) + { + Screen [N >> 1] = ScreenColors [Pixel]; + Depth [N >> 1] = GFX.Z2; + } + } } -static void WRITE_4PIXELS16_FLIPPED_HALFWIDTH (int32 Offset, uint8 *Pixels, uint16 *ScreenColors) +static void WRITE_4PIXELS16_FLIPPED_HALFWIDTH(int32 Offset, uint8* Pixels, + uint16* ScreenColors) { - uint8 Pixel,N; - uint16 *Screen = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.DB + Offset; + uint8 Pixel, N; + uint16* Screen = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.DB + Offset; for (N = 0; N < 4; N += 2) - { - if (GFX.Z1 > Depth [N] && (Pixel = Pixels[2 - N])) - { - Screen [N >> 1] = ScreenColors [Pixel]; - Depth [N >> 1] = GFX.Z2; - } - } + { + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[2 - N])) + { + Screen [N >> 1] = ScreenColors [Pixel]; + Depth [N >> 1] = GFX.Z2; + } + } } -static void WRITE_4PIXELS16x2 (int32 Offset, uint8 *Pixels, uint16 *ScreenColors) +static void WRITE_4PIXELS16x2(int32 Offset, uint8* Pixels, uint16* ScreenColors) { - uint8 Pixel,N; - uint16 *Screen = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.DB + Offset; + uint8 Pixel, N; + uint16* Screen = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.DB + Offset; for (N = 0; N < 4; N++) - { - if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) - { - Screen [N * 2] = Screen [N * 2 + 1] = ScreenColors [Pixel]; - Depth [N * 2] = Depth [N * 2 + 1] = GFX.Z2; - } - } + { + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) + { + Screen [N * 2] = Screen [N * 2 + 1] = ScreenColors [Pixel]; + Depth [N * 2] = Depth [N * 2 + 1] = GFX.Z2; + } + } } -static void WRITE_4PIXELS16_FLIPPEDx2 (int32 Offset, uint8 *Pixels, uint16 *ScreenColors) +static void WRITE_4PIXELS16_FLIPPEDx2(int32 Offset, uint8* Pixels, + uint16* ScreenColors) { - uint8 Pixel,N; - uint16 *Screen = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.DB + Offset; + uint8 Pixel, N; + uint16* Screen = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.DB + Offset; for (N = 0; N < 4; N++) - { - if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) - { - Screen [N * 2] = Screen [N * 2 + 1] = ScreenColors [Pixel]; - Depth [N * 2] = Depth [N * 2 + 1] = GFX.Z2; - } - } + { + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) + { + Screen [N * 2] = Screen [N * 2 + 1] = ScreenColors [Pixel]; + Depth [N * 2] = Depth [N * 2 + 1] = GFX.Z2; + } + } } -static void WRITE_4PIXELS16x2x2 (int32 Offset, uint8 *Pixels, uint16 *ScreenColors) +static void WRITE_4PIXELS16x2x2(int32 Offset, uint8* Pixels, + uint16* ScreenColors) { - uint8 Pixel,N; - uint16 *Screen = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.DB + Offset; + uint8 Pixel, N; + uint16* Screen = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.DB + Offset; for (N = 0; N < 4; N++) - { - if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) - { - Screen [N * 2] = Screen [N * 2 + 1] = Screen [(GFX.RealPitch >> 1) + N * 2] = Screen [(GFX.RealPitch >> 1) + N * 2 + 1] = ScreenColors [Pixel]; - Depth [N * 2] = Depth [N * 2 + 1] = Depth [(GFX.RealPitch >> 1) + N * 2] = Depth [(GFX.RealPitch >> 1) + N * 2 + 1] = GFX.Z2; - } - } + { + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) + { + Screen [N * 2] = Screen [N * 2 + 1] = Screen [(GFX.RealPitch >> 1) + N * 2] = + Screen [(GFX.RealPitch >> 1) + N * 2 + 1] = ScreenColors [Pixel]; + Depth [N * 2] = Depth [N * 2 + 1] = Depth [(GFX.RealPitch >> 1) + N * 2] = + Depth [(GFX.RealPitch >> 1) + N * 2 + 1] = GFX.Z2; + } + } } -static void WRITE_4PIXELS16_FLIPPEDx2x2 (int32 Offset, uint8 *Pixels, uint16 *ScreenColors) +static void WRITE_4PIXELS16_FLIPPEDx2x2(int32 Offset, uint8* Pixels, + uint16* ScreenColors) { - uint8 Pixel,N; - uint16 *Screen = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.DB + Offset; + uint8 Pixel, N; + uint16* Screen = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.DB + Offset; for (N = 0; N < 4; N++) - { - if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) - { - Screen [N * 2] = Screen [N * 2 + 1] = Screen [(GFX.RealPitch >> 1) + N * 2] = Screen [(GFX.RealPitch >> 1) + N * 2 + 1] = ScreenColors [Pixel]; - Depth [N * 2] = Depth [N * 2 + 1] = Depth [(GFX.RealPitch >> 1) + N * 2] = Depth [(GFX.RealPitch >> 1) + N * 2 + 1] = GFX.Z2; - } - } + { + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) + { + Screen [N * 2] = Screen [N * 2 + 1] = Screen [(GFX.RealPitch >> 1) + N * 2] = + Screen [(GFX.RealPitch >> 1) + N * 2 + 1] = ScreenColors [Pixel]; + Depth [N * 2] = Depth [N * 2 + 1] = Depth [(GFX.RealPitch >> 1) + N * 2] = + Depth [(GFX.RealPitch >> 1) + N * 2 + 1] = GFX.Z2; + } + } } -void DrawTile16 (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount) +void DrawTile16(uint32 Tile, int32 Offset, uint32 StartLine, + uint32 LineCount) { - TILE_PREAMBLE - register uint8 *bp; + TILE_PREAMBLE + register uint8* bp; - RENDER_TILE(WRITE_4PIXELS16, WRITE_4PIXELS16_FLIPPED, 4) + RENDER_TILE(WRITE_4PIXELS16, WRITE_4PIXELS16_FLIPPED, 4) } -void DrawClippedTile16 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount) +void DrawClippedTile16(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount) { - TILE_PREAMBLE - register uint8 *bp; + TILE_PREAMBLE + register uint8* bp; - TILE_CLIP_PREAMBLE - RENDER_CLIPPED_TILE(WRITE_4PIXELS16, WRITE_4PIXELS16_FLIPPED, 4) + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16, WRITE_4PIXELS16_FLIPPED, 4) } -void DrawTile16HalfWidth (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount) +void DrawTile16HalfWidth(uint32 Tile, int32 Offset, uint32 StartLine, + uint32 LineCount) { - TILE_PREAMBLE - register uint8 *bp; + TILE_PREAMBLE + register uint8* bp; - RENDER_TILE(WRITE_4PIXELS16_HALFWIDTH, WRITE_4PIXELS16_FLIPPED_HALFWIDTH, 2) + RENDER_TILE(WRITE_4PIXELS16_HALFWIDTH, WRITE_4PIXELS16_FLIPPED_HALFWIDTH, 2) } -void DrawClippedTile16HalfWidth (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount) +void DrawClippedTile16HalfWidth(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount) { - TILE_PREAMBLE - register uint8 *bp; + TILE_PREAMBLE + register uint8* bp; - TILE_CLIP_PREAMBLE - RENDER_CLIPPED_TILE(WRITE_4PIXELS16_HALFWIDTH, WRITE_4PIXELS16_FLIPPED_HALFWIDTH, 2) + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16_HALFWIDTH, + WRITE_4PIXELS16_FLIPPED_HALFWIDTH, 2) } -void DrawTile16x2 (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount) +void DrawTile16x2(uint32 Tile, int32 Offset, uint32 StartLine, + uint32 LineCount) { - TILE_PREAMBLE - register uint8 *bp; + TILE_PREAMBLE + register uint8* bp; - RENDER_TILE(WRITE_4PIXELS16x2, WRITE_4PIXELS16_FLIPPEDx2, 8) + RENDER_TILE(WRITE_4PIXELS16x2, WRITE_4PIXELS16_FLIPPEDx2, 8) } -void DrawClippedTile16x2 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount) +void DrawClippedTile16x2(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount) { - TILE_PREAMBLE - register uint8 *bp; + TILE_PREAMBLE + register uint8* bp; - TILE_CLIP_PREAMBLE - RENDER_CLIPPED_TILE(WRITE_4PIXELS16x2, WRITE_4PIXELS16_FLIPPEDx2, 8) + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16x2, WRITE_4PIXELS16_FLIPPEDx2, 8) } -void DrawTile16x2x2 (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount) +void DrawTile16x2x2(uint32 Tile, int32 Offset, uint32 StartLine, + uint32 LineCount) { - TILE_PREAMBLE - register uint8 *bp; + TILE_PREAMBLE + register uint8* bp; - RENDER_TILE(WRITE_4PIXELS16x2x2, WRITE_4PIXELS16_FLIPPEDx2x2, 8) + RENDER_TILE(WRITE_4PIXELS16x2x2, WRITE_4PIXELS16_FLIPPEDx2x2, 8) } -void DrawClippedTile16x2x2 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount) +void DrawClippedTile16x2x2(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount) { - TILE_PREAMBLE - register uint8 *bp; + TILE_PREAMBLE + register uint8* bp; - TILE_CLIP_PREAMBLE - RENDER_CLIPPED_TILE(WRITE_4PIXELS16x2x2, WRITE_4PIXELS16_FLIPPEDx2x2, 8) + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16x2x2, WRITE_4PIXELS16_FLIPPEDx2x2, 8) } -void DrawLargePixel16 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Pixels, - uint32 StartLine, uint32 LineCount) +void DrawLargePixel16(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount) { - TILE_PREAMBLE + TILE_PREAMBLE - register uint16 *sp = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.DB + Offset; - uint16 pixel; + register uint16* sp = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.DB + Offset; + uint16 pixel; - RENDER_TILE_LARGE (ScreenColors [pixel], PLOT_PIXEL) + RENDER_TILE_LARGE(ScreenColors [pixel], PLOT_PIXEL) } -void DrawLargePixel16HalfWidth (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Pixels, - uint32 StartLine, uint32 LineCount) +void DrawLargePixel16HalfWidth(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount) { - TILE_PREAMBLE + TILE_PREAMBLE - register uint16 *sp = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.DB + Offset; - uint16 pixel; + register uint16* sp = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.DB + Offset; + uint16 pixel; - RENDER_TILE_LARGE_HALFWIDTH (ScreenColors [pixel], PLOT_PIXEL) + RENDER_TILE_LARGE_HALFWIDTH(ScreenColors [pixel], PLOT_PIXEL) } -static void WRITE_4PIXELS16_ADD (int32 Offset, uint8 *Pixels, uint16 *ScreenColors) +static void WRITE_4PIXELS16_ADD(int32 Offset, uint8* Pixels, + uint16* ScreenColors) { - uint8 Pixel,N; - uint16 *Screen = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.ZBuffer + Offset; - uint8 *SubDepth = GFX.SubZBuffer + Offset; + uint8 Pixel, N; + uint16* Screen = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.ZBuffer + Offset; + uint8* SubDepth = GFX.SubZBuffer + Offset; for (N = 0; N < 4; N++) - { - if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) + { + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) { - switch (SubDepth [N]) - { - case 0: - Screen [N] = ScreenColors [Pixel]; - break; - case 1: - Screen [N] = COLOR_ADD (ScreenColors [Pixel], GFX.FixedColour); - break; - default: - Screen [N] = COLOR_ADD (ScreenColors [Pixel], Screen [GFX.Delta + N]); - break; - } - Depth [N] = GFX.Z2; - } - } + switch (SubDepth [N]) + { + case 0: + Screen [N] = ScreenColors [Pixel]; + break; + case 1: + Screen [N] = COLOR_ADD(ScreenColors [Pixel], GFX.FixedColour); + break; + default: + Screen [N] = COLOR_ADD(ScreenColors [Pixel], Screen [GFX.Delta + N]); + break; + } + Depth [N] = GFX.Z2; + } + } } -static void WRITE_4PIXELS16_FLIPPED_ADD (int32 Offset, uint8 *Pixels, uint16 *ScreenColors) +static void WRITE_4PIXELS16_FLIPPED_ADD(int32 Offset, uint8* Pixels, + uint16* ScreenColors) { - uint8 Pixel,N; - uint16 *Screen = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.ZBuffer + Offset; - uint8 *SubDepth = GFX.SubZBuffer + Offset; + uint8 Pixel, N; + uint16* Screen = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.ZBuffer + Offset; + uint8* SubDepth = GFX.SubZBuffer + Offset; for (N = 0; N < 4; N++) - { - if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) - { - switch (SubDepth [N]) - { - case 0: - Screen [N] = ScreenColors [Pixel]; - break; - case 1: - Screen [N] = COLOR_ADD (ScreenColors [Pixel], GFX.FixedColour); - break; - default: - Screen [N] = COLOR_ADD (ScreenColors [Pixel], Screen [GFX.Delta + N]); - break; - } - Depth [N] = GFX.Z2; - } - } + { + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) + { + switch (SubDepth [N]) + { + case 0: + Screen [N] = ScreenColors [Pixel]; + break; + case 1: + Screen [N] = COLOR_ADD(ScreenColors [Pixel], GFX.FixedColour); + break; + default: + Screen [N] = COLOR_ADD(ScreenColors [Pixel], Screen [GFX.Delta + N]); + break; + } + Depth [N] = GFX.Z2; + } + } } -static void WRITE_4PIXELS16_ADD1_2 (int32 Offset, uint8 *Pixels, uint16 *ScreenColors) +static void WRITE_4PIXELS16_ADD1_2(int32 Offset, uint8* Pixels, + uint16* ScreenColors) { - uint8 Pixel,N; - uint16 *Screen = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.ZBuffer + Offset; - uint8 *SubDepth = GFX.SubZBuffer + Offset; + uint8 Pixel, N; + uint16* Screen = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.ZBuffer + Offset; + uint8* SubDepth = GFX.SubZBuffer + Offset; for (N = 0; N < 4; N++) - { - if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) - { - switch (SubDepth [N]) - { - case 0: - Screen [N] = ScreenColors [Pixel]; - break; - case 1: - Screen [N] = COLOR_ADD (ScreenColors [Pixel], GFX.FixedColour); - break; - default: - Screen [N] = (uint16) (COLOR_ADD1_2 (ScreenColors [Pixel], Screen [GFX.Delta + N])); - break; - } - Depth [N] = GFX.Z2; - } - } + { + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) + { + switch (SubDepth [N]) + { + case 0: + Screen [N] = ScreenColors [Pixel]; + break; + case 1: + Screen [N] = COLOR_ADD(ScreenColors [Pixel], GFX.FixedColour); + break; + default: + Screen [N] = (uint16)(COLOR_ADD1_2(ScreenColors [Pixel], + Screen [GFX.Delta + N])); + break; + } + Depth [N] = GFX.Z2; + } + } } -static void WRITE_4PIXELS16_FLIPPED_ADD1_2 (int32 Offset, uint8 *Pixels, uint16 *ScreenColors) +static void WRITE_4PIXELS16_FLIPPED_ADD1_2(int32 Offset, uint8* Pixels, + uint16* ScreenColors) { - uint8 Pixel,N; - uint16 *Screen = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.ZBuffer + Offset; - uint8 *SubDepth = GFX.SubZBuffer + Offset; + uint8 Pixel, N; + uint16* Screen = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.ZBuffer + Offset; + uint8* SubDepth = GFX.SubZBuffer + Offset; for (N = 0; N < 4; N++) - { - if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) - { - switch (SubDepth [N]) - { - case 0: - Screen [N] = ScreenColors [Pixel]; - break; - case 1: - Screen [N] = COLOR_ADD (ScreenColors [Pixel], GFX.FixedColour); - break; - default: - Screen [N] = (uint16) (COLOR_ADD1_2 (ScreenColors [Pixel], Screen [GFX.Delta + N])); - break; - } - Depth [N] = GFX.Z2; - } - } + { + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) + { + switch (SubDepth [N]) + { + case 0: + Screen [N] = ScreenColors [Pixel]; + break; + case 1: + Screen [N] = COLOR_ADD(ScreenColors [Pixel], GFX.FixedColour); + break; + default: + Screen [N] = (uint16)(COLOR_ADD1_2(ScreenColors [Pixel], + Screen [GFX.Delta + N])); + break; + } + Depth [N] = GFX.Z2; + } + } } -static void WRITE_4PIXELS16_SUB (int32 Offset, uint8 *Pixels, uint16 *ScreenColors) +static void WRITE_4PIXELS16_SUB(int32 Offset, uint8* Pixels, + uint16* ScreenColors) { - uint8 Pixel,N; - uint16 *Screen = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.ZBuffer + Offset; - uint8 *SubDepth = GFX.SubZBuffer + Offset; + uint8 Pixel, N; + uint16* Screen = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.ZBuffer + Offset; + uint8* SubDepth = GFX.SubZBuffer + Offset; for (N = 0; N < 4; N++) - { - if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) - { - switch (SubDepth [N]) - { - case 0: - Screen [N] = ScreenColors [Pixel]; - break; - case 1: - Screen [N] = (uint16) COLOR_SUB (ScreenColors [Pixel], GFX.FixedColour); - break; - default: - Screen [N] = (uint16) COLOR_SUB (ScreenColors [Pixel], Screen [GFX.Delta + N]); - break; - } - Depth [N] = GFX.Z2; - } - } + { + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) + { + switch (SubDepth [N]) + { + case 0: + Screen [N] = ScreenColors [Pixel]; + break; + case 1: + Screen [N] = (uint16) COLOR_SUB(ScreenColors [Pixel], GFX.FixedColour); + break; + default: + Screen [N] = (uint16) COLOR_SUB(ScreenColors [Pixel], Screen [GFX.Delta + N]); + break; + } + Depth [N] = GFX.Z2; + } + } } -static void WRITE_4PIXELS16_FLIPPED_SUB (int32 Offset, uint8 *Pixels, uint16 *ScreenColors) +static void WRITE_4PIXELS16_FLIPPED_SUB(int32 Offset, uint8* Pixels, + uint16* ScreenColors) { - uint8 Pixel,N; - uint16 *Screen = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.ZBuffer + Offset; - uint8 *SubDepth = GFX.SubZBuffer + Offset; + uint8 Pixel, N; + uint16* Screen = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.ZBuffer + Offset; + uint8* SubDepth = GFX.SubZBuffer + Offset; for (N = 0; N < 4; N++) - { - if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) - { - switch (SubDepth [N]) - { - case 0: - Screen [N] = ScreenColors [Pixel]; - break; - case 1: - Screen [N] = (uint16) COLOR_SUB (ScreenColors [Pixel], GFX.FixedColour); - break; - default: - Screen [N] = (uint16) COLOR_SUB (ScreenColors [Pixel], Screen [GFX.Delta + N]); - break; - } - Depth [N] = GFX.Z2; - } - } + { + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) + { + switch (SubDepth [N]) + { + case 0: + Screen [N] = ScreenColors [Pixel]; + break; + case 1: + Screen [N] = (uint16) COLOR_SUB(ScreenColors [Pixel], GFX.FixedColour); + break; + default: + Screen [N] = (uint16) COLOR_SUB(ScreenColors [Pixel], Screen [GFX.Delta + N]); + break; + } + Depth [N] = GFX.Z2; + } + } } -static void WRITE_4PIXELS16_SUB1_2 (int32 Offset, uint8 *Pixels, uint16 *ScreenColors) +static void WRITE_4PIXELS16_SUB1_2(int32 Offset, uint8* Pixels, + uint16* ScreenColors) { - uint8 Pixel,N; - uint16 *Screen = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.ZBuffer + Offset; - uint8 *SubDepth = GFX.SubZBuffer + Offset; + uint8 Pixel, N; + uint16* Screen = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.ZBuffer + Offset; + uint8* SubDepth = GFX.SubZBuffer + Offset; for (N = 0; N < 4; N++) - { - if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) - { - switch (SubDepth [N]) - { - case 0: - Screen [N] = ScreenColors [Pixel]; - break; - case 1: - Screen [N] = (uint16) COLOR_SUB (ScreenColors [Pixel], GFX.FixedColour); - break; - default: - Screen [N] = (uint16) COLOR_SUB1_2 (ScreenColors [Pixel], Screen [GFX.Delta + N]); - break; - } - Depth [N] = GFX.Z2; - } - } + { + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) + { + switch (SubDepth [N]) + { + case 0: + Screen [N] = ScreenColors [Pixel]; + break; + case 1: + Screen [N] = (uint16) COLOR_SUB(ScreenColors [Pixel], GFX.FixedColour); + break; + default: + Screen [N] = (uint16) COLOR_SUB1_2(ScreenColors [Pixel], + Screen [GFX.Delta + N]); + break; + } + Depth [N] = GFX.Z2; + } + } } -static void WRITE_4PIXELS16_FLIPPED_SUB1_2 (int32 Offset, uint8 *Pixels, uint16 *ScreenColors) +static void WRITE_4PIXELS16_FLIPPED_SUB1_2(int32 Offset, uint8* Pixels, + uint16* ScreenColors) { - uint8 Pixel,N; - uint16 *Screen = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.ZBuffer + Offset; - uint8 *SubDepth = GFX.SubZBuffer + Offset; + uint8 Pixel, N; + uint16* Screen = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.ZBuffer + Offset; + uint8* SubDepth = GFX.SubZBuffer + Offset; for (N = 0; N < 4; N++) - { - if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) - { - switch (SubDepth [N]) - { - case 0: - Screen [N] = ScreenColors [Pixel]; - break; - case 1: - Screen [N] = (uint16) COLOR_SUB (ScreenColors [Pixel], GFX.FixedColour); - break; - default: - Screen [N] = (uint16) COLOR_SUB1_2 (ScreenColors [Pixel], Screen [GFX.Delta + N]); - break; - } - Depth [N] = GFX.Z2; - } - } + { + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) + { + switch (SubDepth [N]) + { + case 0: + Screen [N] = ScreenColors [Pixel]; + break; + case 1: + Screen [N] = (uint16) COLOR_SUB(ScreenColors [Pixel], GFX.FixedColour); + break; + default: + Screen [N] = (uint16) COLOR_SUB1_2(ScreenColors [Pixel], + Screen [GFX.Delta + N]); + break; + } + Depth [N] = GFX.Z2; + } + } } -void DrawTile16Add (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount) +void DrawTile16Add(uint32 Tile, int32 Offset, uint32 StartLine, + uint32 LineCount) { - TILE_PREAMBLE - register uint8 *bp; - uint8 Pixel; - uint16 *Screen = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.ZBuffer + Offset; - uint8 *SubDepth = GFX.SubZBuffer + Offset; - - switch (Tile & (V_FLIP | H_FLIP)) - { - case 0: - bp = pCache + StartLine; - for (l = LineCount; l != 0; l--, bp += 8, Screen += GFX.PPL, Depth += GFX.PPL, SubDepth += GFX.PPL) - { - uint8 N; - for (N = 0; N < 8; N++) - { - if (GFX.Z1 > Depth [N] && (Pixel = bp[N])) - { - switch (SubDepth [N]) - { - case 0: - Screen [N] = ScreenColors [Pixel]; - break; - case 1: - Screen [N] = COLOR_ADD (ScreenColors [Pixel], GFX.FixedColour); - break; - default: - Screen [N] = COLOR_ADD (ScreenColors [Pixel], Screen [GFX.Delta + N]); - break; - } - Depth [N] = GFX.Z2; - } - } - } - break; - case H_FLIP: - bp = pCache + StartLine; - for (l = LineCount; l != 0; l--, bp += 8, Screen += GFX.PPL, Depth += GFX.PPL, SubDepth += GFX.PPL) + TILE_PREAMBLE + register uint8* bp; + uint8 Pixel; + uint16* Screen = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.ZBuffer + Offset; + uint8* SubDepth = GFX.SubZBuffer + Offset; + + switch (Tile & (V_FLIP | H_FLIP)) { - uint8 N; - for (N = 0; N < 8; N++) - { - if (GFX.Z1 > Depth [N] && (Pixel = bp[7 - N])) - { - switch (SubDepth [N]) - { - case 0: - Screen [N] = ScreenColors [Pixel]; - break; - case 1: - Screen [N] = COLOR_ADD (ScreenColors [Pixel], GFX.FixedColour); - break; - default: - Screen [N] = COLOR_ADD (ScreenColors [Pixel], Screen [GFX.Delta + N]); - break; - } - Depth [N] = GFX.Z2; - } - } - } - break; - case H_FLIP | V_FLIP: - bp = pCache + 56 - StartLine; - for (l = LineCount; l != 0; l--, bp -= 8, Screen += GFX.PPL, Depth += GFX.PPL, SubDepth += GFX.PPL) - { - uint8 N; - for (N = 0; N < 8; N++) - { - if (GFX.Z1 > Depth [N] && (Pixel = bp[7 - N])) - { - switch (SubDepth [N]) - { - case 0: - Screen [N] = ScreenColors [Pixel]; - break; - case 1: - Screen [N] = COLOR_ADD (ScreenColors [Pixel], GFX.FixedColour); - break; - default: - Screen [N] = COLOR_ADD (ScreenColors [Pixel], Screen [GFX.Delta + N]); - break; - } - Depth [N] = GFX.Z2; - } - } - } - break; - case V_FLIP: - bp = pCache + 56 - StartLine; - for (l = LineCount; l != 0; l--, bp -= 8, Screen += GFX.PPL, Depth += GFX.PPL, SubDepth += GFX.PPL) - { - uint8 N; - for (N = 0; N < 8; N++) - { - if (GFX.Z1 > Depth [N] && (Pixel = bp[N])) - { - switch (SubDepth [N]) - { - case 0: - Screen [N] = ScreenColors [Pixel]; - break; - case 1: - Screen [N] = COLOR_ADD (ScreenColors [Pixel], GFX.FixedColour); - break; - default: - Screen [N] = COLOR_ADD (ScreenColors [Pixel], Screen [GFX.Delta + N]); - break; - } - Depth [N] = GFX.Z2; - } - } - } - break; - default: - break; - } + case 0: + bp = pCache + StartLine; + for (l = LineCount; l != 0; + l--, bp += 8, Screen += GFX.PPL, Depth += GFX.PPL, SubDepth += GFX.PPL) + { + uint8 N; + for (N = 0; N < 8; N++) + { + if (GFX.Z1 > Depth [N] && (Pixel = bp[N])) + { + switch (SubDepth [N]) + { + case 0: + Screen [N] = ScreenColors [Pixel]; + break; + case 1: + Screen [N] = COLOR_ADD(ScreenColors [Pixel], GFX.FixedColour); + break; + default: + Screen [N] = COLOR_ADD(ScreenColors [Pixel], Screen [GFX.Delta + N]); + break; + } + Depth [N] = GFX.Z2; + } + } + } + break; + case H_FLIP: + bp = pCache + StartLine; + for (l = LineCount; l != 0; + l--, bp += 8, Screen += GFX.PPL, Depth += GFX.PPL, SubDepth += GFX.PPL) + { + uint8 N; + for (N = 0; N < 8; N++) + { + if (GFX.Z1 > Depth [N] && (Pixel = bp[7 - N])) + { + switch (SubDepth [N]) + { + case 0: + Screen [N] = ScreenColors [Pixel]; + break; + case 1: + Screen [N] = COLOR_ADD(ScreenColors [Pixel], GFX.FixedColour); + break; + default: + Screen [N] = COLOR_ADD(ScreenColors [Pixel], Screen [GFX.Delta + N]); + break; + } + Depth [N] = GFX.Z2; + } + } + } + break; + case H_FLIP | V_FLIP: + bp = pCache + 56 - StartLine; + for (l = LineCount; l != 0; + l--, bp -= 8, Screen += GFX.PPL, Depth += GFX.PPL, SubDepth += GFX.PPL) + { + uint8 N; + for (N = 0; N < 8; N++) + { + if (GFX.Z1 > Depth [N] && (Pixel = bp[7 - N])) + { + switch (SubDepth [N]) + { + case 0: + Screen [N] = ScreenColors [Pixel]; + break; + case 1: + Screen [N] = COLOR_ADD(ScreenColors [Pixel], GFX.FixedColour); + break; + default: + Screen [N] = COLOR_ADD(ScreenColors [Pixel], Screen [GFX.Delta + N]); + break; + } + Depth [N] = GFX.Z2; + } + } + } + break; + case V_FLIP: + bp = pCache + 56 - StartLine; + for (l = LineCount; l != 0; + l--, bp -= 8, Screen += GFX.PPL, Depth += GFX.PPL, SubDepth += GFX.PPL) + { + uint8 N; + for (N = 0; N < 8; N++) + { + if (GFX.Z1 > Depth [N] && (Pixel = bp[N])) + { + switch (SubDepth [N]) + { + case 0: + Screen [N] = ScreenColors [Pixel]; + break; + case 1: + Screen [N] = COLOR_ADD(ScreenColors [Pixel], GFX.FixedColour); + break; + default: + Screen [N] = COLOR_ADD(ScreenColors [Pixel], Screen [GFX.Delta + N]); + break; + } + Depth [N] = GFX.Z2; + } + } + } + break; + default: + break; + } } -void DrawClippedTile16Add (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount) +void DrawClippedTile16Add(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount) { - TILE_PREAMBLE - register uint8 *bp; + TILE_PREAMBLE + register uint8* bp; - TILE_CLIP_PREAMBLE - RENDER_CLIPPED_TILE(WRITE_4PIXELS16_ADD, WRITE_4PIXELS16_FLIPPED_ADD, 4) + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16_ADD, WRITE_4PIXELS16_FLIPPED_ADD, 4) } -void DrawTile16Add1_2 (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount) +void DrawTile16Add1_2(uint32 Tile, int32 Offset, uint32 StartLine, + uint32 LineCount) { - TILE_PREAMBLE - register uint8 *bp; + TILE_PREAMBLE + register uint8* bp; - RENDER_TILE(WRITE_4PIXELS16_ADD1_2, WRITE_4PIXELS16_FLIPPED_ADD1_2, 4) + RENDER_TILE(WRITE_4PIXELS16_ADD1_2, WRITE_4PIXELS16_FLIPPED_ADD1_2, 4) } -void DrawClippedTile16Add1_2 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount) +void DrawClippedTile16Add1_2(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount) { - TILE_PREAMBLE - register uint8 *bp; + TILE_PREAMBLE + register uint8* bp; - TILE_CLIP_PREAMBLE - RENDER_CLIPPED_TILE(WRITE_4PIXELS16_ADD1_2, WRITE_4PIXELS16_FLIPPED_ADD1_2, 4) + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16_ADD1_2, WRITE_4PIXELS16_FLIPPED_ADD1_2, 4) } -void DrawTile16Sub (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount) +void DrawTile16Sub(uint32 Tile, int32 Offset, uint32 StartLine, + uint32 LineCount) { - TILE_PREAMBLE - register uint8 *bp; + TILE_PREAMBLE + register uint8* bp; - RENDER_TILE(WRITE_4PIXELS16_SUB, WRITE_4PIXELS16_FLIPPED_SUB, 4) + RENDER_TILE(WRITE_4PIXELS16_SUB, WRITE_4PIXELS16_FLIPPED_SUB, 4) } -void DrawClippedTile16Sub (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount) +void DrawClippedTile16Sub(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount) { - TILE_PREAMBLE - register uint8 *bp; + TILE_PREAMBLE + register uint8* bp; - TILE_CLIP_PREAMBLE - RENDER_CLIPPED_TILE(WRITE_4PIXELS16_SUB, WRITE_4PIXELS16_FLIPPED_SUB, 4) + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16_SUB, WRITE_4PIXELS16_FLIPPED_SUB, 4) } -void DrawTile16Sub1_2 (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount) +void DrawTile16Sub1_2(uint32 Tile, int32 Offset, uint32 StartLine, + uint32 LineCount) { - TILE_PREAMBLE - register uint8 *bp; + TILE_PREAMBLE + register uint8* bp; - RENDER_TILE(WRITE_4PIXELS16_SUB1_2, WRITE_4PIXELS16_FLIPPED_SUB1_2, 4) + RENDER_TILE(WRITE_4PIXELS16_SUB1_2, WRITE_4PIXELS16_FLIPPED_SUB1_2, 4) } -void DrawClippedTile16Sub1_2 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount) +void DrawClippedTile16Sub1_2(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount) { - TILE_PREAMBLE - register uint8 *bp; + TILE_PREAMBLE + register uint8* bp; - TILE_CLIP_PREAMBLE - RENDER_CLIPPED_TILE(WRITE_4PIXELS16_SUB1_2, WRITE_4PIXELS16_FLIPPED_SUB1_2, 4) + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16_SUB1_2, WRITE_4PIXELS16_FLIPPED_SUB1_2, 4) } -static void WRITE_4PIXELS16_ADDF1_2 (int32 Offset, uint8 *Pixels, uint16 *ScreenColors) +static void WRITE_4PIXELS16_ADDF1_2(int32 Offset, uint8* Pixels, + uint16* ScreenColors) { - uint8 Pixel,N; - uint16 *Screen = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.ZBuffer + Offset; - uint8 *SubDepth = GFX.SubZBuffer + Offset; + uint8 Pixel, N; + uint16* Screen = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.ZBuffer + Offset; + uint8* SubDepth = GFX.SubZBuffer + Offset; for (N = 0; N < 4; N++) - { - if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) - { - if (SubDepth [N] == 1) - Screen [N] = (uint16) (COLOR_ADD1_2 (ScreenColors [Pixel], GFX.FixedColour)); - else - Screen [N] = ScreenColors [Pixel]; - Depth [N] = GFX.Z2; - } - } + { + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) + { + if (SubDepth [N] == 1) + Screen [N] = (uint16)(COLOR_ADD1_2(ScreenColors [Pixel], GFX.FixedColour)); + else + Screen [N] = ScreenColors [Pixel]; + Depth [N] = GFX.Z2; + } + } } -static void WRITE_4PIXELS16_FLIPPED_ADDF1_2 (int32 Offset, uint8 *Pixels, uint16 *ScreenColors) +static void WRITE_4PIXELS16_FLIPPED_ADDF1_2(int32 Offset, uint8* Pixels, + uint16* ScreenColors) { - uint8 Pixel,N; - uint16 *Screen = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.ZBuffer + Offset; - uint8 *SubDepth = GFX.SubZBuffer + Offset; + uint8 Pixel, N; + uint16* Screen = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.ZBuffer + Offset; + uint8* SubDepth = GFX.SubZBuffer + Offset; for (N = 0; N < 4; N++) - { - if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) - { - if (SubDepth [N] == 1) - Screen [N] = (uint16) (COLOR_ADD1_2 (ScreenColors [Pixel], GFX.FixedColour)); - else - Screen [N] = ScreenColors [Pixel]; - Depth [N] = GFX.Z2; - } - } + { + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) + { + if (SubDepth [N] == 1) + Screen [N] = (uint16)(COLOR_ADD1_2(ScreenColors [Pixel], GFX.FixedColour)); + else + Screen [N] = ScreenColors [Pixel]; + Depth [N] = GFX.Z2; + } + } } -static void WRITE_4PIXELS16_SUBF1_2 (int32 Offset, uint8 *Pixels, uint16 *ScreenColors) +static void WRITE_4PIXELS16_SUBF1_2(int32 Offset, uint8* Pixels, + uint16* ScreenColors) { - uint8 Pixel,N; - uint16 *Screen = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.ZBuffer + Offset; - uint8 *SubDepth = GFX.SubZBuffer + Offset; + uint8 Pixel, N; + uint16* Screen = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.ZBuffer + Offset; + uint8* SubDepth = GFX.SubZBuffer + Offset; for (N = 0; N < 4; N++) - { - if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) - { - if (SubDepth [N] == 1) - Screen [N] = (uint16) COLOR_SUB1_2 (ScreenColors [Pixel], GFX.FixedColour); - else - Screen [N] = ScreenColors [Pixel]; - Depth [N] = GFX.Z2; - } - } + { + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) + { + if (SubDepth [N] == 1) + Screen [N] = (uint16) COLOR_SUB1_2(ScreenColors [Pixel], GFX.FixedColour); + else + Screen [N] = ScreenColors [Pixel]; + Depth [N] = GFX.Z2; + } + } } -static void WRITE_4PIXELS16_FLIPPED_SUBF1_2 (int32 Offset, uint8 *Pixels, uint16 *ScreenColors) +static void WRITE_4PIXELS16_FLIPPED_SUBF1_2(int32 Offset, uint8* Pixels, + uint16* ScreenColors) { - uint8 Pixel,N; - uint16 *Screen = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.ZBuffer + Offset; - uint8 *SubDepth = GFX.SubZBuffer + Offset; + uint8 Pixel, N; + uint16* Screen = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.ZBuffer + Offset; + uint8* SubDepth = GFX.SubZBuffer + Offset; for (N = 0; N < 4; N++) - { - if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) - { - if (SubDepth [N] == 1) - Screen [N] = (uint16) COLOR_SUB1_2 (ScreenColors [Pixel], GFX.FixedColour); - else - Screen [N] = ScreenColors [Pixel]; - Depth [N] = GFX.Z2; - } - } + { + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) + { + if (SubDepth [N] == 1) + Screen [N] = (uint16) COLOR_SUB1_2(ScreenColors [Pixel], GFX.FixedColour); + else + Screen [N] = ScreenColors [Pixel]; + Depth [N] = GFX.Z2; + } + } } -void DrawTile16FixedAdd1_2 (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount) +void DrawTile16FixedAdd1_2(uint32 Tile, int32 Offset, uint32 StartLine, + uint32 LineCount) { - TILE_PREAMBLE - register uint8 *bp; + TILE_PREAMBLE + register uint8* bp; - RENDER_TILE(WRITE_4PIXELS16_ADDF1_2, WRITE_4PIXELS16_FLIPPED_ADDF1_2, 4) + RENDER_TILE(WRITE_4PIXELS16_ADDF1_2, WRITE_4PIXELS16_FLIPPED_ADDF1_2, 4) } -void DrawClippedTile16FixedAdd1_2 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount) +void DrawClippedTile16FixedAdd1_2(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount) { - TILE_PREAMBLE - register uint8 *bp; + TILE_PREAMBLE + register uint8* bp; - TILE_CLIP_PREAMBLE - RENDER_CLIPPED_TILE(WRITE_4PIXELS16_ADDF1_2, - WRITE_4PIXELS16_FLIPPED_ADDF1_2, 4) + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16_ADDF1_2, + WRITE_4PIXELS16_FLIPPED_ADDF1_2, 4) } -void DrawTile16FixedSub1_2 (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount) +void DrawTile16FixedSub1_2(uint32 Tile, int32 Offset, uint32 StartLine, + uint32 LineCount) { - TILE_PREAMBLE - register uint8 *bp; + TILE_PREAMBLE + register uint8* bp; - RENDER_TILE(WRITE_4PIXELS16_SUBF1_2, WRITE_4PIXELS16_FLIPPED_SUBF1_2, 4) + RENDER_TILE(WRITE_4PIXELS16_SUBF1_2, WRITE_4PIXELS16_FLIPPED_SUBF1_2, 4) } -void DrawClippedTile16FixedSub1_2 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount) +void DrawClippedTile16FixedSub1_2(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount) { - TILE_PREAMBLE - register uint8 *bp; + TILE_PREAMBLE + register uint8* bp; - TILE_CLIP_PREAMBLE - RENDER_CLIPPED_TILE(WRITE_4PIXELS16_SUBF1_2, - WRITE_4PIXELS16_FLIPPED_SUBF1_2, 4) + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16_SUBF1_2, + WRITE_4PIXELS16_FLIPPED_SUBF1_2, 4) } -void DrawLargePixel16Add (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Pixels, - uint32 StartLine, uint32 LineCount) +void DrawLargePixel16Add(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount) { - TILE_PREAMBLE + TILE_PREAMBLE - register uint16 *sp = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.ZBuffer + Offset; - uint16 pixel; + register uint16* sp = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.ZBuffer + Offset; + uint16 pixel; #define LARGE_ADD_PIXEL(s, p) \ (Depth [z + GFX.DepthDelta] ? (Depth [z + GFX.DepthDelta] != 1 ? \ - COLOR_ADD (p, *(s + GFX.Delta)) : \ - COLOR_ADD (p, GFX.FixedColour)) \ - : p) - - RENDER_TILE_LARGE (ScreenColors [pixel], LARGE_ADD_PIXEL) + COLOR_ADD (p, *(s + GFX.Delta)) : \ + COLOR_ADD (p, GFX.FixedColour)) \ + : p) + + RENDER_TILE_LARGE(ScreenColors [pixel], LARGE_ADD_PIXEL) } -void DrawLargePixel16Add1_2 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Pixels, - uint32 StartLine, uint32 LineCount) +void DrawLargePixel16Add1_2(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount) { - TILE_PREAMBLE + TILE_PREAMBLE - register uint16 *sp = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.ZBuffer + Offset; - uint16 pixel; + register uint16* sp = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.ZBuffer + Offset; + uint16 pixel; #define LARGE_ADD_PIXEL1_2(s, p) \ ((uint16) (Depth [z + GFX.DepthDelta] ? (Depth [z + GFX.DepthDelta] != 1 ? \ - COLOR_ADD1_2 (p, *(s + GFX.Delta)) : \ - COLOR_ADD (p, GFX.FixedColour)) \ - : p)) - - RENDER_TILE_LARGE (ScreenColors [pixel], LARGE_ADD_PIXEL1_2) + COLOR_ADD1_2 (p, *(s + GFX.Delta)) : \ + COLOR_ADD (p, GFX.FixedColour)) \ + : p)) + + RENDER_TILE_LARGE(ScreenColors [pixel], LARGE_ADD_PIXEL1_2) } -void DrawLargePixel16Sub (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Pixels, - uint32 StartLine, uint32 LineCount) +void DrawLargePixel16Sub(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount) { - TILE_PREAMBLE + TILE_PREAMBLE - register uint16 *sp = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.ZBuffer + Offset; - uint16 pixel; + register uint16* sp = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.ZBuffer + Offset; + uint16 pixel; #define LARGE_SUB_PIXEL(s, p) \ (Depth [z + GFX.DepthDelta] ? (Depth [z + GFX.DepthDelta] != 1 ? \ - COLOR_SUB (p, *(s + GFX.Delta)) : \ - COLOR_SUB (p, GFX.FixedColour)) \ - : p) - - RENDER_TILE_LARGE (ScreenColors [pixel], LARGE_SUB_PIXEL) + COLOR_SUB (p, *(s + GFX.Delta)) : \ + COLOR_SUB (p, GFX.FixedColour)) \ + : p) + + RENDER_TILE_LARGE(ScreenColors [pixel], LARGE_SUB_PIXEL) } -void DrawLargePixel16Sub1_2 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Pixels, - uint32 StartLine, uint32 LineCount) +void DrawLargePixel16Sub1_2(uint32 Tile, int32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount) { - TILE_PREAMBLE + TILE_PREAMBLE - register uint16 *sp = (uint16 *) GFX.S + Offset; - uint8 *Depth = GFX.ZBuffer + Offset; - uint16 pixel; + register uint16* sp = (uint16*) GFX.S + Offset; + uint8* Depth = GFX.ZBuffer + Offset; + uint16 pixel; #define LARGE_SUB_PIXEL1_2(s, p) \ (Depth [z + GFX.DepthDelta] ? (Depth [z + GFX.DepthDelta] != 1 ? \ - COLOR_SUB1_2 (p, *(s + GFX.Delta)) : \ - COLOR_SUB (p, GFX.FixedColour)) \ - : p) - - RENDER_TILE_LARGE (ScreenColors [pixel], LARGE_SUB_PIXEL1_2) + COLOR_SUB1_2 (p, *(s + GFX.Delta)) : \ + COLOR_SUB (p, GFX.FixedColour)) \ + : p) + + RENDER_TILE_LARGE(ScreenColors [pixel], LARGE_SUB_PIXEL1_2) } diff --git a/source/tile.h b/source/tile.h index ee52e19..7e70ddc 100644 --- a/source/tile.h +++ b/source/tile.h @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,46 +43,46 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ @@ -94,7 +94,7 @@ \ uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); \ if ((Tile & 0x1ff) >= 256) \ - TileAddr += BG.NameSelect; \ + TileAddr += BG.NameSelect; \ \ TileAddr &= 0xffff; \ \ @@ -102,64 +102,64 @@ pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) << 6]; \ \ if (!BG.Buffered [TileNumber]) \ - BG.Buffered[TileNumber] = ConvertTile (pCache, TileAddr); \ + BG.Buffered[TileNumber] = ConvertTile (pCache, TileAddr); \ \ if (BG.Buffered [TileNumber] == BLANK_TILE) \ - return; \ + return; \ \ register uint32 l; \ uint16 *ScreenColors; \ if (BG.DirectColourMode) \ { \ - if (IPPU.DirectColourMapsNeedRebuild) \ + if (IPPU.DirectColourMapsNeedRebuild) \ S9xBuildDirectColourMaps (); \ ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; \ } \ else \ - ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; #define RENDER_TILE(NORMAL, FLIPPED, N) \ switch (Tile & (V_FLIP | H_FLIP)) \ { \ case 0: \ - bp = pCache + StartLine; \ - for (l = LineCount; l != 0; l--, bp += 8, Offset += GFX.PPL) \ - { \ - if (*(uint32 *) bp) \ - NORMAL (Offset, bp, ScreenColors); \ - if (*(uint32 *) (bp + 4)) \ - NORMAL (Offset + N, bp + 4, ScreenColors); \ - } \ + bp = pCache + StartLine; \ + for (l = LineCount; l != 0; l--, bp += 8, Offset += GFX.PPL) \ + { \ + if (*(uint32 *) bp) \ + NORMAL (Offset, bp, ScreenColors); \ + if (*(uint32 *) (bp + 4)) \ + NORMAL (Offset + N, bp + 4, ScreenColors); \ + } \ break; \ case H_FLIP: \ - bp = pCache + StartLine; \ - for (l = LineCount; l != 0; l--, bp += 8, Offset += GFX.PPL) \ - { \ - if (*(uint32 *) (bp + 4)) \ - FLIPPED (Offset, bp + 4, ScreenColors); \ - if (*(uint32 *) bp) \ - FLIPPED (Offset + N, bp, ScreenColors); \ - } \ + bp = pCache + StartLine; \ + for (l = LineCount; l != 0; l--, bp += 8, Offset += GFX.PPL) \ + { \ + if (*(uint32 *) (bp + 4)) \ + FLIPPED (Offset, bp + 4, ScreenColors); \ + if (*(uint32 *) bp) \ + FLIPPED (Offset + N, bp, ScreenColors); \ + } \ break; \ case H_FLIP | V_FLIP: \ - bp = pCache + 56 - StartLine; \ - for (l = LineCount; l != 0; l--, bp -= 8, Offset += GFX.PPL) \ - { \ - if (*(uint32 *) (bp + 4)) \ - FLIPPED (Offset, bp + 4, ScreenColors); \ - if (*(uint32 *) bp) \ - FLIPPED (Offset + N, bp, ScreenColors); \ - } \ + bp = pCache + 56 - StartLine; \ + for (l = LineCount; l != 0; l--, bp -= 8, Offset += GFX.PPL) \ + { \ + if (*(uint32 *) (bp + 4)) \ + FLIPPED (Offset, bp + 4, ScreenColors); \ + if (*(uint32 *) bp) \ + FLIPPED (Offset + N, bp, ScreenColors); \ + } \ break; \ case V_FLIP: \ - bp = pCache + 56 - StartLine; \ - for (l = LineCount; l != 0; l--, bp -= 8, Offset += GFX.PPL) \ - { \ - if (*(uint32 *) bp) \ - NORMAL (Offset, bp, ScreenColors); \ - if (*(uint32 *) (bp + 4)) \ - NORMAL (Offset + N, bp + 4, ScreenColors); \ - } \ + bp = pCache + 56 - StartLine; \ + for (l = LineCount; l != 0; l--, bp -= 8, Offset += GFX.PPL) \ + { \ + if (*(uint32 *) bp) \ + NORMAL (Offset, bp, ScreenColors); \ + if (*(uint32 *) (bp + 4)) \ + NORMAL (Offset + N, bp + 4, ScreenColors); \ + } \ break; \ default: \ break; \ @@ -171,76 +171,76 @@ \ if (StartPixel < 4) \ { \ - d1 = HeadMask [StartPixel]; \ - if (StartPixel + Width < 4) \ - d1 &= TailMask [StartPixel + Width]; \ + d1 = HeadMask [StartPixel]; \ + if (StartPixel + Width < 4) \ + d1 &= TailMask [StartPixel + Width]; \ } \ else \ - d1 = 0; \ + d1 = 0; \ \ if (StartPixel + Width > 4) \ { \ - if (StartPixel > 4) \ - d2 = HeadMask [StartPixel - 4]; \ - else \ - d2 = 0xffffffff; \ + if (StartPixel > 4) \ + d2 = HeadMask [StartPixel - 4]; \ + else \ + d2 = 0xffffffff; \ \ - d2 &= TailMask [(StartPixel + Width - 4)]; \ + d2 &= TailMask [(StartPixel + Width - 4)]; \ } \ else \ - d2 = 0; + d2 = 0; #define RENDER_CLIPPED_TILE(NORMAL, FLIPPED, N) \ uint32 dd; \ switch (Tile & (V_FLIP | H_FLIP)) \ { \ case 0: \ - bp = pCache + StartLine; \ - for (l = LineCount; l != 0; l--, bp += 8, Offset += GFX.PPL) \ - { \ + bp = pCache + StartLine; \ + for (l = LineCount; l != 0; l--, bp += 8, Offset += GFX.PPL) \ + { \ /* This is perfectly OK, regardless of endian. The tiles are \ * cached in leftmost-endian order (when not horiz flipped) by \ * the ConvertTile function. \ */ \ - if ((dd = (*(uint32 *) bp) & d1)) \ - NORMAL (Offset, (uint8 *) &dd, ScreenColors); \ - if ((dd = (*(uint32 *) (bp + 4)) & d2)) \ - NORMAL (Offset + N, (uint8 *) &dd, ScreenColors); \ - } \ + if ((dd = (*(uint32 *) bp) & d1)) \ + NORMAL (Offset, (uint8 *) &dd, ScreenColors); \ + if ((dd = (*(uint32 *) (bp + 4)) & d2)) \ + NORMAL (Offset + N, (uint8 *) &dd, ScreenColors); \ + } \ break; \ case H_FLIP: \ - bp = pCache + StartLine; \ - SWAP_DWORD (d1); \ - SWAP_DWORD (d2); \ - for (l = LineCount; l != 0; l--, bp += 8, Offset += GFX.PPL) \ - { \ - if ((dd = *(uint32 *) (bp + 4) & d1)) \ - FLIPPED (Offset, (uint8 *) &dd, ScreenColors); \ - if ((dd = *(uint32 *) bp & d2)) \ - FLIPPED (Offset + N, (uint8 *) &dd, ScreenColors); \ - } \ + bp = pCache + StartLine; \ + SWAP_DWORD (d1); \ + SWAP_DWORD (d2); \ + for (l = LineCount; l != 0; l--, bp += 8, Offset += GFX.PPL) \ + { \ + if ((dd = *(uint32 *) (bp + 4) & d1)) \ + FLIPPED (Offset, (uint8 *) &dd, ScreenColors); \ + if ((dd = *(uint32 *) bp & d2)) \ + FLIPPED (Offset + N, (uint8 *) &dd, ScreenColors); \ + } \ break; \ case H_FLIP | V_FLIP: \ - bp = pCache + 56 - StartLine; \ - SWAP_DWORD (d1); \ - SWAP_DWORD (d2); \ - for (l = LineCount; l != 0; l--, bp -= 8, Offset += GFX.PPL) \ - { \ - if ((dd = *(uint32 *) (bp + 4) & d1)) \ - FLIPPED (Offset, (uint8 *) &dd, ScreenColors); \ - if ((dd = *(uint32 *) bp & d2)) \ - FLIPPED (Offset + N, (uint8 *) &dd, ScreenColors); \ - } \ + bp = pCache + 56 - StartLine; \ + SWAP_DWORD (d1); \ + SWAP_DWORD (d2); \ + for (l = LineCount; l != 0; l--, bp -= 8, Offset += GFX.PPL) \ + { \ + if ((dd = *(uint32 *) (bp + 4) & d1)) \ + FLIPPED (Offset, (uint8 *) &dd, ScreenColors); \ + if ((dd = *(uint32 *) bp & d2)) \ + FLIPPED (Offset + N, (uint8 *) &dd, ScreenColors); \ + } \ break; \ case V_FLIP: \ - bp = pCache + 56 - StartLine; \ - for (l = LineCount; l != 0; l--, bp -= 8, Offset += GFX.PPL) \ - { \ - if ((dd = (*(uint32 *) bp) & d1)) \ - NORMAL (Offset, (uint8 *) &dd, ScreenColors); \ - if ((dd = (*(uint32 *) (bp + 4)) & d2)) \ - NORMAL (Offset + N, (uint8 *) &dd, ScreenColors); \ - } \ + bp = pCache + 56 - StartLine; \ + for (l = LineCount; l != 0; l--, bp -= 8, Offset += GFX.PPL) \ + { \ + if ((dd = (*(uint32 *) bp) & d1)) \ + NORMAL (Offset, (uint8 *) &dd, ScreenColors); \ + if ((dd = (*(uint32 *) (bp + 4)) & d2)) \ + NORMAL (Offset + N, (uint8 *) &dd, ScreenColors); \ + } \ break; \ default: \ break; \ @@ -250,42 +250,42 @@ switch (Tile & (V_FLIP | H_FLIP)) \ { \ case H_FLIP: \ - StartPixel = 7 - StartPixel; \ + StartPixel = 7 - StartPixel; \ /* fallthrough for no-flip case - above was a horizontal flip */ \ case 0: \ - if ((pixel = *(pCache + StartLine + StartPixel))) \ - { \ - pixel = PIXEL; \ - for (l = LineCount; l != 0; l--, sp += GFX.PPL, Depth += GFX.PPL) \ - { \ + if ((pixel = *(pCache + StartLine + StartPixel))) \ + { \ + pixel = PIXEL; \ + for (l = LineCount; l != 0; l--, sp += GFX.PPL, Depth += GFX.PPL) \ + { \ int z; \ for (z = Pixels - 1; z >= 0; z--) \ - if (GFX.Z1 > Depth [z]) \ - { \ - sp [z] = FUNCTION(sp + z, pixel); \ - Depth [z] = GFX.Z2; \ - }\ - } \ - } \ + if (GFX.Z1 > Depth [z]) \ + { \ + sp [z] = FUNCTION(sp + z, pixel); \ + Depth [z] = GFX.Z2; \ + }\ + } \ + } \ break; \ case H_FLIP | V_FLIP: \ - StartPixel = 7 - StartPixel; \ + StartPixel = 7 - StartPixel; \ /* fallthrough for V_FLIP-only case - above was a horizontal flip */ \ case V_FLIP: \ - if ((pixel = *(pCache + 56 - StartLine + StartPixel))) \ - { \ - pixel = PIXEL; \ - for (l = LineCount; l != 0; l--, sp += GFX.PPL, Depth += GFX.PPL) \ - { \ + if ((pixel = *(pCache + 56 - StartLine + StartPixel))) \ + { \ + pixel = PIXEL; \ + for (l = LineCount; l != 0; l--, sp += GFX.PPL, Depth += GFX.PPL) \ + { \ int z; \ for (z = Pixels - 1; z >= 0; z--) \ - if (GFX.Z1 > Depth [z]) \ - { \ - sp [z] = FUNCTION(sp + z, pixel); \ - Depth [z] = GFX.Z2; \ - }\ - } \ - } \ + if (GFX.Z1 > Depth [z]) \ + { \ + sp [z] = FUNCTION(sp + z, pixel); \ + Depth [z] = GFX.Z2; \ + }\ + } \ + } \ break; \ default: \ break; \ @@ -295,42 +295,42 @@ switch (Tile & (V_FLIP | H_FLIP)) \ { \ case H_FLIP: \ - StartPixel = 7 - StartPixel; \ + StartPixel = 7 - StartPixel; \ /* fallthrough for no-flip case - above was a horizontal flip */ \ case 0: \ - if ((pixel = *(pCache + StartLine + StartPixel))) \ - { \ - pixel = PIXEL; \ - for (l = LineCount; l != 0; l--, sp += GFX.PPL, Depth += GFX.PPL) \ - { \ + if ((pixel = *(pCache + StartLine + StartPixel))) \ + { \ + pixel = PIXEL; \ + for (l = LineCount; l != 0; l--, sp += GFX.PPL, Depth += GFX.PPL) \ + { \ int z; \ - for (z = Pixels - 2; z >= 0; z -= 2) \ - if (GFX.Z1 > Depth [z]) \ - { \ - sp [z >> 1] = FUNCTION(sp + z, pixel); \ - Depth [z >> 1] = GFX.Z2; \ - }\ - } \ - } \ + for (z = Pixels - 2; z >= 0; z -= 2) \ + if (GFX.Z1 > Depth [z]) \ + { \ + sp [z >> 1] = FUNCTION(sp + z, pixel); \ + Depth [z >> 1] = GFX.Z2; \ + }\ + } \ + } \ break; \ case H_FLIP | V_FLIP: \ - StartPixel = 7 - StartPixel; \ + StartPixel = 7 - StartPixel; \ /* fallthrough for V_FLIP-only case - above was a horizontal flip */ \ case V_FLIP: \ - if ((pixel = *(pCache + 56 - StartLine + StartPixel))) \ - { \ - pixel = PIXEL; \ - for (l = LineCount; l != 0; l--, sp += GFX.PPL, Depth += GFX.PPL) \ - { \ + if ((pixel = *(pCache + 56 - StartLine + StartPixel))) \ + { \ + pixel = PIXEL; \ + for (l = LineCount; l != 0; l--, sp += GFX.PPL, Depth += GFX.PPL) \ + { \ int z; \ for (z = Pixels - 2; z >= 0; z -= 2) \ - if (GFX.Z1 > Depth [z]) \ - { \ - sp [z >> 1] = FUNCTION(sp + z, pixel); \ - Depth [z >> 1] = GFX.Z2; \ - }\ - } \ - } \ + if (GFX.Z1 > Depth [z]) \ + { \ + sp [z >> 1] = FUNCTION(sp + z, pixel); \ + Depth [z >> 1] = GFX.Z2; \ + }\ + } \ + } \ break; \ default: \ break; \ -- cgit v1.2.3