From b054fd778fa1b8b16862bb0c9961067f30fdd608 Mon Sep 17 00:00:00 2001
From: notaz <notasas@gmail.com>
Date: Sat, 15 Sep 2012 23:29:40 +0300
Subject: [PATCH] initial pandora port

---
 Makefile.pandora          |  52 +++++++
 drivers/arm/asmutils.s    |  12 +-
 drivers/common/menu.c     |   4 +-
 drivers/pandora/pandora.c | 320 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 380 insertions(+), 8 deletions(-)
 create mode 100644 Makefile.pandora
 create mode 100644 drivers/pandora/pandora.c

diff --git a/Makefile.pandora b/Makefile.pandora
new file mode 100644
index 0000000..1724fe1
--- /dev/null
+++ b/Makefile.pandora
@@ -0,0 +1,52 @@
+#CROSS_COMPILE =
+CC	= $(CROSS_COMPILE)gcc
+AS	= $(CROSS_COMPILE)as
+STRIP	= $(CROSS_COMPILE)strip
+TFLAGS  = -Winline -Izlib -DLSB_FIRST -DUNIX -DPSS_STYLE=1 -DHAVE_ASPRINTF -DZLIB -DFRAMESKIP -D_REENTRANT
+RM	= rm -f
+C	= drivers/common/
+L	= drivers/libpicofe/
+
+ifdef DEBUG
+TFLAGS	+= -ggdb
+LDRIVER	+= -ggdb
+else
+TFLAGS	+= -mcpu=cortex-a8 -mtune=cortex-a8 -mfloat-abi=softfp -mfpu=neon -ffast-math
+TFLAGS	+= -O2
+LDRIVER	+= -O2
+endif
+ASFLAGS += -mcpu=cortex-a8
+NOSTRIP = 1
+
+all:		fceu
+
+include zlib/Makefile
+
+OBJDRIVER = drivers/pandora/pandora.o drivers/sdl/throttle.o drivers/arm/asmutils.o \
+	${L}fonts.o ${L}readpng.o ${L}input.o ${L}linux/in_evdev.o ${L}linux/plat.o \
+	${L}linux/sndout_oss.o ${L}linux/fbdev.o ${L}linux/xenv.o ${L}pandora/plat.o \
+	${C}main.o ${C}menu.o ${C}sound-oss.o \
+	${C}cheat.o ${C}config.o ${C}args.o ${C}vidblit.o ${C}unix-netplay.o \
+	${UNZIPOBJS} \
+	ppu.o movie.o fceu098.o ppu098.o
+LDRIVER += -lm -lz -lpng `sdl-config --libs`
+
+OBJDRIVER += x6502.o
+
+x6502.o: x6502.c x6502.h ops.h fce.h sound.h dprintf.h
+
+include Makefile.base
+
+${C}menu.o:		${C}revision.h
+ppu.o:			ppu.c ppu.h
+x6502.o:		TFLAGS += -Wno-inline
+
+${C}revision.h: FORCE
+	@(git describe || echo) | sed -e 's/.*/#define REV "\0"/' > $@_
+	@diff -q $@_ $@ > /dev/null 2>&1 || cp $@_ $@
+	@rm $@_
+.PHONY: FORCE
+
+include Makefile.common
+
+# vim:filetype=make
diff --git a/drivers/arm/asmutils.s b/drivers/arm/asmutils.s
index 1eb1bfa..423560b 100644
--- a/drivers/arm/asmutils.s
+++ b/drivers/arm/asmutils.s
@@ -231,23 +231,23 @@ do_clut_loop:
     ldmia   r1!,{r4,r5}
 
     and     r6, lr, r4, lsl #1
-    ldrh    r6, [r2, r6]
     and     r7, lr, r4, lsr #7
-    ldrh    r7, [r2, r7]
+    ldrh    r6, [r2, r6]
     and     r8, lr, r4, lsr #15
-    ldrh    r8, [r2, r8]
+    ldrh    r7, [r2, r7]
     and     r4, lr, r4, lsr #23
+    ldrh    r8, [r2, r8]
     ldrh    r4, [r2, r4]
 
     orr     r6, r6, r7, lsl #16
     and     r12,lr, r5, lsl #1
-    ldrh    r12, [r2, r12]
     orr     r7, r8, r4, lsl #16
     and     r8, lr, r5, lsr #7
-    ldrh    r8, [r2, r8]
+    ldrh    r12, [r2, r12]
     and     r4, lr, r5, lsr #15
-    ldrh    r4, [r2, r4]
+    ldrh    r8, [r2, r8]
     and     r5, lr, r5, lsr #23
+    ldrh    r4, [r2, r4]
     ldrh    r5, [r2, r5]
     orr     r8, r12,r8, lsl #16
     orr     r12,r4, r5, lsl #16
diff --git a/drivers/common/menu.c b/drivers/common/menu.c
index 607afb1..5858260 100644
--- a/drivers/common/menu.c
+++ b/drivers/common/menu.c
@@ -441,7 +441,7 @@ static int frameskip_i;
 static void config_commit(void)
 {
 	Settings.sound_rate = men_rates_i[sndrate_i];
-	soundvol = sndon ? 0 : 50;
+	soundvol = sndon ? 50 : 0;
 	Settings.turbo_rate_add = (turbo_i * 2 << 24) / 60 + 1;
 	Settings.frameskip = frameskip_i - 1;
 
@@ -606,7 +606,7 @@ int menu_loop(void)
 
 	do {
 		me_loop_d(e_menu_main, &sel, NULL, NULL);
-	} while (!fceugi);
+	} while (!fceugi && menu_loop_ret == 0);
 
 	/* wait until menu, ok, back is released */
 	while (in_menu_wait_any(NULL, 50) & (PBTN_MENU|PBTN_MOK|PBTN_MBACK))
diff --git a/drivers/pandora/pandora.c b/drivers/pandora/pandora.c
new file mode 100644
index 0000000..86f74b4
--- /dev/null
+++ b/drivers/pandora/pandora.c
@@ -0,0 +1,320 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <linux/input.h>
+#include <linux/omapfb.h>
+
+#include "../common/platform.h"
+#include "../common/input.h"
+#include "../common/settings.h"
+#include "../common/main.h"
+#include "../common/args.h"
+#include "../../video.h"
+#include "../arm/asmutils.h"
+#include "../libpicofe/input.h"
+#include "../libpicofe/plat.h"
+#include "../libpicofe/menu.h"
+#include "../libpicofe/linux/in_evdev.h"
+#include "../libpicofe/linux/fbdev.h"
+#include "../libpicofe/linux/xenv.h"
+
+static int g_layer_x, g_layer_y, g_layer_w, g_layer_h;
+static struct vout_fbdev *main_fb, *layer_fb;
+static void *layer_buf;
+static int bounce_buf[320 * 241 / 4];
+static unsigned short pal[256];
+
+static const struct in_default_bind in_evdev_defbinds[] = {
+  { KEY_UP,       IN_BINDTYPE_PLAYER12, NKEYB_UP },
+  { KEY_DOWN,     IN_BINDTYPE_PLAYER12, NKEYB_DOWN },
+  { KEY_LEFT,     IN_BINDTYPE_PLAYER12, NKEYB_LEFT },
+  { KEY_RIGHT,    IN_BINDTYPE_PLAYER12, NKEYB_RIGHT },
+  { KEY_PAGEDOWN, IN_BINDTYPE_PLAYER12, NKEYB_B },
+  { KEY_END,      IN_BINDTYPE_PLAYER12, NKEYB_A },
+  { KEY_HOME,     IN_BINDTYPE_PLAYER12, NKEYB_B_TURBO },
+  { KEY_PAGEUP,   IN_BINDTYPE_PLAYER12, NKEYB_A_TURBO },
+  { KEY_LEFTCTRL, IN_BINDTYPE_PLAYER12, NKEYB_SELECT },
+  { KEY_LEFTALT,  IN_BINDTYPE_PLAYER12, NKEYB_START },
+  { KEY_SPACE,    IN_BINDTYPE_EMU, EACTB_ENTER_MENU },
+  { 0, 0, 0 }
+};
+
+static int omap_setup_layer_(int fd, int enabled, int x, int y, int w, int h)
+{
+	struct omapfb_plane_info pi = { 0, };
+	struct omapfb_mem_info mi = { 0, };
+	int ret;
+
+	ret = ioctl(fd, OMAPFB_QUERY_PLANE, &pi);
+	if (ret != 0) {
+		perror("QUERY_PLANE");
+		return -1;
+	}
+
+	ret = ioctl(fd, OMAPFB_QUERY_MEM, &mi);
+	if (ret != 0) {
+		perror("QUERY_MEM");
+		return -1;
+	}
+
+	/* must disable when changing stuff */
+	if (pi.enabled) {
+		pi.enabled = 0;
+		ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi);
+		if (ret != 0)
+			perror("SETUP_PLANE");
+	}
+
+	if (mi.size < 640*512*3*3) {
+		mi.size = 640*512*3*3;
+		ret = ioctl(fd, OMAPFB_SETUP_MEM, &mi);
+		if (ret != 0) {
+			perror("SETUP_MEM");
+			return -1;
+		}
+	}
+
+	pi.pos_x = x;
+	pi.pos_y = y;
+	pi.out_width = w;
+	pi.out_height = h;
+	pi.enabled = enabled;
+
+	ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi);
+	if (ret != 0) {
+		perror("SETUP_PLANE");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int omap_enable_layer(int enabled)
+{
+	return omap_setup_layer_(vout_fbdev_get_fd(layer_fb), enabled,
+		g_layer_x, g_layer_y, g_layer_w, g_layer_h);
+}
+
+void platform_init(void)
+{
+	const char *main_fb_name, *layer_fb_name;
+	int fd, ret, w, h;
+
+	memset(&Settings, 0, sizeof(Settings));
+	Settings.frameskip = 0;
+	Settings.sound_rate = 44100;
+	Settings.turbo_rate_add = (8*2 << 24) / 60 + 1; // 8Hz turbofire
+	Settings.gamma = 100;
+	Settings.sstate_confirm = 1;
+
+	main_fb_name = getenv("FBDEV_MAIN");
+	if (main_fb_name == NULL)
+		main_fb_name = "/dev/fb0";
+
+	layer_fb_name = getenv("FBDEV_LAYER");
+	if (layer_fb_name == NULL)
+		layer_fb_name = "/dev/fb1";
+
+	// must set the layer up first to be able to use it
+	fd = open(layer_fb_name, O_RDWR);
+	if (fd == -1) {
+		fprintf(stderr, "%s: ", layer_fb_name);
+		perror("open");
+		exit(1);
+	}
+
+	g_layer_x = 80, g_layer_y = 0;
+	g_layer_w = 640, g_layer_h = 480;
+
+	ret = omap_setup_layer_(fd, 0, g_layer_x, g_layer_y, g_layer_w, g_layer_h);
+	close(fd);
+	if (ret != 0) {
+		fprintf(stderr, "failed to set up layer, exiting.\n");
+		exit(1);
+	}
+
+	xenv_init(NULL, "fceu");
+
+	w = h = 0;
+	main_fb = vout_fbdev_init(main_fb_name, &w, &h, 16, 2);
+	if (main_fb == NULL) {
+		fprintf(stderr, "couldn't init fb: %s\n", main_fb_name);
+		exit(1);
+	}
+
+	g_menuscreen_w = w;
+	g_menuscreen_h = h;
+	g_menuscreen_ptr = vout_fbdev_flip(main_fb);
+
+	w = 640;
+	h = 512;
+	layer_fb = vout_fbdev_init(layer_fb_name, &w, &h, 16, 3);
+	if (layer_fb == NULL) {
+		fprintf(stderr, "couldn't init fb: %s\n", layer_fb_name);
+		goto fail0;
+	}
+	layer_buf = vout_fbdev_resize(layer_fb, 256, 240, 16,
+		0, 0, 0, 0, 3);
+	if (layer_buf == NULL) {
+		fprintf(stderr, "couldn't get layer buf\n");
+		goto fail1;
+	}
+
+	plat_target_init();
+	omap_enable_layer(1);
+
+	XBuf = (void *)bounce_buf;
+
+	return;
+
+fail1:
+	vout_fbdev_finish(layer_fb);
+fail0:
+	vout_fbdev_finish(main_fb);
+	xenv_finish();
+	exit(1);
+}
+
+void platform_late_init(void)
+{
+	in_evdev_init(in_evdev_defbinds);
+	in_probe();
+	plat_target_setup_input();
+}
+
+/* video */
+void CleanSurface(void)
+{
+	memset(bounce_buf, 0, sizeof(bounce_buf));
+	vout_fbdev_clear(layer_fb);
+}
+
+void KillVideo(void)
+{
+}
+
+int InitVideo(void)
+{
+	CleanSurface();
+
+	srendline = 0;
+	erendline = 239;
+
+	return 1;
+}
+
+// 16: rrrr rggg gg0b bbbb
+void FCEUD_SetPalette(uint8 index, uint8 r, uint8 g, uint8 b)
+{
+	pal[index] = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
+}
+
+void FCEUD_GetPalette(uint8 index, uint8 *r, uint8 *g, uint8 *b)
+{
+	unsigned int v = pal[index];
+	*r = (v >> 8) & 0xf8;
+	*g = (v >> 3) & 0xfc;
+	*b = v << 3;
+}
+
+void BlitPrepare(int skip)
+{
+	if (skip)
+		return;
+
+	if (eoptions & EO_CLIPSIDES)
+	{
+		int i, *p = bounce_buf + 32/4;
+		for (i = 240; i; i--, p += 320/4)
+		{
+			p[0] = p[1] = p[62] = p[63] = 0;
+		}
+	}
+
+	if (Settings.accurate_mode)
+	{
+		int i, *p = bounce_buf + 32/4;
+		if (srendline > 0)
+			for (i = srendline; i > 0; i--, p += 320/4)
+				memset(p, 0, 256);
+		if (erendline < 239)
+		{
+			int *p = bounce_buf + erendline*320/4 + 32/4;
+			for (i = 239-srendline; i > 0; i--, p += 320/4)
+				memset(p, 0, 256);
+		}
+	}
+}
+
+void BlitScreen(int skip)
+{
+	char *s = (char *)bounce_buf + 32;
+	short *d = (short *)layer_buf;
+	int i;
+
+	if (skip)
+		return;
+
+	for (i = 0; i < 239; i++, d += 256, s += 320)
+		do_clut(d, s, pal, 256);
+	
+	layer_buf = vout_fbdev_flip(layer_fb);
+}
+
+void platform_apply_config(void)
+{
+}
+
+void platform_set_volume(int val)
+{
+}
+
+void plat_video_menu_enter(int is_rom_loaded)
+{
+	omap_enable_layer(0);
+}
+
+void plat_video_menu_begin(void)
+{
+}
+
+void plat_video_menu_end(void)
+{
+	g_menuscreen_ptr = vout_fbdev_flip(main_fb);
+}
+
+void plat_video_menu_leave(void)
+{
+	memset(g_menuscreen_ptr, 0, g_menuscreen_w * g_menuscreen_h * 2);
+	g_menuscreen_ptr = vout_fbdev_flip(main_fb);
+
+	omap_enable_layer(1);
+}
+
+char *DriverUsage="";
+
+ARGPSTRUCT DriverArgs[]={
+         {0,0,0,0}
+};
+
+void DoDriverArgs(void)
+{
+}
+
+void GetBaseDirectory(char *BaseDirectory)
+{
+	strcpy(BaseDirectory, "fceultra");
+}
+
+void platform_finish(void)
+{
+	omap_enable_layer(0);
+	vout_fbdev_finish(layer_fb);
+	vout_fbdev_finish(main_fb);
+	xenv_finish();
+}
-- 
2.39.5