-
-
Save realmonster/8fae4041a612448e0806 to your computer and use it in GitHub Desktop.
Genesis Plus GX patch for support GEMS Loader Board
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/core/cart_hw/md_cart.c b/core/cart_hw/md_cart.c | |
index e382ef3..0472445 100644 | |
--- a/core/cart_hw/md_cart.c | |
+++ b/core/cart_hw/md_cart.c | |
@@ -374,19 +374,22 @@ void md_cart_init(void) | |
if (sram.on && !sram.custom) | |
{ | |
/* disabled on startup if ROM is mapped in same area */ | |
- if (cart.romsize <= sram.start) | |
- { | |
- /* initialize m68k bus handlers */ | |
- m68k.memory_map[sram.start >> 16].base = sram.sram; | |
- m68k.memory_map[sram.start >> 16].read8 = sram_read_byte; | |
- m68k.memory_map[sram.start >> 16].read16 = sram_read_word; | |
- m68k.memory_map[sram.start >> 16].write8 = sram_write_byte; | |
- m68k.memory_map[sram.start >> 16].write16 = sram_write_word; | |
- zbank_memory_map[sram.start >> 16].read = sram_read_byte; | |
- zbank_memory_map[sram.start >> 16].write = sram_write_byte; | |
- } | |
- } | |
- | |
+ if (cart.romsize <= sram.start) | |
+ { | |
+ /* initialize m68k bus handlers */ | |
+ for (i=sram.start; i + (1 << 16) <= sram.end + 1; ++i) | |
+ { | |
+ m68k.memory_map[i >> 16].base = sram.sram; | |
+ m68k.memory_map[i >> 16].read8 = sram_read_byte; | |
+ m68k.memory_map[i >> 16].read16 = sram_read_word; | |
+ m68k.memory_map[i >> 16].write8 = sram_write_byte; | |
+ m68k.memory_map[i >> 16].write16 = sram_write_word; | |
+ zbank_memory_map[i >> 16].read = sram_read_byte; | |
+ zbank_memory_map[i >> 16].write = sram_write_byte; | |
+ } | |
+ } | |
+ } | |
+ | |
/********************************************** | |
SVP CHIP | |
***********************************************/ | |
diff --git a/core/cart_hw/sram.c b/core/cart_hw/sram.c | |
index ed8bea9..9620fcd 100644 | |
--- a/core/cart_hw/sram.c | |
+++ b/core/cart_hw/sram.c | |
@@ -97,15 +97,15 @@ void sram_init() | |
{ | |
/* backup RAM should be disabled */ | |
sram.on = 0; | |
- } | |
- | |
- /* fixe other bad header informations */ | |
- else if ((sram.start > sram.end) || ((sram.end - sram.start) >= 0x10000)) | |
- { | |
- sram.end = sram.start + 0xffff; | |
- } | |
- } | |
- else | |
+ } | |
+ | |
+ /* fixe other bad header informations */ | |
+ else if ((sram.start > sram.end) || ((sram.end - sram.start) >= 0x40000)) | |
+ { | |
+ sram.end = sram.start + 0x3ffff; | |
+ } | |
+ } | |
+ else | |
{ | |
/* autodetect games with missing header infos */ | |
if (strstr(rominfo.product,"T-50086") != NULL) | |
@@ -196,26 +196,26 @@ void sram_init() | |
} | |
} | |
} | |
- | |
-unsigned int sram_read_byte(unsigned int address) | |
-{ | |
- return sram.sram[address & 0xffff]; | |
-} | |
- | |
-unsigned int sram_read_word(unsigned int address) | |
-{ | |
- address &= 0xfffe; | |
- return (sram.sram[address + 1] | (sram.sram[address] << 8)); | |
-} | |
- | |
-void sram_write_byte(unsigned int address, unsigned int data) | |
-{ | |
- sram.sram[address & 0xffff] = data; | |
-} | |
- | |
-void sram_write_word(unsigned int address, unsigned int data) | |
-{ | |
- address &= 0xfffe; | |
- sram.sram[address] = data >> 8; | |
- sram.sram[address + 1] = data & 0xff; | |
-} | |
+ | |
+unsigned int sram_read_byte(unsigned int address) | |
+{ | |
+ return sram.sram[address & 0x3ffff]; | |
+} | |
+ | |
+unsigned int sram_read_word(unsigned int address) | |
+{ | |
+ address &= 0x3fffe; | |
+ return (sram.sram[address + 1] | (sram.sram[address] << 8)); | |
+} | |
+ | |
+void sram_write_byte(unsigned int address, unsigned int data) | |
+{ | |
+ sram.sram[address & 0x3ffff] = data; | |
+} | |
+ | |
+void sram_write_word(unsigned int address, unsigned int data) | |
+{ | |
+ address &= 0x3fffe; | |
+ sram.sram[address] = data >> 8; | |
+ sram.sram[address + 1] = data & 0xff; | |
+} | |
diff --git a/core/input_hw/gems_parallel.c b/core/input_hw/gems_parallel.c | |
new file mode 100644 | |
index 0000000..d829045 | |
--- /dev/null | |
+++ b/core/input_hw/gems_parallel.c | |
@@ -0,0 +1,272 @@ | |
+/*************************************************************************************** | |
+ * Genesis Plus | |
+ * Sega GEMS Sound Driver Loader Board Support | |
+ * | |
+ * Copyright (C) 2014 r57shell | |
+ * | |
+ * Redistribution and use of this code or any derivative works are permitted | |
+ * provided that the following conditions are met: | |
+ * | |
+ * - Redistributions may not be sold, nor may they be used in a commercial | |
+ * product or activity. | |
+ * | |
+ * - Redistributions that are modified from the original source must include the | |
+ * complete source code, including the source code for all components used by a | |
+ * binary built from the modified sources. However, as a special exception, the | |
+ * source code distributed need not include anything that is normally distributed | |
+ * (in either source or binary form) with the major components (compiler, kernel, | |
+ * and so on) of the operating system on which the executable runs, unless that | |
+ * component itself accompanies the executable. | |
+ * | |
+ * - Redistributions must reproduce the above copyright notice, this list of | |
+ * conditions and the following disclaimer in the documentation and/or other | |
+ * materials provided with the distribution. | |
+ * | |
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
+ * POSSIBILITY OF SUCH DAMAGE. | |
+ * | |
+ ****************************************************************************************/ | |
+ | |
+#include "shared.h" | |
+#include "gems_parallel.h" | |
+ | |
+#ifdef LINUX_GEMS_PARALLEL | |
+ | |
+#include <fcntl.h> | |
+ | |
+static int fifo; | |
+static fd_set clientFD; | |
+static struct timeval no_timeout; | |
+static unsigned char reg_last; | |
+static unsigned char byte_received; | |
+static unsigned char available; | |
+ | |
+void gems_parallel_reset() | |
+{ | |
+ fifo = -1; | |
+ available = 0; | |
+} | |
+ | |
+static void try_open() | |
+{ | |
+ if (fifo != -1) | |
+ return; | |
+ | |
+ fifo = open( "/tmp/gems_parallel", O_RDONLY | O_NONBLOCK ); | |
+ if (fifo == -1) | |
+ return; | |
+} | |
+ | |
+static void try_read() | |
+{ | |
+ int iResult; | |
+ if (fifo == -1) | |
+ { | |
+ try_open(); | |
+ if (fifo == -1) | |
+ return; | |
+ } | |
+ | |
+ FD_ZERO( &clientFD ); | |
+ FD_SET( fifo, &clientFD ); | |
+ | |
+ no_timeout.tv_sec = 0; | |
+ no_timeout.tv_usec = 0; | |
+ iResult = select( fifo+1, &clientFD, NULL, NULL, &no_timeout ); | |
+ if (iResult <= 0) | |
+ return; | |
+ | |
+ iResult = read(fifo, &byte_received, 1); | |
+ if (iResult > 0) | |
+ available = 1; | |
+ else if (iResult == 0) | |
+ { | |
+ // end of data, keep waiting | |
+ } | |
+ else // error was | |
+ { | |
+ close(fifo); | |
+ fifo = -1; | |
+ } | |
+} | |
+ | |
+#endif | |
+ | |
+#ifdef WINDOWS_GEMS_PARALLEL | |
+ | |
+#include <ws2tcpip.h> | |
+#include <winsock2.h> | |
+#include <stdlib.h> | |
+#include <stdio.h> | |
+#pragma comment (lib, "Ws2_32.lib") | |
+ | |
+static SOCKET ListenSocket; | |
+static SOCKET ClientSocket; | |
+static fd_set listenFD; | |
+static fd_set clientFD; | |
+static struct timeval no_timeout; | |
+static unsigned char reg_last; | |
+static unsigned char byte_received; | |
+static unsigned char available; | |
+ | |
+void gems_parallel_reset() | |
+{ | |
+ WSADATA wsaData; | |
+ int iResult; | |
+ | |
+ struct addrinfo *result = NULL; | |
+ struct addrinfo hints; | |
+ | |
+ ListenSocket = INVALID_SOCKET; | |
+ ClientSocket = INVALID_SOCKET; | |
+ FD_ZERO( &listenFD ); | |
+ no_timeout.tv_sec = 0; | |
+ no_timeout.tv_usec = 0; | |
+ available = 0; | |
+ | |
+ // Initialize Winsock | |
+ iResult = WSAStartup(MAKEWORD(2,2), &wsaData); | |
+ if (iResult != 0) | |
+ return; | |
+ | |
+ memset(&hints, 0, sizeof(hints)); | |
+ hints.ai_family = AF_INET; | |
+ hints.ai_socktype = SOCK_STREAM; | |
+ hints.ai_protocol = IPPROTO_TCP; | |
+ hints.ai_flags = AI_PASSIVE; | |
+ | |
+ // Resolve the server address and port | |
+ iResult = getaddrinfo(NULL, "5000", &hints, &result); | |
+ if ( iResult != 0 ) | |
+ { | |
+ WSACleanup(); | |
+ return; | |
+ } | |
+ | |
+ // Create a SOCKET for connecting to server | |
+ ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); | |
+ if (ListenSocket == INVALID_SOCKET) | |
+ { | |
+ freeaddrinfo(result); | |
+ WSACleanup(); | |
+ return; | |
+ } | |
+ | |
+ // Setup the TCP listening socket | |
+ iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen); | |
+ if (iResult == SOCKET_ERROR) | |
+ { | |
+ freeaddrinfo(result); | |
+ closesocket(ListenSocket); | |
+ ListenSocket = INVALID_SOCKET; | |
+ WSACleanup(); | |
+ return; | |
+ } | |
+ | |
+ freeaddrinfo(result); | |
+ | |
+ iResult = listen(ListenSocket, 1); | |
+ if (iResult == SOCKET_ERROR) | |
+ { | |
+ closesocket(ListenSocket); | |
+ ListenSocket = INVALID_SOCKET; | |
+ WSACleanup(); | |
+ return; | |
+ } | |
+} | |
+ | |
+static void accept_if_need() | |
+{ | |
+ int iReturnStatus; | |
+ if (ListenSocket == INVALID_SOCKET | |
+ || ClientSocket != INVALID_SOCKET) | |
+ return; | |
+ | |
+ FD_ZERO( &listenFD ); | |
+ FD_SET( ListenSocket, &listenFD ); | |
+ | |
+ iReturnStatus = select( 0, &listenFD, NULL, NULL, &no_timeout ); | |
+ if (iReturnStatus == 0 | |
+ || iReturnStatus == SOCKET_ERROR) | |
+ return; | |
+ | |
+ // Accept a client socket | |
+ ClientSocket = accept(ListenSocket, NULL, NULL); | |
+ if (ClientSocket == INVALID_SOCKET) | |
+ return; | |
+} | |
+ | |
+static void try_read() | |
+{ | |
+ int iResult; | |
+ if (ListenSocket == INVALID_SOCKET) | |
+ return; | |
+ | |
+ if (ClientSocket == INVALID_SOCKET) | |
+ { | |
+ accept_if_need(); | |
+ if (ClientSocket == INVALID_SOCKET) | |
+ return; | |
+ } | |
+ | |
+ FD_ZERO( &clientFD ); | |
+ FD_SET( ClientSocket, &clientFD ); | |
+ | |
+ iResult = select( 0, &clientFD, NULL, NULL, &no_timeout ); | |
+ if (iResult == 0 | |
+ || iResult == SOCKET_ERROR) | |
+ return; | |
+ | |
+ iResult = recv(ClientSocket, &byte_received, 1, 0); | |
+ if (iResult > 0) | |
+ available = 1; | |
+ else if (iResult == 0) | |
+ { | |
+ iResult = shutdown(ClientSocket, SD_BOTH); | |
+ closesocket(ClientSocket); | |
+ ClientSocket = INVALID_SOCKET; | |
+ } | |
+ else // error was | |
+ { | |
+ closesocket(ClientSocket); | |
+ ClientSocket = INVALID_SOCKET; | |
+ } | |
+} | |
+ | |
+#endif | |
+ | |
+#ifdef GEMS_PARALLEL | |
+ | |
+unsigned char gems_parallel_read(void) | |
+{ | |
+ if (!available) | |
+ try_read(); | |
+ | |
+ // NOT ELSE, this is in BOTH cases | |
+ if (available) | |
+ { | |
+ if (reg_last&0x40) | |
+ return byte_received&0xF; | |
+ else | |
+ return (byte_received>>4)&0xF; | |
+ } | |
+ return 0x10; | |
+} | |
+ | |
+void gems_parallel_write(unsigned char data, unsigned char mask) | |
+{ | |
+ if (!(reg_last&0x40) && data&0x40) | |
+ available = 0; | |
+ reg_last = data; | |
+} | |
+ | |
+#endif | |
diff --git a/core/input_hw/gems_parallel.h b/core/input_hw/gems_parallel.h | |
new file mode 100644 | |
index 0000000..60e4530 | |
--- /dev/null | |
+++ b/core/input_hw/gems_parallel.h | |
@@ -0,0 +1,56 @@ | |
+/*************************************************************************************** | |
+ * Genesis Plus | |
+ * Sega GEMS Sound Driver Loader Board Support | |
+ * | |
+ * Copyright (C) 2014 r57shell | |
+ * | |
+ * Redistribution and use of this code or any derivative works are permitted | |
+ * provided that the following conditions are met: | |
+ * | |
+ * - Redistributions may not be sold, nor may they be used in a commercial | |
+ * product or activity. | |
+ * | |
+ * - Redistributions that are modified from the original source must include the | |
+ * complete source code, including the source code for all components used by a | |
+ * binary built from the modified sources. However, as a special exception, the | |
+ * source code distributed need not include anything that is normally distributed | |
+ * (in either source or binary form) with the major components (compiler, kernel, | |
+ * and so on) of the operating system on which the executable runs, unless that | |
+ * component itself accompanies the executable. | |
+ * | |
+ * - Redistributions must reproduce the above copyright notice, this list of | |
+ * conditions and the following disclaimer in the documentation and/or other | |
+ * materials provided with the distribution. | |
+ * | |
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
+ * POSSIBILITY OF SUCH DAMAGE. | |
+ * | |
+ ****************************************************************************************/ | |
+ | |
+#ifndef _GEMS_PARALLEL_H_ | |
+#define _GEMS_PARALLEL_H_ | |
+ | |
+#if defined(WINDOWS_GEMS_PARALLEL) || defined(LINUX_GEMS_PARALLEL) | |
+#define GEMS_PARALLEL | |
+#endif | |
+ | |
+#ifdef GEMS_PARALLEL | |
+ | |
+/* Function prototypes */ | |
+extern void gems_parallel_reset(); | |
+extern unsigned char gems_parallel_read(void); | |
+extern void gems_parallel_write(unsigned char data, unsigned char mask); | |
+ | |
+#endif | |
+ | |
+#endif | |
+ | |
diff --git a/core/io_ctrl.c b/core/io_ctrl.c | |
index 3800f17..7fe6107 100644 | |
--- a/core/io_ctrl.c | |
+++ b/core/io_ctrl.c | |
@@ -49,6 +49,7 @@ | |
#include "paddle.h" | |
#include "sportspad.h" | |
#include "graphic_board.h" | |
+#include "gems_parallel.h" | |
uint8 io_reg[0x10]; | |
@@ -267,9 +268,16 @@ void io_init(void) | |
} | |
} | |
+#ifdef GEMS_PARALLEL | |
+ /* External Port (gems parallel) */ | |
+ port[2].data_w = gems_parallel_write; | |
+ port[2].data_r = gems_parallel_read; | |
+ gems_parallel_reset(); | |
+#else | |
/* External Port (unconnected) */ | |
port[2].data_w = dummy_write; | |
port[2].data_r = dummy_read; | |
+#endif | |
} | |
diff --git a/libretro/msvc/msvc-2010/msvc-2010.vcxproj b/libretro/msvc/msvc-2010/msvc-2010.vcxproj | |
index 11ed4df..b63fc36 100644 | |
--- a/libretro/msvc/msvc-2010/msvc-2010.vcxproj | |
+++ b/libretro/msvc/msvc-2010/msvc-2010.vcxproj | |
@@ -30,6 +30,8 @@ | |
<ClCompile Include="..\..\..\core\genesis.c" /> | |
<ClCompile Include="..\..\..\core\input_hw\activator.c" /> | |
<ClCompile Include="..\..\..\core\input_hw\gamepad.c" /> | |
+ <ClCompile Include="..\..\..\core\input_hw\gems_parallel.c" /> | |
+ <ClCompile Include="..\..\..\core\input_hw\graphic_board.c" /> | |
<ClCompile Include="..\..\..\core\input_hw\input.c" /> | |
<ClCompile Include="..\..\..\core\input_hw\lightgun.c" /> | |
<ClCompile Include="..\..\..\core\input_hw\mouse.c" /> | |
@@ -37,7 +39,7 @@ | |
<ClCompile Include="..\..\..\core\input_hw\sportspad.c" /> | |
<ClCompile Include="..\..\..\core\input_hw\teamplayer.c" /> | |
<ClCompile Include="..\..\..\core\input_hw\terebi_oekaki.c" /> | |
- <ClCompile Include="..\..\..\core\input_hw\xe_a1p.c" /> | |
+ <ClCompile Include="..\..\..\core\input_hw\xe_1ap.c" /> | |
<ClCompile Include="..\..\..\core\io_ctrl.c" /> | |
<ClCompile Include="..\..\..\core\loadrom.c" /> | |
<ClCompile Include="..\..\..\core\m68k\m68kcpu.c" /> | |
diff --git a/libretro/msvc/msvc-2010/msvc-2010.vcxproj.filters b/libretro/msvc/msvc-2010/msvc-2010.vcxproj.filters | |
index 262e025..fb50245 100644 | |
--- a/libretro/msvc/msvc-2010/msvc-2010.vcxproj.filters | |
+++ b/libretro/msvc/msvc-2010/msvc-2010.vcxproj.filters | |
@@ -66,9 +66,6 @@ | |
<ClCompile Include="..\..\..\core\cart_hw\sms_cart.c"> | |
<Filter>Source Files\cart_hw</Filter> | |
</ClCompile> | |
- <ClCompile Include="..\..\..\core\input_hw\xe_a1p.c"> | |
- <Filter>Source Files\input_hw</Filter> | |
- </ClCompile> | |
<ClCompile Include="..\..\..\core\input_hw\activator.c"> | |
<Filter>Source Files\input_hw</Filter> | |
</ClCompile> | |
@@ -237,5 +234,14 @@ | |
<ClCompile Include="..\..\..\core\tremor\vorbisfile.c"> | |
<Filter>Source Files\tremor</Filter> | |
</ClCompile> | |
+ <ClCompile Include="..\..\..\core\input_hw\xe_1ap.c"> | |
+ <Filter>Source Files</Filter> | |
+ </ClCompile> | |
+ <ClCompile Include="..\..\..\core\input_hw\graphic_board.c"> | |
+ <Filter>Source Files\input_hw</Filter> | |
+ </ClCompile> | |
+ <ClCompile Include="..\..\..\core\input_hw\gems_parallel.c"> | |
+ <Filter>Source Files\input_hw</Filter> | |
+ </ClCompile> | |
</ItemGroup> | |
</Project> | |
\ No newline at end of file |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment