From 8b73ba19139c2998a4372d9cabff11f956b256a2 Mon Sep 17 00:00:00 2001 From: Daryl Borth Date: Sun, 11 Nov 2018 18:31:52 -0700 Subject: [PATCH] upgrade core to 1.57 --- source/snes9x/65c816.h | 25 +- source/snes9x/bsx.cpp | 10 +- source/snes9x/c4.cpp | 26 +- source/snes9x/c4.h | 25 +- source/snes9x/c4emu.cpp | 32 +- source/snes9x/cheats2.cpp | 3 +- source/snes9x/clip.cpp | 25 +- source/snes9x/controls.cpp | 45 +- source/snes9x/cpu.cpp | 4 +- source/snes9x/cpuaddr.h | 27 +- source/snes9x/cpumacro.h | 218 +- source/snes9x/dma.h | 25 +- source/snes9x/dsp.cpp | 25 +- source/snes9x/dsp.h | 25 +- source/snes9x/dsp1.cpp | 35 +- source/snes9x/dsp2.cpp | 25 +- source/snes9x/dsp3.cpp | 27 +- source/snes9x/dsp4.cpp | 25 +- source/snes9x/font.h | 25 +- source/snes9x/fxemu.cpp | 5 +- source/snes9x/fxemu.h | 25 +- source/snes9x/fxinst.cpp | 46 +- source/snes9x/fxinst.h | 25 +- source/snes9x/getset.h | 3 +- source/snes9x/gfx.cpp | 312 +-- source/snes9x/gfx.h | 26 +- source/snes9x/globals.cpp | 25 +- source/snes9x/language.h | 27 +- source/snes9x/logger.cpp | 25 +- source/snes9x/logger.h | 25 +- source/snes9x/memmap.cpp | 30 +- source/snes9x/memmap.h | 1 + source/snes9x/messages.h | 25 +- source/snes9x/missing.h | 25 +- source/snes9x/movie.cpp | 69 +- source/snes9x/movie.h | 27 +- source/snes9x/msu1.cpp | 64 +- source/snes9x/msu1.h | 18 +- source/snes9x/obc1.cpp | 25 +- source/snes9x/obc1.h | 25 +- source/snes9x/pixform.h | 25 +- source/snes9x/port.h | 78 +- source/snes9x/ppu.cpp | 4235 +++++++++++++++++----------------- source/snes9x/ppu.h | 35 +- source/snes9x/sa1.cpp | 6 +- source/snes9x/sar.h | 25 +- source/snes9x/screenshot.cpp | 25 +- source/snes9x/screenshot.h | 25 +- source/snes9x/sdd1.cpp | 25 +- source/snes9x/sdd1.h | 25 +- source/snes9x/sdd1emu.cpp | 25 +- source/snes9x/sdd1emu.h | 25 +- source/snes9x/seta.cpp | 25 +- source/snes9x/seta.h | 25 +- source/snes9x/seta010.cpp | 677 +++--- source/snes9x/seta011.cpp | 25 +- source/snes9x/seta018.cpp | 25 +- source/snes9x/sha256.cpp | 5 +- source/snes9x/snapshot.cpp | 31 +- source/snes9x/snapshot.h | 7 +- source/snes9x/snes9x.h | 4 +- source/snes9x/spc7110.cpp | 25 +- source/snes9x/spc7110.h | 25 +- source/snes9x/spc7110dec.cpp | 2 +- source/snes9x/srtc.cpp | 25 +- source/snes9x/srtc.h | 25 +- source/snes9x/stream.cpp | 35 +- source/snes9x/stream.h | 13 +- source/snes9x/tile.cpp | 117 +- source/snes9x/tile.h | 25 +- 70 files changed, 3937 insertions(+), 3238 deletions(-) diff --git a/source/snes9x/65c816.h b/source/snes9x/65c816.h index 995fcbb..183c695 100644 --- a/source/snes9x/65c816.h +++ b/source/snes9x/65c816.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/bsx.cpp b/source/snes9x/bsx.cpp index b279736..07c6b36 100644 --- a/source/snes9x/bsx.cpp +++ b/source/snes9x/bsx.cpp @@ -399,7 +399,7 @@ static void BSX_Map_FlashIO (void) BlockIsROM[i + 0x400] = BlockIsROM[i + 0xC00] = FALSE; } } - } + } } static void BSX_Map_SRAM (void) @@ -677,12 +677,12 @@ static void BSX_Map (void) MapROM = FlashROM; FlashSize = FLASH_SIZE; - + if (BSX.prevMMC[0x02]) BSX_Map_HiROM(); else BSX_Map_LoROM(); - + BSX_Map_FlashIO(); BSX_Map_PSRAM(); @@ -804,7 +804,7 @@ void S9xSetBSX (uint8 byte, uint32 address) } // Flash IO - + // Write to Flash if (BSX.write_enable) { @@ -814,7 +814,7 @@ void S9xSetBSX (uint8 byte, uint32 address) } // Flash Command Handling - + //Memory Pack Type 1 & 3 & 4 BSX.flash_command <<= 8; BSX.flash_command |= byte; diff --git a/source/snes9x/c4.cpp b/source/snes9x/c4.cpp index d586e79..922c205 100644 --- a/source/snes9x/c4.cpp +++ b/source/snes9x/c4.cpp @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in @@ -294,7 +309,6 @@ void C4Op1F (void) { tanval = (double) C41FYVal / C41FXVal; C41FAngleRes = (int16) (atan(tanval) / (C4_PI * 2) * 512); - C41FAngleRes = C41FAngleRes; if (C41FXVal< 0) C41FAngleRes += 0x100; C41FAngleRes &= 0x1FF; diff --git a/source/snes9x/c4.h b/source/snes9x/c4.h index 9b4c607..bbd3780 100644 --- a/source/snes9x/c4.h +++ b/source/snes9x/c4.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/c4emu.cpp b/source/snes9x/c4emu.cpp index 65e0f55..ddab202 100644 --- a/source/snes9x/c4emu.cpp +++ b/source/snes9x/c4emu.cpp @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in @@ -1192,10 +1207,11 @@ void S9xSetC4 (uint8 byte, uint16 Address) if (Memory.C4RAM[0x1f4d] != 0x0e) printf("$7f4d=%02x, expected 0e for command 54 %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]); #endif - int64 a = SAR((int64) READ_3WORD(Memory.C4RAM + 0x1f80) << 40, 40); - //printf("%08X%08X\n", (uint32) (a>>32), (uint32) (a&0xFFFFFFFF)); + int64 b = (int64) READ_3WORD(Memory.C4RAM + 0x1f80); + int64 c = b << 40; + int64 a = SAR(c, 30); + a = SAR(c, 10); 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; diff --git a/source/snes9x/cheats2.cpp b/source/snes9x/cheats2.cpp index ccafe3e..777efb3 100644 --- a/source/snes9x/cheats2.cpp +++ b/source/snes9x/cheats2.cpp @@ -607,6 +607,7 @@ int S9xAddCheatGroup (const char *name, const char *cheat) return -1; Cheat.g.push_back (g); + return Cheat.g.size () - 1; } @@ -942,4 +943,4 @@ int S9xImportCheatsFromDatabase (const char *filename) bml_free_node (bml); return -2; /* No codes */ -} \ No newline at end of file +} diff --git a/source/snes9x/clip.cpp b/source/snes9x/clip.cpp index 8e6baa3..5ff8c8a 100644 --- a/source/snes9x/clip.cpp +++ b/source/snes9x/clip.cpp @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/controls.cpp b/source/snes9x/controls.cpp index 7245809..975c499 100644 --- a/source/snes9x/controls.cpp +++ b/source/snes9x/controls.cpp @@ -3085,6 +3085,16 @@ void S9xSetJoypadLatch (bool latch) FLAG_LATCH = latch; } +// prevent read_idx from overflowing (only latching resets it) +// otherwise $4016/7 reads will start returning input data again +static inline uint8 IncreaseReadIdxPost(uint8 &var) +{ + uint8 oldval = var; + if (var < 255) + var++; + return oldval; +} + uint8 S9xReadJOYSERn (int n) { int i, j, r; @@ -3139,7 +3149,7 @@ uint8 S9xReadJOYSERn (int n) switch (i = curcontrollers[n]) { case MP5: - r = read_idx[n][FLAG_IOBIT(n) ? 0 : 1]++; + r = IncreaseReadIdxPost(read_idx[n][FLAG_IOBIT(n) ? 0 : 1]); j = FLAG_IOBIT(n) ? 0 : 2; for (i = 0; i < 2; i++, j++) @@ -3164,64 +3174,64 @@ uint8 S9xReadJOYSERn (int n) case JOYPAD7: if (read_idx[n][0] >= 16) { - read_idx[n][0]++; + IncreaseReadIdxPost(read_idx[n][0]); return (bits | 1); } else - return (bits | ((joypad[i - JOYPAD0].buttons & (0x8000 >> read_idx[n][0]++)) ? 1 : 0)); + return (bits | ((joypad[i - JOYPAD0].buttons & (0x8000 >> IncreaseReadIdxPost(read_idx[n][0]))) ? 1 : 0)); case MOUSE0: case MOUSE1: if (read_idx[n][0] < 8) { - read_idx[n][0]++; + IncreaseReadIdxPost(read_idx[n][0]); return (bits); } else if (read_idx[n][0] < 16) - return (bits | ((mouse[i - MOUSE0].buttons & (0x8000 >> read_idx[n][0]++)) ? 1 : 0)); + return (bits | ((mouse[i - MOUSE0].buttons & (0x8000 >> IncreaseReadIdxPost(read_idx[n][0]))) ? 1 : 0)); else if (read_idx[n][0] < 24) - return (bits | ((mouse[i - MOUSE0].delta_y & (0x800000 >> read_idx[n][0]++)) ? 1 : 0)); + return (bits | ((mouse[i - MOUSE0].delta_y & (0x800000 >> IncreaseReadIdxPost(read_idx[n][0]))) ? 1 : 0)); else if (read_idx[n][0] < 32) - return (bits | ((mouse[i - MOUSE0].delta_x & (0x80000000 >> read_idx[n][0]++)) ? 1 : 0)); + return (bits | ((mouse[i - MOUSE0].delta_x & (0x80000000 >> IncreaseReadIdxPost(read_idx[n][0]))) ? 1 : 0)); else { - read_idx[n][0]++; + IncreaseReadIdxPost(read_idx[n][0]); return (bits | 1); } case SUPERSCOPE: if (read_idx[n][0] < 8) - return (bits | ((superscope.read_buttons & (0x80 >> read_idx[n][0]++)) ? 1 : 0)); + return (bits | ((superscope.read_buttons & (0x80 >> IncreaseReadIdxPost(read_idx[n][0]))) ? 1 : 0)); else { - read_idx[n][0]++; + IncreaseReadIdxPost(read_idx[n][0]); return (bits | 1); } case ONE_JUSTIFIER: if (read_idx[n][0] < 24) - return (bits | ((0xaa7000 >> read_idx[n][0]++) & 1)); + return (bits | ((0xaa7000 >> IncreaseReadIdxPost(read_idx[n][0])) & 1)); else if (read_idx[n][0] < 32) - return (bits | ((justifier.buttons & (JUSTIFIER_TRIGGER | JUSTIFIER_START | JUSTIFIER_SELECT) & (0x80000000 >> read_idx[n][0]++)) ? 1 : 0)); + return (bits | ((justifier.buttons & (JUSTIFIER_TRIGGER | JUSTIFIER_START | JUSTIFIER_SELECT) & (0x80000000 >> IncreaseReadIdxPost(read_idx[n][0]))) ? 1 : 0)); else { - read_idx[n][0]++; + IncreaseReadIdxPost(read_idx[n][0]); return (bits | 1); } case TWO_JUSTIFIERS: if (read_idx[n][0] < 24) - return (bits | ((0xaa7000 >> read_idx[n][0]++) & 1)); + return (bits | ((0xaa7000 >> IncreaseReadIdxPost(read_idx[n][0])) & 1)); else if (read_idx[n][0] < 32) - return (bits | ((justifier.buttons & (0x80000000 >> read_idx[n][0]++)) ? 1 : 0)); + return (bits | ((justifier.buttons & (0x80000000 >> IncreaseReadIdxPost(read_idx[n][0]))) ? 1 : 0)); else { - read_idx[n][0]++; + IncreaseReadIdxPost(read_idx[n][0]); return (bits | 1); } @@ -3230,7 +3240,7 @@ uint8 S9xReadJOYSERn (int n) return (bits | ((macsrifle.buttons & 0x01) ? 1 : 0)); default: - read_idx[n][0]++; + IncreaseReadIdxPost(read_idx[n][0]); return (bits); } } @@ -3912,3 +3922,4 @@ void MovieSetMacsRifle (int i, uint8 in[5]) macsrifle.y = READ_WORD(ptr); ptr += 2; macsrifle.buttons = *ptr; } + diff --git a/source/snes9x/cpu.cpp b/source/snes9x/cpu.cpp index 74969e2..e9f7831 100644 --- a/source/snes9x/cpu.cpp +++ b/source/snes9x/cpu.cpp @@ -289,7 +289,7 @@ void S9xReset (void) memset(Memory.RAM, 0x55, 0x20000); memset(Memory.VRAM, 0x00, 0x10000); - ZeroMemory(Memory.FillRAM, 0x8000); + memset(Memory.FillRAM, 0, 0x8000); S9xResetBSX(); S9xResetCPU(); @@ -324,7 +324,7 @@ void S9xSoftReset (void) { S9xResetSaveTimer(FALSE); - ZeroMemory(Memory.FillRAM, 0x8000); + memset(Memory.FillRAM, 0, 0x8000); if (Settings.BS) S9xResetBSX(); diff --git a/source/snes9x/cpuaddr.h b/source/snes9x/cpuaddr.h index 3ae55c4..5662788 100644 --- a/source/snes9x/cpuaddr.h +++ b/source/snes9x/cpuaddr.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in @@ -287,6 +302,8 @@ static inline uint32 AbsoluteIndexedIndirectSlow (AccessMode a) // (a,X) static inline uint32 AbsoluteIndexedIndirect (AccessMode a) // (a,X) { uint16 addr = Immediate16Slow(READ); + + AddCycles(ONE_CYCLE); addr += Registers.X.W; // Address load wraps within the bank diff --git a/source/snes9x/cpumacro.h b/source/snes9x/cpumacro.h index 6a173f9..8d81f8e 100644 --- a/source/snes9x/cpumacro.h +++ b/source/snes9x/cpumacro.h @@ -315,57 +315,40 @@ static inline void ADC (uint16 Work16) { if (CheckDecimal()) { - uint16 A1 = Registers.A.W & 0x000F; - uint16 A2 = Registers.A.W & 0x00F0; - uint16 A3 = Registers.A.W & 0x0F00; - uint32 A4 = Registers.A.W & 0xF000; - uint16 W1 = Work16 & 0x000F; - uint16 W2 = Work16 & 0x00F0; - uint16 W3 = Work16 & 0x0F00; - uint16 W4 = Work16 & 0xF000; + uint32 result; + uint32 carry = CheckCarry(); - A1 += W1 + CheckCarry(); - if (A1 > 0x0009) - { - A1 -= 0x000A; - A1 &= 0x000F; - A2 += 0x0010; - } + result = (Registers.A.W & 0x000F) + (Work16 & 0x000F) + carry; + if (result > 0x0009) + result += 0x0006; + carry = (result > 0x000F); - A2 += W2; - if (A2 > 0x0090) - { - A2 -= 0x00A0; - A2 &= 0x00F0; - A3 += 0x0100; - } + result = (Registers.A.W & 0x00F0) + (Work16 & 0x00F0) + (result & 0x000F) + carry * 0x10; + if (result > 0x009F) + result += 0x0060; + carry = (result > 0x00FF); - A3 += W3; - if (A3 > 0x0900) - { - A3 -= 0x0A00; - A3 &= 0x0F00; - A4 += 0x1000; - } + result = (Registers.A.W & 0x0F00) + (Work16 & 0x0F00) + (result & 0x00FF) + carry * 0x100; + if (result > 0x09FF) + result += 0x0600; + carry = (result > 0x0FFF); - A4 += W4; - if (A4 > 0x9000) - { - A4 -= 0xA000; - A4 &= 0xF000; - SetCarry(); - } - else - ClearCarry(); + result = (Registers.A.W & 0xF000) + (Work16 & 0xF000) + (result & 0x0FFF) + carry * 0x1000; - uint16 Ans16 = A4 | A3 | A2 | A1; - - if (~(Registers.A.W ^ Work16) & (Work16 ^ Ans16) & 0x8000) + if ((Registers.A.W & 0x8000) == (Work16 & 0x8000) && (Registers.A.W & 0x8000) != (result & 0x8000)) SetOverflow(); else ClearOverflow(); - Registers.A.W = Ans16; + if (result > 0x9FFF) + result += 0x6000; + + if (result > 0xFFFF) + SetCarry(); + else + ClearCarry(); + + Registers.A.W = result & 0xFFFF; SetZN(Registers.A.W); } else @@ -388,37 +371,30 @@ static inline void ADC (uint8 Work8) { if (CheckDecimal()) { - uint8 A1 = Registers.A.W & 0x0F; - uint16 A2 = Registers.A.W & 0xF0; - uint8 W1 = Work8 & 0x0F; - uint8 W2 = Work8 & 0xF0; + uint32 result; + uint32 carry = CheckCarry(); - A1 += W1 + CheckCarry(); - if (A1 > 0x09) - { - A1 -= 0x0A; - A1 &= 0x0F; - A2 += 0x10; - } + result = (Registers.AL & 0x0F) + (Work8 & 0x0F) + carry; + if ( result > 0x09 ) + result += 0x06; + carry = (result > 0x0F); - A2 += W2; - if (A2 > 0x90) - { - A2 -= 0xA0; - A2 &= 0xF0; - SetCarry(); - } - else - ClearCarry(); + result = (Registers.AL & 0xF0) + (Work8 & 0xF0) + (result & 0x0F) + (carry * 0x10); - uint8 Ans8 = A2 | A1; - - if (~(Registers.AL ^ Work8) & (Work8 ^ Ans8) & 0x80) + if ((Registers.AL & 0x80) == (Work8 & 0x80) && (Registers.AL & 0x80) != (result & 0x80)) SetOverflow(); else ClearOverflow(); - Registers.AL = Ans8; + if (result > 0x9F) + result += 0x60; + + if (result > 0xFF) + SetCarry(); + else + ClearCarry(); + + Registers.AL = result & 0xFF; SetZN(Registers.AL); } else @@ -691,58 +667,42 @@ static inline void SBC (uint16 Work16) { if (CheckDecimal()) { - uint16 A1 = Registers.A.W & 0x000F; - uint16 A2 = Registers.A.W & 0x00F0; - uint16 A3 = Registers.A.W & 0x0F00; - uint32 A4 = Registers.A.W & 0xF000; - uint16 W1 = Work16 & 0x000F; - uint16 W2 = Work16 & 0x00F0; - uint16 W3 = Work16 & 0x0F00; - uint16 W4 = Work16 & 0xF000; + int result; + int carry = CheckCarry(); - A1 -= W1 + !CheckCarry(); - A2 -= W2; - A3 -= W3; - A4 -= W4; + Work16 ^= 0xFFFF; - if (A1 > 0x000F) - { - A1 += 0x000A; - A1 &= 0x000F; - A2 -= 0x0010; - } + result = (Registers.A.W & 0x000F) + (Work16 & 0x000F) + carry; + if (result < 0x0010) + result -= 0x0006; + carry = (result > 0x000F); - if (A2 > 0x00F0) - { - A2 += 0x00A0; - A2 &= 0x00F0; - A3 -= 0x0100; - } + result = (Registers.A.W & 0x00F0) + (Work16 & 0x00F0) + (result & 0x000F) + carry * 0x10; + if (result < 0x0100) + result -= 0x0060; + carry = (result > 0x00FF); - if (A3 > 0x0F00) - { - A3 += 0x0A00; - A3 &= 0x0F00; - A4 -= 0x1000; - } + result = (Registers.A.W & 0x0F00) + (Work16 & 0x0F00) + (result & 0x00FF) + carry * 0x100; + if (result < 0x1000) + result -= 0x0600; + carry = (result > 0x0FFF); - if (A4 > 0xF000) - { - A4 += 0xA000; - A4 &= 0xF000; - ClearCarry(); - } - else - SetCarry(); + result = (Registers.A.W & 0xF000) + (Work16 & 0xF000) + (result & 0x0FFF) + carry * 0x1000; - uint16 Ans16 = A4 | A3 | A2 | A1; - - if ((Registers.A.W ^ Work16) & (Registers.A.W ^ Ans16) & 0x8000) + if (((Registers.A.W ^ Work16) & 0x8000) == 0 && ((Registers.A.W ^ result) & 0x8000)) SetOverflow(); else ClearOverflow(); - Registers.A.W = Ans16; + if (result < 0x10000) + result -= 0x6000; + + if (result > 0xFFFF) + SetCarry(); + else + ClearCarry(); + + Registers.A.W = result & 0xFFFF; SetZN(Registers.A.W); } else @@ -765,38 +725,32 @@ static inline void SBC (uint8 Work8) { if (CheckDecimal()) { - uint8 A1 = Registers.A.W & 0x0F; - uint16 A2 = Registers.A.W & 0xF0; - uint8 W1 = Work8 & 0x0F; - uint8 W2 = Work8 & 0xF0; + int result; + int carry = CheckCarry(); - A1 -= W1 + !CheckCarry(); - A2 -= W2; + Work8 ^= 0xFF; - if (A1 > 0x0F) - { - A1 += 0x0A; - A1 &= 0x0F; - A2 -= 0x10; - } + result = (Registers.AL & 0x0F) + (Work8 & 0x0F) + carry; + if (result < 0x10) + result -= 0x06; + carry = (result > 0x0F); - if (A2 > 0xF0) - { - A2 += 0xA0; - A2 &= 0xF0; - ClearCarry(); - } - else - SetCarry(); + result = (Registers.AL & 0xF0) + (Work8 & 0xF0) + (result & 0x0F) + carry * 0x10; - uint8 Ans8 = A2 | A1; - - if ((Registers.AL ^ Work8) & (Registers.AL ^ Ans8) & 0x80) + if ((Registers.AL & 0x80) == (Work8 & 0x80) && (Registers.AL & 0x80) != (result & 0x80)) SetOverflow(); else ClearOverflow(); - Registers.AL = Ans8; + if (result < 0x100 ) + result -= 0x60; + + if (result > 0xFF) + SetCarry(); + else + ClearCarry(); + + Registers.AL = result & 0xFF; SetZN(Registers.AL); } else diff --git a/source/snes9x/dma.h b/source/snes9x/dma.h index c779a79..b5fa5c1 100644 --- a/source/snes9x/dma.h +++ b/source/snes9x/dma.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/dsp.cpp b/source/snes9x/dsp.cpp index b6e23ff..ab54185 100644 --- a/source/snes9x/dsp.cpp +++ b/source/snes9x/dsp.cpp @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/dsp.h b/source/snes9x/dsp.h index be4d073..7b9d371 100644 --- a/source/snes9x/dsp.h +++ b/source/snes9x/dsp.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/dsp1.cpp b/source/snes9x/dsp1.cpp index 85f9512..1628744 100644 --- a/source/snes9x/dsp1.cpp +++ b/source/snes9x/dsp1.cpp @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in @@ -881,9 +896,9 @@ static void DSP1_Project (int16 X, int16 Y, int16 Z, int16 *H, int16 *V, int16 * Py = DSP1_ShiftR(Py, E - refE); Pz = DSP1_ShiftR(Pz, E3 - refE); - C11 =- (Px * DSP1.Nx >> 15); - C8 =- (Py * DSP1.Ny >> 15); - C9 =- (Pz * DSP1.Nz >> 15); + C11 = -(Px * DSP1.Nx >> 15); + C8 = -(Py * DSP1.Ny >> 15); + C9 = -(Pz * DSP1.Nz >> 15); C12 = C11 + C8 + C9; // this cannot overflow! aux4 = C12; // de-normalization with 32-bits arithmetic @@ -1354,7 +1369,7 @@ void DSP1SetByte (uint8 byte, uint16 address) case 0x17: case 0x37: case 0x3F: - DSP1.command = 0x1f; + DSP1.command = 0x1f; // Fall through case 0x1f: DSP1.in_count = 1; break; default: #ifdef DEBUGGER @@ -1885,7 +1900,7 @@ uint8 DSP1GetByte (uint16 address) DSP1.waiting4command = TRUE; } else - t = 0xff; + t = 0x80; } else t = 0x80; diff --git a/source/snes9x/dsp2.cpp b/source/snes9x/dsp2.cpp index 477209b..fb6c9f8 100644 --- a/source/snes9x/dsp2.cpp +++ b/source/snes9x/dsp2.cpp @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/dsp3.cpp b/source/snes9x/dsp3.cpp index 5c79240..9ee6a5d 100644 --- a/source/snes9x/dsp3.cpp +++ b/source/snes9x/dsp3.cpp @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in @@ -1139,7 +1154,7 @@ static void DSP3_OP10 (void) DSP3_Reset(); else // absorb 2 bytes - DSP3.DR = DSP3.DR; + DSP3.DR = DSP3.DR; // FIXME? } /* diff --git a/source/snes9x/dsp4.cpp b/source/snes9x/dsp4.cpp index 9d6f3fd..63530db 100644 --- a/source/snes9x/dsp4.cpp +++ b/source/snes9x/dsp4.cpp @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/font.h b/source/snes9x/font.h index 27011f6..9614f45 100644 --- a/source/snes9x/font.h +++ b/source/snes9x/font.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/fxemu.cpp b/source/snes9x/fxemu.cpp index 09761a3..4c01a48 100644 --- a/source/snes9x/fxemu.cpp +++ b/source/snes9x/fxemu.cpp @@ -213,8 +213,9 @@ void S9xInitSuperFX (void) void S9xResetSuperFX (void) { - // FIXME: Snes9x can't execute CPU and SuperFX at a time. Don't ask me what is 0.417 :P - SuperFX.speedPerLine = (uint32) (0.417 * 10.5e6 * ((1.0 / (float) Memory.ROMFramesPerSecond) / ((float) (Timings.V_Max)))); + // FIXME: Snes9x only runs the SuperFX at the end of every line. + // 5823405 is a magic number that seems to work for most games. + SuperFX.speedPerLine = (uint32) (5823405 * ((1.0 / (float) Memory.ROMFramesPerSecond) / ((float) (Timings.V_Max)))); SuperFX.oneLineDone = FALSE; SuperFX.vFlags = 0; CPU.IRQExternal = FALSE; diff --git a/source/snes9x/fxemu.h b/source/snes9x/fxemu.h index b2ce64e..ac73d11 100644 --- a/source/snes9x/fxemu.h +++ b/source/snes9x/fxemu.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/fxinst.cpp b/source/snes9x/fxinst.cpp index 5f7df2b..ef661b6 100644 --- a/source/snes9x/fxinst.cpp +++ b/source/snes9x/fxinst.cpp @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in @@ -891,14 +906,14 @@ static void fx_plot_2bit (void) return; #endif + if (!(GSU.vPlotOptionReg & 0x01) && !(COLR & 0xf)) + return; + if (GSU.vPlotOptionReg & 0x02) - c = (x ^ y) & 1 ? (uint8) (GSU.vColorReg >> 4) : (uint8) GSU.vColorReg; + 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); @@ -955,14 +970,14 @@ static void fx_plot_4bit (void) return; #endif + if (!(GSU.vPlotOptionReg & 0x01) && !(COLR & 0xf)) + return; + if (GSU.vPlotOptionReg & 0x02) - c = (x ^ y) & 1 ? (uint8) (GSU.vColorReg >> 4) : (uint8) GSU.vColorReg; + 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); @@ -1034,7 +1049,7 @@ static void fx_plot_8bit (void) c = (uint8) GSU.vColorReg; if (!(GSU.vPlotOptionReg & 0x10)) { - if (!(GSU.vPlotOptionReg & 0x01) && !(c & 0xf)) + if (!(GSU.vPlotOptionReg & 0x01) && (!c || ((GSU.vPlotOptionReg & 0x08) && !(c & 0xf)))) return; } else @@ -1171,7 +1186,7 @@ static void fx_cmode (void) { GSU.vPlotOptionReg = SREG; - if (GSU.vPlotOptionReg & 0x10) + if (GSU.vPlotOptionReg & 0x10) GSU.vScreenHeight = 256; // OBJ Mode (for drawing into sprites) else GSU.vScreenHeight = GSU.vScreenRealHeight; @@ -4137,7 +4152,6 @@ static void fx_sm_r15 (void) uint32 fx_run (uint32 nInstructions) { GSU.vCounter = nInstructions; - READR14; while (TF(G) && (GSU.vCounter-- > 0)) FX_STEP; #if 0 diff --git a/source/snes9x/fxinst.h b/source/snes9x/fxinst.h index dd3736e..d2124bd 100644 --- a/source/snes9x/fxinst.h +++ b/source/snes9x/fxinst.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/getset.h b/source/snes9x/getset.h index 78b2c8e..33b9b45 100644 --- a/source/snes9x/getset.h +++ b/source/snes9x/getset.h @@ -885,8 +885,7 @@ inline void S9xSetPCBase (uint32 Address) Registers.PBPC = Address & 0xffffff; ICPU.ShiftedPB = Address & 0xff0000; - int block; - uint8 *GetAddress = Memory.Map[block = ((Address & 0xffffff) >> MEMMAP_SHIFT)]; + uint8 *GetAddress = Memory.Map[(int)((Address & 0xffffff) >> MEMMAP_SHIFT)]; CPU.MemSpeed = memory_speed(Address); CPU.MemSpeedx2 = CPU.MemSpeed << 1; diff --git a/source/snes9x/gfx.cpp b/source/snes9x/gfx.cpp index 8d314f4..7c6a9cf 100644 --- a/source/snes9x/gfx.cpp +++ b/source/snes9x/gfx.cpp @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in @@ -215,7 +230,7 @@ static uint16 get_crosshair_color (uint8); bool8 S9xGraphicsInit (void) { S9xInitTileRenderer(); - ZeroMemory(BlackColourMap, 256 * sizeof(uint16)); + memset(BlackColourMap, 0, 256 * sizeof(uint16)); #ifdef GFX_MULTI_FORMAT if (GFX.BuildPixel == NULL) @@ -226,9 +241,9 @@ bool8 S9xGraphicsInit (void) GFX.InterlaceFrame = 0; GFX.RealPPL = GFX.Pitch >> 1; IPPU.OBJChanged = TRUE; - IPPU.DirectColourMapsNeedRebuild = TRUE; Settings.BG_Forced = 0; S9xFixColourBrightness(); + S9xBuildDirectColourMaps(); GFX.X2 = (uint16 *) malloc(sizeof(uint16) * 0x10000); GFX.ZERO = (uint16 *) malloc(sizeof(uint16) * 0x10000); @@ -245,7 +260,7 @@ bool8 S9xGraphicsInit (void) } // Lookup table for color addition - ZeroMemory(GFX.X2, 0x10000 * sizeof(uint16)); + memset(GFX.X2, 0, 0x10000 * sizeof(uint16)); for (uint32 r = 0; r <= MAX_RED; r++) { uint32 r2 = r << 1; @@ -271,7 +286,7 @@ bool8 S9xGraphicsInit (void) } // Lookup table for 1/2 color subtraction - ZeroMemory(GFX.ZERO, 0x10000 * sizeof(uint16)); + memset(GFX.ZERO, 0, 0x10000 * sizeof(uint16)); for (uint32 r = 0; r <= MAX_RED; r++) { uint32 r2 = r; @@ -314,6 +329,48 @@ void S9xGraphicsDeinit (void) if (GFX.SubZBuffer) { free(GFX.SubZBuffer); GFX.SubZBuffer = NULL; } } +void S9xGraphicsScreenResize (void) +{ + IPPU.MaxBrightness = PPU.Brightness; + + IPPU.Interlace = Memory.FillRAM[0x2133] & 1; + IPPU.InterlaceOBJ = Memory.FillRAM[0x2133] & 2; + IPPU.PseudoHires = Memory.FillRAM[0x2133] & 8; + + if (Settings.SupportHiRes && (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.PseudoHires)) + { + GFX.RealPPL = GFX.Pitch >> 1; + IPPU.DoubleWidthPixels = TRUE; + IPPU.RenderedScreenWidth = SNES_WIDTH << 1; + } + else + { + #ifdef USE_OPENGL + if (Settings.OpenGLEnable) + GFX.RealPPL = SNES_WIDTH; + else + #endif + GFX.RealPPL = GFX.Pitch >> 1; + + IPPU.DoubleWidthPixels = FALSE; + IPPU.RenderedScreenWidth = SNES_WIDTH; + } + + if (Settings.SupportHiRes && IPPU.Interlace) + { + GFX.PPL = GFX.RealPPL << 1; + IPPU.DoubleHeightPixels = TRUE; + IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1; + GFX.DoInterlace++; + } + else + { + GFX.PPL = GFX.RealPPL; + IPPU.DoubleHeightPixels = FALSE; + IPPU.RenderedScreenHeight = PPU.ScreenHeight; + } +} + void S9xBuildDirectColourMaps (void) { IPPU.XB = mul_brightness[PPU.Brightness]; @@ -321,15 +378,14 @@ void S9xBuildDirectColourMaps (void) for (uint32 p = 0; p < 8; p++) for (uint32 c = 0; c < 256; c++) DirectColourMaps[p][c] = BUILD_PIXEL(IPPU.XB[((c & 7) << 2) | ((p & 1) << 1)], IPPU.XB[((c & 0x38) >> 1) | (p & 2)], IPPU.XB[((c & 0xc0) >> 3) | (p & 4)]); - - IPPU.DirectColourMapsNeedRebuild = FALSE; } void S9xStartScreenRefresh (void) { + GFX.InterlaceFrame = !GFX.InterlaceFrame; + if (IPPU.RenderThisFrame) { - GFX.InterlaceFrame = !GFX.InterlaceFrame; if (!GFX.DoInterlace || !GFX.InterlaceFrame) { if (!S9xInitUpdate()) @@ -341,43 +397,7 @@ void S9xStartScreenRefresh (void) if (GFX.DoInterlace) GFX.DoInterlace--; - IPPU.MaxBrightness = PPU.Brightness; - - IPPU.Interlace = Memory.FillRAM[0x2133] & 1; - IPPU.InterlaceOBJ = Memory.FillRAM[0x2133] & 2; - IPPU.PseudoHires = Memory.FillRAM[0x2133] & 8; - - if (Settings.SupportHiRes && (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.PseudoHires)) - { - GFX.RealPPL = GFX.Pitch >> 1; - IPPU.DoubleWidthPixels = TRUE; - IPPU.RenderedScreenWidth = SNES_WIDTH << 1; - } - else - { - #ifdef USE_OPENGL - if (Settings.OpenGLEnable) - GFX.RealPPL = SNES_WIDTH; - else - #endif - GFX.RealPPL = GFX.Pitch >> 1; - IPPU.DoubleWidthPixels = FALSE; - IPPU.RenderedScreenWidth = SNES_WIDTH; - } - - if (Settings.SupportHiRes && IPPU.Interlace) - { - GFX.PPL = GFX.RealPPL << 1; - IPPU.DoubleHeightPixels = TRUE; - IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1; - GFX.DoInterlace++; - } - else - { - GFX.PPL = GFX.RealPPL; - IPPU.DoubleHeightPixels = FALSE; - IPPU.RenderedScreenHeight = PPU.ScreenHeight; - } + S9xGraphicsScreenResize(); IPPU.RenderedFramesCount++; } @@ -386,8 +406,8 @@ void S9xStartScreenRefresh (void) PPU.RecomputeClipWindows = TRUE; IPPU.PreviousLine = IPPU.CurrentLine = 0; - ZeroMemory(GFX.ZBuffer, GFX.ScreenSize); - ZeroMemory(GFX.SubZBuffer, GFX.ScreenSize); + memset(GFX.ZBuffer, 0, GFX.ScreenSize); + memset(GFX.SubZBuffer, 0, GFX.ScreenSize); } if (++IPPU.FrameCount % Memory.ROMFramesPerSecond == 0) @@ -671,7 +691,7 @@ void S9xUpdateScreen (void) { if (!IPPU.DoubleWidthPixels && (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.PseudoHires)) { - #ifdef USE_OPENGL + #ifdef USE_OPENGL if (Settings.OpenGLEnable && GFX.RealPPL == 256) { // Have to back out of the speed up hack where the low res. @@ -691,42 +711,30 @@ void S9xUpdateScreen (void) GFX.PPL = GFX.RealPPL; // = GFX.Pitch >> 1 above } else - #endif + #endif + // Have to back out of the regular speed hack + for (register uint32 y = 0; y < GFX.StartY; y++) { - // Have to back out of the regular speed hack - for (register uint32 y = 0; y < GFX.StartY; y++) - { - register uint16 *p = GFX.Screen + y * GFX.PPL + 255; - register uint16 *q = GFX.Screen + y * GFX.PPL + 510; + register uint16 *p = GFX.Screen + y * GFX.PPL + 255; + register uint16 *q = GFX.Screen + y * GFX.PPL + 510; - for (register int x = 255; x >= 0; x--, p--, q -= 2) - *q = *(q + 1) = *p; - } + for (register int x = 255; x >= 0; x--, p--, q -= 2) + *q = *(q + 1) = *p; } IPPU.DoubleWidthPixels = TRUE; IPPU.RenderedScreenWidth = 512; } - if (!IPPU.DoubleHeightPixels && IPPU.Interlace) + if (!IPPU.DoubleHeightPixels && IPPU.Interlace && (PPU.BGMode == 5 || PPU.BGMode == 6)) { IPPU.DoubleHeightPixels = TRUE; IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1; GFX.PPL = GFX.RealPPL << 1; GFX.DoInterlace = 2; - for (register int32 y = (int32) GFX.StartY - 1; y >= 0; y--) - memmove(GFX.Screen + y * GFX.PPL, GFX.Screen + y * GFX.RealPPL, IPPU.RenderedScreenWidth * sizeof(uint16)); - } - else if (IPPU.DoubleHeightPixels && !IPPU.Interlace) - { - for (register int32 y = 0; y < (int32) GFX.StartY; y++) - memmove(GFX.Screen + y * GFX.RealPPL, GFX.Screen + y * GFX.PPL, IPPU.RenderedScreenWidth * sizeof(uint16)); - - IPPU.DoubleHeightPixels = FALSE; - IPPU.RenderedScreenHeight = PPU.ScreenHeight; - GFX.PPL = GFX.RealPPL; - GFX.DoInterlace = 0; + for (register int32 y = (int32) GFX.StartY - 2; y >= 0; y--) + memmove(GFX.Screen + (y + 1) * GFX.PPL, GFX.Screen + y * GFX.RealPPL, GFX.PPL * sizeof(uint16)); } } @@ -819,12 +827,12 @@ static void SetupOBJ (void) if (!PPU.OAMPriorityRotation || !(PPU.OAMFlip & PPU.OAMAddr & 1)) // normal case { uint8 LineOBJ[SNES_HEIGHT_EXTENDED]; - ZeroMemory(LineOBJ, sizeof(LineOBJ)); + memset(LineOBJ, 0, sizeof(LineOBJ)); for (int i = 0; i < SNES_HEIGHT_EXTENDED; i++) { GFX.OBJLines[i].RTOFlags = 0; - GFX.OBJLines[i].Tiles = 34; + GFX.OBJLines[i].Tiles = Settings.MaxSpriteTilesPerLine; for (int j = 0; j < 32; j++) GFX.OBJLines[i].OBJ[j].Sprite = -1; } @@ -895,8 +903,14 @@ static void SetupOBJ (void) else // evil FirstSprite+Y case { // First, find out which sprites are on which lines - uint8 OBJOnLine[SNES_HEIGHT_EXTENDED][128]; - ZeroMemory(OBJOnLine, sizeof(OBJOnLine)); + 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++) { @@ -930,6 +944,11 @@ static void SetupOBJ (void) if (Y >= SNES_HEIGHT_EXTENDED) continue; + if (!AnyOBJOnLine[Y]) { + memset(OBJOnLine[Y], 0, sizeof(OBJOnLine[Y])); + 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. @@ -945,31 +964,34 @@ static void SetupOBJ (void) for (int Y = 0; Y < SNES_HEIGHT_EXTENDED; Y++) { GFX.OBJLines[Y].RTOFlags = Y ? GFX.OBJLines[Y - 1].RTOFlags : 0; - GFX.OBJLines[Y].Tiles = 34; + GFX.OBJLines[Y].Tiles = Settings.MaxSpriteTilesPerLine; uint8 FirstSprite = (PPU.FirstSprite + Y) & 0x7f; S = FirstSprite; j = 0; - do + if (AnyOBJOnLine[Y]) { - if (OBJOnLine[Y][S]) + do { - if (j >= 32) + if (OBJOnLine[Y][S]) { - GFX.OBJLines[Y].RTOFlags |= 0x40; - break; + if (j >= 32) + { + GFX.OBJLines[Y].RTOFlags |= 0x40; + 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; } - 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); + S = (S + 1) & 0x7f; + } while (S != FirstSprite); + } if (j < 32) GFX.OBJLines[Y].OBJ[j].Sprite = -1; @@ -979,6 +1001,8 @@ static void SetupOBJ (void) IPPU.OBJChanged = FALSE; } +#pragma GCC push_options +#pragma GCC optimize ("no-tree-vrp") static void DrawOBJS (int D) { void (*DrawTile) (uint32, uint32, uint32, uint32) = NULL; @@ -1071,6 +1095,8 @@ static void DrawOBJS (int D) } } } +#pragma GCC pop_options + static void DrawBackground (int bg, uint8 Zh, uint8 Zl) { @@ -1329,8 +1355,8 @@ static void DrawBackgroundMosaic (int bg, uint8 Zh, uint8 Zl) for (uint32 Y = GFX.StartY - MosaicStart; Y <= GFX.EndY; Y += PPU.Mosaic) { uint32 Y2 = HiresInterlace ? Y * 2 : Y; - uint32 VOffset = LineData[Y].BG[bg].VOffset + (HiresInterlace ? 1 : 0); - uint32 HOffset = LineData[Y].BG[bg].HOffset; + uint32 VOffset = LineData[Y + MosaicStart].BG[bg].VOffset + (HiresInterlace ? 1 : 0); + uint32 HOffset = LineData[Y + MosaicStart].BG[bg].HOffset; Lines = PPU.Mosaic - MosaicStart; if (Y + MosaicStart + Lines > GFX.EndY) @@ -1493,7 +1519,6 @@ static void DrawBackgroundOffset (int bg, uint8 Zh, uint8 Zl, int VOffOff) int PixWidth = IPPU.DoubleWidthPixels ? 2 : 1; bool8 HiresInterlace = IPPU.Interlace && IPPU.DoubleWidthPixels; - void (*DrawTile) (uint32, uint32, uint32, uint32); void (*DrawClippedTile) (uint32, uint32, uint32, uint32, uint32, uint32); for (int clip = 0; clip < GFX.Clip[bg].Count; clip++) @@ -1502,12 +1527,10 @@ static void DrawBackgroundOffset (int bg, uint8 Zh, uint8 Zl, int VOffOff) if (BG.EnableMath && (GFX.Clip[bg].DrawMode[clip] & 2)) { - DrawTile = GFX.DrawTileMath; DrawClippedTile = GFX.DrawClippedTileMath; } else { - DrawTile = GFX.DrawTileNomath; DrawClippedTile = GFX.DrawClippedTileNomath; } @@ -1539,8 +1562,8 @@ static void DrawBackgroundOffset (int bg, uint8 Zh, uint8 Zl, int VOffOff) uint32 Left = GFX.Clip[bg].Left[clip]; uint32 Right = GFX.Clip[bg].Right[clip]; uint32 Offset = Left * PixWidth + Y * GFX.PPL; - uint32 LineHOffset = LineData[Y].BG[bg].HOffset; - bool8 left_edge = (Left < (8 - (LineHOffset & 7))); + uint32 HScroll = LineData[Y].BG[bg].HOffset; + bool8 left_edge = (Left < (8 - (HScroll & 7))); uint32 Width = Right - Left; while (Left < Right) @@ -1551,12 +1574,12 @@ static void DrawBackgroundOffset (int bg, uint8 Zh, uint8 Zl, int VOffOff) { // SNES cannot do OPT for leftmost tile column VOffset = LineData[Y].BG[bg].VOffset; - HOffset = LineHOffset; + HOffset = HScroll; left_edge = FALSE; } else { - int HOffTile = ((HOff + Left - 1) & Offset2Mask) >> 3; + int HOffTile = ((HOff + Left - 1) & Offset2Mask) >> 3; if (BG.OffsetSizeH == 8) { @@ -1595,9 +1618,9 @@ static void DrawBackgroundOffset (int bg, uint8 Zh, uint8 Zl, int VOffOff) VOffset = LineData[Y].BG[bg].VOffset; if (HCellOffset & OffsetEnableMask) - HOffset = (HCellOffset & ~7) | (LineHOffset & 7); + HOffset = (HCellOffset & ~7) | (HScroll & 7); else - HOffset = LineHOffset; + HOffset = HScroll; } if (HiresInterlace) @@ -1719,7 +1742,6 @@ static void DrawBackgroundOffsetMosaic (int bg, uint8 Zh, uint8 Zl, int VOffOff) int Lines; int OffsetMask = (BG.TileSizeH == 16) ? 0x3ff : 0x1ff; int OffsetShift = (BG.TileSizeV == 16) ? 4 : 3; - int Offset2Mask = (BG.OffsetSizeH == 16) ? 0x3ff : 0x1ff; int Offset2Shift = (BG.OffsetSizeV == 16) ? 4 : 3; int OffsetEnableMask = 0x2000 << bg; int PixWidth = IPPU.DoubleWidthPixels ? 2 : 1; @@ -1741,8 +1763,8 @@ static void DrawBackgroundOffsetMosaic (int bg, uint8 Zh, uint8 Zl, int VOffOff) for (uint32 Y = GFX.StartY - MosaicStart; Y <= GFX.EndY; Y += PPU.Mosaic) { uint32 Y2 = HiresInterlace ? Y * 2 : Y; - uint32 VOff = LineData[Y].BG[2].VOffset - 1; - uint32 HOff = LineData[Y].BG[2].HOffset; + uint32 VOff = LineData[Y + MosaicStart].BG[2].VOffset - 1; + uint32 HOff = LineData[Y + MosaicStart].BG[2].HOffset; Lines = PPU.Mosaic - MosaicStart; if (Y + MosaicStart + Lines > GFX.EndY) @@ -1771,24 +1793,22 @@ static void DrawBackgroundOffsetMosaic (int bg, uint8 Zh, uint8 Zl, int VOffOff) uint32 Left = GFX.Clip[bg].Left[clip]; uint32 Right = GFX.Clip[bg].Right[clip]; uint32 Offset = Left * PixWidth + (Y + MosaicStart) * GFX.PPL; - uint32 LineHOffset = LineData[Y].BG[bg].HOffset; - bool8 left_edge = (Left < (8 - (LineHOffset & 7))); + uint32 HScroll = LineData[Y + MosaicStart].BG[bg].HOffset; uint32 Width = Right - Left; while (Left < Right) { uint32 VOffset, HOffset; - if (left_edge) + if (Left < (8 - (HScroll & 7))) { // SNES cannot do OPT for leftmost tile column - VOffset = LineData[Y].BG[bg].VOffset; - HOffset = LineHOffset; - left_edge = FALSE; + VOffset = LineData[Y + MosaicStart].BG[bg].VOffset; + HOffset = HScroll; } else { - int HOffTile = ((HOff + Left - 1) & Offset2Mask) >> 3; + int HOffTile = (((Left + (HScroll & 7)) - 8) + (HOff & ~7)) >> 3; if (BG.OffsetSizeH == 8) { @@ -1824,12 +1844,12 @@ static void DrawBackgroundOffsetMosaic (int bg, uint8 Zh, uint8 Zl, int VOffOff) if (VCellOffset & OffsetEnableMask) VOffset = VCellOffset + 1; else - VOffset = LineData[Y].BG[bg].VOffset; + VOffset = LineData[Y + MosaicStart].BG[bg].VOffset; if (HCellOffset & OffsetEnableMask) - HOffset = (HCellOffset & ~7) | (LineHOffset & 7); + HOffset = (HCellOffset & ~7) | (HScroll & 7); else - HOffset = LineHOffset; + HOffset = HScroll; } if (HiresInterlace) @@ -2052,7 +2072,7 @@ static void DisplayPressedKeys (void) static int KeyOrder[] = { 8, 10, 7, 9, 0, 6, 14, 13, 5, 1, 4, 3, 2, 11, 12 }; // < ^ > v A B Y X L R S s enum controllers controller; - int line = 1; + int line = Settings.DisplayMovieFrame && S9xMovieActive() ? 2 : 1; int8 ids[4]; char string[255]; @@ -2267,43 +2287,37 @@ void S9xDrawCrosshair (const char *crosshair, uint8 fgcolor, uint8 bgcolor, int1 fg = get_crosshair_color(fgcolor); bg = get_crosshair_color(bgcolor); - // XXX: FIXME: why does it crash without this on Linux port? There are no out-of-bound writes without it... -#if (defined(__unix) || defined(__linux) || defined(__sun) || defined(__DJGPP)) - if (x >= 0 && y >= 0) -#endif + uint16 *s = GFX.Screen + y * (int32)GFX.RealPPL + x; + + for (r = 0; r < 15 * rx; r++, s += GFX.RealPPL - 15 * cx) { - uint16 *s = GFX.Screen + y * GFX.RealPPL + x; - - for (r = 0; r < 15 * rx; r++, s += GFX.RealPPL - 15 * cx) + if (y + r < 0) { - if (y + r < 0) - { - s += 15 * cx; + s += 15 * cx; + continue; + } + + if (y + r >= H) + break; + + for (c = 0; c < 15 * cx; c++, s++) + { + if (x + c < 0 || s < GFX.Screen) continue; - } - if (y + r >= H) - break; - - for (c = 0; c < 15 * cx; c++, s++) + if (x + c >= W) { - if (x + c < 0 || s < GFX.Screen) - continue; - - if (x + c >= W) - { - s += 15 * cx - c; - break; - } - - uint8 p = crosshair[(r / rx) * 15 + (c / cx)]; - - if (p == '#' && fgcolor) - *s = (fgcolor & 0x10) ? COLOR_ADD1_2(fg, *s) : fg; - else - if (p == '.' && bgcolor) - *s = (bgcolor & 0x10) ? COLOR_ADD1_2(*s, bg) : bg; + s += 15 * cx - c; + break; } + + uint8 p = crosshair[(r / rx) * 15 + (c / cx)]; + + if (p == '#' && fgcolor) + *s = (fgcolor & 0x10) ? COLOR_ADD1_2(fg, *s) : fg; + else + if (p == '.' && bgcolor) + *s = (bgcolor & 0x10) ? COLOR_ADD1_2(*s, bg) : bg; } } } diff --git a/source/snes9x/gfx.h b/source/snes9x/gfx.h index 75981cc..4c4d594 100644 --- a/source/snes9x/gfx.h +++ b/source/snes9x/gfx.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in @@ -344,6 +359,7 @@ void S9xBuildDirectColourMaps (void); void RenderLine (uint8); void S9xComputeClipWindows (void); void S9xDisplayChar (uint16 *, uint8); +void S9xGraphicsScreenResize (void); // called automatically unless Settings.AutoDisplayMessages is false void S9xDisplayMessages (uint16 *, int, int, int, int); #ifdef GFX_MULTI_FORMAT diff --git a/source/snes9x/globals.cpp b/source/snes9x/globals.cpp index 54312dc..a89e74c 100644 --- a/source/snes9x/globals.cpp +++ b/source/snes9x/globals.cpp @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/language.h b/source/snes9x/language.h index 49a30ae..408a914 100644 --- a/source/snes9x/language.h +++ b/source/snes9x/language.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in @@ -195,7 +210,7 @@ #define SAVE_INFO_LOAD "Loaded" #define SAVE_INFO_OOPS "Auto-saving 'oops' snapshot" #define SAVE_ERR_WRONG_FORMAT "File not in Snes9x snapshot format" -#define SAVE_ERR_WRONG_VERSION "Incompatable snapshot version" +#define SAVE_ERR_WRONG_VERSION "Incompatible snapshot version" #define SAVE_ERR_ROM_NOT_FOUND "ROM image \"%s\" for snapshot not found" #define SAVE_ERR_SAVE_NOT_FOUND "Snapshot %s does not exist" diff --git a/source/snes9x/logger.cpp b/source/snes9x/logger.cpp index 235c533..12dc923 100644 --- a/source/snes9x/logger.cpp +++ b/source/snes9x/logger.cpp @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/logger.h b/source/snes9x/logger.h index 63aa30b..a4dd102 100644 --- a/source/snes9x/logger.h +++ b/source/snes9x/logger.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/memmap.cpp b/source/snes9x/memmap.cpp index b42d569..d5f3458 100644 --- a/source/snes9x/memmap.cpp +++ b/source/snes9x/memmap.cpp @@ -1401,6 +1401,20 @@ int CMemory::ScoreLoROM (bool8 skip_header, int32 romoff) return (score); } +int CMemory::First512BytesCountZeroes() const +{ + const uint8 *buf = ROM; + int zeroCount = 0; + for (int i = 0; i < 512; i++) + { + if (buf[i] == 0) + { + zeroCount++; + } + } + return zeroCount; +} + uint32 CMemory::HeaderRemove (uint32 size, uint8 *buf) { uint32 calc_size = (size / 0x2000) * 0x2000; @@ -1616,13 +1630,21 @@ bool8 CMemory::LoadROMInt (int32 ROMfillSize) ExtendedFormat = NOPE; int hi_score, lo_score; + int score_headered; + int score_nonheadered; hi_score = ScoreHiROM(FALSE); lo_score = ScoreLoROM(FALSE); + score_nonheadered = max(hi_score, lo_score); + score_headered = max(ScoreHiROM(TRUE), ScoreLoROM(TRUE)); - if (HeaderCount == 0 && !Settings.ForceNoHeader && - ((hi_score > lo_score && ScoreHiROM(TRUE) > hi_score) || - (hi_score <= lo_score && ScoreLoROM(TRUE) > lo_score))) + bool size_is_likely_headered = ((ROMfillSize - 512) & 0xFFFF) == 0; + if (size_is_likely_headered) { score_headered += 2; } else { score_headered -= 2; } + if (First512BytesCountZeroes() >= 0x1E0) { score_headered += 2; } else { score_headered -= 2; } + + bool headered_score_highest = score_headered > score_nonheadered; + + if (HeaderCount == 0 && !Settings.ForceNoHeader && headered_score_highest) { memmove(ROM, ROM + 512, ROMfillSize - 512); ROMfillSize -= 512; @@ -3850,7 +3872,7 @@ void CMemory::ApplyROMFixes (void) Timings.HDMAStart = SNES_HDMA_START_HC + Settings.HDMATimingHack - 100; Timings.HBlankStart = SNES_HBLANK_START_HC + Timings.HDMAStart - SNES_HDMA_START_HC; - Timings.IRQTriggerCycles = 10; + Timings.IRQTriggerCycles = 14; if (!Settings.DisableGameSpecificHacks) { diff --git a/source/snes9x/memmap.h b/source/snes9x/memmap.h index 40aa020..d0bdd4e 100644 --- a/source/snes9x/memmap.h +++ b/source/snes9x/memmap.h @@ -294,6 +294,7 @@ struct CMemory int ScoreHiROM (bool8, int32 romoff = 0); int ScoreLoROM (bool8, int32 romoff = 0); + int First512BytesCountZeroes() const; uint32 HeaderRemove (uint32, uint8 *); uint32 FileLoader (uint8 *, const char *, uint32); uint32 MemLoader (uint8 *, const char*, uint32); diff --git a/source/snes9x/messages.h b/source/snes9x/messages.h index f346a7c..168ec52 100644 --- a/source/snes9x/messages.h +++ b/source/snes9x/messages.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/missing.h b/source/snes9x/missing.h index 9a41fab..8c2dd11 100644 --- a/source/snes9x/missing.h +++ b/source/snes9x/missing.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/movie.cpp b/source/snes9x/movie.cpp index 31d0765..d68cbbe 100644 --- a/source/snes9x/movie.cpp +++ b/source/snes9x/movie.cpp @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in @@ -437,14 +452,14 @@ static void reset_controllers (void) MovieSetJoypad(i, 0); uint8 clearedMouse[MOUSE_DATA_SIZE]; - ZeroMemory(clearedMouse, MOUSE_DATA_SIZE); + memset(clearedMouse, 0, MOUSE_DATA_SIZE); clearedMouse[4] = 1; uint8 clearedScope[SCOPE_DATA_SIZE]; - ZeroMemory(clearedScope, SCOPE_DATA_SIZE); + memset(clearedScope, 0, SCOPE_DATA_SIZE); uint8 clearedJustifier[JUSTIFIER_DATA_SIZE]; - ZeroMemory(clearedJustifier, JUSTIFIER_DATA_SIZE); + memset(clearedJustifier, 0, JUSTIFIER_DATA_SIZE); for (int p = 0; p < 2; p++) { @@ -639,7 +654,7 @@ static void write_movie_header (FILE *fd, SMovie *movie) { uint8 buf[SMV_HEADER_SIZE], *ptr = buf; - ZeroMemory(buf, sizeof(buf)); + memset(buf, 0, sizeof(buf)); Write32(SMV_MAGIC, ptr); Write32(SMV_VERSION, ptr); @@ -771,7 +786,8 @@ int S9xMovieUnfreeze (uint8 *buf, uint32 size) } else { - if (current_frame > Movie.MaxFrame || current_sample > Movie.MaxSample || memcmp(Movie.InputBuffer, ptr, space_needed)) + uint32 space_processed = (Movie.BytesPerSample * (current_sample + 1)); + if (current_frame > Movie.MaxFrame || current_sample > Movie.MaxSample || memcmp(Movie.InputBuffer, ptr, space_processed)) return (SNAPSHOT_INCONSISTENT); change_state(MOVIE_STATE_PLAY); @@ -812,14 +828,16 @@ int S9xMovieOpen (const char *filename, bool8 read_only) read_movie_extrarominfo(fd, &Movie); - fn = dup(fileno(fd)); - fclose(fd); + fflush(fd); + fn = fileno(fd); store_previous_settings(); restore_movie_settings(); lseek(fn, Movie.SaveStateOffset, SEEK_SET); - stream = REOPEN_STREAM(fn, "rb"); + + // reopen stream to access as gzipped data + stream = REOPEN_STREAM(fn, "rb"); if (!stream) return (FILE_NOT_FOUND); @@ -832,7 +850,11 @@ int S9xMovieOpen (const char *filename, bool8 read_only) else result = S9xUnfreezeFromStream(stream); - CLOSE_STREAM(stream); + // do not close stream but close FILE * + // (msvcrt will try to close all open FILE *handles on exit - if we do CLOSE_STREAM here + // the underlying file will be closed by zlib, causing problems when msvcrt tries to do it) + delete stream; + fclose(fd); if (result != SUCCESS) return (result); @@ -846,7 +868,10 @@ int S9xMovieOpen (const char *filename, bool8 read_only) } if (fseek(fd, Movie.ControllerDataOffset, SEEK_SET)) + { + fclose(fd); return (WRONG_FORMAT); + } Movie.File = fd; Movie.BytesPerSample = bytes_per_sample(); @@ -879,7 +904,6 @@ int S9xMovieCreate (const char *filename, uint8 controllers_mask, uint8 opts, co { FILE *fd; STREAM stream; - int fn; if (controllers_mask == 0) return (WRONG_FORMAT); @@ -928,10 +952,9 @@ int S9xMovieCreate (const char *filename, uint8 controllers_mask, uint8 opts, co write_movie_extrarominfo(fd, &Movie); - fn = dup(fileno(fd)); fclose(fd); - stream = REOPEN_STREAM(fn, "ab"); + stream = OPEN_STREAM(filename, "ab"); if (!stream) return (FILE_NOT_FOUND); @@ -989,14 +1012,17 @@ int S9xMovieGetInfo (const char *filename, struct MovieInfo *info) flush_movie(); - ZeroMemory(info, sizeof(*info)); + memset(info, 0, sizeof(*info)); if (!(fd = fopen(filename, "rb"))) return (FILE_NOT_FOUND); result = read_movie_header(fd, &local_movie); if (result != SUCCESS) + { + fclose(fd); return (result); + } info->TimeCreated = (time_t) local_movie.MovieId; info->Version = local_movie.Version; @@ -1035,9 +1061,10 @@ int S9xMovieGetInfo (const char *filename, struct MovieInfo *info) strncpy(info->ROMName, local_movie.ROMName, 23); fclose(fd); - - if (access(filename, W_OK)) + if ((fd = fopen(filename, "r+")) == NULL) info->ReadOnly = true; + else + fclose(fd); return (SUCCESS); } @@ -1117,7 +1144,7 @@ void S9xMovieUpdateOnReset (void) void S9xMovieInit (void) { - ZeroMemory(&Movie, sizeof(Movie)); + memset(&Movie, 0, sizeof(Movie)); Movie.State = MOVIE_STATE_NONE; } diff --git a/source/snes9x/movie.h b/source/snes9x/movie.h index f1fb2bb..ff8eed5 100644 --- a/source/snes9x/movie.h +++ b/source/snes9x/movie.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in @@ -184,10 +199,8 @@ #define MOVIE_OPT_NOSAVEDATA (1 << 2) #define MOVIE_SYNC_DATA_EXISTS 0x01 #define MOVIE_SYNC_OBSOLETE 0x02 -#define MOVIE_SYNC_LEFTRIGHT 0x04 #define MOVIE_SYNC_VOLUMEENVX 0x08 #define MOVIE_SYNC_FAKEMUTE 0x10 -#define MOVIE_SYNC_SYNCSOUND 0x20 #define MOVIE_SYNC_HASROMINFO 0x40 #define MOVIE_SYNC_NOCPUSHUTDOWN 0x80 #define MOVIE_MAX_METADATA 512 diff --git a/source/snes9x/msu1.cpp b/source/snes9x/msu1.cpp index 546dc0e..ceb7358 100644 --- a/source/snes9x/msu1.cpp +++ b/source/snes9x/msu1.cpp @@ -22,10 +22,12 @@ (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2016 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 - (c) Copyright 2011 - 2016 Hans-Kristian Arntzen, + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, Daniel De Matteis (Under no circumstances will commercial rights be given) @@ -138,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2016 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -146,14 +148,14 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2016 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles (c) Copyright 2001 - 2011 zones Libretro port - (c) Copyright 2011 - 2016 Hans-Kristian Arntzen, + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, Daniel De Matteis (Under no circumstances will commercial rights be given) @@ -190,12 +192,14 @@ Nintendo Co., Limited and its subsidiary companies. ***********************************************************************************/ -#include "msu1.h" -#include "display.h" -#include "filebrowser.h" +#include "snes9x.h" #include "memmap.h" -#include "snes9xgx.h" +#include "display.h" +#include "msu1.h" #include "apu/blargg_endian.h" +#include "snes9xgx.h" +#include +#include STREAM dataStream = NULL; STREAM audioStream = NULL; @@ -241,9 +245,12 @@ static int unzFindExtension(unzFile &file, const char *ext, bool restart = TRUE, STREAM S9xMSU1OpenFile(const char *msu_ext, bool skip_unpacked) { - char filename[MAXPATHLEN]; +#ifdef GEKKO + char filename[MAXPATHLEN]; sprintf(filename, "%s%s%s", Memory.ROMFilePath, Memory.ROMFilename, msu_ext); - +#else + const char *filename = S9xGetFilename(msu_ext, ROMFILENAME_DIR); +#endif STREAM file = 0; if (!skip_unpacked) @@ -257,10 +264,15 @@ STREAM S9xMSU1OpenFile(const char *msu_ext, bool skip_unpacked) // look for msu1 pack file in the rom or patch dir if msu data file not found in rom dir if (!file) { - char zip_filename[MAXPATHLEN]; - sprintf(zip_filename, "%s%s.msu1", Memory.ROMFilePath, Memory.ROMFilename); + const char *zip_filename = S9xGetFilename(".msu1", ROMFILENAME_DIR); unzFile unzFile = unzOpen(zip_filename); + if (!unzFile) + { + zip_filename = S9xGetFilename(".msu1", PATCH_DIR); + unzFile = unzOpen(zip_filename); + } + if (unzFile) { int port = unzFindExtension(unzFile, msu_ext, true, true, true); @@ -312,8 +324,8 @@ static bool AudioOpen() audioLoopPos = GET_LE32(&audioLoopPos); audioLoopPos <<= 2; audioLoopPos += 8; - - MSU1.MSU1_AUDIO_POS = 8; + + MSU1.MSU1_AUDIO_POS = 8; MSU1.MSU1_STATUS &= ~AudioError; return true; @@ -381,7 +393,6 @@ void S9xMSU1DeInit(void) AudioClose(); } - bool S9xMSU1ROMExists(void) { STREAM s = S9xMSU1OpenFile(".msu"); @@ -391,9 +402,15 @@ bool S9xMSU1ROMExists(void) return true; } #ifdef UNZIP_SUPPORT - char fname[MAXPATHLEN]; - sprintf(fname, "%s%s.msu1", Memory.ROMFilePath, Memory.ROMFilename); - unzFile unzFile = unzOpen(fname); + char drive[_MAX_DRIVE + 1], dir[_MAX_DIR + 1], def[_MAX_FNAME + 1], ext[_MAX_EXT + 1]; + _splitpath(Memory.ROMFilename, drive, dir, def, ext); + if (!strcasecmp(ext, ".msu1")) + return true; + + unzFile unzFile = unzOpen(S9xGetFilename(".msu1", ROMFILENAME_DIR)); + + if(!unzFile) + unzFile = unzOpen(S9xGetFilename(".msu1", PATCH_DIR)); if (unzFile) { @@ -416,14 +433,15 @@ void S9xMSU1Generate(size_t sample_count) int16* left = (int16*)&sample; int16* right = left + 1; - int bytes_read = READ_STREAM((char *)&sample, 4, audioStream); + int bytes_read = READ_STREAM((char *)&sample, 4, audioStream); if (bytes_read == 4) { *left = ((int32)(int16)GET_LE16(left) * MSU1.MSU1_VOLUME / 255); *right = ((int32)(int16)GET_LE16(right) * MSU1.MSU1_VOLUME / 255); + *(bufPos++) = *left; - *(bufPos++) = *right; + *(bufPos++) = *right; MSU1.MSU1_AUDIO_POS += 4; partial_frames -= 3204; } @@ -433,12 +451,12 @@ void S9xMSU1Generate(size_t sample_count) if (MSU1.MSU1_STATUS & AudioRepeating) { MSU1.MSU1_AUDIO_POS = audioLoopPos; - REVERT_STREAM(audioStream, MSU1.MSU1_AUDIO_POS, 0); + REVERT_STREAM(audioStream, MSU1.MSU1_AUDIO_POS, 0); } else { MSU1.MSU1_STATUS &= ~(AudioPlaying | AudioRepeating); - REVERT_STREAM(audioStream, 8, 0); + REVERT_STREAM(audioStream, 8, 0); } } else diff --git a/source/snes9x/msu1.h b/source/snes9x/msu1.h index add366b..8537613 100644 --- a/source/snes9x/msu1.h +++ b/source/snes9x/msu1.h @@ -22,10 +22,12 @@ (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2016 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 - (c) Copyright 2011 - 2016 Hans-Kristian Arntzen, + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, Daniel De Matteis (Under no circumstances will commercial rights be given) @@ -138,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2016 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -146,14 +148,14 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2016 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles (c) Copyright 2001 - 2011 zones Libretro port - (c) Copyright 2011 - 2016 Hans-Kristian Arntzen, + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, Daniel De Matteis (Under no circumstances will commercial rights be given) @@ -193,8 +195,6 @@ #ifndef _MSU1_H_ #define _MSU1_H_ #include "snes9x.h" -#include -#include #define MSU1_REVISION 0x02 @@ -215,8 +215,8 @@ struct SMSU1 enum SMSU1_FLAG { Revision = 0x07, // bitmask, not the actual version number AudioError = 0x08, - AudioPlaying = 0x10, - AudioRepeating = 0x20, + AudioPlaying = 0x10, + AudioRepeating = 0x20, AudioBusy = 0x40, DataBusy = 0x80 }; diff --git a/source/snes9x/obc1.cpp b/source/snes9x/obc1.cpp index 9fe98de..803f6a1 100644 --- a/source/snes9x/obc1.cpp +++ b/source/snes9x/obc1.cpp @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/obc1.h b/source/snes9x/obc1.h index 836850b..a8de868 100644 --- a/source/snes9x/obc1.h +++ b/source/snes9x/obc1.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/pixform.h b/source/snes9x/pixform.h index 1760899..51b143e 100644 --- a/source/snes9x/pixform.h +++ b/source/snes9x/pixform.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/port.h b/source/snes9x/port.h index ef94ded..4300585 100644 --- a/source/snes9x/port.h +++ b/source/snes9x/port.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in @@ -192,7 +207,7 @@ #include #ifdef __WIN32__ -#define NOMINMAX +#define NOMINMAX 1 #include #endif @@ -201,7 +216,14 @@ #define RIGHTSHIFT_int8_IS_SAR #define RIGHTSHIFT_int16_IS_SAR #define RIGHTSHIFT_int32_IS_SAR +#ifndef GEKKO #define SNES_JOY_READ_CALLBACKS +#define GFX_MULTI_FORMAT +#endif +#endif + +#ifdef __LIBRETRO__ +#define GFX_MULTI_FORMAT #endif #ifdef __MACOSX__ @@ -230,30 +252,22 @@ typedef uint64_t uint64; #else // HAVE_STDINT_H #ifdef __WIN32__ typedef intptr_t pint; -#else // __WIN32__ -#ifdef PTR_NOT_INT -typedef long pint; -#else -typedef int pint; -#endif -#endif // __WIN32__ -#ifdef __WIN32__ -#ifdef __BORLANDC__ -#include -#else typedef signed char int8; typedef unsigned char uint8; typedef signed short int16; typedef unsigned short uint16; -#ifndef WSAAP -// winsock2.h typedefs int32 as well -typedef signed int int32; -#endif +typedef signed int int32; typedef unsigned int uint32; -#endif -typedef unsigned char uint8_t; typedef signed __int64 int64; typedef unsigned __int64 uint64; +typedef int8 int8_t; +typedef uint8 uint8_t; +typedef int16 int16_t; +typedef uint16 uint16_t; +typedef int32 int32_t; +typedef uint32 uint32_t; +typedef int64 int64_t; +typedef uint64 uint64_t; typedef int socklen_t; #else // __WIN32__ typedef signed char int8; @@ -268,6 +282,11 @@ __extension__ #endif typedef long long int64; typedef unsigned long long uint64; +#ifdef PTR_NOT_INT +typedef size_t pint; +#else // __PTR_NOT_INT +typedef size_t pint; +#endif // __PTR_NOT_INT #endif // __WIN32__ #endif // HAVE_STDINT_H #endif // snes9x_types_defined @@ -298,21 +317,24 @@ typedef unsigned long long uint64; #endif #ifndef __WIN32__ -#define ZeroMemory(a, b) memset((a), 0, (b)) void _splitpath (const char *, char *, char *, char *, char *); void _makepath (char *, const char *, const char *, const char *, const char *); #define S9xDisplayString DisplayStringFromBottom -#else +#else // __WIN32__ #define snprintf _snprintf #define strcasecmp stricmp #define strncasecmp strnicmp +#ifndef __LIBRETRO__ void WinDisplayStringFromBottom(const char *string, int linesFromBottom, int pixelsFromLeft, bool allowWrap); #define S9xDisplayString WinDisplayStringFromBottom void SetInfoDlgColor(unsigned char, unsigned char, unsigned char); #define SET_UI_COLOR(r,g,b) SetInfoDlgColor(r,g,b) -#endif +#else // __LIBRETRO__ +#define S9xDisplayString DisplayStringFromBottom +#endif // __LIBRETRO__ +#endif // __WIN32__ -#ifdef __DJGPP +#if defined(__DJGPP) || defined(__WIN32__) #define SLASH_STR "\\" #define SLASH_CHAR '\\' #else @@ -333,7 +355,7 @@ void SetInfoDlgColor(unsigned char, unsigned char, unsigned char); #define TITLE "Snes9x" #endif -#if defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(__x86_64__) || defined(__alpha__) || defined(__MIPSEL__) || defined(_M_IX86) || defined(_M_X64) +#if defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(__x86_64__) || defined(__alpha__) || defined(__MIPSEL__) || defined(_M_IX86) || defined(_M_X64) || defined(_XBOX1) || defined(__arm__) || defined(ANDROID) || defined(__aarch64__) || (defined(__BYTE_ORDER__) && __BYTE_ORDER == __ORDER_LITTLE_ENDIAN__) #define LSB_FIRST #define FAST_LSB_WORD_ACCESS #else diff --git a/source/snes9x/ppu.cpp b/source/snes9x/ppu.cpp index c1ed745..6b50a66 100644 --- a/source/snes9x/ppu.cpp +++ b/source/snes9x/ppu.cpp @@ -1,2132 +1,2103 @@ -/*********************************************************************************** - Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - - (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com), - Jerremy Koot (jkoot@snes9x.com) - - (c) Copyright 2002 - 2004 Matthew Kendora - - (c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org) - - (c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/) - - (c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net) - - (c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca), - Kris Bleakley (codeviolation@hotmail.com) - - (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), - Nach (n-a-c-h@users.sourceforge.net), - - (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) - - (c) Copyright 2006 - 2007 nitsuja - - (c) Copyright 2009 - 2018 BearOso, - OV2 - - (c) Copyright 2017 qwertymodo - - (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, - Daniel De Matteis - (Under no circumstances will commercial rights be given) - - - BS-X C emulator code - (c) Copyright 2005 - 2006 Dreamer Nom, - zones - - C4 x86 assembler and some C emulation code - (c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com), - Nach, - zsKnight (zsknight@zsnes.com) - - C4 C++ code - (c) Copyright 2003 - 2006 Brad Jorsch, - Nach - - DSP-1 emulator code - (c) Copyright 1998 - 2006 _Demo_, - Andreas Naive (andreasnaive@gmail.com), - Gary Henderson, - Ivar (ivar@snes9x.com), - John Weidman, - Kris Bleakley, - Matthew Kendora, - Nach, - neviksti (neviksti@hotmail.com) - - DSP-2 emulator code - (c) Copyright 2003 John Weidman, - Kris Bleakley, - Lord Nightmare (lord_nightmare@users.sourceforge.net), - Matthew Kendora, - neviksti - - DSP-3 emulator code - (c) Copyright 2003 - 2006 John Weidman, - Kris Bleakley, - Lancer, - z80 gaiden - - DSP-4 emulator code - (c) Copyright 2004 - 2006 Dreamer Nom, - John Weidman, - Kris Bleakley, - Nach, - z80 gaiden - - OBC1 emulator code - (c) Copyright 2001 - 2004 zsKnight, - pagefault (pagefault@zsnes.com), - Kris Bleakley - Ported from x86 assembler to C by sanmaiwashi - - SPC7110 and RTC C++ emulator code used in 1.39-1.51 - (c) Copyright 2002 Matthew Kendora with research by - zsKnight, - John Weidman, - Dark Force - - SPC7110 and RTC C++ emulator code used in 1.52+ - (c) Copyright 2009 byuu, - neviksti - - S-DD1 C emulator code - (c) Copyright 2003 Brad Jorsch with research by - Andreas Naive, - John Weidman - - S-RTC C emulator code - (c) Copyright 2001 - 2006 byuu, - John Weidman - - ST010 C++ emulator code - (c) Copyright 2003 Feather, - John Weidman, - Kris Bleakley, - Matthew Kendora - - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 _Demo_, - pagefault, - zsKnight - - Super FX C emulator code - (c) Copyright 1997 - 1999 Ivar, - Gary Henderson, - John Weidman - - Sound emulator code used in 1.5-1.51 - (c) Copyright 1998 - 2003 Brad Martin - (c) Copyright 1998 - 2006 Charles Bilyue' - - Sound emulator code used in 1.52+ - (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) - - S-SMP emulator code used in 1.54+ - (c) Copyright 2016 byuu - - SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) - - 2xSaI filter - (c) Copyright 1999 - 2001 Derek Liauw Kie Fa - - HQ2x, HQ3x, HQ4x filters - (c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com) - - NTSC filter - (c) Copyright 2006 - 2007 Shay Green - - GTK+ GUI code - (c) Copyright 2004 - 2018 BearOso - - Win32 GUI code - (c) Copyright 2003 - 2006 blip, - funkyass, - Matthew Kendora, - Nach, - nitsuja - (c) Copyright 2009 - 2018 OV2 - - Mac OS GUI code - (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2011 zones - - Libretro port - (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, - Daniel De Matteis - (Under no circumstances will commercial rights be given) - - - 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/or 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 or it's derivatives. - - Snes9x is freeware for PERSONAL USE only. Commercial users should - seek permission of the copyright holders first. Commercial use includes, - but is not limited to, charging money for Snes9x or software derived from - Snes9x, including Snes9x or derivatives in commercial game bundles, and/or - using Snes9x as a promotion for your commercial product. - - The copyright holders request that bug fixes and improvements to the code - should be forwarded to them so everyone can benefit from the modifications - in future versions. - - Super NES and Super Nintendo Entertainment System are trademarks of - Nintendo Co., Limited and its subsidiary companies. - ***********************************************************************************/ - - -#include "snes9x.h" -#include "memmap.h" -#include "dma.h" -#include "apu/apu.h" -#include "fxemu.h" -#include "sdd1.h" -#include "srtc.h" -#include "controls.h" -#include "movie.h" -#include "display.h" -#ifdef NETPLAY_SUPPORT -#include "netplay.h" -#endif -#ifdef DEBUGGER -#include "debug.h" -#include "missing.h" -#endif - -extern uint8 *HDMAMemPointers[8]; - - -static inline void S9xLatchCounters (bool force) -{ - if (force || (Memory.FillRAM[0x4213] & 0x80)) - { - // Latch h and v counters, like the gun - #ifdef DEBUGGER - missing.h_v_latch = 1; - #endif - - PPU.HVBeamCounterLatched = 1; - PPU.VBeamPosLatched = (uint16) CPU.V_Counter; - - // From byuu: - // All dots are 4 cycles long, except dots 322 and 326. dots 322 and 326 are 6 cycles long. - // This holds true for all scanlines except scanline 240 on non-interlace odd frames. - // The reason for this is because this scanline is only 1360 cycles long, - // instead of 1364 like all other scanlines. - // This makes the effective range of hscan_pos 0-339 at all times. - int32 hc = CPU.Cycles; - - if (Timings.H_Max == Timings.H_Max_Master) // 1364 - { - if (hc >= 1292) - hc -= (ONE_DOT_CYCLE / 2); - if (hc >= 1308) - hc -= (ONE_DOT_CYCLE / 2); - } - - PPU.HBeamPosLatched = (uint16) (hc / ONE_DOT_CYCLE); - - Memory.FillRAM[0x213f] |= 0x40; - } - - if (CPU.V_Counter > PPU.GunVLatch || (CPU.V_Counter == PPU.GunVLatch && CPU.Cycles >= PPU.GunHLatch * ONE_DOT_CYCLE)) - PPU.GunVLatch = 1000; -} - -static inline void S9xTryGunLatch (bool force) -{ - if (CPU.V_Counter > PPU.GunVLatch || (CPU.V_Counter == PPU.GunVLatch && CPU.Cycles >= PPU.GunHLatch * ONE_DOT_CYCLE)) - { - if (force || (Memory.FillRAM[0x4213] & 0x80)) - { - #ifdef DEBUGGER - missing.h_v_latch = 1; - #endif - - PPU.HVBeamCounterLatched = 1; - PPU.VBeamPosLatched = (uint16) PPU.GunVLatch; - PPU.HBeamPosLatched = (uint16) PPU.GunHLatch; - - Memory.FillRAM[0x213f] |= 0x40; - } - - PPU.GunVLatch = 1000; - } -} - -static int CyclesUntilNext (int hc, int vc) -{ - int32 total = 0; - int vpos = CPU.V_Counter; - - if (vc - vpos > 0) - { - // It's still in this frame */ - // Add number of lines - total += (vc - vpos) * Timings.H_Max_Master; - // If line 240 is in there and we're odd, subtract a dot - if (vpos <= 240 && vc > 240 && Timings.InterlaceField & !IPPU.Interlace) - total -= ONE_DOT_CYCLE; - } - else - { - if (vc == vpos && (hc > CPU.Cycles)) - { - return hc; - } - - total += (Timings.V_Max - vpos) * Timings.H_Max_Master; - if (vpos <= 240 && Timings.InterlaceField && !IPPU.Interlace) - total -= ONE_DOT_CYCLE; - - total += (vc) * Timings.H_Max_Master; - if (vc > 240 && !Timings.InterlaceField && !IPPU.Interlace) - total -= ONE_DOT_CYCLE; - } - - total += hc; - - return total; -} - -void S9xUpdateIRQPositions (bool initial) -{ - PPU.HTimerPosition = PPU.IRQHBeamPos * ONE_DOT_CYCLE + Timings.IRQTriggerCycles; - PPU.HTimerPosition -= PPU.IRQHBeamPos ? 0 : ONE_DOT_CYCLE; - PPU.HTimerPosition += PPU.IRQHBeamPos > 322 ? (ONE_DOT_CYCLE / 2) : 0; - PPU.HTimerPosition += PPU.IRQHBeamPos > 326 ? (ONE_DOT_CYCLE / 2) : 0; - PPU.VTimerPosition = PPU.IRQVBeamPos; - - if (PPU.VTimerEnabled && (PPU.VTimerPosition >= (Timings.V_Max + (IPPU.Interlace ? 1 : 0)))) - { - Timings.NextIRQTimer = 0x0fffffff; - } - else if (!PPU.HTimerEnabled && !PPU.VTimerEnabled) - { - Timings.NextIRQTimer = 0x0fffffff; - } - else if (PPU.HTimerEnabled && !PPU.VTimerEnabled) - { - int v_pos = CPU.V_Counter; - - Timings.NextIRQTimer = PPU.HTimerPosition; - if (CPU.Cycles > Timings.NextIRQTimer - Timings.IRQTriggerCycles) - { - Timings.NextIRQTimer += Timings.H_Max; - v_pos++; - } - - // Check for short dot scanline - if (v_pos == 240 && Timings.InterlaceField && !IPPU.Interlace) - { - Timings.NextIRQTimer -= PPU.IRQHBeamPos <= 322 ? ONE_DOT_CYCLE / 2 : 0; - Timings.NextIRQTimer -= PPU.IRQHBeamPos <= 326 ? ONE_DOT_CYCLE / 2 : 0; - } - } - else if (!PPU.HTimerEnabled && PPU.VTimerEnabled) - { - if (CPU.V_Counter == PPU.VTimerPosition && initial) - Timings.NextIRQTimer = CPU.Cycles + Timings.IRQTriggerCycles; - else - Timings.NextIRQTimer = CyclesUntilNext (Timings.IRQTriggerCycles, PPU.VTimerPosition); - } - else - { - Timings.NextIRQTimer = CyclesUntilNext (PPU.HTimerPosition, PPU.VTimerPosition); - - // Check for short dot scanline - int field = Timings.InterlaceField; - - if (PPU.VTimerPosition < CPU.V_Counter || - (PPU.VTimerPosition == CPU.V_Counter && Timings.NextIRQTimer > Timings.H_Max)) - { - field = !field; - } - - if (PPU.VTimerPosition == 240 && field && !IPPU.Interlace) - { - Timings.NextIRQTimer -= PPU.IRQHBeamPos <= 322 ? ONE_DOT_CYCLE / 2 : 0; - Timings.NextIRQTimer -= PPU.IRQHBeamPos <= 326 ? ONE_DOT_CYCLE / 2 : 0; - } - } - -#ifdef DEBUGGER - S9xTraceFormattedMessage("--- IRQ Timer HC:%d VC:%d set %d cycles HTimer:%d Pos:%04d->%04d VTimer:%d Pos:%03d->%03d", CPU.Cycles, CPU.V_Counter, - Timings.NextIRQTimer, PPU.HTimerEnabled, PPU.IRQHBeamPos, PPU.HTimerPosition, PPU.VTimerEnabled, PPU.IRQVBeamPos, PPU.VTimerPosition); -#endif -} - -void S9xFixColourBrightness (void) -{ - IPPU.XB = mul_brightness[PPU.Brightness]; - - for (int 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]); - } -} - -void S9xSetPPU (uint8 Byte, uint16 Address) -{ - // MAP_PPU: $2000-$3FFF - - if (CPU.InDMAorHDMA) - { - if (CPU.CurrentDMAorHDMAChannel >= 0 && DMA[CPU.CurrentDMAorHDMAChannel].ReverseTransfer) - { - // S9xSetPPU() is called to write to DMA[].AAddress - if ((Address & 0xff00) == 0x2100) - { - // Cannot access to Address Bus B ($2100-$21ff) via (H)DMA - return; - } - else - { - // 0x2000-0x3FFF is connected to Address Bus A - // SA1, SuperFX and SRTC are mapped here - // I don't bother for now... - return; - } - } - else - { - // S9xSetPPU() is called to read from $21xx - // Take care of DMA wrapping - if (Address > 0x21ff) - Address = 0x2100 + (Address & 0xff); - } - } - -#ifdef DEBUGGER - if (CPU.InHDMA) - S9xTraceFormattedMessage("--- HDMA PPU %04X -> %02X", Address, Byte); -#endif - - if (Settings.MSU1 && (Address & 0xfff8) == 0x2000) // MSU-1 - S9xMSU1WritePort(Address & 7, Byte); - else - if ((Address & 0xffc0) == 0x2140) // APUIO0, APUIO1, APUIO2, APUIO3 - // write_port will run the APU until given clock before writing value - S9xAPUWritePort(Address & 3, Byte); - else - if (Address <= 0x2183) - { - switch (Address) - { - case 0x2100: // INIDISP - if (Byte != Memory.FillRAM[0x2100]) - { - FLUSH_REDRAW(); - - if (PPU.Brightness != (Byte & 0xf)) - { - IPPU.ColorsChanged = TRUE; - PPU.Brightness = Byte & 0xf; - S9xFixColourBrightness(); - S9xBuildDirectColourMaps(); - if (PPU.Brightness > IPPU.MaxBrightness) - IPPU.MaxBrightness = PPU.Brightness; - } - - if ((Memory.FillRAM[0x2100] & 0x80) != (Byte & 0x80)) - { - IPPU.ColorsChanged = TRUE; - PPU.ForcedBlanking = (Byte >> 7) & 1; - } - } - - if ((Memory.FillRAM[0x2100] & 0x80) && CPU.V_Counter == PPU.ScreenHeight + FIRST_VISIBLE_LINE) - { - 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; - } - - break; - - case 0x2101: // OBSEL - 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: // OAMADDL - PPU.OAMAddr = ((Memory.FillRAM[0x2103] & 1) << 8) | Byte; - PPU.OAMFlip = 0; - PPU.OAMReadFlip = 0; - PPU.SavedOAMAddr = PPU.OAMAddr; - if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1)) - { - PPU.FirstSprite = (PPU.OAMAddr & 0xfe) >> 1; - IPPU.OBJChanged = TRUE; - #ifdef DEBUGGER - missing.sprite_priority_rotation = 1; - #endif - } - - break; - - case 0x2103: // OAMADDH - 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; - #ifdef DEBUGGER - missing.sprite_priority_rotation = 1; - #endif - } - } - else - { - if (PPU.FirstSprite != 0) - { - PPU.FirstSprite = 0; - IPPU.OBJChanged = TRUE; - #ifdef DEBUGGER - missing.sprite_priority_rotation = 1; - #endif - } - } - - PPU.OAMFlip = 0; - PPU.OAMReadFlip = 0; - PPU.SavedOAMAddr = PPU.OAMAddr; - - break; - - case 0x2104: // OAMDATA - REGISTER_2104(Byte); - break; - - case 0x2105: // BGMODE - 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 == 6 || PPU.BGMode == 5 || PPU.BGMode == 7) - IPPU.Interlace = Memory.FillRAM[0x2133] & 1; - else - IPPU.Interlace = 0; - #ifdef DEBUGGER - missing.modes[PPU.BGMode] = 1; - #endif - } - - break; - - case 0x2106: // MOSAIC - if (Byte != Memory.FillRAM[0x2106]) - { - FLUSH_REDRAW(); - PPU.MosaicStart = CPU.V_Counter; - if (PPU.MosaicStart > PPU.ScreenHeight) - PPU.MosaicStart = 0; - PPU.Mosaic = (Byte >> 4) + 1; - PPU.BGMosaic[0] = (Byte & 1); - PPU.BGMosaic[1] = (Byte & 2); - PPU.BGMosaic[2] = (Byte & 4); - PPU.BGMosaic[3] = (Byte & 8); - #ifdef DEBUGGER - if ((Byte & 0xf0) && (Byte & 0x0f)) - missing.mosaic = 1; - #endif - } - - break; - - case 0x2107: // BG1SC - if (Byte != Memory.FillRAM[0x2107]) - { - FLUSH_REDRAW(); - PPU.BG[0].SCSize = Byte & 3; - PPU.BG[0].SCBase = (Byte & 0x7c) << 8; - } - - break; - - case 0x2108: // BG2SC - if (Byte != Memory.FillRAM[0x2108]) - { - FLUSH_REDRAW(); - PPU.BG[1].SCSize = Byte & 3; - PPU.BG[1].SCBase = (Byte & 0x7c) << 8; - } - - break; - - case 0x2109: // BG3SC - if (Byte != Memory.FillRAM[0x2109]) - { - FLUSH_REDRAW(); - PPU.BG[2].SCSize = Byte & 3; - PPU.BG[2].SCBase = (Byte & 0x7c) << 8; - } - - break; - - case 0x210a: // BG4SC - if (Byte != Memory.FillRAM[0x210a]) - { - FLUSH_REDRAW(); - PPU.BG[3].SCSize = Byte & 3; - PPU.BG[3].SCBase = (Byte & 0x7c) << 8; - } - - break; - - case 0x210b: // BG12NBA - 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: // BG34NBA - if (Byte != Memory.FillRAM[0x210c]) - { - FLUSH_REDRAW(); - PPU.BG[2].NameBase = (Byte & 7) << 12; - PPU.BG[3].NameBase = ((Byte >> 4) & 7) << 12; - } - - break; - - case 0x210d: // BG1HOFS, M7HOFS - PPU.BG[0].HOffset = (Byte << 8) | (PPU.BGnxOFSbyte & ~7) | ((PPU.BG[0].HOffset >> 8) & 7); - PPU.M7HOFS = (Byte << 8) | PPU.M7byte; - PPU.BGnxOFSbyte = Byte; - PPU.M7byte = Byte; - break; - - case 0x210e: // BG1VOFS, M7VOFS - PPU.BG[0].VOffset = (Byte << 8) | PPU.BGnxOFSbyte; - PPU.M7VOFS = (Byte << 8) | PPU.M7byte; - PPU.BGnxOFSbyte = Byte; - PPU.M7byte = Byte; - break; - - case 0x210f: // BG2HOFS - PPU.BG[1].HOffset = (Byte << 8) | (PPU.BGnxOFSbyte & ~7) | ((PPU.BG[1].HOffset >> 8) & 7); - PPU.BGnxOFSbyte = Byte; - break; - - case 0x2110: // BG2VOFS - PPU.BG[1].VOffset = (Byte << 8) | PPU.BGnxOFSbyte; - PPU.BGnxOFSbyte = Byte; - break; - - case 0x2111: // BG3HOFS - PPU.BG[2].HOffset = (Byte << 8) | (PPU.BGnxOFSbyte & ~7) | ((PPU.BG[2].HOffset >> 8) & 7); - PPU.BGnxOFSbyte = Byte; - break; - - case 0x2112: // BG3VOFS - PPU.BG[2].VOffset = (Byte << 8) | PPU.BGnxOFSbyte; - PPU.BGnxOFSbyte = Byte; - break; - - case 0x2113: // BG4HOFS - PPU.BG[3].HOffset = (Byte << 8) | (PPU.BGnxOFSbyte & ~7) | ((PPU.BG[3].HOffset >> 8) & 7); - PPU.BGnxOFSbyte = Byte; - break; - - case 0x2114: // BG4VOFS - PPU.BG[3].VOffset = (Byte << 8) | PPU.BGnxOFSbyte; - PPU.BGnxOFSbyte = Byte; - break; - - case 0x2115: // VMAIN - 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: PPU.VMA.Increment = 128; break; - case 3: PPU.VMA.Increment = 128; break; - } - - if (Byte & 0x0c) - { - static uint16 Shift[4] = { 0, 5, 6, 7 }; - static uint16 IncCount[4] = { 0, 32, 64, 128 }; - - uint8 i = (Byte & 0x0c) >> 2; - PPU.VMA.FullGraphicCount = IncCount[i]; - PPU.VMA.Mask1 = IncCount[i] * 8 - 1; - PPU.VMA.Shift = Shift[i]; - #ifdef DEBUGGER - missing.vram_full_graphic_inc = (Byte & 0x0c) >> 2; - #endif - } - else - PPU.VMA.FullGraphicCount = 0; - #ifdef DEBUGGER - if (Byte & 3) - missing.vram_inc = Byte & 3; - #endif - break; - - case 0x2116: // VMADDL - PPU.VMA.Address &= 0xff00; - PPU.VMA.Address |= Byte; - - 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)); - - break; - - case 0x2117: // VMADDH - PPU.VMA.Address &= 0x00ff; - PPU.VMA.Address |= Byte << 8; - - 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)); - - break; - - case 0x2118: // VMDATAL - REGISTER_2118(Byte); - break; - - case 0x2119: // VMDATAH - REGISTER_2119(Byte); - break; - - case 0x211a: // M7SEL - 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: // M7A - PPU.MatrixA = PPU.M7byte | (Byte << 8); - PPU.Need16x8Mulitply = TRUE; - PPU.M7byte = Byte; - break; - - case 0x211c: // M7B - PPU.MatrixB = PPU.M7byte | (Byte << 8); - PPU.Need16x8Mulitply = TRUE; - PPU.M7byte = Byte; - break; - - case 0x211d: // M7C - PPU.MatrixC = PPU.M7byte | (Byte << 8); - PPU.M7byte = Byte; - break; - - case 0x211e: // M7D - PPU.MatrixD = PPU.M7byte | (Byte << 8); - PPU.M7byte = Byte; - break; - - case 0x211f: // M7X - PPU.CentreX = PPU.M7byte | (Byte << 8); - PPU.M7byte = Byte; - break; - - case 0x2120: // M7Y - PPU.CentreY = PPU.M7byte | (Byte << 8); - PPU.M7byte = Byte; - break; - - case 0x2121: // CGADD - PPU.CGFLIP = 0; - PPU.CGFLIPRead = 0; - PPU.CGADD = Byte; - break; - - case 0x2122: // CGDATA - REGISTER_2122(Byte); - break; - - case 0x2123: // W12SEL - 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; - #ifdef DEBUGGER - if (Byte & 0x80) - missing.window2[1] = 1; - if (Byte & 0x20) - missing.window1[1] = 1; - if (Byte & 0x08) - missing.window2[0] = 1; - if (Byte & 0x02) - missing.window1[0] = 1; - #endif - } - - break; - - case 0x2124: // W34SEL - 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; - #ifdef DEBUGGER - if (Byte & 0x80) - missing.window2[3] = 1; - if (Byte & 0x20) - missing.window1[3] = 1; - if (Byte & 0x08) - missing.window2[2] = 1; - if (Byte & 0x02) - missing.window1[2] = 1; - #endif - } - - break; - - case 0x2125: // WOBJSEL - 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; - #ifdef DEBUGGER - if (Byte & 0x80) - missing.window2[5] = 1; - if (Byte & 0x20) - missing.window1[5] = 1; - if (Byte & 0x08) - missing.window2[4] = 1; - if (Byte & 0x02) - missing.window1[4] = 1; - #endif - } - - break; - - case 0x2126: // WH0 - if (Byte != Memory.FillRAM[0x2126]) - { - FLUSH_REDRAW(); - PPU.Window1Left = Byte; - PPU.RecomputeClipWindows = TRUE; - } - - break; - - case 0x2127: // WH1 - if (Byte != Memory.FillRAM[0x2127]) - { - FLUSH_REDRAW(); - PPU.Window1Right = Byte; - PPU.RecomputeClipWindows = TRUE; - } - - break; - - case 0x2128: // WH2 - if (Byte != Memory.FillRAM[0x2128]) - { - FLUSH_REDRAW(); - PPU.Window2Left = Byte; - PPU.RecomputeClipWindows = TRUE; - } - - break; - - case 0x2129: // WH3 - if (Byte != Memory.FillRAM[0x2129]) - { - FLUSH_REDRAW(); - PPU.Window2Right = Byte; - PPU.RecomputeClipWindows = TRUE; - } - - break; - - case 0x212a: // WBGLOG - 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: // WOBJLOG - if (Byte != Memory.FillRAM[0x212b]) - { - FLUSH_REDRAW(); - PPU.ClipWindowOverlapLogic[4] = (Byte & 0x03); - PPU.ClipWindowOverlapLogic[5] = (Byte & 0x0c) >> 2; - PPU.RecomputeClipWindows = TRUE; - } - - break; - - case 0x212c: // TM - if (Byte != Memory.FillRAM[0x212c]) - { - FLUSH_REDRAW(); - PPU.RecomputeClipWindows = TRUE; - } - - break; - - case 0x212d: // TS - if (Byte != Memory.FillRAM[0x212d]) - { - FLUSH_REDRAW(); - PPU.RecomputeClipWindows = TRUE; - #ifdef DEBUGGER - if (Byte & 0x1f) - missing.subscreen = 1; - #endif - } - - break; - - case 0x212e: // TMW - if (Byte != Memory.FillRAM[0x212e]) - { - FLUSH_REDRAW(); - PPU.RecomputeClipWindows = TRUE; - } - - break; - - case 0x212f: // TSW - if (Byte != Memory.FillRAM[0x212f]) - { - FLUSH_REDRAW(); - PPU.RecomputeClipWindows = TRUE; - } - - break; - - case 0x2130: // CGWSEL - if (Byte != Memory.FillRAM[0x2130]) - { - FLUSH_REDRAW(); - PPU.RecomputeClipWindows = TRUE; - #ifdef DEBUGGER - if ((Byte & 1) && (PPU.BGMode == 3 || PPU.BGMode == 4 || PPU.BGMode == 7)) - missing.direct = 1; - #endif - } - - break; - - case 0x2131: // CGADSUB - if (Byte != Memory.FillRAM[0x2131]) - { - FLUSH_REDRAW(); - #ifdef DEBUGGER - if (Byte & 0x80) - { - if (Memory.FillRAM[0x2130] & 0x02) - missing.subscreen_sub = 1; - else - missing.fixed_colour_sub = 1; - } - else - { - if (Memory.FillRAM[0x2130] & 0x02) - missing.subscreen_add = 1; - else - missing.fixed_colour_add = 1; - } - #endif - } - - break; - - case 0x2132: // COLDATA - if (Byte != Memory.FillRAM[0x2132]) - { - FLUSH_REDRAW(); - if (Byte & 0x80) - PPU.FixedColourBlue = Byte & 0x1f; - if (Byte & 0x40) - PPU.FixedColourGreen = Byte & 0x1f; - if (Byte & 0x20) - PPU.FixedColourRed = Byte & 0x1f; - } - - break; - - case 0x2133: // SETINI - if (Byte != Memory.FillRAM[0x2133]) - { - if ((Memory.FillRAM[0x2133] ^ Byte) & 8) - { - FLUSH_REDRAW(); - IPPU.PseudoHires = Byte & 8; - } - - if (Byte & 0x04) - { - PPU.ScreenHeight = SNES_HEIGHT_EXTENDED; - if (IPPU.DoubleHeightPixels) - IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1; - else - IPPU.RenderedScreenHeight = PPU.ScreenHeight; - #ifdef DEBUGGER - missing.lines_239 = 1; - #endif - } - else - { - PPU.ScreenHeight = SNES_HEIGHT; - if (IPPU.DoubleHeightPixels) - IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1; - else - IPPU.RenderedScreenHeight = PPU.ScreenHeight; - } - - if ((Memory.FillRAM[0x2133] ^ Byte) & 3) - { - FLUSH_REDRAW(); - if ((Memory.FillRAM[0x2133] ^ Byte) & 2) - IPPU.OBJChanged = TRUE; - - IPPU.Interlace = Byte & 1; - IPPU.InterlaceOBJ = Byte & 2; - } - #ifdef DEBUGGER - if (Byte & 0x40) - missing.mode7_bgmode = 1; - if (Byte & 0x08) - missing.pseudo_512 = 1; - if (Byte & 0x02) - missing.sprite_double_height = 1; - if (Byte & 0x01) - missing.interlace = 1; - #endif - } - - break; - - case 0x2134: // MPYL - case 0x2135: // MPYM - case 0x2136: // MPYH - case 0x2137: // SLHV - case 0x2138: // OAMDATAREAD - case 0x2139: // VMDATALREAD - case 0x213a: // VMDATAHREAD - case 0x213b: // CGDATAREAD - case 0x213c: // OPHCT - case 0x213d: // OPVCT - case 0x213e: // STAT77 - case 0x213f: // STAT78 - return; - - case 0x2180: // WMDATA - if (!CPU.InWRAMDMAorHDMA) - REGISTER_2180(Byte); - break; - - case 0x2181: // WMADDL - if (!CPU.InWRAMDMAorHDMA) - { - PPU.WRAM &= 0x1ff00; - PPU.WRAM |= Byte; - } - - break; - - case 0x2182: // WMADDM - if (!CPU.InWRAMDMAorHDMA) - { - PPU.WRAM &= 0x100ff; - PPU.WRAM |= Byte << 8; - } - - break; - - case 0x2183: // WMADDH - if (!CPU.InWRAMDMAorHDMA) - { - PPU.WRAM &= 0x0ffff; - PPU.WRAM |= Byte << 16; - PPU.WRAM &= 0x1ffff; - } - - break; - } - } - else - { - if (Settings.SuperFX && Address >= 0x3000 && Address <= 0x32ff) - { - S9xSetSuperFX(Byte, Address); - return; - } - else - if (Settings.SA1 && Address >= 0x2200) - { - if (Address <= 0x23ff) - S9xSetSA1(Byte, Address); - else - Memory.FillRAM[Address] = Byte; - return; - } - else - if (Settings.BS && Address >= 0x2188 && Address <= 0x219f) - S9xSetBSXPPU(Byte, Address); - else - if (Settings.SRTC && Address == 0x2801) - S9xSetSRTC(Byte, Address); - #ifdef DEBUGGER - else - { - missing.unknownppu_write = Address; - if (Settings.TraceUnknownRegisters) - { - sprintf(String, "Unknown register write: $%02X->$%04X\n", Byte, Address); - S9xMessage(S9X_TRACE, S9X_PPU_TRACE, String); - } - } - #endif - } - - Memory.FillRAM[Address] = Byte; -} - -uint8 S9xGetPPU (uint16 Address) -{ - // MAP_PPU: $2000-$3FFF - if (Settings.MSU1 && (Address & 0xfff8) == 0x2000) - return (S9xMSU1ReadPort(Address & 7)); - else - if (Address < 0x2100) - return (OpenBus); - - if (CPU.InDMAorHDMA) - { - if (CPU.CurrentDMAorHDMAChannel >= 0 && !DMA[CPU.CurrentDMAorHDMAChannel].ReverseTransfer) - { - // S9xGetPPU() is called to read from DMA[].AAddress - if ((Address & 0xff00) == 0x2100) - // Cannot access to Address Bus B ($2100-$21FF) via (H)DMA - return (OpenBus); - else - // $2200-$3FFF are connected to Address Bus A - // SA1, SuperFX and SRTC are mapped here - // I don't bother for now... - return (OpenBus); - } - else - { - // S9xGetPPU() is called to write to $21xx - // Take care of DMA wrapping - if (Address > 0x21ff) - Address = 0x2100 + (Address & 0xff); - } - } - - if ((Address & 0xffc0) == 0x2140) // APUIO0, APUIO1, APUIO2, APUIO3 - // read_port will run the APU until given APU time before reading value - return (S9xAPUReadPort(Address & 3)); - else - if (Address <= 0x2183) - { - uint8 byte; - - switch (Address) - { - case 0x2104: // OAMDATA - case 0x2105: // BGMODE - case 0x2106: // MOSAIC - case 0x2108: // BG2SC - case 0x2109: // BG3SC - case 0x210a: // BG4SC - case 0x2114: // BG4VOFS - case 0x2115: // VMAIN - case 0x2116: // VMADDL - case 0x2118: // VMDATAL - case 0x2119: // VMDATAH - case 0x211a: // M7SEL - case 0x2124: // W34SEL - case 0x2125: // WOBJSEL - case 0x2126: // WH0 - case 0x2128: // WH2 - case 0x2129: // WH3 - case 0x212a: // WBGLOG - return (PPU.OpenBus1); - - case 0x2134: // MPYL - case 0x2135: // MPYM - case 0x2136: // MPYH - 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; - } - #ifdef DEBUGGER - missing.matrix_multiply = 1; - #endif - return (PPU.OpenBus1 = Memory.FillRAM[Address]); - - case 0x2137: // SLHV - S9xLatchCounters(0); - return (PPU.OpenBus1); - - case 0x2138: // OAMDATAREAD - 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; - #ifdef DEBUGGER - missing.sprite_priority_rotation = 1; - #endif - } - } - } - 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; - #ifdef DEBUGGER - missing.sprite_priority_rotation = 1; - #endif - } - } - } - - PPU.OAMFlip ^= 1; - #ifdef DEBUGGER - missing.oam_read = 1; - #endif - return (PPU.OpenBus1 = byte); - - case 0x2139: // VMDATALREAD - 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; - } - - #ifdef DEBUGGER - missing.vram_read = 1; - #endif - return (PPU.OpenBus1 = byte); - - case 0x213a: // VMDATAHREAD - 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; - } - #ifdef DEBUGGER - missing.vram_read = 1; - #endif - return (PPU.OpenBus1 = byte); - - case 0x213b: // CGDATAREAD - if (PPU.CGFLIPRead) - byte = (PPU.OpenBus2 & 0x80) | ((PPU.CGDATA[PPU.CGADD++] >> 8) & 0x7f); - else - byte = PPU.CGDATA[PPU.CGADD] & 0xff; - PPU.CGFLIPRead ^= 1; - #ifdef DEBUGGER - missing.cgram_read = 1; - #endif - return (PPU.OpenBus2 = byte); - - case 0x213c: // OPHCT - S9xTryGunLatch(false); - if (PPU.HBeamFlip) - byte = (PPU.OpenBus2 & 0xfe) | ((PPU.HBeamPosLatched >> 8) & 0x01); - else - byte = (uint8) PPU.HBeamPosLatched; - PPU.HBeamFlip ^= 1; - #ifdef DEBUGGER - missing.h_counter_read = 1; - #endif - return (PPU.OpenBus2 = byte); - - case 0x213d: // OPVCT - S9xTryGunLatch(false); - if (PPU.VBeamFlip) - byte = (PPU.OpenBus2 & 0xfe) | ((PPU.VBeamPosLatched >> 8) & 0x01); - else - byte = (uint8) PPU.VBeamPosLatched; - PPU.VBeamFlip ^= 1; - #ifdef DEBUGGER - missing.v_counter_read = 1; - #endif - return (PPU.OpenBus2 = byte); - - case 0x213e: // STAT77 - FLUSH_REDRAW(); - byte = (PPU.OpenBus1 & 0x10) | PPU.RangeTimeOver | Model->_5C77; - return (PPU.OpenBus1 = byte); - - case 0x213f: // STAT78 - S9xTryGunLatch(false); - PPU.VBeamFlip = PPU.HBeamFlip = 0; - byte = (PPU.OpenBus2 & 0x20) | (Memory.FillRAM[0x213f] & 0xc0) | (Settings.PAL ? 0x10 : 0) | Model->_5C78; - Memory.FillRAM[0x213f] &= ~0x40; - return (PPU.OpenBus2 = byte); - - case 0x2180: // WMDATA - if (!CPU.InWRAMDMAorHDMA) - { - byte = Memory.RAM[PPU.WRAM++]; - PPU.WRAM &= 0x1ffff; - } - else - byte = OpenBus; - #ifdef DEBUGGER - missing.wram_read = 1; - #endif - return (byte); - - default: - return (OpenBus); - } - } - else - { - if (Settings.SuperFX && Address >= 0x3000 && Address <= 0x32ff) - return (S9xGetSuperFX(Address)); - else - if (Settings.SA1 && Address >= 0x2200) - return (S9xGetSA1(Address)); - else - if (Settings.BS && Address >= 0x2188 && Address <= 0x219f) - return (S9xGetBSXPPU(Address)); - else - if (Settings.SRTC && Address == 0x2800) - return (S9xGetSRTC(Address)); - else - switch (Address) - { - case 0x21c2: - if (Model->_5C77 == 2) - return (0x20); - return (OpenBus); - - case 0x21c3: - if (Model->_5C77 == 2) - return (0); - return (OpenBus); - - default: - return (OpenBus); - } - } -} - -void S9xSetCPU (uint8 Byte, uint16 Address) -{ - if (Address < 0x4200) - { - switch (Address) - { - case 0x4016: // JOYSER0 - S9xSetJoypadLatch(Byte & 1); - break; - - case 0x4017: // JOYSER1 - return; - - default: - break; - } - } - else - if ((Address & 0xff80) == 0x4300) - { - if (CPU.InDMAorHDMA) - return; - - int d = (Address >> 4) & 0x7; - - switch (Address & 0xf) - { - case 0x0: // 0x43x0: DMAPx - DMA[d].ReverseTransfer = (Byte & 0x80) ? TRUE : FALSE; - DMA[d].HDMAIndirectAddressing = (Byte & 0x40) ? TRUE : FALSE; - DMA[d].UnusedBit43x0 = (Byte & 0x20) ? TRUE : FALSE; - DMA[d].AAddressDecrement = (Byte & 0x10) ? TRUE : FALSE; - DMA[d].AAddressFixed = (Byte & 0x08) ? TRUE : FALSE; - DMA[d].TransferMode = (Byte & 7); - return; - - case 0x1: // 0x43x1: BBADx - DMA[d].BAddress = Byte; - return; - - case 0x2: // 0x43x2: A1TxL - DMA[d].AAddress &= 0xff00; - DMA[d].AAddress |= Byte; - return; - - case 0x3: // 0x43x3: A1TxH - DMA[d].AAddress &= 0xff; - DMA[d].AAddress |= Byte << 8; - return; - - case 0x4: // 0x43x4: A1Bx - DMA[d].ABank = Byte; - HDMAMemPointers[d] = NULL; - return; - - case 0x5: // 0x43x5: DASxL - DMA[d].DMACount_Or_HDMAIndirectAddress &= 0xff00; - DMA[d].DMACount_Or_HDMAIndirectAddress |= Byte; - HDMAMemPointers[d] = NULL; - return; - - case 0x6: // 0x43x6: DASxH - DMA[d].DMACount_Or_HDMAIndirectAddress &= 0xff; - DMA[d].DMACount_Or_HDMAIndirectAddress |= Byte << 8; - HDMAMemPointers[d] = NULL; - return; - - case 0x7: // 0x43x7: DASBx - DMA[d].IndirectBank = Byte; - HDMAMemPointers[d] = NULL; - return; - - case 0x8: // 0x43x8: A2AxL - DMA[d].Address &= 0xff00; - DMA[d].Address |= Byte; - HDMAMemPointers[d] = NULL; - return; - - case 0x9: // 0x43x9: A2AxH - DMA[d].Address &= 0xff; - DMA[d].Address |= Byte << 8; - HDMAMemPointers[d] = NULL; - return; - - case 0xa: // 0x43xa: NLTRx - if (Byte & 0x7f) - { - DMA[d].LineCount = Byte & 0x7f; - DMA[d].Repeat = !(Byte & 0x80); - } - else - { - DMA[d].LineCount = 128; - DMA[d].Repeat = !!(Byte & 0x80); - } - - return; - - case 0xb: // 0x43xb: ????x - case 0xf: // 0x43xf: mirror of 0x43xb - DMA[d].UnknownByte = Byte; - return; - - default: - break; - } - } - else - { - uint16 pos; - - switch (Address) - { - case 0x4200: // NMITIMEN - #ifdef DEBUGGER - if (Settings.TraceHCEvent) - S9xTraceFormattedMessage("Write to 0x4200. Byte is %2x was %2x\n", Byte, Memory.FillRAM[Address]); - #endif - - if (Byte == Memory.FillRAM[0x4200]) - break; - - if (Byte & 0x20) - { - PPU.VTimerEnabled = TRUE; - - #ifdef DEBUGGER - missing.virq = 1; - missing.virq_pos = PPU.IRQVBeamPos; - #endif - } - else - PPU.VTimerEnabled = FALSE; - - if (Byte & 0x10) - { - PPU.HTimerEnabled = TRUE; - - #ifdef DEBUGGER - missing.hirq = 1; - missing.hirq_pos = PPU.IRQHBeamPos; - #endif - } - else - PPU.HTimerEnabled = FALSE; - - if (!(Byte & 0x10) && !(Byte & 0x20)) - { - CPU.IRQLine = FALSE; - CPU.IRQTransition = FALSE; - } - - S9xUpdateIRQPositions(true); - - // NMI can trigger immediately during VBlank as long as NMI_read ($4210) wasn't cleard. - if ((Byte & 0x80) && !(Memory.FillRAM[0x4200] & 0x80) && - (CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE) && (Memory.FillRAM[0x4210] & 0x80)) - { - // FIXME: triggered at HC+=6, checked just before the final CPU cycle, - // then, when to call S9xOpcode_NMI()? - CPU.NMIPending = TRUE; - Timings.NMITriggerPos = CPU.Cycles + 6 + 6; - - #ifdef DEBUGGER - if (Settings.TraceHCEvent) - S9xTraceFormattedMessage("NMI Triggered on low-to-high occurring at next HC=%d\n", Timings.NMITriggerPos); - #endif - } - - #ifdef DEBUGGER - S9xTraceFormattedMessage("--- IRQ Timer Enable HTimer:%d Pos:%04d VTimer:%d Pos:%03d", - PPU.HTimerEnabled, PPU.HTimerPosition, PPU.VTimerEnabled, PPU.VTimerPosition); - #endif - - break; - - case 0x4201: // WRIO - if ((Byte & 0x80) == 0 && (Memory.FillRAM[0x4213] & 0x80) == 0x80) - S9xLatchCounters(1); - else - S9xTryGunLatch((Byte & 0x80) ? true : false); - Memory.FillRAM[0x4201] = Memory.FillRAM[0x4213] = Byte; - break; - - case 0x4202: // WRMPYA - break; - - case 0x4203: // WRMPYB - { - uint32 res = Memory.FillRAM[0x4202] * Byte; - // FIXME: The update occurs 8 machine cycles after $4203 is set. - Memory.FillRAM[0x4216] = (uint8) res; - Memory.FillRAM[0x4217] = (uint8) (res >> 8); - break; - } - - case 0x4204: // WRDIVL - case 0x4205: // WRDIVH - break; - - case 0x4206: // WRDIVB - { - uint16 a = Memory.FillRAM[0x4204] + (Memory.FillRAM[0x4205] << 8); - uint16 div = Byte ? a / Byte : 0xffff; - uint16 rem = Byte ? a % Byte : a; - // FIXME: The update occurs 16 machine cycles after $4206 is set. - Memory.FillRAM[0x4214] = (uint8) div; - Memory.FillRAM[0x4215] = div >> 8; - Memory.FillRAM[0x4216] = (uint8) rem; - Memory.FillRAM[0x4217] = rem >> 8; - break; - } - - case 0x4207: // HTIMEL - pos = PPU.IRQHBeamPos; - PPU.IRQHBeamPos = (PPU.IRQHBeamPos & 0xff00) | Byte; - if (PPU.IRQHBeamPos != pos) - S9xUpdateIRQPositions(false); - #ifdef DEBUGGER - missing.hirq_pos = PPU.IRQHBeamPos; - #endif - break; - - case 0x4208: // HTIMEH - pos = PPU.IRQHBeamPos; - PPU.IRQHBeamPos = (PPU.IRQHBeamPos & 0xff) | ((Byte & 1) << 8); - if (PPU.IRQHBeamPos != pos) - S9xUpdateIRQPositions(false); - #ifdef DEBUGGER - missing.hirq_pos = PPU.IRQHBeamPos; - #endif - break; - - case 0x4209: // VTIMEL - pos = PPU.IRQVBeamPos; - PPU.IRQVBeamPos = (PPU.IRQVBeamPos & 0xff00) | Byte; - if (PPU.IRQVBeamPos != pos) - S9xUpdateIRQPositions(true); - #ifdef DEBUGGER - missing.virq_pos = PPU.IRQVBeamPos; - #endif - break; - - case 0x420a: // VTIMEH - pos = PPU.IRQVBeamPos; - PPU.IRQVBeamPos = (PPU.IRQVBeamPos & 0xff) | ((Byte & 1) << 8); - if (PPU.IRQVBeamPos != pos) - S9xUpdateIRQPositions(true); - #ifdef DEBUGGER - missing.virq_pos = PPU.IRQVBeamPos; - #endif - break; - - case 0x420b: // MDMAEN - if (CPU.InDMAorHDMA) - return; - // XXX: Not quite right... - if (Byte) { - CPU.Cycles += Timings.DMACPUSync; - } - if (Byte & 0x01) - S9xDoDMA(0); - if (Byte & 0x02) - S9xDoDMA(1); - if (Byte & 0x04) - S9xDoDMA(2); - if (Byte & 0x08) - S9xDoDMA(3); - if (Byte & 0x10) - S9xDoDMA(4); - if (Byte & 0x20) - S9xDoDMA(5); - if (Byte & 0x40) - S9xDoDMA(6); - if (Byte & 0x80) - S9xDoDMA(7); - #ifdef DEBUGGER - missing.dma_this_frame = Byte; - missing.dma_channels = Byte; - #endif - break; - - case 0x420c: // HDMAEN - if (CPU.InDMAorHDMA) - return; - Memory.FillRAM[0x420c] = Byte; - // Yoshi's Island, Genjyu Ryodan, Mortal Kombat, Tales of Phantasia - PPU.HDMA = Byte & ~PPU.HDMAEnded; - #ifdef DEBUGGER - missing.hdma_this_frame |= Byte; - missing.hdma_channels |= Byte; - #endif - break; - - case 0x420d: // MEMSEL - if ((Byte & 1) != (Memory.FillRAM[0x420d] & 1)) - { - if (Byte & 1) - { - CPU.FastROMSpeed = ONE_CYCLE; - #ifdef DEBUGGER - missing.fast_rom = 1; - #endif - } - else - CPU.FastROMSpeed = SLOW_ONE_CYCLE; - } - - break; - - case 0x4210: // RDNMI - case 0x4211: // TIMEUP - case 0x4212: // HVBJOY - case 0x4213: // RDIO - case 0x4214: // RDDIVL - case 0x4215: // RDDIVH - case 0x4216: // RDMPYL - case 0x4217: // RDMPYH - case 0x4218: // JOY1L - case 0x4219: // JOY1H - case 0x421a: // JOY2L - case 0x421b: // JOY2H - case 0x421c: // JOY3L - case 0x421d: // JOY3H - case 0x421e: // JOY4L - case 0x421f: // JOY4H - return; - - default: - if (Settings.SPC7110 && Address >= 0x4800) - S9xSetSPC7110(Byte, Address); - else - if (Settings.SDD1 && Address >= 0x4804 && Address <= 0x4807) - S9xSetSDD1MemoryMap(Address - 0x4804, Byte & 7); - break; - } - } - - Memory.FillRAM[Address] = Byte; -} - -uint8 S9xGetCPU (uint16 Address) -{ - if (Address < 0x4200) - { - #ifdef SNES_JOY_READ_CALLBACKS - extern bool8 pad_read; - if (Address == 0x4016 || Address == 0x4017) - { - S9xOnSNESPadRead(); - pad_read = TRUE; - } - #endif - - switch (Address) - { - case 0x4016: // JOYSER0 - case 0x4017: // JOYSER1 - return (S9xReadJOYSERn(Address)); - - default: - return (OpenBus); - } - } - else - if ((Address & 0xff80) == 0x4300) - { - if (CPU.InDMAorHDMA) - return (OpenBus); - - int d = (Address >> 4) & 0x7; - - switch (Address & 0xf) - { - case 0x0: // 0x43x0: DMAPx - return ((DMA[d].ReverseTransfer ? 0x80 : 0) | - (DMA[d].HDMAIndirectAddressing ? 0x40 : 0) | - (DMA[d].UnusedBit43x0 ? 0x20 : 0) | - (DMA[d].AAddressDecrement ? 0x10 : 0) | - (DMA[d].AAddressFixed ? 0x08 : 0) | - (DMA[d].TransferMode & 7)); - - case 0x1: // 0x43x1: BBADx - return (DMA[d].BAddress); - - case 0x2: // 0x43x2: A1TxL - return (DMA[d].AAddress & 0xff); - - case 0x3: // 0x43x3: A1TxH - return (DMA[d].AAddress >> 8); - - case 0x4: // 0x43x4: A1Bx - return (DMA[d].ABank); - - case 0x5: // 0x43x5: DASxL - return (DMA[d].DMACount_Or_HDMAIndirectAddress & 0xff); - - case 0x6: // 0x43x6: DASxH - return (DMA[d].DMACount_Or_HDMAIndirectAddress >> 8); - - case 0x7: // 0x43x7: DASBx - return (DMA[d].IndirectBank); - - case 0x8: // 0x43x8: A2AxL - return (DMA[d].Address & 0xff); - - case 0x9: // 0x43x9: A2AxH - return (DMA[d].Address >> 8); - - case 0xa: // 0x43xa: NLTRx - return (DMA[d].LineCount ^ (DMA[d].Repeat ? 0x00 : 0x80)); - - case 0xb: // 0x43xb: ????x - case 0xf: // 0x43xf: mirror of 0x43xb - return (DMA[d].UnknownByte); - - default: - return (OpenBus); - } - } - else - { - uint8 byte; - - switch (Address) - { - case 0x4210: // RDNMI - byte = Memory.FillRAM[0x4210]; - Memory.FillRAM[0x4210] = Model->_5A22; - return ((byte & 0x80) | (OpenBus & 0x70) | Model->_5A22); - - case 0x4211: // TIMEUP - byte = 0; - if (CPU.IRQLine) - { - byte = 0x80; - CPU.IRQLine = FALSE; - CPU.IRQTransition = FALSE; - } - - return (byte | (OpenBus & 0x7f)); - - case 0x4212: // HVBJOY - return (REGISTER_4212() | (OpenBus & 0x3e)); - - case 0x4213: // RDIO - return (Memory.FillRAM[0x4213]); - - case 0x4214: // RDDIVL - case 0x4215: // RDDIVH - case 0x4216: // RDMPYL - case 0x4217: // RDMPYH - return (Memory.FillRAM[Address]); - - case 0x4218: // JOY1L - case 0x4219: // JOY1H - case 0x421a: // JOY2L - case 0x421b: // JOY2H - case 0x421c: // JOY3L - case 0x421d: // JOY3H - case 0x421e: // JOY4L - case 0x421f: // JOY4H - #ifdef SNES_JOY_READ_CALLBACKS - extern bool8 pad_read; - if (Memory.FillRAM[0x4200] & 1) - { - S9xOnSNESPadRead(); - pad_read = TRUE; - } - #endif - return (Memory.FillRAM[Address]); - - default: - if (Settings.SPC7110 && Address >= 0x4800) - return (S9xGetSPC7110(Address)); - if (Settings.SDD1 && Address >= 0x4800 && Address <= 0x4807) - return (Memory.FillRAM[Address]); - return (OpenBus); - } - } -} - -void S9xResetPPU (void) -{ - S9xSoftResetPPU(); - S9xControlsReset(); - PPU.M7HOFS = 0; - PPU.M7VOFS = 0; - PPU.M7byte = 0; -} - -void S9xResetPPUFast (void) -{ - PPU.RecomputeClipWindows = TRUE; - IPPU.ColorsChanged = TRUE; - IPPU.OBJChanged = TRUE; - memset(IPPU.TileCached[TILE_2BIT], 0, MAX_2BIT_TILES); - memset(IPPU.TileCached[TILE_4BIT], 0, MAX_4BIT_TILES); - memset(IPPU.TileCached[TILE_8BIT], 0, MAX_8BIT_TILES); - memset(IPPU.TileCached[TILE_2BIT_EVEN], 0, MAX_2BIT_TILES); - memset(IPPU.TileCached[TILE_2BIT_ODD], 0, MAX_2BIT_TILES); - memset(IPPU.TileCached[TILE_4BIT_EVEN], 0, MAX_4BIT_TILES); - memset(IPPU.TileCached[TILE_4BIT_ODD], 0, MAX_4BIT_TILES); -} - -void S9xSoftResetPPU (void) -{ - S9xControlsSoftReset(); - - PPU.VMA.High = 0; - PPU.VMA.Increment = 1; - PPU.VMA.Address = 0; - PPU.VMA.FullGraphicCount = 0; - PPU.VMA.Shift = 0; - - PPU.WRAM = 0; - - for (int c = 0; c < 4; c++) - { - PPU.BG[c].SCBase = 0; - PPU.BG[c].HOffset = 0; - PPU.BG[c].VOffset = 0; - PPU.BG[c].BGSize = 0; - PPU.BG[c].NameBase = 0; - PPU.BG[c].SCSize = 0; - } - - PPU.BGMode = 0; - PPU.BG3Priority = 0; - - PPU.CGFLIP = 0; - PPU.CGFLIPRead = 0; - PPU.CGADD = 0; - - for (int 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); - } - - for (int c = 0; c < 128; c++) - { - PPU.OBJ[c].HPos = 0; - PPU.OBJ[c].VPos = 0; - PPU.OBJ[c].HFlip = 0; - PPU.OBJ[c].VFlip = 0; - PPU.OBJ[c].Name = 0; - PPU.OBJ[c].Priority = 0; - PPU.OBJ[c].Palette = 0; - PPU.OBJ[c].Size = 0; - } - - PPU.OBJThroughMain = FALSE; - PPU.OBJThroughSub = FALSE; - PPU.OBJAddition = FALSE; - PPU.OBJNameBase = 0; - PPU.OBJNameSelect = 0; - PPU.OBJSizeSelect = 0; - - PPU.OAMAddr = 0; - PPU.SavedOAMAddr = 0; - PPU.OAMPriorityRotation = 0; - PPU.OAMFlip = 0; - PPU.OAMReadFlip = 0; - PPU.OAMTileAddress = 0; - PPU.OAMWriteRegister = 0; - memset(PPU.OAMData, 0, 512 + 32); - - PPU.FirstSprite = 0; - PPU.LastSprite = 127; - PPU.RangeTimeOver = 0; - - PPU.HTimerEnabled = FALSE; - PPU.VTimerEnabled = FALSE; - PPU.HTimerPosition = Timings.H_Max + 1; - PPU.VTimerPosition = Timings.V_Max + 1; - PPU.IRQHBeamPos = 0x1ff; - PPU.IRQVBeamPos = 0x1ff; - - PPU.HBeamFlip = 0; - PPU.VBeamFlip = 0; - PPU.HBeamPosLatched = 0; - PPU.VBeamPosLatched = 0; - PPU.GunHLatch = 0; - PPU.GunVLatch = 1000; - PPU.HVBeamCounterLatched = 0; - - PPU.Mode7HFlip = FALSE; - PPU.Mode7VFlip = FALSE; - PPU.Mode7Repeat = 0; - PPU.MatrixA = 0; - PPU.MatrixB = 0; - PPU.MatrixC = 0; - PPU.MatrixD = 0; - PPU.CentreX = 0; - PPU.CentreY = 0; - - PPU.Mosaic = 0; - PPU.BGMosaic[0] = FALSE; - PPU.BGMosaic[1] = FALSE; - PPU.BGMosaic[2] = FALSE; - PPU.BGMosaic[3] = FALSE; - - PPU.Window1Left = 1; - PPU.Window1Right = 0; - PPU.Window2Left = 1; - PPU.Window2Right = 0; - PPU.RecomputeClipWindows = TRUE; - - for (int c = 0; c < 6; c++) - { - PPU.ClipCounts[c] = 0; - PPU.ClipWindowOverlapLogic[c] = CLIP_OR; - PPU.ClipWindow1Enable[c] = FALSE; - PPU.ClipWindow2Enable[c] = FALSE; - PPU.ClipWindow1Inside[c] = TRUE; - PPU.ClipWindow2Inside[c] = TRUE; - } - - PPU.ForcedBlanking = TRUE; - - PPU.FixedColourRed = 0; - PPU.FixedColourGreen = 0; - PPU.FixedColourBlue = 0; - PPU.Brightness = 0; - PPU.ScreenHeight = SNES_HEIGHT; - - PPU.Need16x8Mulitply = FALSE; - PPU.BGnxOFSbyte = 0; - - PPU.HDMA = 0; - PPU.HDMAEnded = 0; - - PPU.OpenBus1 = 0; - PPU.OpenBus2 = 0; - - for (int c = 0; c < 2; c++) - memset(&IPPU.Clip[c], 0, sizeof(struct ClipData)); - IPPU.ColorsChanged = TRUE; - IPPU.OBJChanged = TRUE; - memset(IPPU.TileCached[TILE_2BIT], 0, MAX_2BIT_TILES); - memset(IPPU.TileCached[TILE_4BIT], 0, MAX_4BIT_TILES); - memset(IPPU.TileCached[TILE_8BIT], 0, MAX_8BIT_TILES); - memset(IPPU.TileCached[TILE_2BIT_EVEN], 0, MAX_2BIT_TILES); - memset(IPPU.TileCached[TILE_2BIT_ODD], 0, MAX_2BIT_TILES); - memset(IPPU.TileCached[TILE_4BIT_EVEN], 0, MAX_4BIT_TILES); - memset(IPPU.TileCached[TILE_4BIT_ODD], 0, MAX_4BIT_TILES); - IPPU.VRAMReadBuffer = 0; // XXX: FIXME: anything better? - GFX.InterlaceFrame = 0; - IPPU.Interlace = FALSE; - IPPU.InterlaceOBJ = FALSE; - IPPU.DoubleWidthPixels = FALSE; - IPPU.DoubleHeightPixels = FALSE; - IPPU.CurrentLine = 0; - IPPU.PreviousLine = 0; - IPPU.XB = NULL; - for (int c = 0; c < 256; c++) - IPPU.ScreenColors[c] = c; - IPPU.MaxBrightness = 0; - IPPU.RenderThisFrame = TRUE; - IPPU.RenderedScreenWidth = SNES_WIDTH; - IPPU.RenderedScreenHeight = SNES_HEIGHT; - IPPU.FrameCount = 0; - IPPU.RenderedFramesCount = 0; - IPPU.DisplayedRenderedFrameCount = 0; - IPPU.SkippedFrames = 0; - IPPU.FrameSkip = 0; - - S9xFixColourBrightness(); - S9xBuildDirectColourMaps(); - - for (int c = 0; c < 0x8000; c += 0x100) - memset(&Memory.FillRAM[c], c >> 8, 0x100); - memset(&Memory.FillRAM[0x2100], 0, 0x100); - memset(&Memory.FillRAM[0x4200], 0, 0x100); - memset(&Memory.FillRAM[0x4000], 0, 0x100); - // For BS Suttehakkun 2... - memset(&Memory.FillRAM[0x1000], 0, 0x1000); - - Memory.FillRAM[0x4201] = Memory.FillRAM[0x4213] = 0xff; - Memory.FillRAM[0x2126] = Memory.FillRAM[0x2128] = 1; -} +/*********************************************************************************** + Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com), + Jerremy Koot (jkoot@snes9x.com) + + (c) Copyright 2002 - 2004 Matthew Kendora + + (c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org) + + (c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/) + + (c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net) + + (c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca), + Kris Bleakley (codeviolation@hotmail.com) + + (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), + Nach (n-a-c-h@users.sourceforge.net), + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2006 - 2007 nitsuja + + (c) Copyright 2009 - 2018 BearOso, + OV2 + + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + + + BS-X C emulator code + (c) Copyright 2005 - 2006 Dreamer Nom, + zones + + C4 x86 assembler and some C emulation code + (c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com), + Nach, + zsKnight (zsknight@zsnes.com) + + C4 C++ code + (c) Copyright 2003 - 2006 Brad Jorsch, + Nach + + DSP-1 emulator code + (c) Copyright 1998 - 2006 _Demo_, + Andreas Naive (andreasnaive@gmail.com), + Gary Henderson, + Ivar (ivar@snes9x.com), + John Weidman, + Kris Bleakley, + Matthew Kendora, + Nach, + neviksti (neviksti@hotmail.com) + + DSP-2 emulator code + (c) Copyright 2003 John Weidman, + Kris Bleakley, + Lord Nightmare (lord_nightmare@users.sourceforge.net), + Matthew Kendora, + neviksti + + DSP-3 emulator code + (c) Copyright 2003 - 2006 John Weidman, + Kris Bleakley, + Lancer, + z80 gaiden + + DSP-4 emulator code + (c) Copyright 2004 - 2006 Dreamer Nom, + John Weidman, + Kris Bleakley, + Nach, + z80 gaiden + + OBC1 emulator code + (c) Copyright 2001 - 2004 zsKnight, + pagefault (pagefault@zsnes.com), + Kris Bleakley + Ported from x86 assembler to C by sanmaiwashi + + SPC7110 and RTC C++ emulator code used in 1.39-1.51 + (c) Copyright 2002 Matthew Kendora with research by + zsKnight, + John Weidman, + Dark Force + + SPC7110 and RTC C++ emulator code used in 1.52+ + (c) Copyright 2009 byuu, + neviksti + + S-DD1 C emulator code + (c) Copyright 2003 Brad Jorsch with research by + Andreas Naive, + John Weidman + + S-RTC C emulator code + (c) Copyright 2001 - 2006 byuu, + John Weidman + + ST010 C++ emulator code + (c) Copyright 2003 Feather, + John Weidman, + Kris Bleakley, + Matthew Kendora + + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 _Demo_, + pagefault, + zsKnight + + Super FX C emulator code + (c) Copyright 1997 - 1999 Ivar, + Gary Henderson, + John Weidman + + Sound emulator code used in 1.5-1.51 + (c) Copyright 1998 - 2003 Brad Martin + (c) Copyright 1998 - 2006 Charles Bilyue' + + Sound emulator code used in 1.52+ + (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + + SH assembler code partly based on x86 assembler code + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + + 2xSaI filter + (c) Copyright 1999 - 2001 Derek Liauw Kie Fa + + HQ2x, HQ3x, HQ4x filters + (c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com) + + NTSC filter + (c) Copyright 2006 - 2007 Shay Green + + GTK+ GUI code + (c) Copyright 2004 - 2018 BearOso + + Win32 GUI code + (c) Copyright 2003 - 2006 blip, + funkyass, + Matthew Kendora, + Nach, + nitsuja + (c) Copyright 2009 - 2018 OV2 + + Mac OS GUI code + (c) Copyright 1998 - 2001 John Stiles + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + + + 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/or 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 or it's derivatives. + + Snes9x is freeware for PERSONAL USE only. Commercial users should + seek permission of the copyright holders first. Commercial use includes, + but is not limited to, charging money for Snes9x or software derived from + Snes9x, including Snes9x or derivatives in commercial game bundles, and/or + using Snes9x as a promotion for your commercial product. + + The copyright holders request that bug fixes and improvements to the code + should be forwarded to them so everyone can benefit from the modifications + in future versions. + + Super NES and Super Nintendo Entertainment System are trademarks of + Nintendo Co., Limited and its subsidiary companies. + ***********************************************************************************/ + + +#include "snes9x.h" +#include "memmap.h" +#include "dma.h" +#include "apu/apu.h" +#include "fxemu.h" +#include "sdd1.h" +#include "srtc.h" +#include "controls.h" +#include "movie.h" +#include "display.h" +#ifdef NETPLAY_SUPPORT +#include "netplay.h" +#endif +#ifdef DEBUGGER +#include "debug.h" +#include "missing.h" +#endif + +extern uint8 *HDMAMemPointers[8]; + + +static inline void S9xLatchCounters (bool force) +{ + if (force || (Memory.FillRAM[0x4213] & 0x80)) + { + // Latch h and v counters, like the gun + #ifdef DEBUGGER + missing.h_v_latch = 1; + #endif + + PPU.HVBeamCounterLatched = 1; + PPU.VBeamPosLatched = (uint16) CPU.V_Counter; + + // From byuu: + // All dots are 4 cycles long, except dots 322 and 326. dots 322 and 326 are 6 cycles long. + // This holds true for all scanlines except scanline 240 on non-interlace odd frames. + // The reason for this is because this scanline is only 1360 cycles long, + // instead of 1364 like all other scanlines. + // This makes the effective range of hscan_pos 0-339 at all times. + int32 hc = CPU.Cycles; + + if (Timings.H_Max == Timings.H_Max_Master) // 1364 + { + if (hc >= 1292) + hc -= (ONE_DOT_CYCLE / 2); + if (hc >= 1308) + hc -= (ONE_DOT_CYCLE / 2); + } + + PPU.HBeamPosLatched = (uint16) (hc / ONE_DOT_CYCLE); + + Memory.FillRAM[0x213f] |= 0x40; + } + + if (CPU.V_Counter > PPU.GunVLatch || (CPU.V_Counter == PPU.GunVLatch && CPU.Cycles >= PPU.GunHLatch * ONE_DOT_CYCLE)) + PPU.GunVLatch = 1000; +} + +static inline void S9xTryGunLatch (bool force) +{ + if (CPU.V_Counter > PPU.GunVLatch || (CPU.V_Counter == PPU.GunVLatch && CPU.Cycles >= PPU.GunHLatch * ONE_DOT_CYCLE)) + { + if (force || (Memory.FillRAM[0x4213] & 0x80)) + { + #ifdef DEBUGGER + missing.h_v_latch = 1; + #endif + + PPU.HVBeamCounterLatched = 1; + PPU.VBeamPosLatched = (uint16) PPU.GunVLatch; + PPU.HBeamPosLatched = (uint16) PPU.GunHLatch; + + Memory.FillRAM[0x213f] |= 0x40; + } + + PPU.GunVLatch = 1000; + } +} + +static int CyclesUntilNext (int hc, int vc) +{ + int32 total = 0; + int vpos = CPU.V_Counter; + + if (vc - vpos > 0) + { + // It's still in this frame */ + // Add number of lines + total += (vc - vpos) * Timings.H_Max_Master; + // If line 240 is in there and we're odd, subtract a dot + if (vpos <= 240 && vc > 240 && Timings.InterlaceField & !IPPU.Interlace) + total -= ONE_DOT_CYCLE; + } + else + { + if (vc == vpos && (hc > CPU.Cycles)) + { + return hc; + } + + total += (Timings.V_Max - vpos) * Timings.H_Max_Master; + if (vpos <= 240 && Timings.InterlaceField && !IPPU.Interlace) + total -= ONE_DOT_CYCLE; + + total += (vc) * Timings.H_Max_Master; + if (vc > 240 && !Timings.InterlaceField && !IPPU.Interlace) + total -= ONE_DOT_CYCLE; + } + + total += hc; + + return total; +} + +void S9xUpdateIRQPositions (bool initial) +{ + PPU.HTimerPosition = PPU.IRQHBeamPos * ONE_DOT_CYCLE + Timings.IRQTriggerCycles; + PPU.HTimerPosition -= PPU.IRQHBeamPos ? 0 : ONE_DOT_CYCLE; + PPU.HTimerPosition += PPU.IRQHBeamPos > 322 ? (ONE_DOT_CYCLE / 2) : 0; + PPU.HTimerPosition += PPU.IRQHBeamPos > 326 ? (ONE_DOT_CYCLE / 2) : 0; + PPU.VTimerPosition = PPU.IRQVBeamPos; + + if (PPU.VTimerEnabled && (PPU.VTimerPosition >= (Timings.V_Max + (IPPU.Interlace ? 1 : 0)))) + { + Timings.NextIRQTimer = 0x0fffffff; + } + else if (!PPU.HTimerEnabled && !PPU.VTimerEnabled) + { + Timings.NextIRQTimer = 0x0fffffff; + } + else if (PPU.HTimerEnabled && !PPU.VTimerEnabled) + { + int v_pos = CPU.V_Counter; + + Timings.NextIRQTimer = PPU.HTimerPosition; + if (CPU.Cycles > Timings.NextIRQTimer - Timings.IRQTriggerCycles) + { + Timings.NextIRQTimer += Timings.H_Max; + v_pos++; + } + + // Check for short dot scanline + if (v_pos == 240 && Timings.InterlaceField && !IPPU.Interlace) + { + Timings.NextIRQTimer -= PPU.IRQHBeamPos <= 322 ? ONE_DOT_CYCLE / 2 : 0; + Timings.NextIRQTimer -= PPU.IRQHBeamPos <= 326 ? ONE_DOT_CYCLE / 2 : 0; + } + } + else if (!PPU.HTimerEnabled && PPU.VTimerEnabled) + { + if (CPU.V_Counter == PPU.VTimerPosition && initial) + Timings.NextIRQTimer = CPU.Cycles + Timings.IRQTriggerCycles - ONE_DOT_CYCLE; + else + Timings.NextIRQTimer = CyclesUntilNext (Timings.IRQTriggerCycles - ONE_DOT_CYCLE, PPU.VTimerPosition); + } + else + { + Timings.NextIRQTimer = CyclesUntilNext (PPU.HTimerPosition, PPU.VTimerPosition); + + // Check for short dot scanline + int field = Timings.InterlaceField; + + if (PPU.VTimerPosition < CPU.V_Counter || + (PPU.VTimerPosition == CPU.V_Counter && Timings.NextIRQTimer > Timings.H_Max)) + { + field = !field; + } + + if (PPU.VTimerPosition == 240 && field && !IPPU.Interlace) + { + Timings.NextIRQTimer -= PPU.IRQHBeamPos <= 322 ? ONE_DOT_CYCLE / 2 : 0; + Timings.NextIRQTimer -= PPU.IRQHBeamPos <= 326 ? ONE_DOT_CYCLE / 2 : 0; + } + } + +#ifdef DEBUGGER + S9xTraceFormattedMessage("--- IRQ Timer HC:%d VC:%d set %d cycles HTimer:%d Pos:%04d->%04d VTimer:%d Pos:%03d->%03d", CPU.Cycles, CPU.V_Counter, + Timings.NextIRQTimer, PPU.HTimerEnabled, PPU.IRQHBeamPos, PPU.HTimerPosition, PPU.VTimerEnabled, PPU.IRQVBeamPos, PPU.VTimerPosition); +#endif +} + +void S9xFixColourBrightness (void) +{ + IPPU.XB = mul_brightness[PPU.Brightness]; + + for (int 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]); + } +} + +void S9xSetPPU (uint8 Byte, uint16 Address) +{ + // MAP_PPU: $2000-$3FFF + + if (CPU.InDMAorHDMA) + { + if (CPU.CurrentDMAorHDMAChannel >= 0 && DMA[CPU.CurrentDMAorHDMAChannel].ReverseTransfer) + { + // S9xSetPPU() is called to write to DMA[].AAddress + if ((Address & 0xff00) == 0x2100) + { + // Cannot access to Address Bus B ($2100-$21ff) via (H)DMA + return; + } + else + { + // 0x2000-0x3FFF is connected to Address Bus A + // SA1, SuperFX and SRTC are mapped here + // I don't bother for now... + return; + } + } + else + { + // S9xSetPPU() is called to read from $21xx + // Take care of DMA wrapping + if (Address > 0x21ff) + Address = 0x2100 + (Address & 0xff); + } + } + +#ifdef DEBUGGER + if (CPU.InHDMA) + S9xTraceFormattedMessage("--- HDMA PPU %04X -> %02X", Address, Byte); +#endif + + if (Settings.MSU1 && (Address & 0xfff8) == 0x2000) // MSU-1 + S9xMSU1WritePort(Address & 7, Byte); + else + if ((Address & 0xffc0) == 0x2140) // APUIO0, APUIO1, APUIO2, APUIO3 + // write_port will run the APU until given clock before writing value + S9xAPUWritePort(Address & 3, Byte); + else + if (Address <= 0x2183) + { + switch (Address) + { + case 0x2100: // INIDISP + if (Byte != Memory.FillRAM[0x2100]) + { + FLUSH_REDRAW(); + + if (PPU.Brightness != (Byte & 0xf)) + { + IPPU.ColorsChanged = TRUE; + PPU.Brightness = Byte & 0xf; + S9xFixColourBrightness(); + S9xBuildDirectColourMaps(); + if (PPU.Brightness > IPPU.MaxBrightness) + IPPU.MaxBrightness = PPU.Brightness; + } + + if ((Memory.FillRAM[0x2100] & 0x80) != (Byte & 0x80)) + { + IPPU.ColorsChanged = TRUE; + PPU.ForcedBlanking = (Byte >> 7) & 1; + } + } + + if ((Memory.FillRAM[0x2100] & 0x80) && CPU.V_Counter == PPU.ScreenHeight + FIRST_VISIBLE_LINE) + { + 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; + } + + break; + + case 0x2101: // OBSEL + 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: // OAMADDL + PPU.OAMAddr = ((Memory.FillRAM[0x2103] & 1) << 8) | Byte; + PPU.OAMFlip = 0; + PPU.OAMReadFlip = 0; + PPU.SavedOAMAddr = PPU.OAMAddr; + if (PPU.OAMPriorityRotation && PPU.FirstSprite != (PPU.OAMAddr >> 1)) + { + PPU.FirstSprite = (PPU.OAMAddr & 0xfe) >> 1; + IPPU.OBJChanged = TRUE; + #ifdef DEBUGGER + missing.sprite_priority_rotation = 1; + #endif + } + + break; + + case 0x2103: // OAMADDH + 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; + #ifdef DEBUGGER + missing.sprite_priority_rotation = 1; + #endif + } + } + else + { + if (PPU.FirstSprite != 0) + { + PPU.FirstSprite = 0; + IPPU.OBJChanged = TRUE; + #ifdef DEBUGGER + missing.sprite_priority_rotation = 1; + #endif + } + } + + PPU.OAMFlip = 0; + PPU.OAMReadFlip = 0; + PPU.SavedOAMAddr = PPU.OAMAddr; + + break; + + case 0x2104: // OAMDATA + REGISTER_2104(Byte); + break; + + case 0x2105: // BGMODE + 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 == 6 || PPU.BGMode == 5 || PPU.BGMode == 7) + IPPU.Interlace = Memory.FillRAM[0x2133] & 1; + else + IPPU.Interlace = 0; + #ifdef DEBUGGER + missing.modes[PPU.BGMode] = 1; + #endif + } + + break; + + case 0x2106: // MOSAIC + if (Byte != Memory.FillRAM[0x2106]) + { + FLUSH_REDRAW(); + PPU.MosaicStart = CPU.V_Counter; + if (PPU.MosaicStart > PPU.ScreenHeight) + PPU.MosaicStart = 0; + PPU.Mosaic = (Byte >> 4) + 1; + PPU.BGMosaic[0] = (Byte & 1); + PPU.BGMosaic[1] = (Byte & 2); + PPU.BGMosaic[2] = (Byte & 4); + PPU.BGMosaic[3] = (Byte & 8); + #ifdef DEBUGGER + if ((Byte & 0xf0) && (Byte & 0x0f)) + missing.mosaic = 1; + #endif + } + + break; + + case 0x2107: // BG1SC + if (Byte != Memory.FillRAM[0x2107]) + { + FLUSH_REDRAW(); + PPU.BG[0].SCSize = Byte & 3; + PPU.BG[0].SCBase = (Byte & 0x7c) << 8; + } + + break; + + case 0x2108: // BG2SC + if (Byte != Memory.FillRAM[0x2108]) + { + FLUSH_REDRAW(); + PPU.BG[1].SCSize = Byte & 3; + PPU.BG[1].SCBase = (Byte & 0x7c) << 8; + } + + break; + + case 0x2109: // BG3SC + if (Byte != Memory.FillRAM[0x2109]) + { + FLUSH_REDRAW(); + PPU.BG[2].SCSize = Byte & 3; + PPU.BG[2].SCBase = (Byte & 0x7c) << 8; + } + + break; + + case 0x210a: // BG4SC + if (Byte != Memory.FillRAM[0x210a]) + { + FLUSH_REDRAW(); + PPU.BG[3].SCSize = Byte & 3; + PPU.BG[3].SCBase = (Byte & 0x7c) << 8; + } + + break; + + case 0x210b: // BG12NBA + 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: // BG34NBA + if (Byte != Memory.FillRAM[0x210c]) + { + FLUSH_REDRAW(); + PPU.BG[2].NameBase = (Byte & 7) << 12; + PPU.BG[3].NameBase = ((Byte >> 4) & 7) << 12; + } + + break; + + case 0x210d: // BG1HOFS, M7HOFS + PPU.BG[0].HOffset = (Byte << 8) | (PPU.BGnxOFSbyte & ~7) | ((PPU.BG[0].HOffset >> 8) & 7); + PPU.M7HOFS = (Byte << 8) | PPU.M7byte; + PPU.BGnxOFSbyte = Byte; + PPU.M7byte = Byte; + break; + + case 0x210e: // BG1VOFS, M7VOFS + PPU.BG[0].VOffset = (Byte << 8) | PPU.BGnxOFSbyte; + PPU.M7VOFS = (Byte << 8) | PPU.M7byte; + PPU.BGnxOFSbyte = Byte; + PPU.M7byte = Byte; + break; + + case 0x210f: // BG2HOFS + PPU.BG[1].HOffset = (Byte << 8) | (PPU.BGnxOFSbyte & ~7) | ((PPU.BG[1].HOffset >> 8) & 7); + PPU.BGnxOFSbyte = Byte; + break; + + case 0x2110: // BG2VOFS + PPU.BG[1].VOffset = (Byte << 8) | PPU.BGnxOFSbyte; + PPU.BGnxOFSbyte = Byte; + break; + + case 0x2111: // BG3HOFS + PPU.BG[2].HOffset = (Byte << 8) | (PPU.BGnxOFSbyte & ~7) | ((PPU.BG[2].HOffset >> 8) & 7); + PPU.BGnxOFSbyte = Byte; + break; + + case 0x2112: // BG3VOFS + PPU.BG[2].VOffset = (Byte << 8) | PPU.BGnxOFSbyte; + PPU.BGnxOFSbyte = Byte; + break; + + case 0x2113: // BG4HOFS + PPU.BG[3].HOffset = (Byte << 8) | (PPU.BGnxOFSbyte & ~7) | ((PPU.BG[3].HOffset >> 8) & 7); + PPU.BGnxOFSbyte = Byte; + break; + + case 0x2114: // BG4VOFS + PPU.BG[3].VOffset = (Byte << 8) | PPU.BGnxOFSbyte; + PPU.BGnxOFSbyte = Byte; + break; + + case 0x2115: // VMAIN + 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: PPU.VMA.Increment = 128; break; + case 3: PPU.VMA.Increment = 128; break; + } + + if (Byte & 0x0c) + { + static uint16 Shift[4] = { 0, 5, 6, 7 }; + static uint16 IncCount[4] = { 0, 32, 64, 128 }; + + uint8 i = (Byte & 0x0c) >> 2; + PPU.VMA.FullGraphicCount = IncCount[i]; + PPU.VMA.Mask1 = IncCount[i] * 8 - 1; + PPU.VMA.Shift = Shift[i]; + #ifdef DEBUGGER + missing.vram_full_graphic_inc = (Byte & 0x0c) >> 2; + #endif + } + else + PPU.VMA.FullGraphicCount = 0; + #ifdef DEBUGGER + if (Byte & 3) + missing.vram_inc = Byte & 3; + #endif + break; + + case 0x2116: // VMADDL + PPU.VMA.Address &= 0xff00; + PPU.VMA.Address |= Byte; + + S9xUpdateVRAMReadBuffer(); + + break; + + case 0x2117: // VMADDH + PPU.VMA.Address &= 0x00ff; + PPU.VMA.Address |= Byte << 8; + + S9xUpdateVRAMReadBuffer(); + + break; + + case 0x2118: // VMDATAL + REGISTER_2118(Byte); + break; + + case 0x2119: // VMDATAH + REGISTER_2119(Byte); + break; + + case 0x211a: // M7SEL + 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: // M7A + PPU.MatrixA = PPU.M7byte | (Byte << 8); + PPU.Need16x8Mulitply = TRUE; + PPU.M7byte = Byte; + break; + + case 0x211c: // M7B + PPU.MatrixB = PPU.M7byte | (Byte << 8); + PPU.Need16x8Mulitply = TRUE; + PPU.M7byte = Byte; + break; + + case 0x211d: // M7C + PPU.MatrixC = PPU.M7byte | (Byte << 8); + PPU.M7byte = Byte; + break; + + case 0x211e: // M7D + PPU.MatrixD = PPU.M7byte | (Byte << 8); + PPU.M7byte = Byte; + break; + + case 0x211f: // M7X + PPU.CentreX = PPU.M7byte | (Byte << 8); + PPU.M7byte = Byte; + break; + + case 0x2120: // M7Y + PPU.CentreY = PPU.M7byte | (Byte << 8); + PPU.M7byte = Byte; + break; + + case 0x2121: // CGADD + PPU.CGFLIP = 0; + PPU.CGFLIPRead = 0; + PPU.CGADD = Byte; + break; + + case 0x2122: // CGDATA + REGISTER_2122(Byte); + break; + + case 0x2123: // W12SEL + 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; + #ifdef DEBUGGER + if (Byte & 0x80) + missing.window2[1] = 1; + if (Byte & 0x20) + missing.window1[1] = 1; + if (Byte & 0x08) + missing.window2[0] = 1; + if (Byte & 0x02) + missing.window1[0] = 1; + #endif + } + + break; + + case 0x2124: // W34SEL + 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; + #ifdef DEBUGGER + if (Byte & 0x80) + missing.window2[3] = 1; + if (Byte & 0x20) + missing.window1[3] = 1; + if (Byte & 0x08) + missing.window2[2] = 1; + if (Byte & 0x02) + missing.window1[2] = 1; + #endif + } + + break; + + case 0x2125: // WOBJSEL + 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; + #ifdef DEBUGGER + if (Byte & 0x80) + missing.window2[5] = 1; + if (Byte & 0x20) + missing.window1[5] = 1; + if (Byte & 0x08) + missing.window2[4] = 1; + if (Byte & 0x02) + missing.window1[4] = 1; + #endif + } + + break; + + case 0x2126: // WH0 + if (Byte != Memory.FillRAM[0x2126]) + { + FLUSH_REDRAW(); + PPU.Window1Left = Byte; + PPU.RecomputeClipWindows = TRUE; + } + + break; + + case 0x2127: // WH1 + if (Byte != Memory.FillRAM[0x2127]) + { + FLUSH_REDRAW(); + PPU.Window1Right = Byte; + PPU.RecomputeClipWindows = TRUE; + } + + break; + + case 0x2128: // WH2 + if (Byte != Memory.FillRAM[0x2128]) + { + FLUSH_REDRAW(); + PPU.Window2Left = Byte; + PPU.RecomputeClipWindows = TRUE; + } + + break; + + case 0x2129: // WH3 + if (Byte != Memory.FillRAM[0x2129]) + { + FLUSH_REDRAW(); + PPU.Window2Right = Byte; + PPU.RecomputeClipWindows = TRUE; + } + + break; + + case 0x212a: // WBGLOG + 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: // WOBJLOG + if (Byte != Memory.FillRAM[0x212b]) + { + FLUSH_REDRAW(); + PPU.ClipWindowOverlapLogic[4] = (Byte & 0x03); + PPU.ClipWindowOverlapLogic[5] = (Byte & 0x0c) >> 2; + PPU.RecomputeClipWindows = TRUE; + } + + break; + + case 0x212c: // TM + if (Byte != Memory.FillRAM[0x212c]) + { + FLUSH_REDRAW(); + PPU.RecomputeClipWindows = TRUE; + } + + break; + + case 0x212d: // TS + if (Byte != Memory.FillRAM[0x212d]) + { + FLUSH_REDRAW(); + PPU.RecomputeClipWindows = TRUE; + #ifdef DEBUGGER + if (Byte & 0x1f) + missing.subscreen = 1; + #endif + } + + break; + + case 0x212e: // TMW + if (Byte != Memory.FillRAM[0x212e]) + { + FLUSH_REDRAW(); + PPU.RecomputeClipWindows = TRUE; + } + + break; + + case 0x212f: // TSW + if (Byte != Memory.FillRAM[0x212f]) + { + FLUSH_REDRAW(); + PPU.RecomputeClipWindows = TRUE; + } + + break; + + case 0x2130: // CGWSEL + if (Byte != Memory.FillRAM[0x2130]) + { + FLUSH_REDRAW(); + PPU.RecomputeClipWindows = TRUE; + #ifdef DEBUGGER + if ((Byte & 1) && (PPU.BGMode == 3 || PPU.BGMode == 4 || PPU.BGMode == 7)) + missing.direct = 1; + #endif + } + + break; + + case 0x2131: // CGADSUB + if (Byte != Memory.FillRAM[0x2131]) + { + FLUSH_REDRAW(); + #ifdef DEBUGGER + if (Byte & 0x80) + { + if (Memory.FillRAM[0x2130] & 0x02) + missing.subscreen_sub = 1; + else + missing.fixed_colour_sub = 1; + } + else + { + if (Memory.FillRAM[0x2130] & 0x02) + missing.subscreen_add = 1; + else + missing.fixed_colour_add = 1; + } + #endif + } + + break; + + case 0x2132: // COLDATA + if (Byte != Memory.FillRAM[0x2132]) + { + FLUSH_REDRAW(); + if (Byte & 0x80) + PPU.FixedColourBlue = Byte & 0x1f; + if (Byte & 0x40) + PPU.FixedColourGreen = Byte & 0x1f; + if (Byte & 0x20) + PPU.FixedColourRed = Byte & 0x1f; + } + + break; + + case 0x2133: // SETINI + if (Byte != Memory.FillRAM[0x2133]) + { + if ((Memory.FillRAM[0x2133] ^ Byte) & 8) + { + FLUSH_REDRAW(); + IPPU.PseudoHires = Byte & 8; + } + + if (Byte & 0x04) + { + PPU.ScreenHeight = SNES_HEIGHT_EXTENDED; + if (IPPU.DoubleHeightPixels) + IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1; + else + IPPU.RenderedScreenHeight = PPU.ScreenHeight; + #ifdef DEBUGGER + missing.lines_239 = 1; + #endif + } + else + { + PPU.ScreenHeight = SNES_HEIGHT; + if (IPPU.DoubleHeightPixels) + IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1; + else + IPPU.RenderedScreenHeight = PPU.ScreenHeight; + } + + if ((Memory.FillRAM[0x2133] ^ Byte) & 3) + { + FLUSH_REDRAW(); + if ((Memory.FillRAM[0x2133] ^ Byte) & 2) + IPPU.OBJChanged = TRUE; + + IPPU.Interlace = Byte & 1; + IPPU.InterlaceOBJ = Byte & 2; + } + #ifdef DEBUGGER + if (Byte & 0x40) + missing.mode7_bgmode = 1; + if (Byte & 0x08) + missing.pseudo_512 = 1; + if (Byte & 0x02) + missing.sprite_double_height = 1; + if (Byte & 0x01) + missing.interlace = 1; + #endif + } + + break; + + case 0x2134: // MPYL + case 0x2135: // MPYM + case 0x2136: // MPYH + case 0x2137: // SLHV + case 0x2138: // OAMDATAREAD + case 0x2139: // VMDATALREAD + case 0x213a: // VMDATAHREAD + case 0x213b: // CGDATAREAD + case 0x213c: // OPHCT + case 0x213d: // OPVCT + case 0x213e: // STAT77 + case 0x213f: // STAT78 + return; + + case 0x2180: // WMDATA + if (!CPU.InWRAMDMAorHDMA) + REGISTER_2180(Byte); + break; + + case 0x2181: // WMADDL + if (!CPU.InWRAMDMAorHDMA) + { + PPU.WRAM &= 0x1ff00; + PPU.WRAM |= Byte; + } + + break; + + case 0x2182: // WMADDM + if (!CPU.InWRAMDMAorHDMA) + { + PPU.WRAM &= 0x100ff; + PPU.WRAM |= Byte << 8; + } + + break; + + case 0x2183: // WMADDH + if (!CPU.InWRAMDMAorHDMA) + { + PPU.WRAM &= 0x0ffff; + PPU.WRAM |= Byte << 16; + PPU.WRAM &= 0x1ffff; + } + + break; + } + } + else + { + if (Settings.SuperFX && Address >= 0x3000 && Address <= 0x32ff) + { + S9xSetSuperFX(Byte, Address); + return; + } + else + if (Settings.SA1 && Address >= 0x2200) + { + if (Address <= 0x23ff) + S9xSetSA1(Byte, Address); + else + Memory.FillRAM[Address] = Byte; + return; + } + else + if (Settings.BS && Address >= 0x2188 && Address <= 0x219f) + S9xSetBSXPPU(Byte, Address); + else + if (Settings.SRTC && Address == 0x2801) + S9xSetSRTC(Byte, Address); + #ifdef DEBUGGER + else + { + missing.unknownppu_write = Address; + if (Settings.TraceUnknownRegisters) + { + sprintf(String, "Unknown register write: $%02X->$%04X\n", Byte, Address); + S9xMessage(S9X_TRACE, S9X_PPU_TRACE, String); + } + } + #endif + } + + Memory.FillRAM[Address] = Byte; +} + +uint8 S9xGetPPU (uint16 Address) +{ + // MAP_PPU: $2000-$3FFF + if (Settings.MSU1 && (Address & 0xfff8) == 0x2000) + return (S9xMSU1ReadPort(Address & 7)); + else + if (Address < 0x2100) + return (OpenBus); + + if (CPU.InDMAorHDMA) + { + if (CPU.CurrentDMAorHDMAChannel >= 0 && !DMA[CPU.CurrentDMAorHDMAChannel].ReverseTransfer) + { + // S9xGetPPU() is called to read from DMA[].AAddress + if ((Address & 0xff00) == 0x2100) + // Cannot access to Address Bus B ($2100-$21FF) via (H)DMA + return (OpenBus); + else + // $2200-$3FFF are connected to Address Bus A + // SA1, SuperFX and SRTC are mapped here + // I don't bother for now... + return (OpenBus); + } + else + { + // S9xGetPPU() is called to write to $21xx + // Take care of DMA wrapping + if (Address > 0x21ff) + Address = 0x2100 + (Address & 0xff); + } + } + + if ((Address & 0xffc0) == 0x2140) // APUIO0, APUIO1, APUIO2, APUIO3 + // read_port will run the APU until given APU time before reading value + return (S9xAPUReadPort(Address & 3)); + else + if (Address <= 0x2183) + { + uint8 byte; + + switch (Address) + { + case 0x2104: // OAMDATA + case 0x2105: // BGMODE + case 0x2106: // MOSAIC + case 0x2108: // BG2SC + case 0x2109: // BG3SC + case 0x210a: // BG4SC + case 0x2114: // BG4VOFS + case 0x2115: // VMAIN + case 0x2116: // VMADDL + case 0x2118: // VMDATAL + case 0x2119: // VMDATAH + case 0x211a: // M7SEL + case 0x2124: // W34SEL + case 0x2125: // WOBJSEL + case 0x2126: // WH0 + case 0x2128: // WH2 + case 0x2129: // WH3 + case 0x212a: // WBGLOG + return (PPU.OpenBus1); + + case 0x2134: // MPYL + case 0x2135: // MPYM + case 0x2136: // MPYH + 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; + } + #ifdef DEBUGGER + missing.matrix_multiply = 1; + #endif + return (PPU.OpenBus1 = Memory.FillRAM[Address]); + + case 0x2137: // SLHV + S9xLatchCounters(0); + return (PPU.OpenBus1); + + case 0x2138: // OAMDATAREAD + 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; + #ifdef DEBUGGER + missing.sprite_priority_rotation = 1; + #endif + } + } + } + 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; + #ifdef DEBUGGER + missing.sprite_priority_rotation = 1; + #endif + } + } + } + + PPU.OAMFlip ^= 1; + #ifdef DEBUGGER + missing.oam_read = 1; + #endif + return (PPU.OpenBus1 = byte); + + case 0x2139: // VMDATALREAD + byte = PPU.VRAMReadBuffer & 0xff; + if (!PPU.VMA.High) + { + S9xUpdateVRAMReadBuffer(); + + PPU.VMA.Address += PPU.VMA.Increment; + } + + #ifdef DEBUGGER + missing.vram_read = 1; + #endif + return (PPU.OpenBus1 = byte); + + case 0x213a: // VMDATAHREAD + byte = (PPU.VRAMReadBuffer >> 8) & 0xff; + if (PPU.VMA.High) + { + S9xUpdateVRAMReadBuffer(); + + PPU.VMA.Address += PPU.VMA.Increment; + } + #ifdef DEBUGGER + missing.vram_read = 1; + #endif + return (PPU.OpenBus1 = byte); + + case 0x213b: // CGDATAREAD + if (PPU.CGFLIPRead) + byte = (PPU.OpenBus2 & 0x80) | ((PPU.CGDATA[PPU.CGADD++] >> 8) & 0x7f); + else + byte = PPU.CGDATA[PPU.CGADD] & 0xff; + PPU.CGFLIPRead ^= 1; + #ifdef DEBUGGER + missing.cgram_read = 1; + #endif + return (PPU.OpenBus2 = byte); + + case 0x213c: // OPHCT + S9xTryGunLatch(false); + if (PPU.HBeamFlip) + byte = (PPU.OpenBus2 & 0xfe) | ((PPU.HBeamPosLatched >> 8) & 0x01); + else + byte = (uint8) PPU.HBeamPosLatched; + PPU.HBeamFlip ^= 1; + #ifdef DEBUGGER + missing.h_counter_read = 1; + #endif + return (PPU.OpenBus2 = byte); + + case 0x213d: // OPVCT + S9xTryGunLatch(false); + if (PPU.VBeamFlip) + byte = (PPU.OpenBus2 & 0xfe) | ((PPU.VBeamPosLatched >> 8) & 0x01); + else + byte = (uint8) PPU.VBeamPosLatched; + PPU.VBeamFlip ^= 1; + #ifdef DEBUGGER + missing.v_counter_read = 1; + #endif + return (PPU.OpenBus2 = byte); + + case 0x213e: // STAT77 + FLUSH_REDRAW(); + byte = (PPU.OpenBus1 & 0x10) | PPU.RangeTimeOver | Model->_5C77; + return (PPU.OpenBus1 = byte); + + case 0x213f: // STAT78 + S9xTryGunLatch(false); + PPU.VBeamFlip = PPU.HBeamFlip = 0; + byte = (PPU.OpenBus2 & 0x20) | (Memory.FillRAM[0x213f] & 0xc0) | (Settings.PAL ? 0x10 : 0) | Model->_5C78; + Memory.FillRAM[0x213f] &= ~0x40; + return (PPU.OpenBus2 = byte); + + case 0x2180: // WMDATA + if (!CPU.InWRAMDMAorHDMA) + { + byte = Memory.RAM[PPU.WRAM++]; + PPU.WRAM &= 0x1ffff; + } + else + byte = OpenBus; + #ifdef DEBUGGER + missing.wram_read = 1; + #endif + return (byte); + + default: + return (OpenBus); + } + } + else + { + if (Settings.SuperFX && Address >= 0x3000 && Address <= 0x32ff) + return (S9xGetSuperFX(Address)); + else + if (Settings.SA1 && Address >= 0x2200) + return (S9xGetSA1(Address)); + else + if (Settings.BS && Address >= 0x2188 && Address <= 0x219f) + return (S9xGetBSXPPU(Address)); + else + if (Settings.SRTC && Address == 0x2800) + return (S9xGetSRTC(Address)); + else + switch (Address) + { + case 0x21c2: + if (Model->_5C77 == 2) + return (0x20); + return (OpenBus); + + case 0x21c3: + if (Model->_5C77 == 2) + return (0); + return (OpenBus); + + default: + return (OpenBus); + } + } +} + +void S9xSetCPU (uint8 Byte, uint16 Address) +{ + if (Address < 0x4200) + { + switch (Address) + { + case 0x4016: // JOYSER0 + S9xSetJoypadLatch(Byte & 1); + break; + + case 0x4017: // JOYSER1 + return; + + default: + break; + } + } + else + if ((Address & 0xff80) == 0x4300) + { + if (CPU.InDMAorHDMA) + return; + + int d = (Address >> 4) & 0x7; + + switch (Address & 0xf) + { + case 0x0: // 0x43x0: DMAPx + DMA[d].ReverseTransfer = (Byte & 0x80) ? TRUE : FALSE; + DMA[d].HDMAIndirectAddressing = (Byte & 0x40) ? TRUE : FALSE; + DMA[d].UnusedBit43x0 = (Byte & 0x20) ? TRUE : FALSE; + DMA[d].AAddressDecrement = (Byte & 0x10) ? TRUE : FALSE; + DMA[d].AAddressFixed = (Byte & 0x08) ? TRUE : FALSE; + DMA[d].TransferMode = (Byte & 7); + return; + + case 0x1: // 0x43x1: BBADx + DMA[d].BAddress = Byte; + return; + + case 0x2: // 0x43x2: A1TxL + DMA[d].AAddress &= 0xff00; + DMA[d].AAddress |= Byte; + return; + + case 0x3: // 0x43x3: A1TxH + DMA[d].AAddress &= 0xff; + DMA[d].AAddress |= Byte << 8; + return; + + case 0x4: // 0x43x4: A1Bx + DMA[d].ABank = Byte; + HDMAMemPointers[d] = NULL; + return; + + case 0x5: // 0x43x5: DASxL + DMA[d].DMACount_Or_HDMAIndirectAddress &= 0xff00; + DMA[d].DMACount_Or_HDMAIndirectAddress |= Byte; + HDMAMemPointers[d] = NULL; + return; + + case 0x6: // 0x43x6: DASxH + DMA[d].DMACount_Or_HDMAIndirectAddress &= 0xff; + DMA[d].DMACount_Or_HDMAIndirectAddress |= Byte << 8; + HDMAMemPointers[d] = NULL; + return; + + case 0x7: // 0x43x7: DASBx + DMA[d].IndirectBank = Byte; + HDMAMemPointers[d] = NULL; + return; + + case 0x8: // 0x43x8: A2AxL + DMA[d].Address &= 0xff00; + DMA[d].Address |= Byte; + HDMAMemPointers[d] = NULL; + return; + + case 0x9: // 0x43x9: A2AxH + DMA[d].Address &= 0xff; + DMA[d].Address |= Byte << 8; + HDMAMemPointers[d] = NULL; + return; + + case 0xa: // 0x43xa: NLTRx + if (Byte & 0x7f) + { + DMA[d].LineCount = Byte & 0x7f; + DMA[d].Repeat = !(Byte & 0x80); + } + else + { + DMA[d].LineCount = 128; + DMA[d].Repeat = !!(Byte & 0x80); + } + + return; + + case 0xb: // 0x43xb: ????x + case 0xf: // 0x43xf: mirror of 0x43xb + DMA[d].UnknownByte = Byte; + return; + + default: + break; + } + } + else + { + uint16 pos; + + switch (Address) + { + case 0x4200: // NMITIMEN + #ifdef DEBUGGER + if (Settings.TraceHCEvent) + S9xTraceFormattedMessage("Write to 0x4200. Byte is %2x was %2x\n", Byte, Memory.FillRAM[Address]); + #endif + + if (Byte == Memory.FillRAM[0x4200]) + break; + + if (Byte & 0x20) + { + PPU.VTimerEnabled = TRUE; + + #ifdef DEBUGGER + missing.virq = 1; + missing.virq_pos = PPU.IRQVBeamPos; + #endif + } + else + PPU.VTimerEnabled = FALSE; + + if (Byte & 0x10) + { + PPU.HTimerEnabled = TRUE; + + #ifdef DEBUGGER + missing.hirq = 1; + missing.hirq_pos = PPU.IRQHBeamPos; + #endif + } + else + PPU.HTimerEnabled = FALSE; + + if (!(Byte & 0x10) && !(Byte & 0x20)) + { + CPU.IRQLine = FALSE; + CPU.IRQTransition = FALSE; + } + + if ((Byte & 0x30) != (Memory.FillRAM[0x4200] & 0x30)) + S9xUpdateIRQPositions(true); + + // NMI can trigger immediately during VBlank as long as NMI_read ($4210) wasn't cleard. + if ((Byte & 0x80) && !(Memory.FillRAM[0x4200] & 0x80) && + (CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE) && (Memory.FillRAM[0x4210] & 0x80)) + { + // FIXME: triggered at HC+=6, checked just before the final CPU cycle, + // then, when to call S9xOpcode_NMI()? + CPU.NMIPending = TRUE; + Timings.NMITriggerPos = CPU.Cycles + 6 + 6; + + #ifdef DEBUGGER + if (Settings.TraceHCEvent) + S9xTraceFormattedMessage("NMI Triggered on low-to-high occurring at next HC=%d\n", Timings.NMITriggerPos); + #endif + } + + #ifdef DEBUGGER + S9xTraceFormattedMessage("--- IRQ Timer Enable HTimer:%d Pos:%04d VTimer:%d Pos:%03d", + PPU.HTimerEnabled, PPU.HTimerPosition, PPU.VTimerEnabled, PPU.VTimerPosition); + #endif + + break; + + case 0x4201: // WRIO + if ((Byte & 0x80) == 0 && (Memory.FillRAM[0x4213] & 0x80) == 0x80) + S9xLatchCounters(1); + else + S9xTryGunLatch((Byte & 0x80) ? true : false); + Memory.FillRAM[0x4201] = Memory.FillRAM[0x4213] = Byte; + break; + + case 0x4202: // WRMPYA + break; + + case 0x4203: // WRMPYB + { + uint32 res = Memory.FillRAM[0x4202] * Byte; + // FIXME: The update occurs 8 machine cycles after $4203 is set. + Memory.FillRAM[0x4216] = (uint8) res; + Memory.FillRAM[0x4217] = (uint8) (res >> 8); + break; + } + + case 0x4204: // WRDIVL + case 0x4205: // WRDIVH + break; + + case 0x4206: // WRDIVB + { + uint16 a = Memory.FillRAM[0x4204] + (Memory.FillRAM[0x4205] << 8); + uint16 div = Byte ? a / Byte : 0xffff; + uint16 rem = Byte ? a % Byte : a; + // FIXME: The update occurs 16 machine cycles after $4206 is set. + Memory.FillRAM[0x4214] = (uint8) div; + Memory.FillRAM[0x4215] = div >> 8; + Memory.FillRAM[0x4216] = (uint8) rem; + Memory.FillRAM[0x4217] = rem >> 8; + break; + } + + case 0x4207: // HTIMEL + pos = PPU.IRQHBeamPos; + PPU.IRQHBeamPos = (PPU.IRQHBeamPos & 0xff00) | Byte; + if (PPU.IRQHBeamPos != pos) + S9xUpdateIRQPositions(false); + #ifdef DEBUGGER + missing.hirq_pos = PPU.IRQHBeamPos; + #endif + break; + + case 0x4208: // HTIMEH + pos = PPU.IRQHBeamPos; + PPU.IRQHBeamPos = (PPU.IRQHBeamPos & 0xff) | ((Byte & 1) << 8); + if (PPU.IRQHBeamPos != pos) + S9xUpdateIRQPositions(false); + #ifdef DEBUGGER + missing.hirq_pos = PPU.IRQHBeamPos; + #endif + break; + + case 0x4209: // VTIMEL + pos = PPU.IRQVBeamPos; + PPU.IRQVBeamPos = (PPU.IRQVBeamPos & 0xff00) | Byte; + if (PPU.IRQVBeamPos != pos) + S9xUpdateIRQPositions(true); + #ifdef DEBUGGER + missing.virq_pos = PPU.IRQVBeamPos; + #endif + break; + + case 0x420a: // VTIMEH + pos = PPU.IRQVBeamPos; + PPU.IRQVBeamPos = (PPU.IRQVBeamPos & 0xff) | ((Byte & 1) << 8); + if (PPU.IRQVBeamPos != pos) + S9xUpdateIRQPositions(true); + #ifdef DEBUGGER + missing.virq_pos = PPU.IRQVBeamPos; + #endif + break; + + case 0x420b: // MDMAEN + if (CPU.InDMAorHDMA) + return; + // XXX: Not quite right... + if (Byte) { + CPU.Cycles += Timings.DMACPUSync; + } + if (Byte & 0x01) + S9xDoDMA(0); + if (Byte & 0x02) + S9xDoDMA(1); + if (Byte & 0x04) + S9xDoDMA(2); + if (Byte & 0x08) + S9xDoDMA(3); + if (Byte & 0x10) + S9xDoDMA(4); + if (Byte & 0x20) + S9xDoDMA(5); + if (Byte & 0x40) + S9xDoDMA(6); + if (Byte & 0x80) + S9xDoDMA(7); + #ifdef DEBUGGER + missing.dma_this_frame = Byte; + missing.dma_channels = Byte; + #endif + break; + + case 0x420c: // HDMAEN + if (CPU.InDMAorHDMA) + return; + Memory.FillRAM[0x420c] = Byte; + // Yoshi's Island, Genjyu Ryodan, Mortal Kombat, Tales of Phantasia + PPU.HDMA = Byte & ~PPU.HDMAEnded; + #ifdef DEBUGGER + missing.hdma_this_frame |= Byte; + missing.hdma_channels |= Byte; + #endif + break; + + case 0x420d: // MEMSEL + if ((Byte & 1) != (Memory.FillRAM[0x420d] & 1)) + { + if (Byte & 1) + { + CPU.FastROMSpeed = ONE_CYCLE; + #ifdef DEBUGGER + missing.fast_rom = 1; + #endif + } + else + CPU.FastROMSpeed = SLOW_ONE_CYCLE; + // we might currently be in FastROMSpeed region, S9xSetPCBase will update CPU.MemSpeed + S9xSetPCBase(Registers.PBPC); + } + + break; + + case 0x4210: // RDNMI + case 0x4211: // TIMEUP + case 0x4212: // HVBJOY + case 0x4213: // RDIO + case 0x4214: // RDDIVL + case 0x4215: // RDDIVH + case 0x4216: // RDMPYL + case 0x4217: // RDMPYH + case 0x4218: // JOY1L + case 0x4219: // JOY1H + case 0x421a: // JOY2L + case 0x421b: // JOY2H + case 0x421c: // JOY3L + case 0x421d: // JOY3H + case 0x421e: // JOY4L + case 0x421f: // JOY4H + return; + + default: + if (Settings.SPC7110 && Address >= 0x4800) + S9xSetSPC7110(Byte, Address); + else + if (Settings.SDD1 && Address >= 0x4804 && Address <= 0x4807) + S9xSetSDD1MemoryMap(Address - 0x4804, Byte & 7); + break; + } + } + + Memory.FillRAM[Address] = Byte; +} + +uint8 S9xGetCPU (uint16 Address) +{ + if (Address < 0x4200) + { + #ifdef SNES_JOY_READ_CALLBACKS + extern bool8 pad_read; + if (Address == 0x4016 || Address == 0x4017) + { + S9xOnSNESPadRead(); + pad_read = TRUE; + } + #endif + + switch (Address) + { + case 0x4016: // JOYSER0 + case 0x4017: // JOYSER1 + return (S9xReadJOYSERn(Address)); + + default: + return (OpenBus); + } + } + else + if ((Address & 0xff80) == 0x4300) + { + if (CPU.InDMAorHDMA) + return (OpenBus); + + int d = (Address >> 4) & 0x7; + + switch (Address & 0xf) + { + case 0x0: // 0x43x0: DMAPx + return ((DMA[d].ReverseTransfer ? 0x80 : 0) | + (DMA[d].HDMAIndirectAddressing ? 0x40 : 0) | + (DMA[d].UnusedBit43x0 ? 0x20 : 0) | + (DMA[d].AAddressDecrement ? 0x10 : 0) | + (DMA[d].AAddressFixed ? 0x08 : 0) | + (DMA[d].TransferMode & 7)); + + case 0x1: // 0x43x1: BBADx + return (DMA[d].BAddress); + + case 0x2: // 0x43x2: A1TxL + return (DMA[d].AAddress & 0xff); + + case 0x3: // 0x43x3: A1TxH + return (DMA[d].AAddress >> 8); + + case 0x4: // 0x43x4: A1Bx + return (DMA[d].ABank); + + case 0x5: // 0x43x5: DASxL + return (DMA[d].DMACount_Or_HDMAIndirectAddress & 0xff); + + case 0x6: // 0x43x6: DASxH + return (DMA[d].DMACount_Or_HDMAIndirectAddress >> 8); + + case 0x7: // 0x43x7: DASBx + return (DMA[d].IndirectBank); + + case 0x8: // 0x43x8: A2AxL + return (DMA[d].Address & 0xff); + + case 0x9: // 0x43x9: A2AxH + return (DMA[d].Address >> 8); + + case 0xa: // 0x43xa: NLTRx + return (DMA[d].LineCount ^ (DMA[d].Repeat ? 0x00 : 0x80)); + + case 0xb: // 0x43xb: ????x + case 0xf: // 0x43xf: mirror of 0x43xb + return (DMA[d].UnknownByte); + + default: + return (OpenBus); + } + } + else + { + uint8 byte; + + switch (Address) + { + case 0x4210: // RDNMI + byte = Memory.FillRAM[0x4210]; + Memory.FillRAM[0x4210] = Model->_5A22; + return ((byte & 0x80) | (OpenBus & 0x70) | Model->_5A22); + + case 0x4211: // TIMEUP + byte = 0; + if (CPU.IRQLine) + { + byte = 0x80; + CPU.IRQLine = FALSE; + CPU.IRQTransition = FALSE; + } + + return (byte | (OpenBus & 0x7f)); + + case 0x4212: // HVBJOY + return (REGISTER_4212() | (OpenBus & 0x3e)); + + case 0x4213: // RDIO + return (Memory.FillRAM[0x4213]); + + case 0x4214: // RDDIVL + case 0x4215: // RDDIVH + case 0x4216: // RDMPYL + case 0x4217: // RDMPYH + return (Memory.FillRAM[Address]); + + case 0x4218: // JOY1L + case 0x4219: // JOY1H + case 0x421a: // JOY2L + case 0x421b: // JOY2H + case 0x421c: // JOY3L + case 0x421d: // JOY3H + case 0x421e: // JOY4L + case 0x421f: // JOY4H + #ifdef SNES_JOY_READ_CALLBACKS + extern bool8 pad_read; + if (Memory.FillRAM[0x4200] & 1) + { + S9xOnSNESPadRead(); + pad_read = TRUE; + } + #endif + return (Memory.FillRAM[Address]); + + default: + if (Settings.SPC7110 && Address >= 0x4800) + return (S9xGetSPC7110(Address)); + if (Settings.SDD1 && Address >= 0x4800 && Address <= 0x4807) + return (Memory.FillRAM[Address]); + return (OpenBus); + } + } +} + +void S9xResetPPU (void) +{ + S9xSoftResetPPU(); + S9xControlsReset(); + PPU.M7HOFS = 0; + PPU.M7VOFS = 0; + PPU.M7byte = 0; +} + +void S9xResetPPUFast (void) +{ + PPU.RecomputeClipWindows = TRUE; + IPPU.ColorsChanged = TRUE; + IPPU.OBJChanged = TRUE; + memset(IPPU.TileCached[TILE_2BIT], 0, MAX_2BIT_TILES); + memset(IPPU.TileCached[TILE_4BIT], 0, MAX_4BIT_TILES); + memset(IPPU.TileCached[TILE_8BIT], 0, MAX_8BIT_TILES); + memset(IPPU.TileCached[TILE_2BIT_EVEN], 0, MAX_2BIT_TILES); + memset(IPPU.TileCached[TILE_2BIT_ODD], 0, MAX_2BIT_TILES); + memset(IPPU.TileCached[TILE_4BIT_EVEN], 0, MAX_4BIT_TILES); + memset(IPPU.TileCached[TILE_4BIT_ODD], 0, MAX_4BIT_TILES); +} + +void S9xSoftResetPPU (void) +{ + S9xControlsSoftReset(); + + PPU.VMA.High = 0; + PPU.VMA.Increment = 1; + PPU.VMA.Address = 0; + PPU.VMA.FullGraphicCount = 0; + PPU.VMA.Shift = 0; + + PPU.WRAM = 0; + + for (int c = 0; c < 4; c++) + { + PPU.BG[c].SCBase = 0; + PPU.BG[c].HOffset = 0; + PPU.BG[c].VOffset = 0; + PPU.BG[c].BGSize = 0; + PPU.BG[c].NameBase = 0; + PPU.BG[c].SCSize = 0; + } + + PPU.BGMode = 0; + PPU.BG3Priority = 0; + + PPU.CGFLIP = 0; + PPU.CGFLIPRead = 0; + PPU.CGADD = 0; + + for (int 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); + } + + for (int c = 0; c < 128; c++) + { + PPU.OBJ[c].HPos = 0; + PPU.OBJ[c].VPos = 0; + PPU.OBJ[c].HFlip = 0; + PPU.OBJ[c].VFlip = 0; + PPU.OBJ[c].Name = 0; + PPU.OBJ[c].Priority = 0; + PPU.OBJ[c].Palette = 0; + PPU.OBJ[c].Size = 0; + } + + PPU.OBJThroughMain = FALSE; + PPU.OBJThroughSub = FALSE; + PPU.OBJAddition = FALSE; + PPU.OBJNameBase = 0; + PPU.OBJNameSelect = 0; + PPU.OBJSizeSelect = 0; + + PPU.OAMAddr = 0; + PPU.SavedOAMAddr = 0; + PPU.OAMPriorityRotation = 0; + PPU.OAMFlip = 0; + PPU.OAMReadFlip = 0; + PPU.OAMTileAddress = 0; + PPU.OAMWriteRegister = 0; + memset(PPU.OAMData, 0, 512 + 32); + + PPU.FirstSprite = 0; + PPU.LastSprite = 127; + PPU.RangeTimeOver = 0; + + PPU.HTimerEnabled = FALSE; + PPU.VTimerEnabled = FALSE; + PPU.HTimerPosition = Timings.H_Max + 1; + PPU.VTimerPosition = Timings.V_Max + 1; + PPU.IRQHBeamPos = 0x1ff; + PPU.IRQVBeamPos = 0x1ff; + + PPU.HBeamFlip = 0; + PPU.VBeamFlip = 0; + PPU.HBeamPosLatched = 0; + PPU.VBeamPosLatched = 0; + PPU.GunHLatch = 0; + PPU.GunVLatch = 1000; + PPU.HVBeamCounterLatched = 0; + + PPU.Mode7HFlip = FALSE; + PPU.Mode7VFlip = FALSE; + PPU.Mode7Repeat = 0; + PPU.MatrixA = 0; + PPU.MatrixB = 0; + PPU.MatrixC = 0; + PPU.MatrixD = 0; + PPU.CentreX = 0; + PPU.CentreY = 0; + + PPU.Mosaic = 0; + PPU.BGMosaic[0] = FALSE; + PPU.BGMosaic[1] = FALSE; + PPU.BGMosaic[2] = FALSE; + PPU.BGMosaic[3] = FALSE; + + PPU.Window1Left = 1; + PPU.Window1Right = 0; + PPU.Window2Left = 1; + PPU.Window2Right = 0; + PPU.RecomputeClipWindows = TRUE; + + for (int c = 0; c < 6; c++) + { + PPU.ClipCounts[c] = 0; + PPU.ClipWindowOverlapLogic[c] = CLIP_OR; + PPU.ClipWindow1Enable[c] = FALSE; + PPU.ClipWindow2Enable[c] = FALSE; + PPU.ClipWindow1Inside[c] = TRUE; + PPU.ClipWindow2Inside[c] = TRUE; + } + + PPU.ForcedBlanking = TRUE; + + PPU.FixedColourRed = 0; + PPU.FixedColourGreen = 0; + PPU.FixedColourBlue = 0; + PPU.Brightness = 0; + PPU.ScreenHeight = SNES_HEIGHT; + + PPU.Need16x8Mulitply = FALSE; + PPU.BGnxOFSbyte = 0; + + PPU.HDMA = 0; + PPU.HDMAEnded = 0; + + PPU.OpenBus1 = 0; + PPU.OpenBus2 = 0; + + for (int c = 0; c < 2; c++) + memset(&IPPU.Clip[c], 0, sizeof(struct ClipData)); + IPPU.ColorsChanged = TRUE; + IPPU.OBJChanged = TRUE; + memset(IPPU.TileCached[TILE_2BIT], 0, MAX_2BIT_TILES); + memset(IPPU.TileCached[TILE_4BIT], 0, MAX_4BIT_TILES); + memset(IPPU.TileCached[TILE_8BIT], 0, MAX_8BIT_TILES); + memset(IPPU.TileCached[TILE_2BIT_EVEN], 0, MAX_2BIT_TILES); + memset(IPPU.TileCached[TILE_2BIT_ODD], 0, MAX_2BIT_TILES); + memset(IPPU.TileCached[TILE_4BIT_EVEN], 0, MAX_4BIT_TILES); + memset(IPPU.TileCached[TILE_4BIT_ODD], 0, MAX_4BIT_TILES); + PPU.VRAMReadBuffer = 0; // XXX: FIXME: anything better? + GFX.InterlaceFrame = 0; + IPPU.Interlace = FALSE; + IPPU.InterlaceOBJ = FALSE; + IPPU.DoubleWidthPixels = FALSE; + IPPU.DoubleHeightPixels = FALSE; + IPPU.CurrentLine = 0; + IPPU.PreviousLine = 0; + IPPU.XB = NULL; + for (int c = 0; c < 256; c++) + IPPU.ScreenColors[c] = c; + IPPU.MaxBrightness = 0; + IPPU.RenderThisFrame = TRUE; + IPPU.RenderedScreenWidth = SNES_WIDTH; + IPPU.RenderedScreenHeight = SNES_HEIGHT; + IPPU.FrameCount = 0; + IPPU.RenderedFramesCount = 0; + IPPU.DisplayedRenderedFrameCount = 0; + IPPU.SkippedFrames = 0; + IPPU.FrameSkip = 0; + + S9xFixColourBrightness(); + S9xBuildDirectColourMaps(); + + for (int c = 0; c < 0x8000; c += 0x100) + memset(&Memory.FillRAM[c], c >> 8, 0x100); + memset(&Memory.FillRAM[0x2100], 0, 0x100); + memset(&Memory.FillRAM[0x4200], 0, 0x100); + memset(&Memory.FillRAM[0x4000], 0, 0x100); + // For BS Suttehakkun 2... + memset(&Memory.FillRAM[0x1000], 0, 0x1000); + + Memory.FillRAM[0x4201] = Memory.FillRAM[0x4213] = 0xff; + Memory.FillRAM[0x2126] = Memory.FillRAM[0x2128] = 1; +} diff --git a/source/snes9x/ppu.h b/source/snes9x/ppu.h index 6a6f7da..b4fcf1b 100644 --- a/source/snes9x/ppu.h +++ b/source/snes9x/ppu.h @@ -225,10 +225,8 @@ struct InternalPPU struct ClipData Clip[2][6]; bool8 ColorsChanged; bool8 OBJChanged; - bool8 DirectColourMapsNeedRebuild; uint8 *TileCache[7]; uint8 *TileCached[7]; - uint16 VRAMReadBuffer; bool8 Interlace; bool8 InterlaceOBJ; bool8 PseudoHires; @@ -295,6 +293,7 @@ struct SPPU bool8 CGFLIP; uint8 CGFLIPRead; uint8 CGADD; + uint8 CGSavedByte; uint16 CGDATA[256]; struct SOBJ OBJ[128]; @@ -378,6 +377,8 @@ struct SPPU uint8 OpenBus1; uint8 OpenBus2; + + uint16 VRAMReadBuffer; }; extern uint16 SignExtend[2]; @@ -419,6 +420,19 @@ static inline void FLUSH_REDRAW (void) S9xUpdateScreen(); } +static inline void S9xUpdateVRAMReadBuffer() +{ + 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); + PPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((address << 1) & 0xffff)); + } + else + PPU.VRAMReadBuffer = READ_WORD(Memory.VRAM + ((PPU.VMA.Address << 1) & 0xffff)); +} + static inline void REGISTER_2104 (uint8 Byte) { if (!(PPU.OAMFlip & 1)) @@ -720,12 +734,12 @@ static inline void REGISTER_2122 (uint8 Byte) { if (PPU.CGFLIP) { - if ((Byte & 0x7f) != (PPU.CGDATA[PPU.CGADD] >> 8)) + if ((Byte & 0x7f) != (PPU.CGDATA[PPU.CGADD] >> 8) || PPU.CGSavedByte != (uint8) (PPU.CGDATA[PPU.CGADD] & 0xff)) { FLUSH_REDRAW(); - PPU.CGDATA[PPU.CGADD] &= 0x00ff; - PPU.CGDATA[PPU.CGADD] |= (Byte & 0x7f) << 8; + PPU.CGDATA[PPU.CGADD] = (Byte & 0x7f) << 8 | PPU.CGSavedByte; IPPU.ColorsChanged = TRUE; + IPPU.Red[PPU.CGADD] = IPPU.XB[PPU.CGSavedByte & 0x1f]; 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]); @@ -735,16 +749,7 @@ static inline void REGISTER_2122 (uint8 Byte) } 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.CGSavedByte = Byte; } PPU.CGFLIP ^= 1; diff --git a/source/snes9x/sa1.cpp b/source/snes9x/sa1.cpp index 961169c..8819e76 100644 --- a/source/snes9x/sa1.cpp +++ b/source/snes9x/sa1.cpp @@ -229,7 +229,7 @@ void S9xSA1Init (void) SA1.op2 = 0; SA1.sum = 0; SA1.overflow = FALSE; - SA1.VirtualBitmapFormat = 0; + SA1.VirtualBitmapFormat = 4; SA1.variable_bit_pos = 0; SA1Registers.PBPC = 0; @@ -303,6 +303,10 @@ void S9xSA1PostLoadState (void) SA1.VirtualBitmapFormat = (Memory.FillRAM[0x223f] & 0x80) ? 2 : 4; Memory.BWRAM = Memory.SRAM + (Memory.FillRAM[0x2224] & 7) * 0x2000; S9xSA1SetBWRAMMemMap(Memory.FillRAM[0x2225]); + S9xSetSA1(Memory.FillRAM[0x2220], 0x2220); + S9xSetSA1(Memory.FillRAM[0x2221], 0x2221); + S9xSetSA1(Memory.FillRAM[0x2222], 0x2222); + S9xSetSA1(Memory.FillRAM[0x2223], 0x2223); } static void S9xSetSA1MemMap (uint32 which1, uint8 map) diff --git a/source/snes9x/sar.h b/source/snes9x/sar.h index f53de57..9bc6555 100644 --- a/source/snes9x/sar.h +++ b/source/snes9x/sar.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/screenshot.cpp b/source/snes9x/screenshot.cpp index ec8f750..8410944 100644 --- a/source/snes9x/screenshot.cpp +++ b/source/snes9x/screenshot.cpp @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/screenshot.h b/source/snes9x/screenshot.h index 6839ba0..1cb6efc 100644 --- a/source/snes9x/screenshot.h +++ b/source/snes9x/screenshot.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/sdd1.cpp b/source/snes9x/sdd1.cpp index 40cd4c9..f56b4b1 100644 --- a/source/snes9x/sdd1.cpp +++ b/source/snes9x/sdd1.cpp @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/sdd1.h b/source/snes9x/sdd1.h index 7419b5b..244704f 100644 --- a/source/snes9x/sdd1.h +++ b/source/snes9x/sdd1.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/sdd1emu.cpp b/source/snes9x/sdd1emu.cpp index c4f4d36..00e0c79 100644 --- a/source/snes9x/sdd1emu.cpp +++ b/source/snes9x/sdd1emu.cpp @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/sdd1emu.h b/source/snes9x/sdd1emu.h index 5722b4b..a53c9b9 100644 --- a/source/snes9x/sdd1emu.h +++ b/source/snes9x/sdd1emu.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/seta.cpp b/source/snes9x/seta.cpp index e7fd24c..c726399 100644 --- a/source/snes9x/seta.cpp +++ b/source/snes9x/seta.cpp @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/seta.h b/source/snes9x/seta.h index ee49097..2cd64ea 100644 --- a/source/snes9x/seta.h +++ b/source/snes9x/seta.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/seta010.cpp b/source/snes9x/seta010.cpp index 45cf877..dce3ee6 100644 --- a/source/snes9x/seta010.cpp +++ b/source/snes9x/seta010.cpp @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in @@ -216,72 +231,72 @@ static const int16 ST010_SinTable[256] = -0x18f8, -0x15e2, -0x12c8, -0x0fab, -0x0c8b, -0x096a, -0x0647, -0x0324 }; -static const uint8 ST010_ArcTan[32][32] = +static const uint8 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 } + { 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 }, + { 0x40, 0x20, 0x13, 0x0D, 0x0A, 0x08, 0x07, 0x06, 0x05, 0x05, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01 }, + { 0x40, 0x2D, 0x20, 0x18, 0x13, 0x10, 0x0D, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x07, 0x06, 0x06, 0x05, + 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 }, + { 0x40, 0x33, 0x28, 0x20, 0x1A, 0x16, 0x13, 0x10, 0x0F, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x09, 0x08, + 0x08, 0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04 }, + { 0x40, 0x36, 0x2D, 0x26, 0x20, 0x1B, 0x18, 0x15, 0x13, 0x11, 0x10, 0x0E, 0x0D, 0x0C, 0x0B, 0x0B, + 0x0A, 0x09, 0x09, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x06, 0x05, 0x05 }, + { 0x40, 0x38, 0x30, 0x2A, 0x25, 0x20, 0x1C, 0x19, 0x17, 0x15, 0x13, 0x11, 0x10, 0x0F, 0x0E, 0x0D, + 0x0C, 0x0C, 0x0B, 0x0A, 0x0A, 0x0A, 0x09, 0x09, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07 }, + { 0x40, 0x39, 0x33, 0x2D, 0x28, 0x24, 0x20, 0x1D, 0x1A, 0x18, 0x16, 0x14, 0x13, 0x12, 0x10, 0x10, + 0x0F, 0x0E, 0x0D, 0x0C, 0x0C, 0x0B, 0x0B, 0x0A, 0x0A, 0x0A, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08 }, + { 0x40, 0x3A, 0x35, 0x30, 0x2B, 0x27, 0x23, 0x20, 0x1D, 0x1B, 0x19, 0x17, 0x16, 0x14, 0x13, 0x12, + 0x11, 0x10, 0x0F, 0x0E, 0x0E, 0x0D, 0x0D, 0x0C, 0x0C, 0x0B, 0x0B, 0x0A, 0x0A, 0x0A, 0x09, 0x09 }, + { 0x40, 0x3B, 0x36, 0x31, 0x2D, 0x29, 0x26, 0x23, 0x20, 0x1E, 0x1B, 0x1A, 0x18, 0x16, 0x15, 0x14, + 0x13, 0x12, 0x11, 0x10, 0x10, 0x0F, 0x0E, 0x0E, 0x0D, 0x0D, 0x0C, 0x0C, 0x0B, 0x0B, 0x0B, 0x0A }, + { 0x40, 0x3B, 0x37, 0x33, 0x2F, 0x2B, 0x28, 0x25, 0x22, 0x20, 0x1E, 0x1C, 0x1A, 0x19, 0x17, 0x16, + 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x10, 0x0F, 0x0F, 0x0E, 0x0E, 0x0D, 0x0D, 0x0C, 0x0C, 0x0C }, + { 0x40, 0x3C, 0x38, 0x34, 0x30, 0x2D, 0x2A, 0x27, 0x25, 0x20, 0x20, 0x1E, 0x1C, 0x1B, 0x19, 0x18, + 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x11, 0x10, 0x10, 0x0F, 0x0E, 0x0E, 0x0E, 0x0D, 0x0D }, + { 0x40, 0x3C, 0x39, 0x35, 0x32, 0x2F, 0x2C, 0x29, 0x26, 0x24, 0x22, 0x20, 0x1E, 0x1D, 0x1B, 0x1A, + 0x19, 0x17, 0x16, 0x15, 0x14, 0x14, 0x13, 0x12, 0x12, 0x11, 0x10, 0x10, 0x0F, 0x0F, 0x0E, 0x0E }, + { 0x40, 0x3D, 0x39, 0x36, 0x33, 0x30, 0x2D, 0x2A, 0x28, 0x26, 0x24, 0x22, 0x20, 0x1E, 0x1D, 0x1B, + 0x1A, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x14, 0x13, 0x12, 0x12, 0x11, 0x10, 0x10, 0x10, 0x0F }, + { 0x40, 0x3D, 0x3A, 0x37, 0x34, 0x31, 0x2E, 0x2C, 0x2A, 0x27, 0x25, 0x23, 0x22, 0x20, 0x1E, 0x1D, + 0x1C, 0x1B, 0x19, 0x18, 0x17, 0x17, 0x16, 0x15, 0x14, 0x14, 0x13, 0x12, 0x12, 0x11, 0x11, 0x10 }, + { 0x40, 0x3D, 0x3A, 0x37, 0x35, 0x32, 0x30, 0x2D, 0x2B, 0x29, 0x27, 0x25, 0x23, 0x22, 0x20, 0x1F, + 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x16, 0x15, 0x14, 0x13, 0x13, 0x12, 0x12, 0x11 }, + { 0x40, 0x3D, 0x3B, 0x38, 0x35, 0x33, 0x30, 0x2E, 0x2C, 0x2A, 0x28, 0x26, 0x25, 0x23, 0x21, 0x20, + 0x1F, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x18, 0x17, 0x16, 0x15, 0x15, 0x14, 0x13, 0x13, 0x12 }, + { 0x40, 0x3D, 0x3B, 0x38, 0x36, 0x34, 0x31, 0x2F, 0x2D, 0x2B, 0x29, 0x27, 0x26, 0x24, 0x23, 0x21, + 0x20, 0x1F, 0x1E, 0x1D, 0x1B, 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14, 0x13 }, + { 0x40, 0x3E, 0x3B, 0x39, 0x37, 0x34, 0x32, 0x30, 0x2E, 0x2C, 0x2A, 0x29, 0x27, 0x25, 0x24, 0x23, + 0x21, 0x20, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x18, 0x17, 0x16, 0x16, 0x15, 0x14 }, + { 0x40, 0x3E, 0x3B, 0x39, 0x37, 0x35, 0x33, 0x31, 0x2F, 0x2D, 0x2B, 0x2A, 0x28, 0x27, 0x25, 0x24, + 0x22, 0x21, 0x20, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x15 }, + { 0x40, 0x3E, 0x3C, 0x3A, 0x38, 0x36, 0x34, 0x32, 0x30, 0x2E, 0x2C, 0x2B, 0x29, 0x28, 0x26, 0x25, + 0x23, 0x22, 0x21, 0x20, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x1A, 0x19, 0x18, 0x18, 0x17, 0x16 }, + { 0x40, 0x3E, 0x3C, 0x3A, 0x38, 0x36, 0x34, 0x32, 0x30, 0x2F, 0x2D, 0x2C, 0x2A, 0x29, 0x27, 0x26, + 0x25, 0x23, 0x22, 0x21, 0x20, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1B, 0x1A, 0x19, 0x19, 0x18, 0x17 }, + { 0x40, 0x3E, 0x3C, 0x3A, 0x38, 0x36, 0x35, 0x33, 0x31, 0x30, 0x2E, 0x2C, 0x2B, 0x29, 0x28, 0x27, + 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1F, 0x1E, 0x1D, 0x1C, 0x1C, 0x1B, 0x1A, 0x1A, 0x19, 0x18 }, + { 0x40, 0x3E, 0x3C, 0x3A, 0x39, 0x37, 0x35, 0x33, 0x32, 0x30, 0x2F, 0x2D, 0x2C, 0x2A, 0x29, 0x28, + 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1F, 0x1E, 0x1D, 0x1D, 0x1C, 0x1B, 0x1A, 0x1A, 0x19 }, + { 0x40, 0x3E, 0x3C, 0x3B, 0x39, 0x37, 0x36, 0x34, 0x32, 0x31, 0x2F, 0x2E, 0x2C, 0x2B, 0x2A, 0x28, + 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1F, 0x1E, 0x1E, 0x1D, 0x1C, 0x1B, 0x1B, 0x1A }, + { 0x40, 0x3E, 0x3D, 0x3B, 0x39, 0x38, 0x36, 0x34, 0x33, 0x31, 0x30, 0x2E, 0x2D, 0x2C, 0x2A, 0x29, + 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1F, 0x1E, 0x1E, 0x1D, 0x1C, 0x1B, 0x1B }, + { 0x40, 0x3E, 0x3D, 0x3B, 0x3A, 0x38, 0x36, 0x35, 0x33, 0x32, 0x30, 0x2F, 0x2E, 0x2C, 0x2B, 0x2A, + 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1F, 0x1E, 0x1E, 0x1D, 0x1C, 0x1C }, + { 0x40, 0x3E, 0x3D, 0x3B, 0x3A, 0x38, 0x37, 0x35, 0x34, 0x32, 0x31, 0x30, 0x2E, 0x2D, 0x2C, 0x2B, + 0x2A, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x22, 0x21, 0x20, 0x1F, 0x1E, 0x1E, 0x1D, 0x1C }, + { 0x40, 0x3E, 0x3D, 0x3B, 0x3A, 0x39, 0x37, 0x36, 0x34, 0x33, 0x32, 0x30, 0x2F, 0x2E, 0x2D, 0x2B, + 0x2A, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x22, 0x21, 0x20, 0x1F, 0x1F, 0x1E, 0x1D }, + { 0x40, 0x3F, 0x3D, 0x3C, 0x3A, 0x39, 0x37, 0x36, 0x35, 0x33, 0x32, 0x31, 0x30, 0x2E, 0x2D, 0x2C, + 0x2B, 0x2A, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x22, 0x21, 0x20, 0x1F, 0x1F, 0x1E }, + { 0x40, 0x3F, 0x3D, 0x3C, 0x3A, 0x39, 0x38, 0x36, 0x35, 0x34, 0x32, 0x31, 0x30, 0x2F, 0x2E, 0x2D, + 0x2B, 0x2A, 0x29, 0x28, 0x27, 0x26, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20, 0x1F, 0x1F }, + { 0x40, 0x3F, 0x3D, 0x3C, 0x3B, 0x39, 0x38, 0x37, 0x35, 0x34, 0x33, 0x32, 0x30, 0x2F, 0x2E, 0x2D, + 0x2C, 0x2B, 0x2A, 0x29, 0x28, 0x27, 0x26, 0x25, 0x25, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20, 0x1F }, + { 0x40, 0x3F, 0x3D, 0x3C, 0x3B, 0x39, 0x38, 0x37, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2F, 0x2E, + 0x2D, 0x2C, 0x2B, 0x2A, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20 } }; // Mode 7 scaling constants for all raster lines @@ -316,6 +331,7 @@ static const int16 ST010_M7Scale[176] = #endif #define ST010_WORD(offset) (Memory.SRAM[offset + 1] << 8) | Memory.SRAM[offset] +#define ST010_DWORD(offset) (Memory.SRAM[offset + 3] << 24) | (Memory.SRAM[offset + 2] << 16) | (Memory.SRAM[offset + 1] << 8) | Memory.SRAM[offset] static int16 ST010_Sin (int16 Theta) @@ -328,47 +344,43 @@ static int16 ST010_Cos (int16 Theta) return (ST010_SinTable[((Theta + 0x4000) >> 8) & 0xff]); } -static void ST010_OP01 (int16 x0, int16 y0, int16 &x1, int16 &y1, int16 &Quadrant, int16 &Theta) -{ - if ((x0 < 0) && (y0 < 0)) - { +void ST010_Compass(int16 x0, int16 y0, int16 &x1, int16 &y1, int16 &Quadrant, int16 &Theta) +{ + if ((x0 <= 0) && (y0 < 0)) + { x1 = -x0; y1 = -y0; Quadrant = -0x8000; } - else - if (x0 < 0) + else if (x0 < 0) { - x1 = y0; + x1 = y0; y1 = -x0; Quadrant = -0x4000; } - else - if (y0 < 0) + else if (y0 < 0) { x1 = -y0; - y1 = x0; - Quadrant = 0x4000; + y1 = x0; + Quadrant = 0x4000; } else { - x1 = x0; - y1 = y0; - Quadrant = 0x0000; + x1 = x0; + y1 = y0; + Quadrant = 0x0000; } - while ((x1 > 0x1f) || (y1 > 0x1f)) + while ((x1 > 0x1f) || (y1 > 0x1f)) { - if (x1 > 1) - x1 >>= 1; - if (y1 > 1) - y1 >>= 1; + if (x1 > 1) x1 >>= 1; + if (y1 > 1) y1 >>= 1; } - if (y1 == 0) - Quadrant += 0x4000; + Theta = ST010_ArcTan[x1 & 0x1f][y1 & 0x1f] << 8; + Theta = (Theta | Quadrant) ^ 0x8000; - Theta = (ST010_ArcTan[y1][x1] << 8) ^ Quadrant; + if ((x0 == 0) && (y0 < 0)) Quadrant = 0x4000; } static void ST010_Scale (int16 Multiplier, int16 X0, int16 Y0, int32 &X1, int32 &Y1) @@ -421,17 +433,108 @@ static void ST010_SortDrivers (uint16 Positions, uint16 Places[32], uint16 Drive } } -/* -static void SETA_Distance (int16 Y0, int16 X0, int16 &Distance) +static void ST010_Raster(int16 Theta) { - if (X0 < 0) - X0 = -X0; - if (Y0 < 0) - Y0 = -Y0; + int16 data; + int offset = 0; - Distance = ((X0 * 0x7af0) + 0x4000) >> 15; + for (int i = 0; i < 176; i++) + { + data = ST010_M7Scale[i] * ST010_Cos(Theta) >> 15; + + Memory.SRAM[0x00f0 + offset] = data; + Memory.SRAM[0x00f1 + offset] = data >> 8; + + Memory.SRAM[0x0510 + offset] = data; + Memory.SRAM[0x0511 + offset] = data >> 8; + + data = ST010_M7Scale[i] * ST010_Sin(Theta) >> 15; + + Memory.SRAM[0x0250 + offset] = data; + Memory.SRAM[0x0251 + offset] = data >> 8; + + if (data) data = ~data; + + Memory.SRAM[0x03b0 + offset] = data; + Memory.SRAM[0x03b1 + offset] = data >> 8; + + offset += 2; + } +} + +static void ST010_Distance(int16 x0, int16 y0, int16 &Distance) +{ + int32 Product; + + x0 = (x0 < 0) ? -x0 : x0; + y0 = (y0 < 0) ? -y0 : y0; + + if((uint16) x0 >= ((uint16) y0)) + Product = ((x0 * 0x3d78 << 1) + (y0 * 0x1976 << 1)) << 1; + else + Product = ((y0 * 0x3d78 << 1) + (x0 * 0x1976 << 1)) << 1; + + Distance = (Product + 0x8000) >> 16; +} + +static void ST010_Navigation(int16 &MaxX, int16 &MaxY, int32 &x0, int32 &y0, int16 &Theta0, int16 &Theta1, int16 &x1, int16 &y1, uint16 &Radius, uint16 Increment, uint16 MaxRadius, int16 &Compass, int16 &Flags, int16 NewMaxX, int16 NewMaxY) +{ + int16 dummy1,dummy2,dummy3; + uint16 utemp16; + int32 temp32; + + + x1 = MaxX - (x0 >> 16); + y1 = MaxY - (y0 >> 16); + + ST010_Compass(x1, y1, dummy1, dummy2, dummy3, Theta1); + Theta1 -= Theta0; + + if (Theta1 & 0xff00) + Theta0 += (Theta1 & 0x8000) ? 0xfd80 : 0x0280; + + // compiler notice: -0x8000 ==> +0x8000 + utemp16 = ((Theta1 < 0) ? (int16) -Theta1 : Theta1) >> 4; + + if (utemp16 < 0x0100) + { + temp32 = Radius + Increment; + Radius = (temp32 >= MaxRadius) ? MaxRadius : (uint16) temp32; + } + + else + { + temp32 = Radius - utemp16; + Radius = (temp32 <= 0) ? 0 : (uint16) temp32; + } + + x0 -= ((ST010_Sin(Theta0) >> 5) * (Radius >> 8)) << 1; + y0 -= ((ST010_Cos(Theta0) >> 5) * (Radius >> 8)) << 1; + + x0 &= 0x1fffffff; + y0 &= 0x1fffffff; + + + int16 MaxRadiusX, MaxRadiusY; + if (Compass & 0x8000) + { + MaxRadiusX = 0x0008; + MaxRadiusY = 0x0080; + } + else + { + MaxRadiusX = 0x0080; + MaxRadiusY = 0x0008; + } + + if ((abs(x1) < MaxRadiusX) && (abs(y1) < MaxRadiusY)) + { + MaxX = NewMaxX; + MaxY = NewMaxY & 0x0fff; + Compass = (NewMaxY & 0x8000) ? 0xffff : 0x0000; + Flags |= 0x0008; + } } -*/ uint8 S9xGetST010 (uint32 Address) { @@ -471,16 +574,32 @@ void S9xSetST010 (uint32 Address, uint8 Byte) { switch (ST010.op_reg) { + // Heading + case 0x01: + { + Memory.SRAM[0x0006] = Memory.SRAM[0x0002]; + Memory.SRAM[0x0007] = Memory.SRAM[0x0003]; + + #ifdef FAST_LSB_WORD_ACCESS + ST010_Compass(*(int16 *) &Memory.SRAM[0x0000], *(int16 *) &Memory.SRAM[0x0002], (int16 &) Memory.SRAM[0x0000], (int16 &) Memory.SRAM[0x0002], (int16 &) Memory.SRAM[0x0004], (int16 &) Memory.SRAM[0x0010]); + #else + int16 x1, y1, Quadrant, Theta; + + ST010_Compass(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; + } + // 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 @@ -513,15 +632,6 @@ void S9xSetST010 (uint32 Address, uint8 Byte) } // 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 @@ -543,14 +653,74 @@ void S9xSetST010 (uint32 Address, uint8 Byte) break; } + // calculate the vector length of (x, y) + case 0x04: + { + #ifdef FAST_LSB_WORD_ACCESS + ST010_Distance(*(int16 *) &Memory.SRAM[0x0000], *(int16 *) &Memory.SRAM[0x0002], (int16 &) Memory.SRAM[0x0010]); + #else + int16 square; + + ST010_Distance(ST010_WORD(0x0000), ST010_WORD(0x0002), square); + + Memory.SRAM[0x10] = (uint8) (square); + Memory.SRAM[0x11] = (uint8) (square >> 8); + #endif + break; + } + + // calculate AI orientation based on specific guidelines + case 0x05: + { + #ifdef FAST_LSB_WORD_ACCESS + ST010_Navigation((int16 &) Memory.SRAM[0x00c0], (int16 &) Memory.SRAM[0x00c2], (int32 &) Memory.SRAM[0x00c4], (int32 &) Memory.SRAM[0x00c8], (int16 &) Memory.SRAM[0x00cc], (int16 &) Memory.SRAM[0x00ce], (int16 &) Memory.SRAM[0x00d0], (int16 &) Memory.SRAM[0x00d2], (uint16 &) Memory.SRAM[0x00d4], *(uint16 *) &Memory.SRAM[0x00d6], *(uint16 *) &Memory.SRAM[0x00d8], (int16 &) Memory.SRAM[0x00da], (int16 &) Memory.SRAM[0x00dc], *(int16 *) &Memory.SRAM[0x00de], *(int16 *) &Memory.SRAM[0x00e0]); + #else + int32 x0,y0; + int16 MaxX,MaxY,Theta0,Theta1,x1,y1,Compass,Flags; + uint16 Radius; + + MaxX = ST010_WORD(0x00c0); + MaxY = ST010_WORD(0x00c2); + x0 = ST010_DWORD(0x00c4); + y0 = ST010_DWORD(0x00c8); + Theta0 = ST010_WORD(0x00cc); + Radius = ST010_WORD(0x00d4); + Compass = ST010_WORD(0x00da); + Flags = ST010_WORD(0x00dc); + + ST010_Navigation(MaxX, MaxY, x0, y0, Theta0, Theta1, x1, y1, Radius, ST010_WORD(0x00d6), ST010_WORD(0x00d8), Compass, Flags, ST010_WORD(0x00de), ST010_WORD(0x00e0)); + + Memory.SRAM[0x00c0] = (uint8) (MaxX); + Memory.SRAM[0x00c1] = (uint8) (MaxX >> 8); + Memory.SRAM[0x00c2] = (uint8) (MaxY); + Memory.SRAM[0x00c3] = (uint8) (MaxY >> 8); + Memory.SRAM[0x00c4] = (uint8) (x0); + Memory.SRAM[0x00c5] = (uint8) (x0 >> 8); + Memory.SRAM[0x00c6] = (uint8) (x0 >> 16); + Memory.SRAM[0x00c7] = (uint8) (x0 >> 24); + Memory.SRAM[0x00c8] = (uint8) (y0); + Memory.SRAM[0x00c9] = (uint8) (y0 >> 8); + Memory.SRAM[0x00ca] = (uint8) (y0 >> 16); + Memory.SRAM[0x00cb] = (uint8) (y0 >> 24); + Memory.SRAM[0x00cc] = (uint8) (Theta0); + Memory.SRAM[0x00cd] = (uint8) (Theta0 >> 8); + Memory.SRAM[0x00ce] = (uint8) (Theta1); + Memory.SRAM[0x00cf] = (uint8) (Theta1 >> 8); + Memory.SRAM[0x00d0] = (uint8) (x1); + Memory.SRAM[0x00d1] = (uint8) (x1 >> 8); + Memory.SRAM[0x00d2] = (uint8) (y1); + Memory.SRAM[0x00d3] = (uint8) (y1 >> 8); + Memory.SRAM[0x00d4] = (uint8) (Radius); + Memory.SRAM[0x00d5] = (uint8) (Radius >> 8); + Memory.SRAM[0x00da] = (uint8) (Compass); + Memory.SRAM[0x00db] = (uint8) (Compass >> 8); + Memory.SRAM[0x00dc] = (uint8) (Flags); + Memory.SRAM[0x00dd] = (uint8) (Flags >> 8); + #endif + 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 @@ -569,45 +739,13 @@ void S9xSetST010 (uint32 Address, uint8 Byte) } // 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); - - for (int32 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; - } + #ifdef FAST_LSB_WORD_ACCESS + ST010_Raster(*(int16 *) &Memory.SRAM[0x0000]); + #else + ST010_Raster(ST010_WORD(0x0000)); + #endif // Shift Angle for use with Lookup table Memory.SRAM[0x00] = Memory.SRAM[0x01]; @@ -617,15 +755,6 @@ void S9xSetST010 (uint32 Address, uint8 Byte) } // 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 @@ -643,212 +772,6 @@ void S9xSetST010 (uint32 Address, uint8 Byte) 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(*(int16 *) &Memory.SRAM[0x0000], *(int16 *) &Memory.SRAM[0x0002], (int16 &) Memory.SRAM[0x0000], (int16 &) Memory.SRAM[0x0002], (int16 &) Memory.SRAM[0x0004], (int16 &) Memory.SRAM[0x0010]); - #else - int16 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; - } - - // 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]); - #else - 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); - - #ifdef FAST_LSB_WORD_ACCESS - *((int16 *) &Memory.SRAM[0x10]) = square; - #else - Memory.SRAM[0x10] = (uint8) (square); - Memory.SRAM[0x11] = (uint8) (square >> 8); - #endif - break; - } - - // calculate AI orientation based on specific guidelines - case 0x05: - { - int32 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 < rot) - if (abs(o1 - rot) > 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: #ifdef DEBUGGER printf("Unknown Op\n"); diff --git a/source/snes9x/seta011.cpp b/source/snes9x/seta011.cpp index b49a8b8..3590692 100644 --- a/source/snes9x/seta011.cpp +++ b/source/snes9x/seta011.cpp @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/seta018.cpp b/source/snes9x/seta018.cpp index 24efb5c..80d24bd 100644 --- a/source/snes9x/seta018.cpp +++ b/source/snes9x/seta018.cpp @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/sha256.cpp b/source/snes9x/sha256.cpp index d46010d..22691d7 100644 --- a/source/snes9x/sha256.cpp +++ b/source/snes9x/sha256.cpp @@ -13,8 +13,9 @@ *********************************************************************/ /*************************** HEADER FILES ***************************/ +#include #include -#include +#include /****************************** MACROS ******************************/ #define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b)))) @@ -35,7 +36,7 @@ typedef unsigned int WORD; /* 32-bit word, change to "long" for 16- typedef struct { BYTE data[64]; WORD datalen; - unsigned long long bitlen; + uint64_t bitlen; WORD state[8]; } SHA256_CTX; diff --git a/source/snes9x/snapshot.cpp b/source/snes9x/snapshot.cpp index 786d201..e3d4333 100644 --- a/source/snes9x/snapshot.cpp +++ b/source/snes9x/snapshot.cpp @@ -204,6 +204,7 @@ #include "movie.h" #include "display.h" #include "language.h" +#include "gfx.h" #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) @@ -433,6 +434,7 @@ static FreezeData SnapPPU[] = INT_ENTRY(6, CGFLIP), INT_ENTRY(6, CGFLIPRead), INT_ENTRY(6, CGADD), + INT_ENTRY(11, CGSavedByte), ARRAY_ENTRY(6, CGDATA, 256, uint16_ARRAY_V), #define O(N) \ INT_ENTRY(6, OBJ[N].HPos), \ @@ -529,7 +531,8 @@ static FreezeData SnapPPU[] = INT_ENTRY(6, HDMA), INT_ENTRY(6, HDMAEnded), INT_ENTRY(6, OpenBus1), - INT_ENTRY(6, OpenBus2) + INT_ENTRY(6, OpenBus2), + INT_ENTRY(11, VRAMReadBuffer) }; #undef STRUCT @@ -599,7 +602,8 @@ static FreezeData SnapTimings[] = INT_ENTRY(6, IRQFlagChanging), INT_ENTRY(6, APUSpeedup), INT_ENTRY(7, IRQTriggerCycles), - INT_ENTRY(7, APUAllowTimeOverflow) + INT_ENTRY(7, APUAllowTimeOverflow), + INT_ENTRY(11, NextIRQTimer) }; #undef STRUCT @@ -1825,11 +1829,13 @@ int S9xUnfreezeFromStream (STREAM stream) ICPU.ShiftedDB = Registers.DB << 16; S9xSetPCBase(Registers.PBPC); S9xUnpackStatus(); - S9xUpdateIRQPositions(false); + if(version < SNAPSHOT_VERSION_IRQ_2018) + S9xUpdateIRQPositions(false); // calculate the new trigger pos from saved PPU data S9xFixCycles(); for (int d = 0; d < 8; d++) DMA[d] = dma_snap.dma[d]; + // TODO: these should already be correct since they are stored in the snapshot CPU.InDMA = CPU.InHDMA = FALSE; CPU.InDMAorHDMA = CPU.InWRAMDMAorHDMA = FALSE; CPU.HDMARanInDMA = 0; @@ -1839,9 +1845,18 @@ int S9xUnfreezeFromStream (STREAM stream) IPPU.ColorsChanged = TRUE; IPPU.OBJChanged = TRUE; IPPU.RenderThisFrame = TRUE; + + GFX.InterlaceFrame = Timings.InterlaceField; + GFX.DoInterlace = 0; - uint8 hdma_byte = Memory.FillRAM[0x420c]; - S9xSetCPU(hdma_byte, 0x420c); + S9xGraphicsScreenResize(); + + if (Settings.FastSavestates == 0) + memset(GFX.Screen,0,GFX.Pitch * MAX_SNES_HEIGHT); + + // TODO: this seems to be a relic from 1.43 changes, completely remove if no issues in the future + /*uint8 hdma_byte = Memory.FillRAM[0x420c]; + S9xSetCPU(hdma_byte, 0x420c);*/ S9xControlPostLoadState(&ctl_snap); @@ -1935,12 +1950,6 @@ int S9xUnfreezeFromStream (STREAM stream) delete ssi; } - else - { - // couldn't load graphics, so black out the screen instead - for (uint32 y = 0; y < (uint32) (IMAGE_HEIGHT); y++) - memset(GFX.Screen + y * GFX.RealPPL, 0, GFX.RealPPL * 2); - } } if (local_cpu) delete [] local_cpu; diff --git a/source/snes9x/snapshot.h b/source/snes9x/snapshot.h index a88d612..b26397d 100644 --- a/source/snes9x/snapshot.h +++ b/source/snes9x/snapshot.h @@ -196,9 +196,10 @@ #include "snes9x.h" #define SNAPSHOT_MAGIC "#!s9xsnp" -#define SNAPSHOT_VERSION_IRQ 7 -#define SNAPSHOT_VERSION_BAPU 8 -#define SNAPSHOT_VERSION 10 +#define SNAPSHOT_VERSION_IRQ 7 +#define SNAPSHOT_VERSION_BAPU 8 +#define SNAPSHOT_VERSION_IRQ_2018 11 // irq changes were introduced earlier, since this we store NextIRQTimer directly +#define SNAPSHOT_VERSION 11 #define SUCCESS 1 #define WRONG_FORMAT (-1) diff --git a/source/snes9x/snes9x.h b/source/snes9x/snes9x.h index 117ac7e..84696d4 100644 --- a/source/snes9x/snes9x.h +++ b/source/snes9x/snes9x.h @@ -194,7 +194,7 @@ #define _SNES9X_H_ #ifndef VERSION -#define VERSION "1.56.2" +#define VERSION "1.57" #endif #include "port.h" @@ -276,7 +276,7 @@ #define SNES_HDMA_START_HC 1106 // FIXME: not true #define SNES_HBLANK_END_HC 4 // H=1 #define SNES_HDMA_INIT_HC 20 // FIXME: not true -#define SNES_RENDER_START_HC (48 * ONE_DOT_CYCLE) // FIXME: Snes9x renders a line at a time. +#define SNES_RENDER_START_HC (128 * ONE_DOT_CYCLE) // FIXME: Snes9x renders a line at a time. #define SNES_TR_MASK (1 << 4) #define SNES_TL_MASK (1 << 5) diff --git a/source/snes9x/spc7110.cpp b/source/snes9x/spc7110.cpp index 5ead658..533f45f 100644 --- a/source/snes9x/spc7110.cpp +++ b/source/snes9x/spc7110.cpp @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/spc7110.h b/source/snes9x/spc7110.h index 7002b50..8e7ecd2 100644 --- a/source/snes9x/spc7110.h +++ b/source/snes9x/spc7110.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/spc7110dec.cpp b/source/snes9x/spc7110dec.cpp index 6cc2867..ab7521b 100644 --- a/source/snes9x/spc7110dec.cpp +++ b/source/snes9x/spc7110dec.cpp @@ -498,7 +498,7 @@ void SPC7110Decomp::reset() { } SPC7110Decomp::SPC7110Decomp() { - decomp_buffer = new uint8_t[decomp_buffer_size]; + decomp_buffer = new uint8[decomp_buffer_size]; reset(); //initialize reverse morton lookup tables diff --git a/source/snes9x/srtc.cpp b/source/snes9x/srtc.cpp index ca7b91c..978a207 100644 --- a/source/snes9x/srtc.cpp +++ b/source/snes9x/srtc.cpp @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/srtc.h b/source/snes9x/srtc.h index 8bc441c..d21ea98 100644 --- a/source/snes9x/srtc.h +++ b/source/snes9x/srtc.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in diff --git a/source/snes9x/stream.cpp b/source/snes9x/stream.cpp index b385e51..c8e8af6 100644 --- a/source/snes9x/stream.cpp +++ b/source/snes9x/stream.cpp @@ -253,6 +253,24 @@ std::string Stream::getline (bool &eof) return (ret); } +size_t Stream::pos_from_origin_offset(uint8 origin, int32 offset) +{ + size_t position = 0; + switch (origin) + { + case SEEK_SET: + position = offset; + break; + case SEEK_END: + position = size() + offset; + break; + case SEEK_CUR: + position = pos() + offset; + break; + } + return position; +} + // snes9x.h FSTREAM Stream fStream::fStream (FSTREAM f) @@ -299,9 +317,9 @@ size_t fStream::size (void) return sz; } -int fStream::revert (size_t from, size_t offset) +int fStream::revert (uint8 origin, int32 offset) { - return (REVERT_FSTREAM(fp, offset, from)); + return (REVERT_FSTREAM(fp, offset, origin)); } void fStream::closeStream() @@ -428,9 +446,9 @@ size_t unzStream::size (void) return info.uncompressed_size; } -int unzStream::revert (size_t from, size_t offset) +int unzStream::revert (uint8 origin, int32 offset) { - size_t target_pos = from + offset; + size_t target_pos = pos_from_origin_offset(origin, offset); // new pos inside buffered data if (target_pos >= buf_pos_in_unzipped && target_pos < buf_pos_in_unzipped + bytes_in_buf) @@ -547,9 +565,9 @@ size_t memStream::size (void) return msize; } -int memStream::revert (size_t from, size_t offset) +int memStream::revert (uint8 origin, int32 offset) { - size_t pos = from + offset; + size_t pos = pos_from_origin_offset(origin, offset); if(pos > msize) return -1; @@ -610,9 +628,10 @@ size_t nulStream::size (void) return bytes_written; } -int nulStream::revert (size_t from, size_t offset) +int nulStream::revert (uint8 origin, int32 offset) { - bytes_written = from + offset; + size_t target_pos = pos_from_origin_offset(origin, offset); + bytes_written = target_pos; return 0; } diff --git a/source/snes9x/stream.h b/source/snes9x/stream.h index 16ceee5..c62da9c 100644 --- a/source/snes9x/stream.h +++ b/source/snes9x/stream.h @@ -208,8 +208,11 @@ class Stream virtual size_t write (void *, size_t) = 0; virtual size_t pos (void) = 0; virtual size_t size (void) = 0; - virtual int revert (size_t from, size_t offset) = 0; + virtual int revert (uint8 origin, int32 offset) = 0; virtual void closeStream() = 0; + + protected: + size_t pos_from_origin_offset(uint8 origin, int32 offset); }; class fStream : public Stream @@ -223,7 +226,7 @@ class fStream : public Stream virtual size_t write (void *, size_t); virtual size_t pos (void); virtual size_t size (void); - virtual int revert (size_t from, size_t offset); + virtual int revert (uint8 origin, int32 offset); virtual void closeStream(); private: @@ -250,7 +253,7 @@ class unzStream : public Stream virtual size_t write (void *, size_t); virtual size_t pos (void); virtual size_t size (void); - virtual int revert (size_t from, size_t offset); + virtual int revert (uint8 origin, int32 offset); virtual void closeStream(); private: @@ -279,7 +282,7 @@ class memStream : public Stream virtual size_t write (void *, size_t); virtual size_t pos (void); virtual size_t size (void); - virtual int revert (size_t from, size_t offset); + virtual int revert (uint8 origin, int32 offset); virtual void closeStream(); private: @@ -304,7 +307,7 @@ class nulStream : public Stream virtual size_t write (void *, size_t); virtual size_t pos (void); virtual size_t size (void); - virtual int revert (size_t from, size_t offset); + virtual int revert (uint8 origin, int32 offset); virtual void closeStream(); private: diff --git a/source/snes9x/tile.cpp b/source/snes9x/tile.cpp index f8d2082..fad941e 100644 --- a/source/snes9x/tile.cpp +++ b/source/snes9x/tile.cpp @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in @@ -474,7 +489,6 @@ static uint8 ConvertTile4h_even (uint8 *pCache, uint32 TileAddr, uint32 Tile) #undef DOBIT // First-level include: Get all the renderers. - #include "tile.cpp" // Functions to select which converter and renderer to use. @@ -697,13 +711,11 @@ void S9xSelectTileConverter (int depth, bool8 hires, bool8 sub, bool8 mosaic) } #define IS_BLANK_TILE() \ - (BG.Buffered[TileNumber] == BLANK_TILE) + ( ( (Tile & H_FLIP) ? BG.BufferedFlip[TileNumber] : BG.Buffered[TileNumber]) == BLANK_TILE) #define SELECT_PALETTE() \ if (BG.DirectColourMode) \ { \ - if (IPPU.DirectColourMapsNeedRebuild) \ - S9xBuildDirectColourMaps(); \ GFX.RealScreenColors = DirectColourMaps[(Tile >> 10) & 7]; \ } \ else \ @@ -749,6 +761,7 @@ void S9xSelectTileConverter (int depth, bool8 hires, bool8 sub, bool8 mosaic) if (!(Tile & (V_FLIP | H_FLIP))) \ { \ bp = pCache + BPSTART; \ + OFFSET_IN_LINE; \ for (l = LineCount; l > 0; l--, bp += 8 * PITCH, Offset += GFX.PPL) \ { \ DRAW_PIXEL(0, Pix = bp[0]); \ @@ -765,6 +778,7 @@ void S9xSelectTileConverter (int depth, bool8 hires, bool8 sub, bool8 mosaic) if (!(Tile & V_FLIP)) \ { \ bp = pCache + BPSTART; \ + OFFSET_IN_LINE; \ for (l = LineCount; l > 0; l--, bp += 8 * PITCH, Offset += GFX.PPL) \ { \ DRAW_PIXEL(0, Pix = bp[7]); \ @@ -781,6 +795,7 @@ void S9xSelectTileConverter (int depth, bool8 hires, bool8 sub, bool8 mosaic) if (!(Tile & H_FLIP)) \ { \ bp = pCache + 56 - BPSTART; \ + OFFSET_IN_LINE; \ for (l = LineCount; l > 0; l--, bp -= 8 * PITCH, Offset += GFX.PPL) \ { \ DRAW_PIXEL(0, Pix = bp[0]); \ @@ -796,6 +811,7 @@ void S9xSelectTileConverter (int depth, bool8 hires, bool8 sub, bool8 mosaic) else \ { \ bp = pCache + 56 - BPSTART; \ + OFFSET_IN_LINE; \ for (l = LineCount; l > 0; l--, bp -= 8 * PITCH, Offset += GFX.PPL) \ { \ DRAW_PIXEL(0, Pix = bp[7]); \ @@ -840,18 +856,19 @@ void S9xSelectTileConverter (int depth, bool8 hires, bool8 sub, bool8 mosaic) if (!(Tile & (V_FLIP | H_FLIP))) \ { \ bp = pCache + BPSTART; \ + OFFSET_IN_LINE; \ for (l = LineCount; l > 0; l--, bp += 8 * PITCH, Offset += GFX.PPL) \ { \ w = Width; \ switch (StartPixel) \ { \ - case 0: DRAW_PIXEL(0, Pix = bp[0]); if (!--w) break; \ - case 1: DRAW_PIXEL(1, Pix = bp[1]); if (!--w) break; \ - case 2: DRAW_PIXEL(2, Pix = bp[2]); if (!--w) break; \ - case 3: DRAW_PIXEL(3, Pix = bp[3]); if (!--w) break; \ - case 4: DRAW_PIXEL(4, Pix = bp[4]); if (!--w) break; \ - case 5: DRAW_PIXEL(5, Pix = bp[5]); if (!--w) break; \ - case 6: DRAW_PIXEL(6, Pix = bp[6]); if (!--w) break; \ + case 0: DRAW_PIXEL(0, Pix = bp[0]); if (!--w) break; /* Fall through */ \ + case 1: DRAW_PIXEL(1, Pix = bp[1]); if (!--w) break; /* Fall through */ \ + case 2: DRAW_PIXEL(2, Pix = bp[2]); if (!--w) break; /* Fall through */ \ + case 3: DRAW_PIXEL(3, Pix = bp[3]); if (!--w) break; /* Fall through */ \ + case 4: DRAW_PIXEL(4, Pix = bp[4]); if (!--w) break; /* Fall through */ \ + case 5: DRAW_PIXEL(5, Pix = bp[5]); if (!--w) break; /* Fall through */ \ + case 6: DRAW_PIXEL(6, Pix = bp[6]); if (!--w) break; /* Fall through */ \ case 7: DRAW_PIXEL(7, Pix = bp[7]); break; \ } \ } \ @@ -860,18 +877,19 @@ void S9xSelectTileConverter (int depth, bool8 hires, bool8 sub, bool8 mosaic) if (!(Tile & V_FLIP)) \ { \ bp = pCache + BPSTART; \ + OFFSET_IN_LINE; \ for (l = LineCount; l > 0; l--, bp += 8 * PITCH, Offset += GFX.PPL) \ { \ w = Width; \ switch (StartPixel) \ { \ - case 0: DRAW_PIXEL(0, Pix = bp[7]); if (!--w) break; \ - case 1: DRAW_PIXEL(1, Pix = bp[6]); if (!--w) break; \ - case 2: DRAW_PIXEL(2, Pix = bp[5]); if (!--w) break; \ - case 3: DRAW_PIXEL(3, Pix = bp[4]); if (!--w) break; \ - case 4: DRAW_PIXEL(4, Pix = bp[3]); if (!--w) break; \ - case 5: DRAW_PIXEL(5, Pix = bp[2]); if (!--w) break; \ - case 6: DRAW_PIXEL(6, Pix = bp[1]); if (!--w) break; \ + case 0: DRAW_PIXEL(0, Pix = bp[7]); if (!--w) break; /* Fall through */ \ + case 1: DRAW_PIXEL(1, Pix = bp[6]); if (!--w) break; /* Fall through */ \ + case 2: DRAW_PIXEL(2, Pix = bp[5]); if (!--w) break; /* Fall through */ \ + case 3: DRAW_PIXEL(3, Pix = bp[4]); if (!--w) break; /* Fall through */ \ + case 4: DRAW_PIXEL(4, Pix = bp[3]); if (!--w) break; /* Fall through */ \ + case 5: DRAW_PIXEL(5, Pix = bp[2]); if (!--w) break; /* Fall through */ \ + case 6: DRAW_PIXEL(6, Pix = bp[1]); if (!--w) break; /* Fall through */ \ case 7: DRAW_PIXEL(7, Pix = bp[0]); break; \ } \ } \ @@ -880,18 +898,19 @@ void S9xSelectTileConverter (int depth, bool8 hires, bool8 sub, bool8 mosaic) if (!(Tile & H_FLIP)) \ { \ bp = pCache + 56 - BPSTART; \ + OFFSET_IN_LINE; \ for (l = LineCount; l > 0; l--, bp -= 8 * PITCH, Offset += GFX.PPL) \ { \ w = Width; \ switch (StartPixel) \ { \ - case 0: DRAW_PIXEL(0, Pix = bp[0]); if (!--w) break; \ - case 1: DRAW_PIXEL(1, Pix = bp[1]); if (!--w) break; \ - case 2: DRAW_PIXEL(2, Pix = bp[2]); if (!--w) break; \ - case 3: DRAW_PIXEL(3, Pix = bp[3]); if (!--w) break; \ - case 4: DRAW_PIXEL(4, Pix = bp[4]); if (!--w) break; \ - case 5: DRAW_PIXEL(5, Pix = bp[5]); if (!--w) break; \ - case 6: DRAW_PIXEL(6, Pix = bp[6]); if (!--w) break; \ + case 0: DRAW_PIXEL(0, Pix = bp[0]); if (!--w) break; /* Fall through */ \ + case 1: DRAW_PIXEL(1, Pix = bp[1]); if (!--w) break; /* Fall through */ \ + case 2: DRAW_PIXEL(2, Pix = bp[2]); if (!--w) break; /* Fall through */ \ + case 3: DRAW_PIXEL(3, Pix = bp[3]); if (!--w) break; /* Fall through */ \ + case 4: DRAW_PIXEL(4, Pix = bp[4]); if (!--w) break; /* Fall through */ \ + case 5: DRAW_PIXEL(5, Pix = bp[5]); if (!--w) break; /* Fall through */ \ + case 6: DRAW_PIXEL(6, Pix = bp[6]); if (!--w) break; /* Fall through */ \ case 7: DRAW_PIXEL(7, Pix = bp[7]); break; \ } \ } \ @@ -899,18 +918,19 @@ void S9xSelectTileConverter (int depth, bool8 hires, bool8 sub, bool8 mosaic) else \ { \ bp = pCache + 56 - BPSTART; \ + OFFSET_IN_LINE; \ for (l = LineCount; l > 0; l--, bp -= 8 * PITCH, Offset += GFX.PPL) \ { \ w = Width; \ switch (StartPixel) \ { \ - case 0: DRAW_PIXEL(0, Pix = bp[7]); if (!--w) break; \ - case 1: DRAW_PIXEL(1, Pix = bp[6]); if (!--w) break; \ - case 2: DRAW_PIXEL(2, Pix = bp[5]); if (!--w) break; \ - case 3: DRAW_PIXEL(3, Pix = bp[4]); if (!--w) break; \ - case 4: DRAW_PIXEL(4, Pix = bp[3]); if (!--w) break; \ - case 5: DRAW_PIXEL(5, Pix = bp[2]); if (!--w) break; \ - case 6: DRAW_PIXEL(6, Pix = bp[1]); if (!--w) break; \ + case 0: DRAW_PIXEL(0, Pix = bp[7]); if (!--w) break; /* Fall through */ \ + case 1: DRAW_PIXEL(1, Pix = bp[6]); if (!--w) break; /* Fall through */ \ + case 2: DRAW_PIXEL(2, Pix = bp[5]); if (!--w) break; /* Fall through */ \ + case 3: DRAW_PIXEL(3, Pix = bp[4]); if (!--w) break; /* Fall through */ \ + case 4: DRAW_PIXEL(4, Pix = bp[3]); if (!--w) break; /* Fall through */ \ + case 5: DRAW_PIXEL(5, Pix = bp[2]); if (!--w) break; /* Fall through */ \ + case 6: DRAW_PIXEL(6, Pix = bp[1]); if (!--w) break; /* Fall through */ \ case 7: DRAW_PIXEL(7, Pix = bp[0]); break; \ } \ } \ @@ -955,6 +975,7 @@ void S9xSelectTileConverter (int depth, bool8 hires, bool8 sub, bool8 mosaic) \ if (Pix) \ { \ + OFFSET_IN_LINE; \ for (l = LineCount; l > 0; l--, Offset += GFX.PPL) \ { \ for (w = Width - 1; w >= 0; w--) \ @@ -991,6 +1012,7 @@ void S9xSelectTileConverter (int depth, bool8 hires, bool8 sub, bool8 mosaic) GFX.RealScreenColors = IPPU.ScreenColors; \ GFX.ScreenColors = GFX.ClipColors ? BlackColourMap : GFX.RealScreenColors; \ \ + OFFSET_IN_LINE; \ for (l = GFX.StartY; l <= GFX.EndY; l++, Offset += GFX.PPL) \ { \ for (x = Left; x < Right; x++) \ @@ -1036,8 +1058,6 @@ extern struct SLineMatrixData LineMatrixData[240]; \ if (DCMODE) \ { \ - if (IPPU.DirectColourMapsNeedRebuild) \ - S9xBuildDirectColourMaps(); \ GFX.RealScreenColors = DirectColourMaps[0]; \ } \ else \ @@ -1051,6 +1071,7 @@ extern struct SLineMatrixData LineMatrixData[240]; uint32 Offset = GFX.StartY * GFX.PPL; \ struct SLineMatrixData *l = &LineMatrixData[GFX.StartY]; \ \ + OFFSET_IN_LINE; \ for (uint32 Line = GFX.StartY; Line <= GFX.EndY; Line++, Offset += GFX.PPL, l++) \ { \ int yy, starty; \ @@ -1133,8 +1154,6 @@ extern struct SLineMatrixData LineMatrixData[240]; \ if (DCMODE) \ { \ - if (IPPU.DirectColourMapsNeedRebuild) \ - S9xBuildDirectColourMaps(); \ GFX.RealScreenColors = DirectColourMaps[0]; \ } \ else \ @@ -1166,6 +1185,7 @@ extern struct SLineMatrixData LineMatrixData[240]; uint32 Offset = StartY * GFX.PPL; \ struct SLineMatrixData *l = &LineMatrixData[StartY]; \ \ + OFFSET_IN_LINE; \ for (uint32 Line = StartY; Line <= GFX.EndY; Line += VMosaic, Offset += VMosaic * GFX.PPL, l += VMosaic) \ { \ if (Line + VMosaic > GFX.EndY) \ @@ -1341,6 +1361,7 @@ extern struct SLineMatrixData LineMatrixData[240]; // The 1x1 pixel plotter, for speedhacking modes. +#define OFFSET_IN_LINE #define DRAW_PIXEL(N, M) \ if (Z1 > GFX.DB[Offset + N] && (M)) \ { \ @@ -1375,6 +1396,7 @@ extern struct SLineMatrixData LineMatrixData[240]; #undef NAME2 #undef DRAW_PIXEL +#undef OFFSET_IN_LINE // Hires pixel plotter, this combines the main and subscreen pixels as appropriate to render hires or pseudo-hires images. // Use it only on the main screen, subscreen should use Normal2x1 instead. @@ -1388,11 +1410,16 @@ extern struct SLineMatrixData LineMatrixData[240]; #define DRAW_PIXEL_H2x1(N, M) \ if (Z1 > GFX.DB[Offset + 2 * N] && (M)) \ { \ - GFX.S[Offset + 2 * N] = MATH((GFX.ClipColors ? 0 : GFX.SubScreen[Offset + 2 * N]), GFX.RealScreenColors[Pix], GFX.SubZBuffer[Offset + 2 * N]); \ GFX.S[Offset + 2 * N + 1] = MATH(GFX.ScreenColors[Pix], GFX.SubScreen[Offset + 2 * N], GFX.SubZBuffer[Offset + 2 * N]); \ + if ((OffsetInLine + 2 * N ) != (SNES_WIDTH - 1) << 1) \ + GFX.S[Offset + 2 * N + 2] = MATH((GFX.ClipColors ? 0 : GFX.SubScreen[Offset + 2 * N + 2]), GFX.RealScreenColors[Pix], GFX.SubZBuffer[Offset + 2 * N]); \ + if ((OffsetInLine + 2 * N) == 0 || (OffsetInLine + 2 * N) == GFX.RealPPL) \ + GFX.S[Offset + 2 * N] = MATH((GFX.ClipColors ? 0 : GFX.SubScreen[Offset + 2 * N]), GFX.RealScreenColors[Pix], GFX.SubZBuffer[Offset + 2 * N]); \ GFX.DB[Offset + 2 * N] = GFX.DB[Offset + 2 * N + 1] = Z2; \ } +#define OFFSET_IN_LINE \ + uint32 OffsetInLine = Offset % GFX.RealPPL; #define DRAW_PIXEL(N, M) DRAW_PIXEL_H2x1(N, M) #define NAME2 Hires @@ -1402,6 +1429,7 @@ extern struct SLineMatrixData LineMatrixData[240]; #undef NAME2 #undef DRAW_PIXEL +#undef OFFSET_IN_LINE // Interlace: Only draw every other line, so we'll redefine BPSTART and PITCH to do so. // Otherwise, it's the same as Normal2x1/Hires2x1. @@ -1414,6 +1442,7 @@ extern struct SLineMatrixData LineMatrixData[240]; #ifndef NO_INTERLACE +#define OFFSET_IN_LINE #define DRAW_PIXEL(N, M) DRAW_PIXEL_N2x1(N, M) #define NAME2 Interlace @@ -1423,7 +1452,10 @@ extern struct SLineMatrixData LineMatrixData[240]; #undef NAME2 #undef DRAW_PIXEL +#undef OFFSET_IN_LINE +#define OFFSET_IN_LINE \ + uint32 OffsetInLine = Offset % GFX.RealPPL; #define DRAW_PIXEL(N, M) DRAW_PIXEL_H2x1(N, M) #define NAME2 HiresInterlace @@ -1433,6 +1465,7 @@ extern struct SLineMatrixData LineMatrixData[240]; #undef NAME2 #undef DRAW_PIXEL +#undef OFFSET_IN_LINE #endif diff --git a/source/snes9x/tile.h b/source/snes9x/tile.h index d4bd94f..04b5075 100644 --- a/source/snes9x/tile.h +++ b/source/snes9x/tile.h @@ -17,13 +17,20 @@ (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net), Nach (n-a-c-h@users.sourceforge.net), - zones (kasumitokoduck@yahoo.com) + + (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com) (c) Copyright 2006 - 2007 nitsuja - (c) Copyright 2009 - 2010 BearOso, + (c) Copyright 2009 - 2018 BearOso, OV2 + (c) Copyright 2017 qwertymodo + + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) + BS-X C emulator code (c) Copyright 2005 - 2006 Dreamer Nom, @@ -117,6 +124,9 @@ Sound emulator code used in 1.52+ (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com) + S-SMP emulator code used in 1.54+ + (c) Copyright 2016 byuu + SH assembler code partly based on x86 assembler code (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) @@ -130,7 +140,7 @@ (c) Copyright 2006 - 2007 Shay Green GTK+ GUI code - (c) Copyright 2004 - 2010 BearOso + (c) Copyright 2004 - 2018 BearOso Win32 GUI code (c) Copyright 2003 - 2006 blip, @@ -138,11 +148,16 @@ Matthew Kendora, Nach, nitsuja - (c) Copyright 2009 - 2010 OV2 + (c) Copyright 2009 - 2018 OV2 Mac OS GUI code (c) Copyright 1998 - 2001 John Stiles - (c) Copyright 2001 - 2010 zones + (c) Copyright 2001 - 2011 zones + + Libretro port + (c) Copyright 2011 - 2017 Hans-Kristian Arntzen, + Daniel De Matteis + (Under no circumstances will commercial rights be given) Specific ports contains the works of other authors. See headers in