pico/cd/gfx_cd.o: CFLAGS += -fno-strict-aliasing
ifeq (1,$(use_sh2drc))
ifneq (,$(findstring -flto,$(CFLAGS)))
-# if using the DRC, memory and sh2soc use a global register variable to avoid
-# saving and reloading the SH2 SR. However, this collides with the use of LTO.
+# if using the DRC, memory and sh2soc directly use the DRC register for SH2 SR
+# to avoid saving and reloading it. However, this collides with the use of LTO.
pico/32x/memory.o: CFLAGS += -fno-lto
pico/32x/sh2soc.o: CFLAGS += -fno-lto
endif
--- /dev/null
+This is my foray into dynamic recompilation using PicoDrive, a
+Megadrive / Genesis / Sega CD / Mega CD / 32X / SMS emulator.
+
+I added support for MIPS (mips32r1) and ARM64 (aarch64) to the recompiler, as
+well as spent much effort to optimize the code generated by the DRC.
+I also optimized SH2 memory access inside the emulator, and did some work on
+M68K/SH2 CPU synchronization to fix some problems and speed up the emulator.
+
+It got a bit out of hand. I ended up doing fixes and optimzations all over the
+place, mainly for 32X and CD, 32X graphics handling, and probably some more,
+see the commit history.
+
+### compiling
+
+I mainly worked with standalone PicoDrive versions as created by configure/make.
+A list of platforms for which this is possible can be obtained with
+
+> configure --help
+
+If you want to build an executable for a unixoid platform not listed in the
+platform list, just use
+
+> configure --platform=generic
+
+If DRC is available for the platform, it should be enabled automatically.
+
+For other platforms using a cross-compiling toolchain I used this,
+assuming $TC points to the appropriate cross compile toolchain directory:
+
+platform|toolchain|configure command
+--------|---------|-----------------
+gp2x,wiz,caanoo|open2x|CROSS_COMPILE=arm-open2x-linux- CFLAGS="-I$TC/gcc-4.1.1-glibc-2.3.6/arm-open2x-linux/include -fno-stack-protector -fno-common -finline-limit=42" LDFLAGS="--sysroot $TC/gcc-4.1.1-glibc-2.3.6/arm-open2x-linux -L$TC/gcc-4.1.1-glibc-2.3.6/arm-open2x-linux/lib" ./configure --platform=gp2x
+gp2x,wiz,caanoo|open2x with ubuntu arm gcc 4.7|CROSS_COMPILE=arm-linux-gnueabi- CFLAGS="-I$TC/gcc-4.1.1-glibc-2.3.6/arm-open2x-linux/include -fno-stack-protector -fno-common -finline-limit=42 -fipa-pta" LDFLAGS="-B$TC/gcc-4.1.1-glibc-2.3.6/lib/gcc/arm-open2x-linux/4.1.1 -B$TC/gcc-4.1.1-glibc-2.3.6/arm-open2x-linux/lib -L$TC/gcc-4.1.1-glibc-2.3.6/arm-open2x-linux/lib" ./configure --platform=gp2x
+opendingux|opendingux|CROSS_COMPILE=mipsel-linux- CFLAGS="-I$TC/usr/include -I$TC/usr/include/SDL -fno-stack-protector -fno-common -finline-limit=42 -fipa-pta" LDFLAGS="--sysroot $TC -L$TC/lib" ./configure --platform=opendingux
+opendingux|opendingux with ubuntu mips gcc 5.4|CROSS_COMPILE=mipsel-linux-gnu- CFLAGS="-I$TC/usr/include -I$TC/usr/include/SDL -fno-stack-protector -fno-common -finline-limit=42 -fipa-pta" LDFLAGS="-B$TC/usr/lib -B$TC/lib -Wl,-rpath-link=$TC/usr/lib -Wl,-rpath-link=$TC/lib" ./configure --platform=opendingux
+gcw0|gcw0|CROSS_COMPILE=mipsel-gcw0-linux-uclibc- CFLAGS="-I$TC/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/include -I$TC/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/include/SDL -fno-stack-protector -fno-common -finline-limit=42 -fipa-pta" LDFLAGS="--sysroot $TC/usr/mipsel-gcw0-linux-uclibc/sysroot" ./configure --platform=gcw0
+
+For gp2x, wiz, and caanoo you may need to compile libpng first, and additionally
+this patch may need to be applied to the cpu/cyclone submodule:
+> diff --git a/OpArith.cpp b/OpArith.cpp
+> index 96c7e0d..09517b8 100644
+> --- a/OpArith.cpp
+> +++ b/OpArith.cpp
+> @@ -425,7 +425,7 @@ int OpAbcd(int op)
+> ot(" add r1,r1,r0\n");
+> ot(" add r1,r1,r6\n");
+> ot(" mov r12,r1\n");
+> - ot(" addhi r12,#6 ;@ Decimal adjust units\n");
+> + ot(" addhi r12,r12,#6 ;@ Decimal adjust units\n");
+> ot(" tst r1,#0x80\n");
+> ot(" orreq r10,r10,#0x10000000 ;@ Undefined V behavior\n");
+> ot(" cmp r12,#0x9f\n");
+> @@ -452,7 +452,7 @@ int OpAbcd(int op)
+> ot(" cmp r1,r12\n");
+> ot(" orrlt r10,r10,#0x20000000 ;@ C\n");
+> ot(" cmp r1,#0xff\n");
+> - ot(" addhi r1,#0xa0\n");
+> + ot(" addhi r1,r1,#0xa0\n");
+> ot(" sub r12,r1,r12\n");
+> ot(" movs r0,r12,lsl #24\n");
+> ot(" bicmi r10,r10,#0x10000000 ;@ Undefined V behavior part II\n");
+> diff --git a/OpLogic.cpp b/OpLogic.cpp
+> index 012e35a..d40d814 100644
+> --- a/OpLogic.cpp
+> +++ b/OpLogic.cpp
+> @@ -74,12 +74,12 @@ const char *TestCond(int m68k_cc, int invert)
+> break;
+> case 0x0e: // gt
+> ot(" eor r0,r10,r10,lsl #3 ;@ gt: !Z && N == V\n");
+> - ot(" orrs r0,r10,lsl #1\n");
+> + ot(" orrs r0,r0,r10,lsl #1\n");
+> cond="pl", icond="mi";
+> break;
+> case 0x0f: // le
+> ot(" eor r0,r10,r10,lsl #3 ;@ le: Z || N != V\n");
+> - ot(" orrs r0,r10,lsl #1\n");
+> + ot(" orrs r0,r0,r10,lsl #1\n");
+> cond="mi", icond="pl";
+> break;
+> default:
+
+After configure, compile with
+
+> make opk # for opendingux and gcw0
+>
+> make # for anything else
+
+### helix MP3 decoder
+
+For 32 bit ARM platforms, there is the possibility to compile the helix MP3
+decoder into a shared library to be able to use MP3 audio files with CD games.
+The helix source files aren't supplied because of licensing issues. However, if
+you have obtained the sources, put them into the platform/common/helix
+directory, set CROSS to your cross compiler prefix (e.g. arm-linux-gnueabi-)
+and LIBGCC to your cross compiler's libgcc.a
+(e.g. /usr/lib/gcc-cross/arm-linux-gnueabi/4.7/libgcc.a), and compile with
+
+> make -C platform/common/helix CROSS=$CROSS LIBGCC=$LIBGCC
+
+Copy the resulting ${CROSS}helix_mp3.so as libhelix.so to the directory where
+the PicoDrive binary is.
+
+### installing
+
+You need to install the resulting binary onto your device manually.
+For opendingux and gcw0, copy the opk to your SD card.
+For gp2x, wiz and caanoo, the easiest way is to unpack
+[PicoDrive_191.zip](http://notaz.gp2x.de/releases/PicoDrive/PicoDrive_191.zip)
+on you SD card and replace the PicoDrive binary.
+
+Send bug reports, fixes etc to <derkub@gmail.com>
+Kai-Uwe Bloem
# Automatically generated by configure
-# Configured with: './configure' '--platform=generic'
+# Configured with: './configure' '--platform=opendingux'
CC = mipsel-linux-gcc
CXX = mipsel-linux-g++
AS = mipsel-linux-as
# Automatically generated by configure
-# Configured with: './configure' '--platform=generic'
+# Configured with: './configure' '--platform=opendingux'
CC = mipsel-linux-gnu-gcc
CXX = mipsel-linux-gnu-g++
AS = mipsel-linux-gnu-as
# Automatically generated by configure
-# Configured with: './configure' '--platform=generic'
+# Configured with: './configure' '--platform=gcw0'
CC = mipsel-gcw0-linux-uclibc-gcc
CXX = mipsel-gcw0-linux-uclibc-g++
AS = mipsel-gcw0-linux-uclibc-as
CXX = arm-open2x-linux-g++
AS = arm-open2x-linux-as
STRIP = arm-open2x-linux-strip
-CFLAGS += -I${HOME}/opt/open2x/gcc-4.1.1-glibc-2.3.6/arm-open2x-linux/include -I${HOME}/src/gp2x/armroot/include -D__GP2X__ -Wno-unused-result
-CFLAGS += -msoft-float -mcpu=arm920t -mtune=arm920t
+CFLAGS += -I${HOME}/opt/open2x/gcc-4.1.1-glibc-2.3.6/arm-open2x-linux/include -I${HOME}/src/gp2x/armroot/include -D__GP2X__
+CFLAGS += -mfloat-abi=soft -mcpu=arm920t -mtune=arm920t -mno-thumb-interwork -fno-stack-protector -fno-common
CFLAGS += -finline-limit=42 -fipa-cp -fno-ipa-pure-const
ASFLAGS += -mcpu=arm920t -mfloat-abi=soft
LDFLAGS += --sysroot ${HOME}/opt/open2x/gcc-4.1.1-glibc-2.3.6/arm-open2x-linux -L${HOME}/opt/open2x/gcc-4.1.1-glibc-2.3.6/arm-open2x-linux/lib -L${HOME}/src/gp2x/armroot/lib -static
AS = arm-linux-gnueabi-as
STRIP = arm-linux-gnueabi-strip
CFLAGS += -I${HOME}/opt/open2x/gcc-4.1.1-glibc-2.3.6/arm-open2x-linux/include -I${HOME}/src/gp2x/armroot/include -D__GP2X__ -Wno-unused-result
-CFLAGS += -mabi=apcs-gnu -mfloat-abi=soft -mfpu=fpa -mcpu=arm920t -mtune=arm920t
-CFLAGS += -mno-thumb-interwork -fno-stack-protector -fno-common
+CFLAGS += -mabi=apcs-gnu -mfloat-abi=soft -mfpu=fpa -mcpu=arm920t -mtune=arm920t -mno-thumb-interwork -fno-stack-protector -fno-common
CFLAGS += -finline-limit=42 -fipa-pta -fno-ipa-sra -fno-ipa-pure-const
ASFLAGS += -mabi=apcs-gnu -mfloat-abi=soft -mfpu=fpa -mcpu=arm920t
LDFLAGS += -mabi=apcs-gnu -mfpu=fpa -B${HOME}/opt/open2x/gcc-4.1.1-glibc-2.3.6/lib/gcc/arm-open2x-linux/4.1.1 -B${HOME}/opt/open2x/gcc-4.1.1-glibc-2.3.6/arm-open2x-linux/lib -L${HOME}/opt/open2x/gcc-4.1.1-glibc-2.3.6/arm-open2x-linux/usr/lib -L${HOME}/src/gp2x/armroot/lib -static
$c >> config.log 2>&1
}
+check_option()
+{
+ echo 'void test(void) { }' >$TMPC
+ compile_object $1 || return 1
+ return 0
+}
+
check_define()
{
$CC -E -dD $CFLAGS pico/arm_features.h | grep -q $1 || return 1
# setting options to "yes" or "no" will make that choice default,
# "" means "autodetect".
-platform_list="generic pandora gp2x opendingux rpi1 rpi2"
+platform_list="generic pandora gp2x wiz caanoo opendingux gcw0 rpi1 rpi2"
platform="generic"
sound_driver_list="oss alsa sdl"
sound_drivers=""
have_armv5=""
have_armv6=""
have_armv7=""
+have_arm_oabi=""
have_arm_neon=""
have_libavcodec=""
need_sdl="no"
-need_xlib="no"
+need_zlib="no"
# these are for known platforms
optimize_cortexa8="no"
optimize_cortexa7="no"
CXX="${CXX-${CROSS_COMPILE}g++}"
AS="${AS-${CROSS_COMPILE}as}"
STRIP="${STRIP-${CROSS_COMPILE}strip}"
-test -n "$SDL_CONFIG" || SDL_CONFIG="`$CC --print-sysroot 2> /dev/null || true`/usr/bin/sdl-config"
+test -n "$SDL_CONFIG" || SDL_CONFIG="`$CC $CFLAGS $LDFLAGS --print-sysroot 2> /dev/null || true`/usr/bin/sdl-config"
MAIN_LDLIBS="$LDLIBS -lm"
config_mak="config.mak"
;;
generic)
;;
- opendingux)
+ opendingux | gcw0)
sound_drivers="sdl"
+ # both are really an opendingux
+ platform="opendingux"
;;
pandora)
sound_drivers="oss alsa"
optimize_cortexa8="yes"
have_arm_neon="yes"
;;
- gp2x)
+ gp2x | wiz | caanoo)
sound_drivers="oss"
optimize_arm920="yes"
+ # compile for OABI if toolchain provides it (faster code on caanoo)
+ have_arm_oabi="yes"
+ # always use static linking, since caanoo doesn't have OABI libs. Moreover,
+ # dynamic linking slows Wiz 1-10%, and libm on F100 isn't compatible
+ LDFLAGS="$LDFLAGS -static"
+ # unified binary for all of them
CFLAGS="$CFLAGS -D__GP2X__"
- if [ "$CROSS_COMPILE" = "arm-linux-" ]; then
- # still using static, dynamic linking slows Wiz 1-10%
- # also libm on F100 is not compatible
- MAIN_LDLIBS="$MAIN_LDLIBS -static"
- fi
+ platform="gp2x"
;;
*)
fail "unsupported platform: $platform"
# fi
#fi
-# basic compiler test
-cat > $TMPC <<EOF
-int main(void) { return 0; }
-EOF
-if ! compile_binary; then
- fail "compiler test failed, please check config.log"
-fi
-
if [ -z "$ARCH" ]; then
ARCH=`$CC -dumpmachine | awk -F '-' '{print $1}'`
fi
+# CPU/ABI stuff first, else compile test may fail
case "$ARCH" in
arm*)
# ARM stuff
have_armv5=`check_define HAVE_ARMV5 && echo yes` || true
fi
+ # must disable thumb as recompiler can't handle it
+ if check_define __thumb__; then
+ CFLAGS="$CFLAGS -marm"
+ fi
+ # OABI/EABI selection
+ if [ "$have_arm_oabi" = "yes" ] && check_option -mabi=apcs-gnu; then
+ echo "$CFLAGS" | grep -q -- '-mabi=' || CFLAGS="$CFLAGS -mabi=apcs-gnu"
+ echo "$CFLAGS" | grep -q -- '-m\(no-\)*thumb-interwork' || CFLAGS="$CFLAGS -mno-thumb-interwork"
+ echo "$ASFLAGS" | grep -q -- '-mabi=' || ASFLAGS="$ASFLAGS -mabi=apcs-gnu"
+ fi
+
# automatically set mfpu and mfloat-abi if they are not set
if [ "$have_arm_neon" = "yes" ]; then
fpu="neon"
+ abi="hard"
elif [ "$have_armv6" = "yes" ]; then
fpu="vfp"
+ abi="softfp"
+ elif check_option -mfpu=fpa; then
+ fpu="fpa" # compatibility option for arm-linux-gnueabi-gcc on ubuntu
+ abi="soft"
fi
if [ "x$fpu" != "x" ]; then
echo "$CFLAGS" | grep -q -- '-mfpu=' || CFLAGS="$CFLAGS -mfpu=$fpu"
echo "$ASFLAGS" | grep -q -- '-mfpu=' || ASFLAGS="$ASFLAGS -mfpu=$fpu"
- floatabi_set_by_gcc=`$CC -v 2>&1 | grep -q -- --with-float= && echo yes` || true
- if [ "$floatabi_set_by_gcc" != "yes" ]; then
- echo "$CFLAGS" | grep -q -- '-mfloat-abi=' || CFLAGS="$CFLAGS -mfloat-abi=softfp"
- echo "$ASFLAGS" | grep -q -- '-mfloat-abi=' || ASFLAGS="$ASFLAGS -mfloat-abi=softfp"
- fi
+ echo "$CFLAGS" | grep -q -- '-mfloat-abi=' || CFLAGS="$CFLAGS -mfloat-abi=$abi"
+ echo "$ASFLAGS" | grep -q -- '-mfloat-abi=' || ASFLAGS="$ASFLAGS -mfloat-abi=$abi"
fi
- # must disable thumb as recompiler can't handle it
- if check_define __thumb__; then
- CFLAGS="$CFLAGS -marm"
- fi
+ # add -ldl for helix support
+ case "$MAIN_LDLIBS" in
+ *"-ldl"*) ;;
+ *) MAIN_LDLIBS="-ldl $MAIN_LDLIBS" ;;
+ esac
# warn about common mistakes
if [ "$platform" != "gp2x" -a "$have_armv5" != "yes" ]; then
;;
esac
+# basic compiler test
+cat > $TMPC <<EOF
+int main(void) { return 0; }
+EOF
+if ! compile_binary; then
+ fail "compiler test failed, please check config.log"
+fi
+
# header/library presence tests
check_zlib()
{
compile_object "$@"
}
-MAIN_LDLIBS="$MAIN_LDLIBS -lz"
-check_zlib -lz || fail "please install zlib (libz-dev)"
+check_zlib -lz &&MAIN_LDLIBS="$MAIN_LDLIBS -lz" || need_zlib="yes"
MAIN_LDLIBS="-lpng $MAIN_LDLIBS"
check_libpng || fail "please install libpng (libpng-dev)"
check_sdl `$SDL_CONFIG --libs` || fail "please install libsdl (libsdl1.2-dev)"
fi
-cat > $TMPC <<EOF
-void test(void *f, void *d) { fread(d, 1, 1, f); }
-EOF
-if compile_object -Wno-unused-result; then
+if check_option -Wno-unused_result; then
CFLAGS="$CFLAGS -Wno-unused-result"
fi
if [ "$have_libavcodec" = "yes" ]; then
echo "HAVE_LIBAVCODEC = 1" >> $config_mak
fi
+if [ "$need_zlib" = "yes" ]; then
+ echo "PLATFORM_ZLIB = 1" >> $config_mak
+fi
# GP2X toolchains are too old for UAL asm,
# so add this here to not litter main Makefile
-if [ "$platform" = "g1p2x" ]; then
- echo >> $config_mak
- echo "%.o: %.S" >> $config_mak
- echo " $(CC) $(CFLAGS) -E -c $^ -o /tmp/$(notdir $@).s" >> $config_mak
- echo " $(AS) $(ASFLAGS) /tmp/$(notdir $@).s -o $@" >> $config_mak
-fi
+#if [ "$platform" = "gp2x" ]; then
+# echo >> $config_mak
+# echo '%.o: %.S' >> $config_mak
+# echo ' $(CC) $(CFLAGS) -E -c $^ -o /tmp/$(notdir $@).s' >> $config_mak
+# echo ' $(AS) $(ASFLAGS) /tmp/$(notdir $@).s -o $@' >> $config_mak
+#fi
# use pandora's skin (for now)
test -e skin || ln -s platform/pandora/skin skin
/*
* Basic macros to emit ARM instructions and some utils
* Copyright (C) 2008,2009,2010 notaz
+ * Copyright (C) 2019 kub
*
* This work is licensed under the terms of MAME license.
* See COPYING file in the top-level directory.
/*
* Basic macros to emit x86 instructions and some utils
* Copyright (C) 2008,2009,2010 notaz
+ * Copyright (C) 2019 kuv
*
* This work is licensed under the terms of MAME license.
* See COPYING file in the top-level directory.
AS = $(CROSS)as
AR = $(CROSS)ar
TOOLCHAIN = $(notdir $(CROSS))
+LIBGCC ?= ${HOME}/opt/open2x/gcc-4.1.1-glibc-2.3.6/lib/gcc/arm-open2x-linux/4.1.1/libgcc.a
CFLAGS += -Ipub -O2 -Wall -fstrict-aliasing -ffast-math
ifneq ($(findstring arm-,$(TOOLCHAIN)),)
$(LIB) : $(OBJS)
$(AR) r $@ $^
-$(SHLIB) : $(OBJS) /home/build/opt/open2x/gcc-4.1.1-glibc-2.3.6/lib/gcc/arm-open2x-linux/4.1.1/libgcc.a
+$(SHLIB) : $(OBJS) $(LIBGCC)
$(CC) -o $@ -nostdlib -shared $(CFLAGS) $^
clean: