mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
gp2x+wiz binary support, wiz code wip
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@705 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
parent
0d9bf4fcda
commit
ee2a3bdfa5
18 changed files with 911 additions and 95 deletions
19
pico/patch.c
19
pico/patch.c
|
@ -21,10 +21,6 @@
|
||||||
* (of course, that's handled by a different source file :)
|
* (of course, that's handled by a different source file :)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//#include <stdio.h>
|
|
||||||
//#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#include "pico_int.h"
|
#include "pico_int.h"
|
||||||
#include "patch.h"
|
#include "patch.h"
|
||||||
|
|
||||||
|
@ -217,6 +213,12 @@ unsigned int PicoRead16(unsigned int a);
|
||||||
void PicoWrite16(unsigned int a, unsigned short d);
|
void PicoWrite16(unsigned int a, unsigned short d);
|
||||||
|
|
||||||
|
|
||||||
|
/* avoid dependency on newer glibc */
|
||||||
|
static int isspace_(int c)
|
||||||
|
{
|
||||||
|
return (0x09 <= c && c <= 0x0d) || c == ' ';
|
||||||
|
}
|
||||||
|
|
||||||
void PicoPatchUnload(void)
|
void PicoPatchUnload(void)
|
||||||
{
|
{
|
||||||
if (PicoPatches != NULL)
|
if (PicoPatches != NULL)
|
||||||
|
@ -248,7 +250,8 @@ int PicoPatchLoad(const char *fname)
|
||||||
|
|
||||||
llen = strlen(buff);
|
llen = strlen(buff);
|
||||||
for (clen = 0; clen < llen; clen++)
|
for (clen = 0; clen < llen; clen++)
|
||||||
if (isspace(buff[clen])) break;
|
if (isspace_(buff[clen]))
|
||||||
|
break;
|
||||||
buff[clen] = 0;
|
buff[clen] = 0;
|
||||||
|
|
||||||
if (clen > 11 || clen < 8)
|
if (clen > 11 || clen < 8)
|
||||||
|
@ -271,9 +274,11 @@ int PicoPatchLoad(const char *fname)
|
||||||
strcpy(PicoPatches[PicoPatchCount].code, buff);
|
strcpy(PicoPatches[PicoPatchCount].code, buff);
|
||||||
/* strip */
|
/* strip */
|
||||||
for (clen++; clen < llen; clen++)
|
for (clen++; clen < llen; clen++)
|
||||||
if (!isspace(buff[clen])) break;
|
if (!isspace_(buff[clen]))
|
||||||
|
break;
|
||||||
for (llen--; llen > 0; llen--)
|
for (llen--; llen > 0; llen--)
|
||||||
if (!isspace(buff[llen])) break;
|
if (!isspace_(buff[llen]))
|
||||||
|
break;
|
||||||
buff[llen+1] = 0;
|
buff[llen+1] = 0;
|
||||||
strncpy(PicoPatches[PicoPatchCount].name, buff + clen, 51);
|
strncpy(PicoPatches[PicoPatchCount].name, buff + clen, 51);
|
||||||
PicoPatches[PicoPatchCount].name[51] = 0;
|
PicoPatches[PicoPatchCount].name[51] = 0;
|
||||||
|
|
|
@ -451,13 +451,13 @@ static int custom_read(menu_entry *me, const char *var, const char *val)
|
||||||
#ifdef __GP2X__
|
#ifdef __GP2X__
|
||||||
if (strcasecmp(var, "Scaling") != 0) return 0;
|
if (strcasecmp(var, "Scaling") != 0) return 0;
|
||||||
if (strcasecmp(val, "OFF") == 0) {
|
if (strcasecmp(val, "OFF") == 0) {
|
||||||
currentConfig.scaling = 0;
|
currentConfig.scaling = EOPT_SCALE_NONE;
|
||||||
} else if (strcasecmp(val, "hw horizontal") == 0) {
|
} else if (strcasecmp(val, "hw horizontal") == 0) {
|
||||||
currentConfig.scaling = 1;
|
currentConfig.scaling = EOPT_SCALE_HW_H;
|
||||||
} else if (strcasecmp(val, "hw horiz. + vert.") == 0) {
|
} else if (strcasecmp(val, "hw horiz. + vert.") == 0) {
|
||||||
currentConfig.scaling = 2;
|
currentConfig.scaling = EOPT_SCALE_HW_HV;
|
||||||
} else if (strcasecmp(val, "sw horizontal") == 0) {
|
} else if (strcasecmp(val, "sw horizontal") == 0) {
|
||||||
currentConfig.scaling = 3;
|
currentConfig.scaling = EOPT_SCALE_SW_H;
|
||||||
} else
|
} else
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ctype.h> // tolower
|
|
||||||
#ifndef NO_SYNC
|
#ifndef NO_SYNC
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -47,12 +46,13 @@ unsigned char *movie_data = NULL;
|
||||||
static int movie_size = 0;
|
static int movie_size = 0;
|
||||||
|
|
||||||
|
|
||||||
// utilities
|
/* don't use tolower() for easy old glibc binary compatibility */
|
||||||
static void strlwr_(char *string)
|
static void strlwr_(char *string)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
for (p = string; *p; p++)
|
for (p = string; *p; p++)
|
||||||
*p = (char)tolower(*p);
|
if ('A' <= *p && *p <= 'Z')
|
||||||
|
*p += 'a' - 'A';
|
||||||
}
|
}
|
||||||
|
|
||||||
static int try_rfn_cut(char *fname)
|
static int try_rfn_cut(char *fname)
|
||||||
|
@ -621,17 +621,21 @@ int emu_ReadConfig(int game, int no_defaults)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
plat_validate_config();
|
||||||
|
|
||||||
// some sanity checks
|
// some sanity checks
|
||||||
if (currentConfig.CPUclock < 10 || currentConfig.CPUclock > 4096) currentConfig.CPUclock = 200;
|
|
||||||
#ifdef PSP
|
#ifdef PSP
|
||||||
|
/* TODO: mv to plat_validate_config() */
|
||||||
|
if (currentConfig.CPUclock < 10 || currentConfig.CPUclock > 4096) currentConfig.CPUclock = 200;
|
||||||
if (currentConfig.gamma < -4 || currentConfig.gamma > 16) currentConfig.gamma = 0;
|
if (currentConfig.gamma < -4 || currentConfig.gamma > 16) currentConfig.gamma = 0;
|
||||||
if (currentConfig.gamma2 < 0 || currentConfig.gamma2 > 2) currentConfig.gamma2 = 0;
|
if (currentConfig.gamma2 < 0 || currentConfig.gamma2 > 2) currentConfig.gamma2 = 0;
|
||||||
#else
|
|
||||||
if (currentConfig.gamma < 10 || currentConfig.gamma > 300) currentConfig.gamma = 100;
|
|
||||||
#endif
|
#endif
|
||||||
if (currentConfig.volume < 0 || currentConfig.volume > 99) currentConfig.volume = 50;
|
if (currentConfig.volume < 0 || currentConfig.volume > 99)
|
||||||
|
currentConfig.volume = 50;
|
||||||
|
|
||||||
|
if (ret == 0)
|
||||||
|
config_slot_current = config_slot;
|
||||||
|
|
||||||
if (ret == 0) config_slot_current = config_slot;
|
|
||||||
return (ret == 0);
|
return (ret == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,8 +27,16 @@ extern int g_screen_height;
|
||||||
#define EOPT_MMUHACK (1<<4)
|
#define EOPT_MMUHACK (1<<4)
|
||||||
#define EOPT_NO_AUTOSVCFG (1<<5)
|
#define EOPT_NO_AUTOSVCFG (1<<5)
|
||||||
#define EOPT_RAM_TIMINGS (1<<8)
|
#define EOPT_RAM_TIMINGS (1<<8)
|
||||||
|
#define EOPT_A_SN_GAMMA (1<<12)
|
||||||
#define EOPT_PSYNC (1<<13)
|
#define EOPT_PSYNC (1<<13)
|
||||||
|
|
||||||
|
enum {
|
||||||
|
EOPT_SCALE_NONE = 0,
|
||||||
|
EOPT_SCALE_SW_H,
|
||||||
|
EOPT_SCALE_HW_H,
|
||||||
|
EOPT_SCALE_HW_HV,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct _currentConfig_t {
|
typedef struct _currentConfig_t {
|
||||||
// char lastRomFile[512];
|
// char lastRomFile[512];
|
||||||
int EmuOpt; // LSb->MSb: use_sram, show_fps, enable_sound, gzip_saves,
|
int EmuOpt; // LSb->MSb: use_sram, show_fps, enable_sound, gzip_saves,
|
||||||
|
|
|
@ -1443,12 +1443,12 @@ static int menu_loop_adv_options(menu_id id, int keys)
|
||||||
|
|
||||||
static const char *mgn_opt_scaling(menu_id id, int *offs)
|
static const char *mgn_opt_scaling(menu_id id, int *offs)
|
||||||
{
|
{
|
||||||
*offs = -12;
|
*offs = -13;
|
||||||
switch (currentConfig.scaling) {
|
switch (currentConfig.scaling) {
|
||||||
default: return " OFF";
|
default: return " OFF";
|
||||||
case 1: return "hw horizontal";
|
case EOPT_SCALE_HW_H: return " hw horizontal";
|
||||||
case 2: return "hw horiz. + vert.";
|
case EOPT_SCALE_HW_HV: return "hw horiz. + vert";
|
||||||
case 3: return "sw horizontal";
|
case EOPT_SCALE_SW_H: return " sw horizontal";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1462,8 +1462,8 @@ static menu_entry e_menu_gfx_options[] =
|
||||||
{
|
{
|
||||||
mee_range_cust("Scaling", MA_OPT_SCALING, currentConfig.scaling, 0, 3, mgn_opt_scaling),
|
mee_range_cust("Scaling", MA_OPT_SCALING, currentConfig.scaling, 0, 3, mgn_opt_scaling),
|
||||||
mee_range_cust("Gamma correction", MA_OPT2_GAMMA, currentConfig.gamma, 1, 300, mgn_aopt_gamma),
|
mee_range_cust("Gamma correction", MA_OPT2_GAMMA, currentConfig.gamma, 1, 300, mgn_aopt_gamma),
|
||||||
mee_onoff ("A_SN's gamma curve", MA_OPT2_A_SN_GAMMA, currentConfig.EmuOpt, 0x1000),
|
mee_onoff ("A_SN's gamma curve", MA_OPT2_A_SN_GAMMA, currentConfig.EmuOpt, EOPT_A_SN_GAMMA),
|
||||||
mee_onoff ("Perfect vsync", MA_OPT2_VSYNC, currentConfig.EmuOpt, 0x2000),
|
mee_onoff ("Perfect vsync", MA_OPT2_VSYNC, currentConfig.EmuOpt, EOPT_PSYNC),
|
||||||
mee_end,
|
mee_end,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2044,6 +2044,22 @@ void me_update_msg(const char *msg)
|
||||||
|
|
||||||
// ------------ util ------------
|
// ------------ util ------------
|
||||||
|
|
||||||
|
/* wiz for now, probably extend later */
|
||||||
|
void menu_plat_setup(int is_wiz)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!is_wiz)
|
||||||
|
return;
|
||||||
|
|
||||||
|
me_enable(e_menu_adv_options, MA_OPT_ARM940_SOUND, 0);
|
||||||
|
me_enable(e_menu_gfx_options, MA_OPT2_GAMMA, 0);
|
||||||
|
me_enable(e_menu_gfx_options, MA_OPT2_A_SN_GAMMA, 0);
|
||||||
|
|
||||||
|
i = me_id2offset(e_menu_gfx_options, MA_OPT_SCALING);
|
||||||
|
e_menu_gfx_options[i].max = 1; /* only off and sw */
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: rename */
|
/* TODO: rename */
|
||||||
void menu_darken_bg(void *dst, int pixels, int darker)
|
void menu_darken_bg(void *dst, int pixels, int darker)
|
||||||
{
|
{
|
||||||
|
|
|
@ -153,6 +153,7 @@ extern me_bind_action me_ctrl_actions[15];
|
||||||
extern me_bind_action emuctrl_actions[]; // platform code
|
extern me_bind_action emuctrl_actions[]; // platform code
|
||||||
|
|
||||||
void menu_init(void);
|
void menu_init(void);
|
||||||
|
void menu_plat_setup(int is_wiz);
|
||||||
void text_out16(int x, int y, const char *texto, ...);
|
void text_out16(int x, int y, const char *texto, ...);
|
||||||
void me_update_msg(const char *msg);
|
void me_update_msg(const char *msg);
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ int emu_getMainDir(char *dst, int len);
|
||||||
void menu_romload_prepare(const char *rom_name);
|
void menu_romload_prepare(const char *rom_name);
|
||||||
void menu_romload_end(void);
|
void menu_romload_end(void);
|
||||||
|
|
||||||
|
void plat_early_init(void);
|
||||||
void plat_init(void);
|
void plat_init(void);
|
||||||
void plat_finish(void);
|
void plat_finish(void);
|
||||||
|
|
||||||
|
@ -27,6 +28,8 @@ void plat_video_menu_enter(int is_rom_loaded);
|
||||||
void plat_video_menu_begin(void);
|
void plat_video_menu_begin(void);
|
||||||
void plat_video_menu_end(void);
|
void plat_video_menu_end(void);
|
||||||
|
|
||||||
|
void plat_validate_config(void);
|
||||||
|
|
||||||
int plat_is_dir(const char *path);
|
int plat_is_dir(const char *path);
|
||||||
int plat_wait_event(int *fds_hnds, int count, int timeout_ms);
|
int plat_wait_event(int *fds_hnds, int count, int timeout_ms);
|
||||||
void plat_sleep_ms(int ms);
|
void plat_sleep_ms(int ms);
|
||||||
|
|
|
@ -32,20 +32,20 @@ use_cyclone = 1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
DEFINC = -I../.. -I. -DARM -D__GP2X__ -DIN_GP2X # -DBENCHMARK
|
DEFINC = -I../.. -I. -DARM -D__GP2X__ -DIN_GP2X # -DBENCHMARK
|
||||||
COPT_COMMON = -Wall -Winline
|
CFLAGS += -Wall -Winline
|
||||||
COPT_COMMON += -static
|
|
||||||
ifeq ($(DEBUG),)
|
ifeq ($(DEBUG),)
|
||||||
COPT_COMMON += -O3 -ftracer -fstrength-reduce -fomit-frame-pointer -fstrict-aliasing -ffast-math
|
# -ftracer # TODO measure impact
|
||||||
|
CFLAGS += -O3 -fstrength-reduce -fomit-frame-pointer -fstrict-aliasing -ffast-math
|
||||||
else
|
else
|
||||||
COPT_COMMON += -ggdb
|
CFLAGS += -ggdb
|
||||||
endif
|
endif
|
||||||
ifeq "$(profile)" "1"
|
ifeq "$(profile)" "1"
|
||||||
COPT_COMMON += -fprofile-generate
|
CFLAGS += -fprofile-generate
|
||||||
endif
|
endif
|
||||||
ifeq "$(profile)" "2"
|
ifeq "$(profile)" "2"
|
||||||
COPT_COMMON += -fprofile-use
|
CFLAGS += -fprofile-use
|
||||||
endif
|
endif
|
||||||
CFLAGS = $(COPT_COMMON) -mcpu=arm920t -mtune=arm920t
|
CFLAGS += -mcpu=arm920t -mtune=arm920t
|
||||||
SFLAGS = $(CFLAGS)
|
SFLAGS = $(CFLAGS)
|
||||||
ASFLAGS = -mcpu=arm920t -mfloat-abi=soft
|
ASFLAGS = -mcpu=arm920t -mfloat-abi=soft
|
||||||
CC = $(CROSS)gcc
|
CC = $(CROSS)gcc
|
||||||
|
@ -55,7 +55,7 @@ LD = $(CROSS)ld
|
||||||
OBJCOPY = $(CROSS)objcopy
|
OBJCOPY = $(CROSS)objcopy
|
||||||
|
|
||||||
# frontend
|
# frontend
|
||||||
OBJS += main.o soc.o soc_mmsp2.o soc_pollux.o emu.o in_gp2x.o plat.o warm.o
|
OBJS += main.o soc.o soc_mmsp2.o soc_pollux.o pollux_set.o emu.o in_gp2x.o plat.o warm.o
|
||||||
# 940 core control
|
# 940 core control
|
||||||
OBJS += 940ctl.o
|
OBJS += 940ctl.o
|
||||||
|
|
||||||
|
@ -122,22 +122,22 @@ DIRS = platform platform/gp2x platform/linux platform/common pico pico/cd pico/p
|
||||||
pico/carthw/svp zlib unzip cpu cpu/musashi cpu/Cyclone/proj cpu/Cyclone/tools cpu/mz80 cpu/DrZ80
|
pico/carthw/svp zlib unzip cpu cpu/musashi cpu/Cyclone/proj cpu/Cyclone/tools cpu/mz80 cpu/DrZ80
|
||||||
|
|
||||||
|
|
||||||
all: mkdirs PicoDrive.gpe
|
all: mkdirs PicoDrive
|
||||||
|
|
||||||
include ../common/common_arm.mak
|
include ../common/common_arm.mak
|
||||||
|
|
||||||
PicoDrive.gpe : $(OBJS) ../common/helix/$(CROSS)helix-mp3.a
|
PicoDrive : $(OBJS) ../common/helix/$(CROSS)helix-mp3.a
|
||||||
@echo ">>>" $@
|
@echo ">>>" $@
|
||||||
$(CC) -o $@ $(CFLAGS) $^ -lm -lpng -Wl,-Map=PicoDrive.map
|
$(CC) -o $@ $(CFLAGS) $^ -lm -lpng -Wl,-Map=PicoDrive.map
|
||||||
ifeq ($(DEBUG),)
|
ifeq ($(DEBUG),)
|
||||||
$(STRIP) $@
|
$(STRIP) $@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
up: PicoDrive.gpe
|
up: PicoDrive
|
||||||
@cp -v PicoDrive.gpe /mnt/gp2x/mnt/sd/emus/PicoDrive/
|
@cp -v PicoDrive /mnt/gp2x/mnt/sd/emus/PicoDrive/
|
||||||
|
|
||||||
clean: tidy
|
clean: tidy
|
||||||
$(RM) PicoDrive.gpe
|
$(RM) PicoDrive
|
||||||
tidy:
|
tidy:
|
||||||
$(RM) $(OBJS)
|
$(RM) $(OBJS)
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ $(error need VER)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
rel: PicoDrive.gpe code940/pico940_v3.bin readme.txt PicoDrive.man.txt PicoDrive.png ../game_def.cfg
|
rel: PicoDrive PicoDrive.gpe code940/pico940_v3.bin readme.txt PicoDrive.man.txt PicoDrive.png ../game_def.cfg
|
||||||
zip -9 -j ../../PicoDrive_$(VER).zip $^ mmuhack.o
|
zip -9 -j ../../PicoDrive_$(VER).zip $^ mmuhack.o
|
||||||
zip -9 -r ../../PicoDrive_$(VER).zip skin -i \*.png -i \*.txt
|
zip -9 -r ../../PicoDrive_$(VER).zip skin -i \*.png -i \*.txt
|
||||||
mkdir bin_to_cso_mp3
|
mkdir bin_to_cso_mp3
|
||||||
|
|
|
@ -101,12 +101,16 @@ void emu_Init(void)
|
||||||
|
|
||||||
static void scaling_update(void)
|
static void scaling_update(void)
|
||||||
{
|
{
|
||||||
PicoOpt &= ~0x4100;
|
PicoOpt &= ~(POPT_DIS_32C_BORDER|POPT_EN_SOFTSCALE);
|
||||||
switch (currentConfig.scaling) {
|
switch (currentConfig.scaling) {
|
||||||
default: break; // off
|
default:break;
|
||||||
case 1: // hw hor
|
case EOPT_SCALE_HW_H:
|
||||||
case 2: PicoOpt |= 0x0100; break; // hw hor+vert
|
case EOPT_SCALE_HW_HV:
|
||||||
case 3: PicoOpt |= 0x4000; break; // sw hor
|
PicoOpt |= POPT_DIS_32C_BORDER;
|
||||||
|
break;
|
||||||
|
case EOPT_SCALE_SW_H:
|
||||||
|
PicoOpt |= POPT_EN_SOFTSCALE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,19 +137,25 @@ void emu_Deinit(void)
|
||||||
|
|
||||||
void emu_prepareDefaultConfig(void)
|
void emu_prepareDefaultConfig(void)
|
||||||
{
|
{
|
||||||
|
gp2x_soc_t soc;
|
||||||
|
|
||||||
memset(&defaultConfig, 0, sizeof(defaultConfig));
|
memset(&defaultConfig, 0, sizeof(defaultConfig));
|
||||||
defaultConfig.EmuOpt = 0x9d | 0x00700; // | <- ram_tmng, confirm_save, cd_leds
|
defaultConfig.EmuOpt = 0x9d | EOPT_RAM_TIMINGS | 0x600; // | <- confirm_save, cd_leds
|
||||||
defaultConfig.s_PicoOpt = 0x0f | POPT_EXT_FM|POPT_EN_MCD_PCM|POPT_EN_MCD_CDDA|POPT_EN_SVP_DRC|POPT_ACC_SPRITES;
|
defaultConfig.s_PicoOpt = 0x0f | POPT_EN_MCD_PCM|POPT_EN_MCD_CDDA|POPT_EN_SVP_DRC|POPT_ACC_SPRITES;
|
||||||
defaultConfig.s_PsndRate = 44100;
|
defaultConfig.s_PsndRate = 44100;
|
||||||
defaultConfig.s_PicoRegion = 0; // auto
|
defaultConfig.s_PicoRegion = 0; // auto
|
||||||
defaultConfig.s_PicoAutoRgnOrder = 0x184; // US, EU, JP
|
defaultConfig.s_PicoAutoRgnOrder = 0x184; // US, EU, JP
|
||||||
defaultConfig.s_PicoCDBuffers = 0;
|
defaultConfig.s_PicoCDBuffers = 0;
|
||||||
defaultConfig.Frameskip = -1; // auto
|
defaultConfig.Frameskip = -1; // auto
|
||||||
defaultConfig.CPUclock = -1;
|
defaultConfig.CPUclock = default_cpu_clock;
|
||||||
defaultConfig.volume = 50;
|
defaultConfig.volume = 50;
|
||||||
defaultConfig.gamma = 100;
|
defaultConfig.gamma = 100;
|
||||||
defaultConfig.scaling = 0;
|
defaultConfig.scaling = 0;
|
||||||
defaultConfig.turbo_rate = 15;
|
defaultConfig.turbo_rate = 15;
|
||||||
|
|
||||||
|
soc = soc_detect();
|
||||||
|
if (soc == SOCID_MMSP2)
|
||||||
|
defaultConfig.s_PicoOpt |= POPT_EXT_FM;
|
||||||
}
|
}
|
||||||
|
|
||||||
void osd_text(int x, int y, const char *text)
|
void osd_text(int x, int y, const char *text)
|
||||||
|
@ -295,8 +305,10 @@ static void blit(const char *fps, const char *notice)
|
||||||
|
|
||||||
if (notice || (emu_opt & 2)) {
|
if (notice || (emu_opt & 2)) {
|
||||||
int h = 232;
|
int h = 232;
|
||||||
if (currentConfig.scaling == 2 && !(Pico.video.reg[1]&8)) h -= 8;
|
if (currentConfig.scaling == EOPT_SCALE_HW_HV && !(Pico.video.reg[1]&8))
|
||||||
if (notice) osd_text(4, h, notice);
|
h -= 8;
|
||||||
|
if (notice)
|
||||||
|
osd_text(4, h, notice);
|
||||||
if (emu_opt & 2)
|
if (emu_opt & 2)
|
||||||
osd_text(osd_fps_x, h, fps);
|
osd_text(osd_fps_x, h, fps);
|
||||||
}
|
}
|
||||||
|
@ -362,7 +374,7 @@ static void vidResetMode(void)
|
||||||
}
|
}
|
||||||
Pico.m.dirtyPal = 1;
|
Pico.m.dirtyPal = 1;
|
||||||
// reset scaling
|
// reset scaling
|
||||||
if (currentConfig.scaling == 2 && !(Pico.video.reg[1]&8))
|
if (currentConfig.scaling == EOPT_SCALE_HW_HV && !(Pico.video.reg[1]&8))
|
||||||
gp2x_video_RGB_setscaling(8, (PicoOpt&0x100)&&!(Pico.video.reg[12]&1) ? 256 : 320, 224);
|
gp2x_video_RGB_setscaling(8, (PicoOpt&0x100)&&!(Pico.video.reg[12]&1) ? 256 : 320, 224);
|
||||||
else gp2x_video_RGB_setscaling(0, (PicoOpt&0x100)&&!(Pico.video.reg[12]&1) ? 256 : 320, 240);
|
else gp2x_video_RGB_setscaling(0, (PicoOpt&0x100)&&!(Pico.video.reg[12]&1) ? 256 : 320, 240);
|
||||||
}
|
}
|
||||||
|
@ -773,16 +785,13 @@ void emu_Loop(void)
|
||||||
|
|
||||||
if ((EmuOpt_old ^ currentConfig.EmuOpt) & EOPT_RAM_TIMINGS) {
|
if ((EmuOpt_old ^ currentConfig.EmuOpt) & EOPT_RAM_TIMINGS) {
|
||||||
if (currentConfig.EmuOpt & EOPT_RAM_TIMINGS)
|
if (currentConfig.EmuOpt & EOPT_RAM_TIMINGS)
|
||||||
/* craigix: --cas 2 --trc 6 --tras 4 --twr 1 --tmrd 1 --trfc 1 --trp 2 --trcd 2 */
|
set_ram_timings();
|
||||||
set_ram_timings(2, 6, 4, 1, 1, 1, 2, 2);
|
|
||||||
else
|
else
|
||||||
unset_ram_timings();
|
unset_ram_timings();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gp2x_old_clock < 0)
|
if (gp2x_old_clock < 0)
|
||||||
gp2x_old_clock = default_cpu_clock;
|
gp2x_old_clock = default_cpu_clock;
|
||||||
if (currentConfig.CPUclock < 0)
|
|
||||||
currentConfig.CPUclock = default_cpu_clock;
|
|
||||||
if (gp2x_old_clock != currentConfig.CPUclock) {
|
if (gp2x_old_clock != currentConfig.CPUclock) {
|
||||||
printf("changing clock to %i...", currentConfig.CPUclock); fflush(stdout);
|
printf("changing clock to %i...", currentConfig.CPUclock); fflush(stdout);
|
||||||
gp2x_set_cpuclk(currentConfig.CPUclock);
|
gp2x_set_cpuclk(currentConfig.CPUclock);
|
||||||
|
@ -885,7 +894,8 @@ void emu_Loop(void)
|
||||||
vidCpyM2 = vidCpyM2_32col;
|
vidCpyM2 = vidCpyM2_32col;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (currentConfig.scaling == 2 && !(modes&8)) // want vertical scaling and game is not in 240 line mode
|
/* want vertical scaling and game is not in 240 line mode */
|
||||||
|
if (currentConfig.scaling == EOPT_SCALE_HW_HV && !(modes&8))
|
||||||
gp2x_video_RGB_setscaling(8, scalex, 224);
|
gp2x_video_RGB_setscaling(8, scalex, 224);
|
||||||
else gp2x_video_RGB_setscaling(0, scalex, 240);
|
else gp2x_video_RGB_setscaling(0, scalex, 240);
|
||||||
oldmodes = modes;
|
oldmodes = modes;
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "../common/input.h"
|
#include "../common/input.h"
|
||||||
#include "in_gp2x.h"
|
#include "in_gp2x.h"
|
||||||
|
@ -12,6 +17,9 @@
|
||||||
* both must be pressed for action to happen) */
|
* both must be pressed for action to happen) */
|
||||||
static int in_gp2x_combo_keys = 0;
|
static int in_gp2x_combo_keys = 0;
|
||||||
static int in_gp2x_combo_acts = 0;
|
static int in_gp2x_combo_acts = 0;
|
||||||
|
static int gpiodev = -1; /* Wiz only */
|
||||||
|
|
||||||
|
static int (*in_gp2x_get_bits)(void);
|
||||||
|
|
||||||
enum { BTN_UP = 0, BTN_LEFT = 2, BTN_DOWN = 4, BTN_RIGHT = 6,
|
enum { BTN_UP = 0, BTN_LEFT = 2, BTN_DOWN = 4, BTN_RIGHT = 6,
|
||||||
BTN_START = 8, BTN_SELECT = 9, BTN_L = 10, BTN_R = 11,
|
BTN_START = 8, BTN_SELECT = 9, BTN_L = 10, BTN_R = 11,
|
||||||
|
@ -28,18 +36,48 @@ static const char * const in_gp2x_keys[IN_GP2X_NBUTTONS] = {
|
||||||
[BTN_PUSH] = "PUSH"
|
[BTN_PUSH] = "PUSH"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int in_gp2x_get_mmsp2_bits(void);
|
||||||
|
static int in_gp2x_get_wiz_bits(void);
|
||||||
|
|
||||||
static void in_gp2x_probe(void)
|
static void in_gp2x_probe(void)
|
||||||
{
|
{
|
||||||
|
gp2x_soc_t soc;
|
||||||
|
|
||||||
|
soc = soc_detect();
|
||||||
|
switch (soc)
|
||||||
|
{
|
||||||
|
case SOCID_MMSP2:
|
||||||
|
in_gp2x_get_bits = in_gp2x_get_mmsp2_bits;
|
||||||
|
break;
|
||||||
|
case SOCID_POLLUX:
|
||||||
|
gpiodev = open("/dev/GPIO", O_RDONLY);
|
||||||
|
if (gpiodev < 0) {
|
||||||
|
perror("in_gp2x: couldn't open /dev/GPIO");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
in_gp2x_get_bits = in_gp2x_get_wiz_bits;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
in_register(IN_PREFIX "GP2X pad", IN_DRVID_GP2X, -1, (void *)1, 1);
|
in_register(IN_PREFIX "GP2X pad", IN_DRVID_GP2X, -1, (void *)1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void in_gp2x_free(void *drv_data)
|
||||||
|
{
|
||||||
|
if (gpiodev >= 0) {
|
||||||
|
close(gpiodev);
|
||||||
|
gpiodev = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int in_gp2x_get_bind_count(void)
|
static int in_gp2x_get_bind_count(void)
|
||||||
{
|
{
|
||||||
return IN_GP2X_NBUTTONS;
|
return IN_GP2X_NBUTTONS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int in_gp2x_get_gpio_bits(void)
|
static int in_gp2x_get_mmsp2_bits(void)
|
||||||
{
|
{
|
||||||
#ifndef FAKE_IN_GP2X
|
#ifndef FAKE_IN_GP2X
|
||||||
extern volatile unsigned short *gp2x_memregs;
|
extern volatile unsigned short *gp2x_memregs;
|
||||||
|
@ -60,12 +98,38 @@ static int in_gp2x_get_gpio_bits(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int in_gp2x_get_wiz_bits(void)
|
||||||
|
{
|
||||||
|
int value = 0;
|
||||||
|
read(gpiodev, &value, 4);
|
||||||
|
if (value & 0x02)
|
||||||
|
value |= 0x05;
|
||||||
|
if (value & 0x08)
|
||||||
|
value |= 0x14;
|
||||||
|
if (value & 0x20)
|
||||||
|
value |= 0x50;
|
||||||
|
if (value & 0x80)
|
||||||
|
value |= 0x41;
|
||||||
|
|
||||||
|
/* convert to GP2X style */
|
||||||
|
value &= 0x7ff55;
|
||||||
|
if (value & (1 << 16))
|
||||||
|
value |= 1 << BTN_VOL_UP;
|
||||||
|
if (value & (1 << 17))
|
||||||
|
value |= 1 << BTN_VOL_DOWN;
|
||||||
|
if (value & (1 << 18))
|
||||||
|
value |= 1 << BTN_PUSH;
|
||||||
|
value &= ~0x70000;
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
/* returns bitfield of binds of pressed buttons */
|
/* returns bitfield of binds of pressed buttons */
|
||||||
int in_gp2x_update(void *drv_data, int *binds)
|
int in_gp2x_update(void *drv_data, int *binds)
|
||||||
{
|
{
|
||||||
int i, keys, ret = 0;
|
int i, keys, ret = 0;
|
||||||
|
|
||||||
keys = in_gp2x_get_gpio_bits();
|
keys = in_gp2x_get_bits();
|
||||||
|
|
||||||
if (keys & in_gp2x_combo_keys)
|
if (keys & in_gp2x_combo_keys)
|
||||||
return in_combos_do(keys, binds, BTN_PUSH, in_gp2x_combo_keys, in_gp2x_combo_acts);
|
return in_combos_do(keys, binds, BTN_PUSH, in_gp2x_combo_keys, in_gp2x_combo_acts);
|
||||||
|
@ -84,7 +148,7 @@ int in_gp2x_update_keycode(void *data, int *is_down)
|
||||||
static int old_val = 0;
|
static int old_val = 0;
|
||||||
int val, diff, i;
|
int val, diff, i;
|
||||||
|
|
||||||
val = in_gp2x_get_gpio_bits();
|
val = in_gp2x_get_bits();
|
||||||
diff = val ^ old_val;
|
diff = val ^ old_val;
|
||||||
if (diff == 0)
|
if (diff == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -238,6 +302,7 @@ void in_gp2x_init(void *vdrv)
|
||||||
|
|
||||||
drv->prefix = in_gp2x_prefix;
|
drv->prefix = in_gp2x_prefix;
|
||||||
drv->probe = in_gp2x_probe;
|
drv->probe = in_gp2x_probe;
|
||||||
|
drv->free = in_gp2x_free;
|
||||||
drv->get_bind_count = in_gp2x_get_bind_count;
|
drv->get_bind_count = in_gp2x_get_bind_count;
|
||||||
drv->get_def_binds = in_gp2x_get_def_binds;
|
drv->get_def_binds = in_gp2x_get_def_binds;
|
||||||
drv->clean_binds = in_gp2x_clean_binds;
|
drv->clean_binds = in_gp2x_clean_binds;
|
||||||
|
|
|
@ -66,6 +66,8 @@ int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
g_argv = argv;
|
g_argv = argv;
|
||||||
|
|
||||||
|
plat_early_init();
|
||||||
|
|
||||||
/* in_init() must go before config, config accesses in_ fwk */
|
/* in_init() must go before config, config accesses in_ fwk */
|
||||||
in_init();
|
in_init();
|
||||||
emu_prepareDefaultConfig();
|
emu_prepareDefaultConfig();
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#include "../common/emu.h"
|
#include "../common/emu.h"
|
||||||
#include "../linux/sndout_oss.h"
|
#include "../linux/sndout_oss.h"
|
||||||
|
|
||||||
|
#include <pico/pico.h>
|
||||||
|
|
||||||
/* GP2X local */
|
/* GP2X local */
|
||||||
int default_cpu_clock;
|
int default_cpu_clock;
|
||||||
void *gp2x_screens[4];
|
void *gp2x_screens[4];
|
||||||
|
@ -101,6 +103,41 @@ void plat_video_menu_end(void)
|
||||||
gp2x_video_flip2();
|
gp2x_video_flip2();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void plat_validate_config(void)
|
||||||
|
{
|
||||||
|
gp2x_soc_t soc;
|
||||||
|
|
||||||
|
soc = soc_detect();
|
||||||
|
if (soc != SOCID_MMSP2)
|
||||||
|
PicoOpt &= ~POPT_EXT_FM;
|
||||||
|
|
||||||
|
if (currentConfig.gamma < 10 || currentConfig.gamma > 300)
|
||||||
|
currentConfig.gamma = 100;
|
||||||
|
|
||||||
|
if (currentConfig.CPUclock < 10 || currentConfig.CPUclock > 1024)
|
||||||
|
currentConfig.CPUclock = default_cpu_clock;
|
||||||
|
}
|
||||||
|
|
||||||
|
void plat_early_init(void)
|
||||||
|
{
|
||||||
|
gp2x_soc_t soc;
|
||||||
|
|
||||||
|
soc = soc_detect();
|
||||||
|
switch (soc)
|
||||||
|
{
|
||||||
|
case SOCID_MMSP2:
|
||||||
|
default_cpu_clock = 200;
|
||||||
|
break;
|
||||||
|
case SOCID_POLLUX:
|
||||||
|
strcpy(cpu_clk_name, "Wiz CPU clock");
|
||||||
|
default_cpu_clock = 533;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "could not recognize SoC, bailing out.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void plat_init(void)
|
void plat_init(void)
|
||||||
{
|
{
|
||||||
gp2x_soc_t soc;
|
gp2x_soc_t soc;
|
||||||
|
@ -110,16 +147,13 @@ void plat_init(void)
|
||||||
{
|
{
|
||||||
case SOCID_MMSP2:
|
case SOCID_MMSP2:
|
||||||
mmsp2_init();
|
mmsp2_init();
|
||||||
default_cpu_clock = 200;
|
|
||||||
break;
|
break;
|
||||||
case SOCID_POLLUX:
|
case SOCID_POLLUX:
|
||||||
pollux_init();
|
pollux_init();
|
||||||
strcpy(cpu_clk_name, "Wiz CPU clock");
|
menu_plat_setup(1);
|
||||||
default_cpu_clock = 533;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "could not recognize SoC, bailing out.\n");
|
break;
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
warm_init();
|
warm_init();
|
||||||
|
|
380
platform/gp2x/pollux_set.c
Normal file
380
platform/gp2x/pollux_set.c
Normal file
|
@ -0,0 +1,380 @@
|
||||||
|
/*
|
||||||
|
* quick tool to set various timings for Wiz
|
||||||
|
*
|
||||||
|
* Copyright (c) Gražvydas "notaz" Ignotas, 2009
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form 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.
|
||||||
|
* * Neither the name of the organization nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* 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 COPYRIGHT HOLDER 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.
|
||||||
|
*
|
||||||
|
* HTOTAL: X VTOTAL: 341
|
||||||
|
* HSWIDTH: 1 VSWIDTH: 0
|
||||||
|
* HASTART: 37 VASTART: 17
|
||||||
|
* HAEND: 277 VAEND: 337
|
||||||
|
*
|
||||||
|
* 120Hz
|
||||||
|
* pcd 8, 447: + 594us
|
||||||
|
* pcd 9, 397: + 36us
|
||||||
|
* pcd 10, 357: - 523us
|
||||||
|
* pcd 11, 325: +1153us
|
||||||
|
*
|
||||||
|
* 'lcd_timings=397,1,37,277,341,0,17,337;dpc_clkdiv0=9'
|
||||||
|
* 'ram_timings=2,9,4,1,1,1,1'
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "pollux_set.h"
|
||||||
|
|
||||||
|
/* parse stuff */
|
||||||
|
static int parse_lcd_timings(const char *str, void *data)
|
||||||
|
{
|
||||||
|
int *lcd_timings = data;
|
||||||
|
const char *p = str;
|
||||||
|
int ret, c;
|
||||||
|
ret = sscanf(str, "%d,%d,%d,%d,%d,%d,%d,%d",
|
||||||
|
&lcd_timings[0], &lcd_timings[1], &lcd_timings[2], &lcd_timings[3],
|
||||||
|
&lcd_timings[4], &lcd_timings[5], &lcd_timings[6], &lcd_timings[7]);
|
||||||
|
if (ret != 8)
|
||||||
|
return -1;
|
||||||
|
/* skip seven commas */
|
||||||
|
for (c = 0; c < 7 && *p != 0; p++)
|
||||||
|
if (*p == ',')
|
||||||
|
c++;
|
||||||
|
if (c != 7)
|
||||||
|
return -1;
|
||||||
|
/* skip last number */
|
||||||
|
while ('0' <= *p && *p <= '9')
|
||||||
|
p++;
|
||||||
|
|
||||||
|
return p - str;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_ram_timings(const char *str, void *data)
|
||||||
|
{
|
||||||
|
int *ram_timings = data;
|
||||||
|
const char *p = str;
|
||||||
|
int ret, c;
|
||||||
|
float cas;
|
||||||
|
|
||||||
|
ret = sscanf(p, "%f,%d,%d,%d,%d,%d,%d",
|
||||||
|
&cas, &ram_timings[1], &ram_timings[2], &ram_timings[3],
|
||||||
|
&ram_timings[4], &ram_timings[5], &ram_timings[6]);
|
||||||
|
if (ret != 7)
|
||||||
|
return -1;
|
||||||
|
if (cas == 2)
|
||||||
|
ram_timings[0] = 1;
|
||||||
|
else if (cas == 2.5)
|
||||||
|
ram_timings[0] = 2;
|
||||||
|
else if (cas == 3)
|
||||||
|
ram_timings[0] = 3;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
for (c = 0; c < 6 && *p != 0; p++)
|
||||||
|
if (*p == ',')
|
||||||
|
c++;
|
||||||
|
if (c != 6)
|
||||||
|
return -1;
|
||||||
|
while ('0' <= *p && *p <= '9')
|
||||||
|
p++;
|
||||||
|
|
||||||
|
return p - str;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_decimal(const char *str, void *data)
|
||||||
|
{
|
||||||
|
char *ep;
|
||||||
|
|
||||||
|
*(int *)data = strtoul(str, &ep, 10);
|
||||||
|
if (ep == str)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return ep - str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* validate and apply stuff */
|
||||||
|
static int apply_lcd_timings(volatile unsigned short *memregs, void *data)
|
||||||
|
{
|
||||||
|
int *lcd_timings = data;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
if (lcd_timings[i] & ~0xffff) {
|
||||||
|
fprintf(stderr, "pollux_set: invalid lcd timing %d: %d\n", i, lcd_timings[i]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
memregs[(0x307c>>1) + i] = lcd_timings[i];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
signed char adj; /* how to adjust value passed by user */
|
||||||
|
signed short min; /* range of */
|
||||||
|
signed short max; /* allowed values (inclusive) */
|
||||||
|
}
|
||||||
|
ram_ranges[] = {
|
||||||
|
{ 0, 1, 3 }, /* cas (cl) */
|
||||||
|
{ -2, 0, 15 }, /* trc */
|
||||||
|
{ -2, 0, 15 }, /* tras */
|
||||||
|
{ 0, 0, 15 }, /* twr */
|
||||||
|
{ 0, 0, 15 }, /* tmrd */
|
||||||
|
{ 0, 0, 15 }, /* trp */
|
||||||
|
{ 0, 0, 15 }, /* trcd */
|
||||||
|
};
|
||||||
|
|
||||||
|
static int apply_ram_timings(volatile unsigned short *memregs, void *data)
|
||||||
|
{
|
||||||
|
int *ram_timings = data;
|
||||||
|
int i, val;
|
||||||
|
|
||||||
|
for (i = 0; i < 7; i++)
|
||||||
|
{
|
||||||
|
ram_timings[i] += ram_ranges[i].adj;
|
||||||
|
if (ram_timings[i] < ram_ranges[i].min || ram_timings[i] > ram_ranges[i].max) {
|
||||||
|
fprintf(stderr, "pollux_set: invalid RAM timing %d\n", i);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val = memregs[0x14802>>1] & 0x0f00;
|
||||||
|
val |= (ram_timings[4] << 12) | (ram_timings[5] << 4) | ram_timings[6];
|
||||||
|
memregs[0x14802>>1] = val;
|
||||||
|
|
||||||
|
val = memregs[0x14804>>1] & 0x4000;
|
||||||
|
val |= (ram_timings[0] << 12) | (ram_timings[1] << 8) |
|
||||||
|
(ram_timings[2] << 4) | ram_timings[3];
|
||||||
|
val |= 0x8000;
|
||||||
|
memregs[0x14804>>1] = val;
|
||||||
|
|
||||||
|
for (i = 0; i < 0x100000 && (memregs[0x14804>>1] & 0x8000); i++)
|
||||||
|
;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int apply_dpc_clkdiv0(volatile unsigned short *memregs, void *data)
|
||||||
|
{
|
||||||
|
int pcd = *(int *)data;
|
||||||
|
int tmp;
|
||||||
|
|
||||||
|
if ((pcd - 1) & ~0x3f) {
|
||||||
|
fprintf(stderr, "pollux_set: invalid lcd clkdiv0: %d\n", pcd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pcd = (pcd - 1) & 0x3f;
|
||||||
|
tmp = memregs[0x31c4>>1];
|
||||||
|
memregs[0x31c4>>1] = (tmp & ~0x3f0) | (pcd << 4);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int apply_cpuclk(volatile unsigned short *memregs, void *data)
|
||||||
|
{
|
||||||
|
volatile unsigned int *memregl = (volatile void *)memregs;
|
||||||
|
int mhz = *(int *)data;
|
||||||
|
int mdiv, pdiv, sdiv = 0;
|
||||||
|
int i, v;
|
||||||
|
|
||||||
|
// m = MDIV, p = PDIV, s = SDIV
|
||||||
|
#define SYS_CLK_FREQ 27
|
||||||
|
pdiv = 9;
|
||||||
|
mdiv = (mhz * pdiv) / SYS_CLK_FREQ;
|
||||||
|
if (mdiv & ~0x3ff)
|
||||||
|
return -1;
|
||||||
|
v = (pdiv<<18) | (mdiv<<8) | sdiv;
|
||||||
|
|
||||||
|
memregl[0xf004>>2] = v;
|
||||||
|
memregl[0xf07c>>2] |= 0x8000;
|
||||||
|
for (i = 0; (memregl[0xf07c>>2] & 0x8000) && i < 0x100000; i++)
|
||||||
|
;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcd_timings[8];
|
||||||
|
static int ram_timings[7];
|
||||||
|
static int dpc_clkdiv0;
|
||||||
|
static int cpuclk;
|
||||||
|
|
||||||
|
static const char lcd_t_help[] = "htotal,hswidth,hastart,haend,vtotal,vswidth,vastart,vaend";
|
||||||
|
static const char ram_t_help[] = "CAS,tRC,tRAS,tWR,tMRD,tRP,tRCD";
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
const char *name;
|
||||||
|
const char *help;
|
||||||
|
int (*parse)(const char *str, void *data);
|
||||||
|
int (*apply)(volatile unsigned short *memregs, void *data);
|
||||||
|
void *data;
|
||||||
|
}
|
||||||
|
all_params[] = {
|
||||||
|
{ "lcd_timings", lcd_t_help, parse_lcd_timings, apply_lcd_timings, lcd_timings },
|
||||||
|
{ "ram_timings", ram_t_help, parse_ram_timings, apply_ram_timings, ram_timings },
|
||||||
|
{ "dpc_clkdiv0", "divider", parse_decimal, apply_dpc_clkdiv0, &dpc_clkdiv0 },
|
||||||
|
{ "clkdiv0", "divider", parse_decimal, apply_dpc_clkdiv0, &dpc_clkdiv0 }, /* alias */
|
||||||
|
{ "cpuclk", "MHZ", parse_decimal, apply_cpuclk, &cpuclk },
|
||||||
|
};
|
||||||
|
#define ALL_PARAM_COUNT (sizeof(all_params) / sizeof(all_params[0]))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set timings based on preformated string
|
||||||
|
* returns 0 on success.
|
||||||
|
*/
|
||||||
|
int pollux_set(volatile unsigned short *memregs, const char *str)
|
||||||
|
{
|
||||||
|
int parsed_params[ALL_PARAM_COUNT];
|
||||||
|
int applied_params[ALL_PARAM_COUNT];
|
||||||
|
int applied_something = 0;
|
||||||
|
const char *p, *po;
|
||||||
|
int i, ret;
|
||||||
|
|
||||||
|
if (str == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
memset(parsed_params, 0, sizeof(parsed_params));
|
||||||
|
memset(applied_params, 0, sizeof(applied_params));
|
||||||
|
|
||||||
|
p = str;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
again:
|
||||||
|
while (*p == ';' || *p == ' ')
|
||||||
|
p++;
|
||||||
|
if (*p == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (i = 0; i < ALL_PARAM_COUNT; i++)
|
||||||
|
{
|
||||||
|
int param_len = strlen(all_params[i].name);
|
||||||
|
if (strncmp(p, all_params[i].name, param_len) == 0 && p[param_len] == '=')
|
||||||
|
{
|
||||||
|
p += param_len + 1;
|
||||||
|
ret = all_params[i].parse(p, all_params[i].data);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "pollux_set parser: error at %-10s\n", p);
|
||||||
|
fprintf(stderr, " valid format is: <%s>\n", all_params[i].help);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
parsed_params[i] = 1;
|
||||||
|
p += ret;
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unknown param. Attempt to be forward compatible and ignore it. */
|
||||||
|
for (po = p; *p != 0 && *p != ';'; p++)
|
||||||
|
;
|
||||||
|
|
||||||
|
fprintf(stderr, "unhandled param: ");
|
||||||
|
fwrite(po, 1, p - po, stderr);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* validate and apply */
|
||||||
|
for (i = 0; i < ALL_PARAM_COUNT; i++)
|
||||||
|
{
|
||||||
|
if (!parsed_params[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ret = all_params[i].apply(memregs, all_params[i].data);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "pollux_set: failed to apply %s (bad value?)\n",
|
||||||
|
all_params[i].name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
applied_something = 1;
|
||||||
|
applied_params[i] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (applied_something)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
printf("applied: ");
|
||||||
|
for (i = c = 0; i < ALL_PARAM_COUNT; i++)
|
||||||
|
{
|
||||||
|
if (!applied_params[i])
|
||||||
|
continue;
|
||||||
|
if (c != 0)
|
||||||
|
printf(", ");
|
||||||
|
printf("%s", all_params[i].name);
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BINARY
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
static void usage(const char *binary)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
printf("usage:\n%s <set_str[;set_str[;...]]>\n"
|
||||||
|
"set_str:\n", binary);
|
||||||
|
for (i = 0; i < ALL_PARAM_COUNT; i++)
|
||||||
|
printf(" %s=<%s>\n", all_params[i].name, all_params[i].help);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
volatile unsigned short *memregs;
|
||||||
|
int ret, memdev;
|
||||||
|
|
||||||
|
if (argc != 2) {
|
||||||
|
usage(argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memdev = open("/dev/mem", O_RDWR);
|
||||||
|
if (memdev == -1)
|
||||||
|
{
|
||||||
|
perror("open(/dev/mem) failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memregs = mmap(0, 0x20000, PROT_READ|PROT_WRITE, MAP_SHARED, memdev, 0xc0000000);
|
||||||
|
if (memregs == MAP_FAILED)
|
||||||
|
{
|
||||||
|
perror("mmap(memregs) failed");
|
||||||
|
close(memdev);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = pollux_set(memregs, argv[1]);
|
||||||
|
|
||||||
|
munmap((void *)memregs, 0x20000);
|
||||||
|
close(memdev);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
10
platform/gp2x/pollux_set.h
Normal file
10
platform/gp2x/pollux_set.h
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int pollux_set(volatile unsigned short *memregs, const char *str);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -7,7 +7,23 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "soc.h"
|
#include "soc.h"
|
||||||
#include "../common/emu.h"
|
|
||||||
|
void (*gp2x_video_flip)(void);
|
||||||
|
void (*gp2x_video_flip2)(void);
|
||||||
|
void (*gp2x_video_changemode_ll)(int bpp);
|
||||||
|
void (*gp2x_video_setpalette)(int *pal, int len);
|
||||||
|
void (*gp2x_video_RGB_setscaling)(int ln_offs, int W, int H);
|
||||||
|
void (*gp2x_video_wait_vsync)(void);
|
||||||
|
|
||||||
|
void (*gp2x_set_cpuclk)(unsigned int mhz);
|
||||||
|
|
||||||
|
void (*set_lcd_custom_rate)(int is_pal);
|
||||||
|
void (*unset_lcd_custom_rate)(void);
|
||||||
|
void (*set_lcd_gamma)(int g100, int A_SNs_curve);
|
||||||
|
|
||||||
|
void (*set_ram_timings)(void);
|
||||||
|
void (*unset_ram_timings)(void);
|
||||||
|
|
||||||
|
|
||||||
gp2x_soc_t soc_detect(void)
|
gp2x_soc_t soc_detect(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,19 +12,19 @@ void pollux_init(void);
|
||||||
void pollux_finish(void);
|
void pollux_finish(void);
|
||||||
|
|
||||||
/* SoC specific functions */
|
/* SoC specific functions */
|
||||||
void gp2x_video_flip(void);
|
extern void (*gp2x_video_flip)(void);
|
||||||
void gp2x_video_flip2(void);
|
extern void (*gp2x_video_flip2)(void);
|
||||||
void gp2x_video_changemode_ll(int bpp);
|
extern void (*gp2x_video_changemode_ll)(int bpp);
|
||||||
void gp2x_video_setpalette(int *pal, int len);
|
extern void (*gp2x_video_setpalette)(int *pal, int len);
|
||||||
void gp2x_video_RGB_setscaling(int ln_offs, int W, int H);
|
extern void (*gp2x_video_RGB_setscaling)(int ln_offs, int W, int H);
|
||||||
void gp2x_video_wait_vsync(void);
|
extern void (*gp2x_video_wait_vsync)(void);
|
||||||
|
|
||||||
void gp2x_set_cpuclk(unsigned int mhz);
|
extern void (*gp2x_set_cpuclk)(unsigned int mhz);
|
||||||
|
|
||||||
void set_lcd_custom_rate(int is_pal);
|
extern void (*set_lcd_custom_rate)(int is_pal);
|
||||||
void unset_lcd_custom_rate(void);
|
extern void (*unset_lcd_custom_rate)(void);
|
||||||
void set_lcd_gamma(int g100, int A_SNs_curve);
|
extern void (*set_lcd_gamma)(int g100, int A_SNs_curve);
|
||||||
|
|
||||||
void set_ram_timings(int tCAS, int tRC, int tRAS, int tWR, int tMRD, int tRFC, int tRP, int tRCD);
|
extern void (*set_ram_timings)(void);
|
||||||
void unset_ram_timings(void);
|
extern void (*unset_ram_timings)(void);
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ volatile unsigned long *gp2x_memregl;
|
||||||
extern void *gp2x_screens[4];
|
extern void *gp2x_screens[4];
|
||||||
static int screensel = 0;
|
static int screensel = 0;
|
||||||
|
|
||||||
int memdev = 0; /* used by code940 */
|
int memdev = -1; /* used by code940 */
|
||||||
static int touchdev = -1;
|
static int touchdev = -1;
|
||||||
static int touchcal[7] = { 6203, 0, -1501397, 0, -4200, 16132680, 65536 };
|
static int touchcal[7] = { 6203, 0, -1501397, 0, -4200, 16132680, 65536 };
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ static unsigned short gp2x_screenaddr_old[4];
|
||||||
|
|
||||||
|
|
||||||
/* video stuff */
|
/* video stuff */
|
||||||
void gp2x_video_flip(void)
|
static void gp2x_video_flip_(void)
|
||||||
{
|
{
|
||||||
unsigned short lsw = (unsigned short) gp2x_screenaddrs_use[screensel&3];
|
unsigned short lsw = (unsigned short) gp2x_screenaddrs_use[screensel&3];
|
||||||
unsigned short msw = (unsigned short)(gp2x_screenaddrs_use[screensel&3] >> 16);
|
unsigned short msw = (unsigned short)(gp2x_screenaddrs_use[screensel&3] >> 16);
|
||||||
|
@ -52,7 +52,7 @@ void gp2x_video_flip(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* doulblebuffered flip */
|
/* doulblebuffered flip */
|
||||||
void gp2x_video_flip2(void)
|
static void gp2x_video_flip2_(void)
|
||||||
{
|
{
|
||||||
unsigned short msw = (unsigned short)(gp2x_screenaddrs_use[screensel&1] >> 16);
|
unsigned short msw = (unsigned short)(gp2x_screenaddrs_use[screensel&1] >> 16);
|
||||||
|
|
||||||
|
@ -65,13 +65,13 @@ void gp2x_video_flip2(void)
|
||||||
g_screen_ptr = gp2x_screens[++screensel&1];
|
g_screen_ptr = gp2x_screens[++screensel&1];
|
||||||
}
|
}
|
||||||
|
|
||||||
void gp2x_video_changemode_ll(int bpp)
|
static void gp2x_video_changemode_ll_(int bpp)
|
||||||
{
|
{
|
||||||
gp2x_memregs[0x28DA>>1] = (((bpp+1)/8)<<9)|0xAB; /*8/15/16/24bpp...*/
|
gp2x_memregs[0x28DA>>1] = (((bpp+1)/8)<<9)|0xAB; /*8/15/16/24bpp...*/
|
||||||
gp2x_memregs[0x290C>>1] = 320*((bpp+1)/8); /*line width in bytes*/
|
gp2x_memregs[0x290C>>1] = 320*((bpp+1)/8); /*line width in bytes*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void gp2x_video_setpalette(int *pal, int len)
|
static void gp2x_video_setpalette_(int *pal, int len)
|
||||||
{
|
{
|
||||||
unsigned short *g = (unsigned short *)pal;
|
unsigned short *g = (unsigned short *)pal;
|
||||||
volatile unsigned short *memreg = &gp2x_memregs[0x295A>>1];
|
volatile unsigned short *memreg = &gp2x_memregs[0x295A>>1];
|
||||||
|
@ -83,8 +83,7 @@ void gp2x_video_setpalette(int *pal, int len)
|
||||||
*memreg = *g++;
|
*memreg = *g++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TV Compatible function //
|
static void gp2x_video_RGB_setscaling_(int ln_offs, int W, int H)
|
||||||
void gp2x_video_RGB_setscaling(int ln_offs, int W, int H)
|
|
||||||
{
|
{
|
||||||
float escalaw, escalah;
|
float escalaw, escalah;
|
||||||
int bpp = (gp2x_memregs[0x28DA>>1]>>9)&0x3;
|
int bpp = (gp2x_memregs[0x28DA>>1]>>9)&0x3;
|
||||||
|
@ -110,14 +109,15 @@ void gp2x_video_RGB_setscaling(int ln_offs, int W, int H)
|
||||||
|
|
||||||
// scale horizontal
|
// scale horizontal
|
||||||
scalw = (unsigned short)((float)escalaw *(W/320.0));
|
scalw = (unsigned short)((float)escalaw *(W/320.0));
|
||||||
/* if there is no horizontal scaling, vertical doesn't work. Here is a nasty wrokaround... */
|
/* if there is no horizontal scaling, vertical doesn't work.
|
||||||
|
* Here is a nasty wrokaround... */
|
||||||
if (H != 240 && W == 320) scalw--;
|
if (H != 240 && W == 320) scalw--;
|
||||||
gp2x_memregs[0x2906>>1]=scalw;
|
gp2x_memregs[0x2906>>1]=scalw;
|
||||||
// scale vertical
|
// scale vertical
|
||||||
gp2x_memregl[0x2908>>2]=(unsigned long)((float)escalah *bpp *(H/240.0));
|
gp2x_memregl[0x2908>>2]=(unsigned long)((float)escalah *bpp *(H/240.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void gp2x_video_wait_vsync(void)
|
static void gp2x_video_wait_vsync_(void)
|
||||||
{
|
{
|
||||||
unsigned short v = gp2x_memregs[0x1182>>1];
|
unsigned short v = gp2x_memregs[0x1182>>1];
|
||||||
while (!((v ^ gp2x_memregs[0x1182>>1]) & 0x10))
|
while (!((v ^ gp2x_memregs[0x1182>>1]) & 0x10))
|
||||||
|
@ -148,7 +148,7 @@ void reset940(int yes, int bank)
|
||||||
|
|
||||||
#define SYS_CLK_FREQ 7372800
|
#define SYS_CLK_FREQ 7372800
|
||||||
|
|
||||||
void gp2x_set_cpuclk(unsigned int mhz)
|
static void gp2x_set_cpuclk_(unsigned int mhz)
|
||||||
{
|
{
|
||||||
unsigned int mdiv, pdiv, sdiv = 0;
|
unsigned int mdiv, pdiv, sdiv = 0;
|
||||||
unsigned int v;
|
unsigned int v;
|
||||||
|
@ -176,7 +176,7 @@ static unsigned short memtimex[2];
|
||||||
if (t & ~mask) \
|
if (t & ~mask) \
|
||||||
goto bad
|
goto bad
|
||||||
|
|
||||||
void set_ram_timings(int tCAS, int tRC, int tRAS, int tWR, int tMRD, int tRFC, int tRP, int tRCD)
|
static void set_ram_timing_vals(int tCAS, int tRC, int tRAS, int tWR, int tMRD, int tRFC, int tRP, int tRCD)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
TIMING_CHECK(tCAS, -2, 0x1);
|
TIMING_CHECK(tCAS, -2, 0x1);
|
||||||
|
@ -206,7 +206,13 @@ bad:
|
||||||
fprintf(stderr, "RAM timings invalid.\n");
|
fprintf(stderr, "RAM timings invalid.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void unset_ram_timings(void)
|
static void set_ram_timings_(void)
|
||||||
|
{
|
||||||
|
/* craigix: --cas 2 --trc 6 --tras 4 --twr 1 --tmrd 1 --trfc 1 --trp 2 --trcd 2 */
|
||||||
|
set_ram_timing_vals(2, 6, 4, 1, 1, 1, 2, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void unset_ram_timings_(void)
|
||||||
{
|
{
|
||||||
gp2x_memregs[0x3802>>1] = memtimex[0];
|
gp2x_memregs[0x3802>>1] = memtimex[0];
|
||||||
gp2x_memregs[0x3804>>1] = memtimex[1] | 0x8000;
|
gp2x_memregs[0x3804>>1] = memtimex[1] | 0x8000;
|
||||||
|
@ -279,7 +285,7 @@ static void set_reg_setting(const reg_setting *set)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_lcd_custom_rate(int is_pal)
|
static void set_lcd_custom_rate_(int is_pal)
|
||||||
{
|
{
|
||||||
if (gp2x_memregs[0x2800>>1] & 0x100) // tv-out
|
if (gp2x_memregs[0x2800>>1] & 0x100) // tv-out
|
||||||
return;
|
return;
|
||||||
|
@ -291,13 +297,13 @@ void set_lcd_custom_rate(int is_pal)
|
||||||
printf("done.\n");
|
printf("done.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void unset_lcd_custom_rate(void)
|
static void unset_lcd_custom_rate_(void)
|
||||||
{
|
{
|
||||||
printf("reset to prev LCD refresh.\n");
|
printf("reset to prev LCD refresh.\n");
|
||||||
set_reg_setting(lcd_rate_defaults);
|
set_reg_setting(lcd_rate_defaults);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_lcd_gamma(int g100, int A_SNs_curve)
|
static void set_lcd_gamma_(int g100, int A_SNs_curve)
|
||||||
{
|
{
|
||||||
float gamma = (float) g100 / 100;
|
float gamma = (float) g100 / 100;
|
||||||
int i;
|
int i;
|
||||||
|
@ -473,6 +479,22 @@ void mmsp2_init(void)
|
||||||
|
|
||||||
/* code940 portion */
|
/* code940 portion */
|
||||||
sharedmem940_init();
|
sharedmem940_init();
|
||||||
|
|
||||||
|
gp2x_video_flip = gp2x_video_flip_;
|
||||||
|
gp2x_video_flip2 = gp2x_video_flip2_;
|
||||||
|
gp2x_video_changemode_ll = gp2x_video_changemode_ll_;
|
||||||
|
gp2x_video_setpalette = gp2x_video_setpalette_;
|
||||||
|
gp2x_video_RGB_setscaling = gp2x_video_RGB_setscaling_;
|
||||||
|
gp2x_video_wait_vsync = gp2x_video_wait_vsync_;
|
||||||
|
|
||||||
|
gp2x_set_cpuclk = gp2x_set_cpuclk_;
|
||||||
|
|
||||||
|
set_lcd_custom_rate = set_lcd_custom_rate_;
|
||||||
|
unset_lcd_custom_rate = unset_lcd_custom_rate_;
|
||||||
|
set_lcd_gamma = set_lcd_gamma_;
|
||||||
|
|
||||||
|
set_ram_timings = set_ram_timings_;
|
||||||
|
unset_ram_timings = unset_ram_timings_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mmsp2_finish(void)
|
void mmsp2_finish(void)
|
||||||
|
@ -486,8 +508,8 @@ void mmsp2_finish(void)
|
||||||
gp2x_memregs[0x2912>>1] = gp2x_screenaddr_old[2];
|
gp2x_memregs[0x2912>>1] = gp2x_screenaddr_old[2];
|
||||||
gp2x_memregs[0x2914>>1] = gp2x_screenaddr_old[3];
|
gp2x_memregs[0x2914>>1] = gp2x_screenaddr_old[3];
|
||||||
|
|
||||||
unset_ram_timings();
|
unset_ram_timings_();
|
||||||
unset_lcd_custom_rate();
|
unset_lcd_custom_rate_();
|
||||||
|
|
||||||
munmap(gp2x_screens[0], FRAMEBUFF_WHOLESIZE);
|
munmap(gp2x_screens[0], FRAMEBUFF_WHOLESIZE);
|
||||||
munmap((void *)gp2x_memregs, 0x10000);
|
munmap((void *)gp2x_memregs, 0x10000);
|
||||||
|
|
|
@ -1,9 +1,249 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <linux/fb.h>
|
||||||
|
|
||||||
|
#include "soc.h"
|
||||||
|
#include "plat_gp2x.h"
|
||||||
|
#include "../common/emu.h"
|
||||||
|
#include "../common/arm_utils.h"
|
||||||
|
#include "pollux_set.h"
|
||||||
|
|
||||||
|
static volatile unsigned short *memregs;
|
||||||
|
static volatile unsigned long *memregl;
|
||||||
|
static int memdev = -1;
|
||||||
|
|
||||||
|
extern void *gp2x_screens[4];
|
||||||
|
|
||||||
|
#define fb_buf_count 4
|
||||||
|
static unsigned int fb_paddr[fb_buf_count];
|
||||||
|
static int fb_work_buf;
|
||||||
|
static int fbdev = -1;
|
||||||
|
|
||||||
|
|
||||||
|
/* video stuff */
|
||||||
|
static void pollux_video_flip(int buf_count)
|
||||||
|
{
|
||||||
|
memregl[0x406C>>2] = fb_paddr[fb_work_buf];
|
||||||
|
memregl[0x4058>>2] |= 0x10;
|
||||||
|
fb_work_buf++;
|
||||||
|
if (fb_work_buf >= buf_count)
|
||||||
|
fb_work_buf = 0;
|
||||||
|
g_screen_ptr = gp2x_screens[fb_work_buf];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gp2x_video_flip_(void)
|
||||||
|
{
|
||||||
|
pollux_video_flip(fb_buf_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* doulblebuffered flip */
|
||||||
|
static void gp2x_video_flip2_(void)
|
||||||
|
{
|
||||||
|
pollux_video_flip(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gp2x_video_changemode_ll_(int bpp)
|
||||||
|
{
|
||||||
|
int code = 0, bytes = 2;
|
||||||
|
unsigned int r;
|
||||||
|
switch (bpp)
|
||||||
|
{
|
||||||
|
case 8:
|
||||||
|
code = 0x443a;
|
||||||
|
bytes = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 15:
|
||||||
|
case 16:
|
||||||
|
code = 0x4432;
|
||||||
|
bytes = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("unhandled bpp request: %d\n", bpp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memregl[0x405c>>2] = bytes;
|
||||||
|
memregl[0x4060>>2] = bytes * 320;
|
||||||
|
|
||||||
|
r = memregl[0x4058>>2];
|
||||||
|
r = (r & 0xffff) | (code << 16) | 0x10;
|
||||||
|
memregl[0x4058>>2] = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gp2x_video_setpalette_(int *pal, int len)
|
||||||
|
{
|
||||||
|
/* pollux palette is 16bpp only.. */
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
int c = pal[i];
|
||||||
|
c = ((c >> 8) & 0xf800) | ((c >> 5) & 0x07c0) | ((c >> 3) & 0x001f);
|
||||||
|
memregl[0x4070>>2] = (i << 24) | c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gp2x_video_RGB_setscaling_(int ln_offs, int W, int H)
|
||||||
|
{
|
||||||
|
/* maybe a job for 3d hardware? */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gp2x_video_wait_vsync_(void)
|
||||||
|
{
|
||||||
|
while (!(memregl[0x308c>>2] & (1 << 10)));
|
||||||
|
spend_cycles(128);
|
||||||
|
memregl[0x308c>>2] |= 1 << 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CPU clock */
|
||||||
|
static void gp2x_set_cpuclk_(unsigned int mhz)
|
||||||
|
{
|
||||||
|
char buff[24];
|
||||||
|
snprintf(buff, sizeof(buff), "cpuclk=%u", mhz);
|
||||||
|
pollux_set(memregs, buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* misc */
|
||||||
|
static void pollux_set_fromenv(const char *env_var)
|
||||||
|
{
|
||||||
|
const char *set_string;
|
||||||
|
set_string = getenv(env_var);
|
||||||
|
if (set_string)
|
||||||
|
pollux_set(memregs, set_string);
|
||||||
|
else
|
||||||
|
printf("env var %s not defined.\n", env_var);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RAM timings */
|
||||||
|
static unsigned short memtimex[2];
|
||||||
|
|
||||||
|
static void set_ram_timings_(void)
|
||||||
|
{
|
||||||
|
pollux_set_fromenv("POLLUX_RAM_TIMINGS");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void unset_ram_timings_(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
memregs[0x14802>>1] = memtimex[0];
|
||||||
|
memregs[0x14804>>1] = memtimex[1] | 0x8000;
|
||||||
|
|
||||||
|
for (i = 0; i < 0x100000; i++)
|
||||||
|
if (!(memregs[0x14804>>1] & 0x8000))
|
||||||
|
break;
|
||||||
|
|
||||||
|
printf("RAM timings reset to startup values.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* LCD refresh */
|
||||||
|
static void set_lcd_custom_rate_(int is_pal)
|
||||||
|
{
|
||||||
|
char buff[32];
|
||||||
|
|
||||||
|
snprintf(buff, sizeof(buff), "POLLUX_LCD_TIMINGS_%s", is_pal ? "PAL" : "NTSC");
|
||||||
|
pollux_set_fromenv(buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void unset_lcd_custom_rate_(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_lcd_gamma_(int g100, int A_SNs_curve)
|
||||||
|
{
|
||||||
|
/* hm, the LCD possibly can do it (but not POLLUX) */
|
||||||
|
}
|
||||||
|
|
||||||
void pollux_init(void)
|
void pollux_init(void)
|
||||||
{
|
{
|
||||||
|
struct fb_fix_screeninfo fbfix;
|
||||||
|
int i, 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("/dev/fb0", O_RDWR);
|
||||||
|
if (fbdev < 0) {
|
||||||
|
perror("can't open fbdev");
|
||||||
|
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_paddr[0] = fbfix.smem_start;
|
||||||
|
|
||||||
|
gp2x_screens[0] = mmap(0, 320*240*2*fb_buf_count, PROT_READ|PROT_WRITE,
|
||||||
|
MAP_SHARED, memdev, fb_paddr[0]);
|
||||||
|
if (gp2x_screens[0] == MAP_FAILED)
|
||||||
|
{
|
||||||
|
perror("mmap(gp2x_screens) failed");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
memset(gp2x_screens[0], 0, 320*240*2*fb_buf_count);
|
||||||
|
|
||||||
|
printf(" %p -> %08x\n", gp2x_screens[0], fb_paddr[0]);
|
||||||
|
for (i = 1; i < fb_buf_count; i++)
|
||||||
|
{
|
||||||
|
fb_paddr[i] = fb_paddr[i-1] + 320*240*2;
|
||||||
|
gp2x_screens[i] = (char *)gp2x_screens[i-1] + 320*240*2;
|
||||||
|
printf(" %p -> %08x\n", gp2x_screens[i], fb_paddr[i]);
|
||||||
|
}
|
||||||
|
fb_work_buf = 0;
|
||||||
|
g_screen_ptr = gp2x_screens[0];
|
||||||
|
|
||||||
|
memtimex[0] = memregs[0x14802>>1];
|
||||||
|
memtimex[1] = memregs[0x14804>>1];
|
||||||
|
|
||||||
|
gp2x_video_flip = gp2x_video_flip_;
|
||||||
|
gp2x_video_flip2 = gp2x_video_flip2_;
|
||||||
|
gp2x_video_changemode_ll = gp2x_video_changemode_ll_;
|
||||||
|
gp2x_video_setpalette = gp2x_video_setpalette_;
|
||||||
|
gp2x_video_RGB_setscaling = gp2x_video_RGB_setscaling_;
|
||||||
|
gp2x_video_wait_vsync = gp2x_video_wait_vsync_;
|
||||||
|
|
||||||
|
gp2x_set_cpuclk = gp2x_set_cpuclk_;
|
||||||
|
|
||||||
|
set_lcd_custom_rate = set_lcd_custom_rate_;
|
||||||
|
unset_lcd_custom_rate = unset_lcd_custom_rate_;
|
||||||
|
set_lcd_gamma = set_lcd_gamma_;
|
||||||
|
|
||||||
|
set_ram_timings = set_ram_timings_;
|
||||||
|
unset_ram_timings = unset_ram_timings_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pollux_finish(void)
|
void pollux_finish(void)
|
||||||
{
|
{
|
||||||
|
/* switch to default fb mem, turn portrait off */
|
||||||
|
memregl[0x406C>>2] = fb_paddr[0];
|
||||||
|
memregl[0x4058>>2] |= 0x10;
|
||||||
|
// wiz_lcd_set_portrait(0);
|
||||||
|
close(fbdev);
|
||||||
|
|
||||||
|
munmap((void *)memregs, 0x20000);
|
||||||
|
close(memdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue