add pollux/caanoo port, refactor things
authornotaz <notasas@gmail.com>
Sat, 24 Sep 2011 15:41:41 +0000 (18:41 +0300)
committernotaz <notasas@gmail.com>
Sat, 24 Sep 2011 22:24:11 +0000 (01:24 +0300)
21 files changed:
.gitmodules [new file with mode: 0644]
Makefile
Makefile.caanoo [new file with mode: 0644]
Makefile.maemo
frontend/cspace.c
frontend/menu.c
frontend/menu.h
frontend/pandora.h [deleted file]
frontend/pl_gun_ts.c
frontend/plat.h [new file with mode: 0644]
frontend/plat_dummy.c
frontend/plat_omap.c
frontend/plat_pandora.c [moved from frontend/pandora.c with 83% similarity]
frontend/plat_pollux.c [new file with mode: 0644]
frontend/plugin_lib.c
frontend/plugin_lib.h
frontend/warm [new submodule]
plugins/dfxvideo/draw_fb.c
plugins/dfxvideo/gpu.c
plugins/gpu_unai/Makefile
plugins/gpu_unai/gpu.cpp

diff --git a/.gitmodules b/.gitmodules
new file mode 100644 (file)
index 0000000..88aa475
--- /dev/null
@@ -0,0 +1,3 @@
+[submodule "frontend/warm"]
+       path = frontend/warm
+       url = ssh://notaz.gp2x.de/~/public_git/warm.git
index fa1f673..bf364c7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -5,6 +5,7 @@ LD = $(CROSS_COMPILE)ld
 
 ARM926 ?= 0
 ARM_CORTEXA8 ?= 1
+PLATFORM ?= pandora
 USE_OSS ?= 1
 #USE_ALSA = 1
 #DRC_DBG = 1
@@ -112,16 +113,23 @@ ifeq "$(USE_GTK)" "1"
 OBJS += maemo/hildon.o maemo/main.o
 maemo/%.o: maemo/%.c
 else
-frontend/%.o: CFLAGS += -DVOUT_FBDEV
-OBJS += frontend/menu.o
-OBJS += frontend/linux/fbdev.o frontend/linux/in_evdev.o
+OBJS += frontend/menu.o frontend/linux/in_evdev.o
 OBJS += frontend/common/input.o frontend/linux/oshide.o
-ifeq "$(ARCH)" "arm"
+
+ifeq "$(PLATFORM)" "pandora"
+frontend/%.o: CFLAGS += -DVOUT_FBDEV
+OBJS += frontend/linux/fbdev.o
 OBJS += frontend/plat_omap.o
-OBJS += frontend/pandora.o
+OBJS += frontend/plat_pandora.o
+else
+ifeq "$(PLATFORM)" "caanoo"
+OBJS += frontend/plat_pollux.o
+OBJS += frontend/warm/warm.o
 else
 OBJS += frontend/plat_dummy.o
 endif
+endif
+
 endif # !USE_GTK
 
 ifeq "$(HAVE_NEON)" "1"
diff --git a/Makefile.caanoo b/Makefile.caanoo
new file mode 100644 (file)
index 0000000..54e478c
--- /dev/null
@@ -0,0 +1,5 @@
+export ARM926=1
+export ARM_CORTEXA8=0
+PLATFORM=caanoo
+
+include Makefile
index 2bed079..4e1b577 100644 (file)
@@ -1,6 +1,7 @@
 USE_GTK=1
 USE_ALSA=1
 USE_OSS=0
+PLATFORM=generic
 
 export MAEMO=1
 LDFLAGS += $(shell pkg-config --libs hildon-1 libpulse)
index f5f8d35..eee56ce 100644 (file)
@@ -1,7 +1,21 @@
 #include "cspace.h"
 
+void bgr555_to_rgb565(void *dst_, const void *src_, int bytes)
+{
+       unsigned int *src = (unsigned int *)src_;
+       unsigned int *dst = (unsigned int *)dst_;
+       unsigned int p;
+       int x;
+
+       for (x = 0; x < bytes / 4; x++) {
+               p = src[x];
+               p = ((p & 0x7c007c00) >> 10) | ((p & 0x03e003e0) << 1)
+                       | ((p & 0x001f001f) << 11);
+               dst[x] = p;
+       }
+}
+
 // TODO?
-void bgr555_to_rgb565(void *dst, const void *src, int bytes) {}
 void bgr888_to_rgb888(void *dst, const void *src, int bytes) {}
 void bgr888_to_rgb565(void *dst, const void *src, int bytes) {}
 
index 01b568e..a063fa1 100644 (file)
@@ -20,7 +20,7 @@
 #include "plugin.h"
 #include "plugin_lib.h"
 #include "omap.h"
-#include "pandora.h"
+#include "plat.h"
 #include "pcnt.h"
 #include "cspace.h"
 #include "common/plat.h"
@@ -33,7 +33,6 @@
 #include "../plugins/dfinput/main.h"
 #include "revision.h"
 
-#define MENU_X2 1
 #define array_size(x) (sizeof(x) / sizeof(x[0]))
 
 typedef enum
@@ -55,11 +54,14 @@ typedef enum
        MA_CTRL_EMU,
        MA_CTRL_DEV_FIRST,
        MA_CTRL_DEV_NEXT,
+       MA_CTRL_NUBS_BTNS,
+       MA_CTRL_DEADZONE,
        MA_CTRL_DONE,
        MA_OPT_SAVECFG,
        MA_OPT_SAVECFG_GAME,
        MA_OPT_CPU_CLOCKS,
        MA_OPT_FILTERING,
+       MA_OPT_DISP_OPTS,
 } menu_id;
 
 enum {
@@ -76,7 +78,7 @@ static char rom_fname_reload[MAXPATHLEN];
 static char last_selected_fname[MAXPATHLEN];
 static int warned_about_bios, region, in_type_sel1, in_type_sel2;
 static int memcard1_sel, memcard2_sel;
-int g_opts;
+int g_opts, analog_deadzone;
 
 // sound plugin
 extern int iUseReverb;
@@ -155,7 +157,7 @@ static void menu_sync_config(void)
        default: in_type2 = PSE_PAD_TYPE_STANDARD;
        }
        if (in_evdev_allow_abs_only != allow_abs_only_old) {
-               pandora_rescan_inputs();
+               plat_rescan_inputs();
                allow_abs_only_old = in_evdev_allow_abs_only;
        }
 
@@ -170,6 +172,7 @@ static void menu_set_defconfig(void)
        scaling = SCALE_4_3;
        volume_boost = 0;
        frameskip = 0;
+       analog_deadzone = 50;
 
        region = 0;
        in_type_sel1 = in_type_sel2 = 0;
@@ -247,6 +250,7 @@ static const struct {
        CE_INTVAL(g_opts),
        CE_INTVAL(in_type_sel1),
        CE_INTVAL(in_type_sel2),
+       CE_INTVAL(analog_deadzone),
        CE_INTVAL_V(frameskip, 2),
        CE_INTVAL_P(gpu_peops.iUseDither),
        CE_INTVAL_P(gpu_peops.dwActFixes),
@@ -475,6 +479,12 @@ static const char *filter_exts[] = {
 };
 
 #define MENU_ALIGN_LEFT
+#ifdef __ARM_ARCH_7A__ // assume hires device
+#define MENU_X2 1
+#else
+#define MENU_X2 0
+#endif
+
 #define menu_init menu_init_common
 #include "common/menu.c"
 #undef menu_init
@@ -538,44 +548,26 @@ static void draw_savestate_bg(int slot)
        h = min(g_menuscreen_h, h);
        d = (u16 *)g_menubg_ptr + g_menuscreen_w * y + x;
 
-       for (; h > 0; h--, d += g_menuscreen_w, s += 1024)
+       for (; h > 0; h--, d += g_menuscreen_w, s += 1024) {
                if (gpu->ulStatus & 0x200000)
                        bgr888_to_rgb565(d, s, w * 3);
                else
                        bgr555_to_rgb565(d, s, w * 2);
+#ifndef __ARM_ARCH_7A__
+               // better darken this on small screens
+               menu_darken_bg(d, d, w * 2, 0);
+#endif
+       }
 
 out:
        free(gpu);
 }
 
-// ---------- pandora specific -----------
+// ---------- XXX: pandora specific -----------
 
 static const char pnd_script_base[] = "sudo -n /usr/pandora/scripts";
 static char **pnd_filter_list;
 
-static int get_cpu_clock(void)
-{
-       FILE *f;
-       int ret = 0;
-       f = fopen("/proc/pandora/cpu_mhz_max", "r");
-       if (f) {
-               fscanf(f, "%d", &ret);
-               fclose(f);
-       }
-       return ret;
-}
-
-static void apply_cpu_clock(void)
-{
-       char buf[128];
-
-       if (cpu_clock != 0 && cpu_clock != get_cpu_clock()) {
-               snprintf(buf, sizeof(buf), "unset DISPLAY; echo y | %s/op_cpuspeed.sh %d",
-                        pnd_script_base, cpu_clock);
-               system(buf);
-       }
-}
-
 static void apply_filter(int which)
 {
        static int old = -1;
@@ -611,18 +603,6 @@ static void apply_lcdrate(int pal)
        old = pal;
 }
 
-static int get_bat_capacity(void)
-{
-       FILE *f;
-       int ret = 0;
-       f = fopen("/sys/class/power_supply/bq27500-0/capacity", "r");
-       if (f) {
-               fscanf(f, "%d", &ret);
-               fclose(f);
-       }
-       return ret;
-}
-
 static menu_entry e_menu_gfx_options[];
 
 static void pnd_menu_init(void)
@@ -633,7 +613,7 @@ static void pnd_menu_init(void)
        char buff[64];
        DIR *dir;
 
-       cpu_clock_st = cpu_clock = get_cpu_clock();
+       cpu_clock_st = cpu_clock = plat_cpu_clock_get();
 
        dir = opendir("/etc/pandora/conf/dss_fir");
        if (dir == NULL) {
@@ -700,8 +680,7 @@ static void pnd_menu_init(void)
 
 void menu_finish(void)
 {
-       cpu_clock = cpu_clock_st;
-       apply_cpu_clock();
+       plat_cpu_clock_apply(cpu_clock_st);
 }
 
 // -------------- key config --------------
@@ -969,7 +948,7 @@ static int mh_savecfg(int id, int keys)
 static int mh_input_rescan(int id, int keys)
 {
        //menu_sync_config();
-       pandora_rescan_inputs();
+       plat_rescan_inputs();
        me_update_msg("rescan complete.");
 
        return 0;
@@ -992,7 +971,8 @@ static menu_entry e_menu_keyconfig[] =
        mee_label     (""),
        mee_enum      ("Port 1 device",     0, in_type_sel1,    men_in_type_sel),
        mee_enum      ("Port 2 device",     0, in_type_sel2,    men_in_type_sel),
-       mee_onoff_h   ("Nubs as buttons",   0, in_evdev_allow_abs_only, 1, h_nub_btns),
+       mee_onoff_h   ("Nubs as buttons",   MA_CTRL_NUBS_BTNS,  in_evdev_allow_abs_only, 1, h_nub_btns),
+       mee_range     ("Analog deadzone",   MA_CTRL_DEADZONE,   analog_deadzone, 1, 99),
        mee_onoff_h   ("No TS Gun trigger", 0, g_opts, OPT_TSGUN_NOTRIGGER, h_notsgun),
        mee_cust_nosave("Save global config",       MA_OPT_SAVECFG,      mh_savecfg, mgn_saveloadcfg),
        mee_cust_nosave("Save cfg for loaded game", MA_OPT_SAVECFG_GAME, mh_savecfg, mgn_saveloadcfg),
@@ -1166,9 +1146,9 @@ static int menu_loop_plugin_spu(int id, int keys)
        return 0;
 }
 
-static const char h_bios[]       = "HLE is simulated BIOS. BIOS selection is saved in savestates\n"
-                                  "and can't be changed there. Must save config and reload\n"
-                                  "the game for change to take effect";
+static const char h_bios[]       = "HLE is simulated BIOS. BIOS selection is saved in\n"
+                                  "savestates and can't be changed there. Must save\n"
+                                  "config and reload the game for change to take effect";
 static const char h_plugin_xpu[] = "Must save config and reload the game\n"
                                   "for plugin change to take effect";
 static const char h_gpu_peops[]  = "Configure P.E.Op.S. SoftGL Driver V1.17";
@@ -1274,7 +1254,7 @@ static menu_entry e_menu_options[] =
        mee_onoff     ("Show FPS",                 0, g_opts, OPT_SHOWFPS),
        mee_enum      ("Region",                   0, region, men_region),
        mee_range     ("CPU clock",                MA_OPT_CPU_CLOCKS, cpu_clock, 20, 5000),
-       mee_handler   ("[Display]",                menu_loop_gfx_options),
+       mee_handler_id("[Display]",                MA_OPT_DISP_OPTS, menu_loop_gfx_options),
        mee_handler   ("[BIOS/Plugins]",           menu_loop_plugin_options),
        mee_handler   ("[Advanced]",               menu_loop_adv_options),
        mee_cust_nosave("Save global config",      MA_OPT_SAVECFG,      mh_savecfg, mgn_saveloadcfg),
@@ -1502,7 +1482,7 @@ static void draw_frame_main(void)
                ltime = time(NULL);
                tmp = localtime(&ltime);
                strftime(ltime_s, sizeof(ltime_s), "%H:%M", tmp);
-               snprintf(buff, sizeof(buff), "%s %3d%%", ltime_s, get_bat_capacity());
+               snprintf(buff, sizeof(buff), "%s %3d%%", ltime_s, plat_get_bat_capacity());
                smalltext_out16(4, 1 + me_sfont_h, buff, 0x105f);
        }
 }
@@ -1986,6 +1966,13 @@ void menu_init(void)
                exit(1);
        emu_make_path(buff, "skin/background.png", sizeof(buff));
        readpng(g_menubg_src_ptr, buff, READPNG_BG, g_menuscreen_w, g_menuscreen_h);
+
+#ifndef __ARM_ARCH_7A__ /* XXX */
+       me_enable(e_menu_options, MA_OPT_DISP_OPTS, 0);
+       me_enable(e_menu_keyconfig, MA_CTRL_NUBS_BTNS, 0);
+#else
+       me_enable(e_menu_keyconfig, MA_CTRL_DEADZONE, 0);
+#endif
 }
 
 void menu_notify_mode_change(int w, int h, int bpp)
@@ -2047,6 +2034,8 @@ static void menu_leave_emu(void)
                        fprintf(stderr, "Warning: GPU_close returned %d\n", ret);
        }
 
+       plat_video_menu_enter(ready_to_go);
+
        memcpy(g_menubg_ptr, g_menubg_src_ptr, g_menuscreen_w * g_menuscreen_h * 2);
        if (pl_vout_buf != NULL && ready_to_go && last_psx_bpp == 16) {
                int x = max(0, g_menuscreen_w - last_psx_w);
@@ -2061,9 +2050,7 @@ static void menu_leave_emu(void)
        }
 
        if (ready_to_go)
-               cpu_clock = get_cpu_clock();
-
-       plat_video_menu_enter(ready_to_go);
+               cpu_clock = plat_cpu_clock_get();
 }
 
 void menu_prepare_emu(void)
@@ -2087,7 +2074,7 @@ void menu_prepare_emu(void)
        menu_sync_config();
        apply_lcdrate(Config.PsxType);
        apply_filter(filter);
-       apply_cpu_clock();
+       plat_cpu_clock_apply(cpu_clock);
 
        // push config to GPU plugin
        plugin_call_rearmed_cbs();
index 1635146..3326b69 100644 (file)
@@ -13,4 +13,4 @@ enum opts {
        OPT_TSGUN_NOTRIGGER = 1 << 4,
 };
 
-extern int g_opts;
+extern int g_opts, analog_deadzone;
diff --git a/frontend/pandora.h b/frontend/pandora.h
deleted file mode 100644 (file)
index 9274d4d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-int pandora_rescan_inputs(void);
index 3ee9c25..fbf25e3 100644 (file)
@@ -102,7 +102,11 @@ struct tsdev *pl_gun_ts_init(void)
 
        // FIXME: we should be able to get this somewhere
        // the problem is this doesn't always match resolution due to different display modes
+#ifdef __ARM_ARCH_7A__
        pl_set_gun_rect(0, 0, 800, 480);
+#else
+       pl_set_gun_rect(0, 0, 320, 240);
+#endif
        return ts;
 
 fail_config:
diff --git a/frontend/plat.h b/frontend/plat.h
new file mode 100644 (file)
index 0000000..4f3ab81
--- /dev/null
@@ -0,0 +1,4 @@
+int plat_rescan_inputs(void);
+int plat_cpu_clock_get(void);
+int plat_cpu_clock_apply(int cpu_clock);
+int plat_get_bat_capacity(void);
index bafb184..0b5f090 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "common/input.h"
 #include "linux/fbdev.h"
+#include "plat.h"
 
 struct vout_fbdev *layer_fb;
 int g_layer_x, g_layer_y, g_layer_w, g_layer_h;
@@ -47,6 +48,22 @@ void in_update_analogs(void)
 {
 }
 
-void pandora_rescan_inputs(void)
+int plat_rescan_inputs(void)
 {
+       return -1;
+}
+
+int plat_cpu_clock_get(void)
+{
+       return -1;
+}
+
+int plat_cpu_clock_apply(int cpu_clock)
+{
+       return -1;
+}
+
+int plat_get_bat_capacity(void)
+{
+       return -1;
 }
index 6cc4eaa..65478cb 100644 (file)
@@ -20,7 +20,7 @@
 #include "plugin_lib.h"
 #include "pl_gun_ts.h"
 #include "omap.h"
-#include "pandora.h"
+#include "plat.h"
 
 
 static struct vout_fbdev *main_fb;
@@ -174,7 +174,7 @@ void plat_init(void)
        g_menubg_ptr = temp_frame;
 
        // hmh
-       pandora_rescan_inputs();
+       plat_rescan_inputs();
 
        return;
 
similarity index 83%
rename from frontend/pandora.c
rename to frontend/plat_pandora.c
index b82c78a..d7837ce 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -17,6 +18,7 @@
 
 #include "common/input.h"
 #include "plugin_lib.h"
+#include "plat.h"
 #include "main.h"
 
 static int fdnub[2];
@@ -151,7 +153,7 @@ void in_update_analogs(void)
        //printf("%4d %4d %4d %4d\n", in_a1[0], in_a1[1], in_a2[0], in_a2[1]);
 }
 
-int pandora_rescan_inputs(void)
+int plat_rescan_inputs(void)
 {
        in_probe();
        in_set_config(in_name_to_id("evdev:gpio-keys"), IN_CFG_KEY_NAMES,
@@ -159,3 +161,41 @@ int pandora_rescan_inputs(void)
 
        return 0;
 }
+
+static const char pnd_script_base[] = "sudo -n /usr/pandora/scripts";
+
+int plat_cpu_clock_get(void)
+{
+       FILE *f;
+       int ret = 0;
+       f = fopen("/proc/pandora/cpu_mhz_max", "r");
+       if (f) {
+               fscanf(f, "%d", &ret);
+               fclose(f);
+       }
+       return ret;
+}
+
+int plat_cpu_clock_apply(int cpu_clock)
+{
+       char buf[128];
+
+       if (cpu_clock != 0 && cpu_clock != plat_cpu_clock_get()) {
+               snprintf(buf, sizeof(buf), "unset DISPLAY; echo y | %s/op_cpuspeed.sh %d",
+                        pnd_script_base, cpu_clock);
+               system(buf);
+       }
+       return 0;
+}
+
+int plat_get_bat_capacity(void)
+{
+       FILE *f;
+       int ret = 0;
+       f = fopen("/sys/class/power_supply/bq27500-0/capacity", "r");
+       if (f) {
+               fscanf(f, "%d", &ret);
+               fclose(f);
+       }
+       return ret;
+}
diff --git a/frontend/plat_pollux.c b/frontend/plat_pollux.c
new file mode 100644 (file)
index 0000000..d710e8f
--- /dev/null
@@ -0,0 +1,551 @@
+/*
+ * (C) GraÅžvydas "notaz" Ignotas, 2009-2011
+ *
+ * This work is licensed under the terms of the GNU GPLv2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#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/fb.h>
+#include <sys/mman.h>
+
+#include "common/input.h"
+#include "common/menu.h"
+#include "warm/warm.h"
+#include "plugin_lib.h"
+#include "cspace.h"
+#include "main.h"
+#include "menu.h"
+#include "plat.h"
+
+static int fbdev = -1, memdev = -1, battdev = -1;
+static volatile unsigned short *memregs;
+static volatile unsigned int   *memregl;
+static void *fb_vaddrs[2];
+static unsigned int fb_paddrs[2];
+static int fb_work_buf;
+static int cpu_clock_allowed;
+
+static unsigned short *psx_vram;
+static unsigned int psx_vram_padds[512];
+static int psx_offset, psx_step, psx_width, psx_height, psx_bpp;
+static int fb_offset;
+
+// TODO: get rid of this
+struct vout_fbdev;
+struct vout_fbdev *layer_fb;
+int g_layer_x, g_layer_y, g_layer_w, g_layer_h;
+
+int omap_enable_layer(int enabled)
+{
+       return 0;
+}
+
+static void *fb_flip(void)
+{
+       memregl[0x406C>>2] = fb_paddrs[fb_work_buf];
+       memregl[0x4058>>2] |= 0x10;
+       fb_work_buf ^= 1;
+       return fb_vaddrs[fb_work_buf];
+}
+
+static void pollux_changemode(int bpp, int is_bgr)
+{
+       int code = 0, bytes = 2;
+       unsigned int r;
+
+       printf("changemode: %dbpp %s\n", bpp, is_bgr ? "bgr" : "rgb");
+
+       memregl[0x4004>>2] = 0x00ef013f;
+       memregl[0x4000>>2] |= 1 << 3;
+
+       switch (bpp)
+       {
+               case 8:
+                       code = 0x443a;
+                       bytes = 1;
+                       break;
+               case 16:
+                       code = is_bgr ? 0xc342 : 0x4432;
+                       bytes = 2;
+                       break;
+               case 24:
+                       code = is_bgr ? 0xc653 : 0x4653;
+                       bytes = 3;
+                       break;
+               default:
+                       printf("unhandled bpp request: %d\n", bpp);
+                       return;
+       }
+
+       memregl[0x405c>>2] = bytes;
+       memregl[0x4060>>2] = 320 * bytes;
+
+       r = memregl[0x4058>>2];
+       r = (r & 0xffff) | (code << 16) | 0x10;
+       memregl[0x4058>>2] = r;
+}
+
+/* note: both PLLs are programmed the same way,
+ * the databook incorrectly states that PLL1 differs */
+static int decode_pll(unsigned int reg)
+{
+       long long v;
+       int p, m, s;
+
+       p = (reg >> 18) & 0x3f;
+       m = (reg >> 8) & 0x3ff;
+       s = reg & 0xff;
+
+       if (p == 0)
+               p = 1;
+
+       v = 27000000; // master clock
+       v = v * m / (p << s);
+       return v;
+}
+
+int plat_cpu_clock_get(void)
+{
+       return decode_pll(memregl[0xf004>>2]) / 1000000;
+}
+
+int plat_cpu_clock_apply(int mhz)
+{
+       int adiv, mdiv, pdiv, sdiv = 0;
+       int i, vf000, vf004;
+
+       if (!cpu_clock_allowed)
+               return -1;
+       if (mhz == plat_cpu_clock_get())
+               return 0;
+
+       // m = MDIV, p = PDIV, s = SDIV
+       #define SYS_CLK_FREQ 27
+       pdiv = 9;
+       mdiv = (mhz * pdiv) / SYS_CLK_FREQ;
+       if (mdiv & ~0x3ff)
+               return -1;
+       vf004 = (pdiv<<18) | (mdiv<<8) | sdiv;
+
+       // attempt to keep the AHB divider close to 250, but not higher
+       for (adiv = 1; mhz / adiv > 250; adiv++)
+               ;
+
+       vf000 = memregl[0xf000>>2];
+       vf000 = (vf000 & ~0x3c0) | ((adiv - 1) << 6);
+       memregl[0xf000>>2] = vf000;
+       memregl[0xf004>>2] = vf004;
+       memregl[0xf07c>>2] |= 0x8000;
+       for (i = 0; (memregl[0xf07c>>2] & 0x8000) && i < 0x100000; i++)
+               ;
+
+       printf("clock set to %dMHz, AHB set to %dMHz\n", mhz, mhz / adiv);
+
+       // stupid pll share hack - must restart audio
+       extern long SPUopen(void);
+       extern long SPUclose(void);
+       SPUclose();
+       SPUopen();
+
+       return 0;
+}
+
+int plat_get_bat_capacity(void)
+{
+       unsigned short magic_val = 0;
+
+       if (battdev < 0)
+               return -1;
+       if (read(battdev, &magic_val, sizeof(magic_val)) != sizeof(magic_val))
+               return -1;
+       switch (magic_val) {
+       default:
+       case 1: return 100;
+       case 2: return 66;
+       case 3: return 40;
+       case 4: return 0;
+       }
+}
+
+#define TIMER_BASE3 0x1980
+#define TIMER_REG(x) memregl[(TIMER_BASE3 + x) >> 2]
+
+static __attribute__((unused)) unsigned int timer_get(void)
+{
+       TIMER_REG(0x08) |= 0x48;  /* run timer, latch value */
+       return TIMER_REG(0);
+}
+
+static void timer_cleanup(void)
+{
+       TIMER_REG(0x40) = 0x0c; /* be sure clocks are on */
+       TIMER_REG(0x08) = 0x23; /* stop the timer, clear irq in case it's pending */
+       TIMER_REG(0x00) = 0;    /* clear counter */
+       TIMER_REG(0x40) = 0;    /* clocks off */
+       TIMER_REG(0x44) = 0;    /* dividers back to default */
+}
+
+void plat_video_menu_enter(int is_rom_loaded)
+{
+       if (pl_vout_buf != NULL) {
+               if (psx_bpp == 16)
+                       // have to do rgb conversion for menu bg
+                       bgr555_to_rgb565(pl_vout_buf, pl_vout_buf, 320*240*2);
+               else
+                       memset(pl_vout_buf, 0, 320*240*2);
+       }
+
+       pollux_changemode(16, 0);
+}
+
+void plat_video_menu_begin(void)
+{
+}
+
+void plat_video_menu_end(void)
+{
+       g_menuscreen_ptr = fb_flip();
+}
+
+void plat_video_menu_leave(void)
+{
+       pollux_changemode(psx_bpp, 1);
+       if (psx_vram == NULL) {
+               fprintf(stderr, "GPU plugin did not provide vram\n");
+               exit(1);
+       }
+
+       in_set_config_int(in_name_to_id("evdev:pollux-analog"),
+                       IN_CFG_ABS_DEAD_ZONE, analog_deadzone);
+}
+
+static void pl_vout_set_raw_vram(void *vram)
+{
+       int i;
+
+       psx_vram = vram;
+
+       if (vram == NULL)
+               return;
+
+       if ((long)psx_vram & 0x7ff)
+               fprintf(stderr, "GPU plugin did not align vram\n");
+
+       for (i = 0; i < 512; i++) {
+               psx_vram[i * 1024] = 0; // touch
+               psx_vram_padds[i] = warm_virt2phys(&psx_vram[i * 1024]);
+       }
+}
+
+static void *pl_vout_set_mode(int w, int h, int bpp)
+{
+       static int old_w, old_h, old_bpp;
+       int fboff_w, fboff_h;
+       int poff_w, poff_h;
+
+       if (!w || !h || !bpp || (w == old_w && h == old_h && bpp == old_bpp))
+               return NULL;
+
+       printf("psx mode: %dx%d@%d\n", w, h, bpp);
+
+       psx_step = 1;
+       if (h > 256) {
+               psx_step = 2;
+               h /= 2;
+       }
+
+       poff_w = poff_h = 0;
+       if (w > 320) {
+               poff_w = w / 2 - 320/2;
+               w = 320;
+       }
+       if (h > 240) {
+               poff_h = h / 2 - 240/2;
+               h = 240;
+       }
+       fboff_w = 320/2 - w / 2;
+       fboff_h = 240/2 - h / 2;
+
+       psx_offset = poff_h * 1024 + poff_w;
+       psx_width = w;
+       psx_height = h;
+       psx_bpp = bpp;
+       fb_offset = fboff_h * 320 + fboff_w;
+
+       pollux_changemode(bpp, 1);
+
+       return NULL;
+}
+
+static void spend_cycles(int loops)
+{
+       asm volatile (
+               "   mov  r0,%0    ;\n"
+               "0: subs r0,r0,#1 ;\n"
+               "   bgt  0b"
+               :: "r" (loops) : "cc", "r0");
+}
+
+#define DMA_BASE6 0x0300
+#define DMA_REG(x) memregl[(DMA_BASE6 + x) >> 2]
+
+/* this takes ~1.5ms, while ldm/stm ~1.95ms */
+static void raw_flip_dma(int x, int y)
+{
+       unsigned int dst = fb_paddrs[fb_work_buf] + fb_offset * psx_bpp / 8;
+       int spsx_line = y + (psx_offset >> 10);
+       int spsx_offset = (x + psx_offset) & 0x3f8;
+       int dst_stride = 320 * psx_bpp / 8;
+       int len = psx_width * psx_bpp / 8;
+       //unsigned int st = timer_get();
+       int i;
+
+       warm_cache_op_all(WOP_D_CLEAN);
+
+       dst &= ~7;
+       len &= ~7;
+
+       if (DMA_REG(0x0c) & 0x90000) {
+               printf("already runnig DMA?\n");
+               DMA_REG(0x0c) = 0x100000;
+       }
+       if ((DMA_REG(0x2c) & 0x0f) < 5) {
+               printf("DMA queue busy?\n");
+               DMA_REG(0x24) = 1;
+       }
+
+       for (i = psx_height; i > 0; i--, spsx_line += psx_step, dst += dst_stride) {
+               while ((DMA_REG(0x2c) & 0x0f) < 4)
+                       spend_cycles(10);
+
+               // XXX: it seems we must always set all regs, what is autoincrement there for?
+               DMA_REG(0x20) = 1;              // queue wait cmd
+               DMA_REG(0x10) = psx_vram_padds[spsx_line & 511] + spsx_offset * 2; // DMA src
+               DMA_REG(0x14) = dst;            // DMA dst
+               DMA_REG(0x18) = len - 1;        // len
+               DMA_REG(0x1c) = 0x80000;        // go
+       }
+
+       //printf("d %d\n", timer_get() - st);
+
+       if (psx_bpp == 16) {
+               pl_vout_buf = g_menuscreen_ptr;
+               pl_print_hud(psx_width, psx_height);
+       }
+
+       g_menuscreen_ptr = fb_flip();
+       pl_flip_cnt++;
+}
+
+static void raw_flip_soft(int x, int y)
+{
+       unsigned short *src = psx_vram + y * 1024 + x + psx_offset;
+       unsigned char *dst = (unsigned char *)g_menuscreen_ptr + fb_offset * psx_bpp / 8;
+       int dst_stride = 320 * psx_bpp / 8;
+       int len = psx_width * psx_bpp / 8;
+       //unsigned int st = timer_get();
+       int i;
+
+       for (i = psx_height; i > 0; i--, src += psx_step * 1024, dst += dst_stride)
+               memcpy(dst, src, len);
+
+       //printf("s %d\n", timer_get() - st);
+
+       if (psx_bpp == 16) {
+               pl_vout_buf = g_menuscreen_ptr;
+               pl_print_hud(psx_width, psx_height);
+       }
+
+       g_menuscreen_ptr = fb_flip();
+       pl_flip_cnt++;
+}
+
+void plat_init(void)
+{
+       const char *main_fb_name = "/dev/fb0";
+       struct fb_fix_screeninfo fbfix;
+       int rate, timer_div, timer_div2;
+       int fbdev, ret, warm_ret;
+
+       memdev = open("/dev/mem", O_RDWR);
+       if (memdev == -1) {
+               perror("open(/dev/mem) failed");
+               exit(1);
+       }
+
+       memregs = mmap(0, 0x20000, PROT_READ|PROT_WRITE, MAP_SHARED, memdev, 0xc0000000);
+       if (memregs == MAP_FAILED) {
+               perror("mmap(memregs) failed");
+               exit(1);
+       }
+       memregl = (volatile void *)memregs;
+
+       fbdev = open(main_fb_name, O_RDWR);
+       if (fbdev == -1) {
+               fprintf(stderr, "%s: ", main_fb_name);
+               perror("open");
+               exit(1);
+       }
+
+       ret = ioctl(fbdev, FBIOGET_FSCREENINFO, &fbfix);
+       if (ret == -1) {
+               perror("ioctl(fbdev) failed");
+               exit(1);
+       }
+       printf("framebuffer: \"%s\" @ %08lx\n", fbfix.id, fbfix.smem_start);
+       fb_paddrs[0] = fbfix.smem_start;
+       fb_paddrs[1] = fb_paddrs[0] + 320*240*4; // leave space for 24bpp
+
+       fb_vaddrs[0] = mmap(0, 320*240*2*4, PROT_READ|PROT_WRITE,
+                               MAP_SHARED, memdev, fb_paddrs[0]);
+       if (fb_vaddrs[0] == MAP_FAILED) {
+               perror("mmap(fb_vaddrs) failed");
+               exit(1);
+       }
+       fb_vaddrs[1] = (char *)fb_vaddrs[0] + 320*240*4;
+
+       pollux_changemode(16, 0);
+       g_menuscreen_w = 320;
+       g_menuscreen_h = 240;
+       g_menuscreen_ptr = fb_flip();
+
+       g_menubg_ptr = calloc(320*240*2, 1);
+       if (g_menubg_ptr == NULL) {
+               fprintf(stderr, "OOM\n");
+               exit(1);
+       }
+
+       warm_ret = warm_init();
+       warm_change_cb_upper(WCB_B_BIT, 1);
+
+       /* some firmwares have sys clk on PLL0, we can't adjust CPU clock
+        * by reprogramming the PLL0 then, as it overclocks system bus */
+       if ((memregl[0xf000>>2] & 0x03000030) == 0x01000000)
+               cpu_clock_allowed = 1;
+       else {
+               cpu_clock_allowed = 0;
+               fprintf(stderr, "unexpected PLL config (%08x), overclocking disabled\n",
+                       memregl[0xf000>>2]);
+       }
+
+       /* find what PLL1 runs at, for the timer */
+       rate = decode_pll(memregl[0xf008>>2]);
+       printf("PLL1 @ %dHz\n", rate);
+
+       /* setup timer */
+       timer_div = (rate + 500000) / 1000000;
+       timer_div2 = 0;
+       while (timer_div > 256) {
+               timer_div /= 2;
+               timer_div2++;
+       }
+       if (1 <= timer_div && timer_div <= 256 && timer_div2 < 4) {
+               int timer_rate = (rate >> timer_div2) / timer_div;
+               if (TIMER_REG(0x08) & 8) {
+                       fprintf(stderr, "warning: timer in use, overriding!\n");
+                       timer_cleanup();
+               }
+               if (timer_rate != 1000000)
+                       fprintf(stderr, "warning: timer drift %d us\n", timer_rate - 1000000);
+
+               timer_div2 = (timer_div2 + 3) & 3;
+               TIMER_REG(0x44) = ((timer_div - 1) << 4) | 2;   /* using PLL1 */
+               TIMER_REG(0x40) = 0x0c;                         /* clocks on */
+               TIMER_REG(0x08) = 0x68 | timer_div2;            /* run timer, clear irq, latch value */
+       }
+       else
+               fprintf(stderr, "warning: could not make use of timer\n");
+
+       /* setup DMA */
+       DMA_REG(0x0c) = 0x20000; // pending IRQ clear
+
+       battdev = open("/dev/pollux_batt", O_RDONLY);
+       if (battdev < 0)
+               perror("Warning: could't open pollux_batt");
+
+       // hmh
+       plat_rescan_inputs();
+
+       pl_rearmed_cbs.pl_vout_raw_flip = warm_ret == 0 ? raw_flip_dma : raw_flip_soft;
+       pl_rearmed_cbs.pl_vout_set_mode = pl_vout_set_mode;
+       pl_rearmed_cbs.pl_vout_set_raw_vram = pl_vout_set_raw_vram;
+
+       psx_width = 320;
+       psx_height = 240;
+       psx_bpp = 16;
+}
+
+void plat_finish(void)
+{
+       warm_finish();
+       timer_cleanup();
+       pollux_changemode(16, 0);
+       fb_work_buf = 0;
+       fb_flip();
+
+       if (battdev >= 0)
+               close(battdev);
+       munmap(fb_vaddrs[0], 320*240*2*2);
+       close(fbdev);
+       munmap((void *)memregs, 0x20000);
+       close(memdev);
+}
+
+void in_update_analogs(void)
+{
+}
+
+/* Caanoo stuff, perhaps move later */
+#include <linux/input.h>
+
+struct in_default_bind in_evdev_defbinds[] = {
+       { KEY_UP,       IN_BINDTYPE_PLAYER12, DKEY_UP },
+       { KEY_DOWN,     IN_BINDTYPE_PLAYER12, DKEY_DOWN },
+       { KEY_LEFT,     IN_BINDTYPE_PLAYER12, DKEY_LEFT },
+       { KEY_RIGHT,    IN_BINDTYPE_PLAYER12, DKEY_RIGHT },
+       { BTN_TOP,      IN_BINDTYPE_PLAYER12, DKEY_TRIANGLE },
+       { BTN_THUMB,    IN_BINDTYPE_PLAYER12, DKEY_CROSS },
+       { BTN_THUMB2,   IN_BINDTYPE_PLAYER12, DKEY_CIRCLE },
+       { BTN_TRIGGER,  IN_BINDTYPE_PLAYER12, DKEY_SQUARE },
+       { BTN_BASE3,    IN_BINDTYPE_PLAYER12, DKEY_START },
+       { BTN_BASE4,    IN_BINDTYPE_PLAYER12, DKEY_SELECT },
+       { BTN_TOP2,     IN_BINDTYPE_PLAYER12, DKEY_L1 },
+       { BTN_PINKIE,   IN_BINDTYPE_PLAYER12, DKEY_R1 },
+       { BTN_BASE,     IN_BINDTYPE_EMU, SACTION_ENTER_MENU },
+       { 0, 0, 0 },
+};
+
+static const char * const caanoo_keys[KEY_MAX + 1] = {
+       [0 ... KEY_MAX] = NULL,
+       [KEY_UP]        = "Up",
+       [KEY_LEFT]      = "Left",
+       [KEY_RIGHT]     = "Right",
+       [KEY_DOWN]      = "Down",
+       [BTN_TRIGGER]   = "A",
+       [BTN_THUMB]     = "X",
+       [BTN_THUMB2]    = "B",
+       [BTN_TOP]       = "Y",
+       [BTN_TOP2]      = "L",
+       [BTN_PINKIE]    = "R",
+       [BTN_BASE]      = "Home",
+       [BTN_BASE2]     = "Lock",
+       [BTN_BASE3]     = "I",
+       [BTN_BASE4]     = "II",
+       [BTN_BASE5]     = "Push",
+};
+
+int plat_rescan_inputs(void)
+{
+       in_probe();
+       in_set_config(in_name_to_id("evdev:pollux-analog"), IN_CFG_KEY_NAMES,
+                     caanoo_keys, sizeof(caanoo_keys));
+       return 0;
+}
index fe9fad1..c931518 100644 (file)
 int in_type1, in_type2;
 int in_a1[2] = { 127, 127 }, in_a2[2] = { 127, 127 };
 int in_keystate, in_state_gun;
+int pl_flip_cnt;
 static void *ts;
 void *pl_vout_buf;
 static int pl_vout_w, pl_vout_h, pl_vout_bpp;
-static int flip_cnt, vsync_cnt, flips_per_sec, tick_per_sec;
+static int vsync_cnt, flips_per_sec, tick_per_sec;
 static float vsps_cur;
 static int frame_interval, frame_interval1024, vsync_usec_time;
 
@@ -60,26 +61,26 @@ static __attribute__((noinline)) int get_cpu_ticks(void)
        return ret;
 }
 
-static void print_hud(void)
+static void print_msg(int h)
 {
        if (pl_vout_bpp == 16)
-               pl_text_out16(2, pl_vout_h - 10, "%s", hud_msg);
+               pl_text_out16(2, h - 10, "%s", hud_msg);
 }
 
-static void print_fps(void)
+static void print_fps(int h)
 {
        if (pl_vout_bpp == 16)
-               pl_text_out16(2, pl_vout_h - 10, "%2d %4.1f", flips_per_sec, vsps_cur);
+               pl_text_out16(2, h - 10, "%2d %4.1f", flips_per_sec, vsps_cur);
 }
 
-static void print_cpu_usage(void)
+static void print_cpu_usage(int w, int h)
 {
        if (pl_vout_bpp == 16)
-               pl_text_out16(pl_vout_w - 28, pl_vout_h - 10, "%3d", tick_per_sec);
+               pl_text_out16(w - 28, h - 10, "%3d", tick_per_sec);
 }
 
 // draw 192x8 status of 24 sound channels
-static __attribute__((noinline)) void draw_active_chans(void)
+static __attribute__((noinline)) void draw_active_chans(int vout_w, int vout_h)
 {
        extern void spu_get_debug_info(int *chans_out, int *run_chans,
                int *fmod_chans_out, int *noise_chans_out); // hack
@@ -87,7 +88,7 @@ static __attribute__((noinline)) void draw_active_chans(void)
 
        static const unsigned short colors[2] = { 0x1fe3, 0x0700 };
        unsigned short *dest = (unsigned short *)pl_vout_buf +
-               pl_vout_w * (pl_vout_h - 10) + pl_vout_w / 2 - 192/2;
+               vout_w * (vout_h - 10) + vout_w / 2 - 192/2;
        unsigned short *d, p;
        int c, x, y;
 
@@ -102,12 +103,29 @@ static __attribute__((noinline)) void draw_active_chans(void)
                     (fmod_chans & (1<<c)) ? 0xf000 :
                     (noise_chans & (1<<c)) ? 0x001f :
                     colors[c & 1];
-               for (y = 0; y < 8; y++, d += pl_vout_w)
+               for (y = 0; y < 8; y++, d += vout_w)
                        for (x = 0; x < 8; x++)
                                d[x] = p;
        }
 }
 
+void pl_print_hud(int w, int h)
+{
+       pl_vout_w = w; // used by pollux
+       pl_vout_h = h;
+
+       if (g_opts & OPT_SHOWSPU)
+               draw_active_chans(w, h);
+
+       if (hud_msg[0] != 0)
+               print_msg(h);
+       else if (g_opts & OPT_SHOWFPS)
+               print_fps(h);
+
+       if (g_opts & OPT_SHOWCPU)
+               print_cpu_usage(w, h);
+}
+
 static void *pl_vout_set_mode(int w, int h, int bpp)
 {
        // special h handling, Wipeout likes to change it by 1-6
@@ -143,20 +161,10 @@ static void *pl_vout_set_mode(int w, int h, int bpp)
 
 static void *pl_vout_flip(void)
 {
-       flip_cnt++;
-
-       if (pl_vout_buf != NULL) {
-               if (g_opts & OPT_SHOWSPU)
-                       draw_active_chans();
-
-               if (hud_msg[0] != 0)
-                       print_hud();
-               else if (g_opts & OPT_SHOWFPS)
-                       print_fps();
+       pl_flip_cnt++;
 
-               if (g_opts & OPT_SHOWCPU)
-                       print_cpu_usage();
-       }
+       if (pl_vout_buf != NULL)
+               pl_print_hud(pl_vout_w, pl_vout_h);
 
        // let's flip now
 #if defined(VOUT_FBDEV)
@@ -275,8 +283,8 @@ void pl_frame_limit(void)
                if (0 < diff && diff < 2000000)
                        vsps_cur = 1000000.0f * (vsync_cnt - vsync_cnt_prev) / diff;
                vsync_cnt_prev = vsync_cnt;
-               flips_per_sec = flip_cnt;
-               flip_cnt = 0;
+               flips_per_sec = pl_flip_cnt;
+               pl_flip_cnt = 0;
                tv_old = now;
                if (g_opts & OPT_SHOWCPU)
                        tick_per_sec = get_cpu_ticks();
index 2a6c085..c327348 100644 (file)
@@ -22,11 +22,13 @@ extern int in_keystate, in_state_gun, in_a1[2], in_a2[2];
 void in_update_analogs(void);
 
 extern void *pl_vout_buf;
+extern int pl_flip_cnt;
 
 void  pl_text_out16(int x, int y, const char *texto, ...);
 void  pl_start_watchdog(void);
 void *pl_prepare_screenshot(int *w, int *h, int *bpp);
 void  pl_init(void);
+void  pl_print_hud(int w, int h);
 
 void  pl_timing_prepare(int is_pal);
 void  pl_frame_limit(void);
@@ -39,6 +41,9 @@ struct rearmed_cbs {
        void *(*pl_vout_set_mode)(int w, int h, int bpp);
        void *(*pl_vout_flip)(void);
        void  (*pl_vout_close)(void);
+       // these are only used by some frontends
+       void  (*pl_vout_raw_flip)(int x, int y);
+       void  (*pl_vout_set_raw_vram)(void *vram);
        // gpu options
        int   frameskip;
        int   fskip_advice;
diff --git a/frontend/warm b/frontend/warm
new file mode 160000 (submodule)
index 0000000..c682a39
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit c682a397f4a09a7e9e29fee12ec5101a4284d452
index 7f80724..8814da8 100644 (file)
@@ -80,7 +80,10 @@ void DoBufferSwap(void)
  }
 
  pcnt_start(PCNT_BLIT);
- blit(vout_buf);
+ if (rcbs->pl_vout_raw_flip != NULL)
+  rcbs->pl_vout_raw_flip(PSXDisplay.DisplayPosition.x, PSXDisplay.DisplayPosition.y);
+ else
+  blit(vout_buf);
  pcnt_end(PCNT_BLIT);
 
  vout_buf = rcbs->pl_vout_flip();
index b5fdd97..f9a49bb 100644 (file)
@@ -23,7 +23,6 @@
 // memory image of the PSX vram 
 ////////////////////////////////////////////////////////////////////////
 
-unsigned char  *psxVSecure;
 unsigned char  *psxVub;
 signed   char  *psxVsb;
 unsigned short *psxVuw;
@@ -88,16 +87,15 @@ static void SetFixes(void)
 // INIT, will be called after lib load... well, just do some var init...
 ////////////////////////////////////////////////////////////////////////
 
+// one extra MB for soft drawing funcs security
+static unsigned char vram[1024*512*2 + 1024*1024] __attribute__((aligned(2048)));
+
 long CALLBACK GPUinit(void)                                // GPU INIT
 {
  memset(ulStatusControl,0,256*sizeof(uint32_t));  // init save state scontrol field
 
- psxVSecure = (unsigned char *)malloc((512*2)*1024 + (1024*1024)); // always alloc one extra MB for soft drawing funcs security
- if (!psxVSecure)
-  return -1;
-
  //!!! ATTENTION !!!
- psxVub=psxVSecure + 512 * 1024;                           // security offset into double sized psx vram!
+ psxVub=vram + 512 * 1024;                           // security offset into double sized psx vram!
 
  psxVsb=(signed char *)psxVub;                         // different ways of accessing PSX VRAM
  psxVsw=(signed short *)psxVub;
@@ -107,7 +105,7 @@ long CALLBACK GPUinit(void)                                // GPU INIT
 
  psxVuw_eom=psxVuw+1024*512;                    // pre-calc of end of vram
 
- memset(psxVSecure,0x00,(512*2)*1024 + (1024*1024));
+ memset(vram,0x00,(512*2)*1024 + (1024*1024));
  memset(lGPUInfoVals,0x00,16*sizeof(uint32_t));
 
  PSXDisplay.RGB24        = FALSE;                      // init some stuff
@@ -185,7 +183,6 @@ long CALLBACK GPUclose()                               // GPU CLOSE
 long CALLBACK GPUshutdown(void)                            // GPU SHUTDOWN
 {
  CloseDisplay();                                       // shutdown direct draw
- free(psxVSecure);
  return 0;                                             // nothinh to do
 }
 
@@ -1150,6 +1147,8 @@ void GPUrearmedCallbacks(const struct rearmed_cbs *cbs)
  dwActFixes = cbs->gpu_peops.dwActFixes;
  fFrameRateHz = cbs->gpu_peops.fFrameRateHz;
  dwFrameRateTicks = cbs->gpu_peops.dwFrameRateTicks;
+ if (cbs->pl_vout_set_raw_vram)
+  cbs->pl_vout_set_raw_vram(psxVub);
 
  skip_advice = &cbs->fskip_advice;
  fps_skip = 100.0f;
index 80f82ae..531c9fb 100644 (file)
@@ -7,7 +7,16 @@ endif
 ifdef MAEMO
 CFLAGS += -DMAEMO
 endif
+ARM_CORTEXA8 ?= 1
+ifeq "$(ARM_CORTEXA8)" "1"
 CFLAGS += -mcpu=cortex-a8 -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp
+SRC += ../../frontend/cspace_neon.s
+else
+CFLAGS += -mcpu=arm926ej-s -mtune=arm926ej-s
+SRC += ../../frontend/cspace.c
+endif
+
+SRC += gpu.cpp
 
 TARGET = gpuPCSX4ALL.so
 LDFLAGS += -shared -Wl,-soname,$(TARGET)
@@ -16,7 +25,7 @@ LDFLAGS += -shared -Wl,-soname,$(TARGET)
 
 all: $(TARGET)
 
-$(TARGET): gpu.cpp ../../frontend/cspace_neon.s
+$(TARGET): $(SRC)
        $(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
 
 # $(TARGET): *.h
index fa176d5..a7cf495 100644 (file)
@@ -96,7 +96,7 @@ u32   tInc, tMsk;
 
 GPUPacket PacketBuffer;
 // FRAME_BUFFER_SIZE is defined in bytes; 512K is guard memory for out of range reads
-u16   GPU_FrameBuffer[(FRAME_BUFFER_SIZE+512*1024)/2] __attribute__((aligned(16)));
+u16   GPU_FrameBuffer[(FRAME_BUFFER_SIZE+512*1024)/2] __attribute__((aligned(2048)));
 u32   GPU_GP1;
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -826,10 +826,10 @@ extern "C" {
 
 static const struct rearmed_cbs *cbs;
 static void *screen_buf;
+static s16 old_res_horz, old_res_vert, old_rgb24;
 
 static void blit(void)
 {
-       static s16 old_res_horz, old_res_vert, old_rgb24;
        s16 isRGB24 = (GPU_GP1 & 0x00200000) ? 1 : 0;
        s16 h0, x0, y0, w0, h1;
        u16 *srcs;
@@ -882,6 +882,29 @@ static void blit(void)
        screen_buf = cbs->pl_vout_flip();
 }
 
+static void blit_raw(void)
+{
+       s16 isRGB24 = (GPU_GP1 & 0x00200000) ? 1 : 0;
+       s16 h0, w0, h1;
+
+       w0 = DisplayArea[2];
+       h0 = DisplayArea[3];  // video mode
+       h1 = DisplayArea[5] - DisplayArea[4]; // display needed
+       if (h0 == 480) h1 = Min2(h1*2,480);
+
+       if (h1 <= 0)
+               return;
+
+       if (w0 != old_res_horz || h1 != old_res_vert || isRGB24 != old_rgb24)
+       {
+               old_res_horz = w0;
+               old_res_vert = h1;
+               old_rgb24 = (s16)isRGB24;
+               screen_buf = cbs->pl_vout_set_mode(w0, h1, isRGB24 ? 24 : 16);
+       }
+       cbs->pl_vout_raw_flip(DisplayArea[0], DisplayArea[1]);
+}
+
 void GPU_updateLace(void)
 {
        // Interlace bit toggle
@@ -891,7 +914,10 @@ void GPU_updateLace(void)
                return;
 
        if (!wasSkip) {
-               blit();
+               if (cbs->pl_vout_raw_flip != NULL)
+                       blit_raw();
+               else
+                       blit();
                fb_dirty = false;
                skCount = 0;
        }
@@ -930,6 +956,8 @@ void GPUrearmedCallbacks(const struct rearmed_cbs *cbs_)
        enableAbbeyHack = cbs_->gpu_unai.abe_hack;
        light = !cbs_->gpu_unai.no_light;
        blend = !cbs_->gpu_unai.no_blend;
+       if (cbs_->pl_vout_set_raw_vram)
+               cbs_->pl_vout_set_raw_vram((void *)GPU_FrameBuffer);
 
        cbs = cbs_;
 }