Skip to content

Instantly share code, notes, and snippets.

@realmonster
Last active August 29, 2020 00:15
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save realmonster/8fae4041a612448e0806 to your computer and use it in GitHub Desktop.
Save realmonster/8fae4041a612448e0806 to your computer and use it in GitHub Desktop.
Genesis Plus GX patch for support GEMS Loader Board
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