mirror of
https://github.com/RaySollium99/libpicofe.git
synced 2025-09-04 22:47:44 -04:00
further prep for Wiz port. Cleanups, rm cpuctrl mmuhack; add warm
git-svn-id: file:///home/notaz/opt/svn/PicoDrive/platform@704 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
parent
d572cbad98
commit
fa5e045bdc
24 changed files with 679 additions and 948 deletions
|
@ -24,12 +24,15 @@ extern int g_screen_height;
|
|||
#define EOPT_SHOW_FPS (1<<1)
|
||||
#define EOPT_EN_SOUND (1<<2)
|
||||
#define EOPT_GZIP_SAVES (1<<3)
|
||||
#define EOPT_MMUHACK (1<<4)
|
||||
#define EOPT_NO_AUTOSVCFG (1<<5)
|
||||
#define EOPT_RAM_TIMINGS (1<<8)
|
||||
#define EOPT_PSYNC (1<<13)
|
||||
|
||||
typedef struct _currentConfig_t {
|
||||
// char lastRomFile[512];
|
||||
int EmuOpt; // LSb->MSb: use_sram, show_fps, enable_sound, gzip_saves,
|
||||
// squidgehack, no_save_cfg_on_exit, <unused>, 16_bit_mode
|
||||
// mmuhack, no_save_cfg_on_exit, <unused>, 16_bit_mode
|
||||
// craigix_ram, confirm_save, show_cd_leds, confirm_load
|
||||
// A_SNs_gamma, perfect_vsync, giz_scanlines, giz_dblbuff
|
||||
// vsync_mode, show_clock, no_frame_limitter
|
||||
|
|
|
@ -1415,15 +1415,6 @@ static int menu_loop_cd_options(menu_id id, int keys)
|
|||
|
||||
// ------------ adv options menu ------------
|
||||
|
||||
// TODO FIXME fix if and mv
|
||||
static const char *mgn_aopt_sqhack(menu_id id, int *offs)
|
||||
{
|
||||
*offs = -10;
|
||||
sprintf(static_buff, "%s, %s", 111 ? " active" : "inactive",
|
||||
(currentConfig.EmuOpt & 0x10) ? "ON" : "OFF");
|
||||
return static_buff;
|
||||
}
|
||||
|
||||
static menu_entry e_menu_adv_options[] =
|
||||
{
|
||||
mee_onoff ("SRAM/BRAM saves", MA_OPT_SRAM_STATES, currentConfig.EmuOpt, EOPT_USE_SRAM),
|
||||
|
@ -1434,9 +1425,8 @@ static menu_entry e_menu_adv_options[] =
|
|||
mee_onoff ("Emulate SN76496 (PSG)", MA_OPT2_ENABLE_SN76496,PicoOpt, POPT_EN_PSG),
|
||||
mee_onoff ("gzip savestates", MA_OPT2_GZIP_STATES, currentConfig.EmuOpt, EOPT_GZIP_SAVES),
|
||||
mee_onoff ("Don't save last used ROM", MA_OPT2_NO_LAST_ROM, currentConfig.EmuOpt, EOPT_NO_AUTOSVCFG),
|
||||
mee_label ("- needs restart -"),
|
||||
mee_onoff ("craigix's RAM timings", MA_OPT2_RAMTIMINGS, currentConfig.EmuOpt, 0x0100),
|
||||
mee_onoff_cust("Squidgehack", MA_OPT2_SQUIDGEHACK, currentConfig.EmuOpt, 0x0010, mgn_aopt_sqhack),
|
||||
mee_onoff ("RAM overclock", MA_OPT2_RAMTIMINGS, currentConfig.EmuOpt, EOPT_RAM_TIMINGS),
|
||||
mee_onoff ("MMU hack", MA_OPT2_SQUIDGEHACK, currentConfig.EmuOpt, EOPT_MMUHACK),
|
||||
mee_onoff ("SVP dynarec", MA_OPT2_SVP_DYNAREC, PicoOpt, POPT_EN_SVP_DRC),
|
||||
mee_onoff ("Disable idle loop patching",MA_OPT2_NO_IDLE_LOOPS,PicoOpt, POPT_DIS_IDLE_DET),
|
||||
mee_end,
|
||||
|
|
|
@ -243,7 +243,7 @@ static void internal_reset(void)
|
|||
|
||||
|
||||
/* this must be called after mmu hack, the allocated regions must not get cached */
|
||||
void sharedmem_init(void)
|
||||
void sharedmem940_init(void)
|
||||
{
|
||||
if (shared_mem != NULL) return;
|
||||
|
||||
|
@ -266,7 +266,7 @@ void sharedmem_init(void)
|
|||
}
|
||||
|
||||
|
||||
void sharedmem_deinit(void)
|
||||
void sharedmem940_finish(void)
|
||||
{
|
||||
munmap(shared_mem, 0x210000);
|
||||
munmap(mp3_mem, MP3_SIZE_MAX);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
void sharedmem_init(void);
|
||||
void sharedmem_deinit(void);
|
||||
void sharedmem940_init(void);
|
||||
void sharedmem940_finish(void);
|
||||
|
||||
void YM2612Init_940(int baseclock, int rate);
|
||||
void YM2612ResetChip_940(void);
|
||||
|
|
|
@ -32,7 +32,8 @@ use_cyclone = 1
|
|||
endif
|
||||
|
||||
DEFINC = -I../.. -I. -DARM -D__GP2X__ -DIN_GP2X # -DBENCHMARK
|
||||
COPT_COMMON = -static -Wall -Winline
|
||||
COPT_COMMON = -Wall -Winline
|
||||
COPT_COMMON += -static
|
||||
ifeq ($(DEBUG),)
|
||||
COPT_COMMON += -O3 -ftracer -fstrength-reduce -fomit-frame-pointer -fstrict-aliasing -ffast-math
|
||||
else
|
||||
|
@ -54,8 +55,7 @@ LD = $(CROSS)ld
|
|||
OBJCOPY = $(CROSS)objcopy
|
||||
|
||||
# frontend
|
||||
# TODO: rm cpuctrl
|
||||
OBJS += main.o soc.o soc_mmsp2.o soc_pollux.o emu.o in_gp2x.o plat.o squidgehack.o cpuctrl.o
|
||||
OBJS += main.o soc.o soc_mmsp2.o soc_pollux.o emu.o in_gp2x.o plat.o warm.o
|
||||
# 940 core control
|
||||
OBJS += 940ctl.o
|
||||
|
||||
|
|
300
gp2x/cpuctrl.c
300
gp2x/cpuctrl.c
|
@ -1,300 +0,0 @@
|
|||
/* cpuctrl for GP2X
|
||||
Copyright (C) 2005 Hermes/PS2Reality
|
||||
the gamma-routine was provided by theoddbot
|
||||
parts (c) Rlyehs Work & (C) 2006 god_at_hell
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "cpuctrl.h"
|
||||
|
||||
|
||||
/* system registers */
|
||||
static struct
|
||||
{
|
||||
unsigned short SYSCLKENREG,SYSCSETREG,UPLLVSETREG,FPLLVSETREG,
|
||||
DUALINT920,DUALINT940,DUALCTRL940,MEMTIMEX0,MEMTIMEX1,DISPCSETREG,
|
||||
DPC_HS_WIDTH,DPC_HS_STR,DPC_HS_END,DPC_VS_END,DPC_DE;
|
||||
}
|
||||
system_reg;
|
||||
|
||||
static volatile unsigned short *MEM_REG;
|
||||
|
||||
#define SYS_CLK_FREQ 7372800
|
||||
|
||||
// Fout = (m * Fin) / (p * 2^s)
|
||||
// m = MDIV+8, p = PDIV+2, s = SDIV
|
||||
|
||||
// m = (Fout * p * 2^s) / Fin
|
||||
|
||||
void cpuctrl_init(void)
|
||||
{
|
||||
extern volatile unsigned short *gp2x_memregs; /* from minimal library rlyeh */
|
||||
MEM_REG=&gp2x_memregs[0];
|
||||
system_reg.DISPCSETREG=MEM_REG[0x924>>1];
|
||||
system_reg.UPLLVSETREG=MEM_REG[0x916>>1];
|
||||
system_reg.FPLLVSETREG=MEM_REG[0x912>>1];
|
||||
system_reg.SYSCSETREG=MEM_REG[0x91c>>1];
|
||||
system_reg.SYSCLKENREG=MEM_REG[0x904>>1];
|
||||
system_reg.DUALINT920=MEM_REG[0x3B40>>1];
|
||||
system_reg.DUALINT940=MEM_REG[0x3B42>>1];
|
||||
system_reg.DUALCTRL940=MEM_REG[0x3B48>>1];
|
||||
system_reg.MEMTIMEX0=MEM_REG[0x3802>>1];
|
||||
system_reg.MEMTIMEX1=MEM_REG[0x3804>>1];
|
||||
system_reg.DPC_HS_WIDTH=MEM_REG[0x281A>>1];
|
||||
system_reg.DPC_HS_STR=MEM_REG[0x281C>>1];
|
||||
system_reg.DPC_HS_END=MEM_REG[0x281E>>1];
|
||||
system_reg.DPC_VS_END=MEM_REG[0x2822>>1];
|
||||
system_reg.DPC_DE=MEM_REG[0x2826>>1];
|
||||
}
|
||||
|
||||
|
||||
void cpuctrl_deinit(void)
|
||||
{
|
||||
MEM_REG[0x910>>1]=system_reg.FPLLVSETREG;
|
||||
MEM_REG[0x91c>>1]=system_reg.SYSCSETREG;
|
||||
MEM_REG[0x3B40>>1]=system_reg.DUALINT920;
|
||||
MEM_REG[0x3B42>>1]=system_reg.DUALINT940;
|
||||
MEM_REG[0x3B48>>1]=system_reg.DUALCTRL940;
|
||||
MEM_REG[0x904>>1]=system_reg.SYSCLKENREG;
|
||||
MEM_REG[0x3802>>1]=system_reg.MEMTIMEX0;
|
||||
MEM_REG[0x3804>>1]=system_reg.MEMTIMEX1 /*| 0x9000*/;
|
||||
unset_LCD_custom_rate();
|
||||
}
|
||||
|
||||
|
||||
void set_display_clock_div(unsigned div)
|
||||
{
|
||||
div=((div & 63) | 64)<<8;
|
||||
MEM_REG[0x924>>1]=(MEM_REG[0x924>>1] & ~(255<<8)) | div;
|
||||
}
|
||||
|
||||
|
||||
void set_FCLK(unsigned MHZ)
|
||||
{
|
||||
unsigned v;
|
||||
unsigned mdiv,pdiv=3,scale=0;
|
||||
MHZ*=1000000;
|
||||
mdiv=(MHZ*pdiv)/SYS_CLK_FREQ;
|
||||
mdiv=((mdiv-8)<<8) & 0xff00;
|
||||
pdiv=((pdiv-2)<<2) & 0xfc;
|
||||
scale&=3;
|
||||
v=mdiv | pdiv | scale;
|
||||
MEM_REG[0x910>>1]=v;
|
||||
}
|
||||
|
||||
|
||||
void set_920_Div(unsigned short div)
|
||||
{
|
||||
unsigned short v;
|
||||
v = MEM_REG[0x91c>>1] & (~0x3);
|
||||
MEM_REG[0x91c>>1] = (div & 0x7) | v;
|
||||
}
|
||||
|
||||
|
||||
void set_DCLK_Div( unsigned short div )
|
||||
{
|
||||
unsigned short v;
|
||||
v = (unsigned short)( MEM_REG[0x91c>>1] & (~(0x7 << 6)) );
|
||||
MEM_REG[0x91c>>1] = ((div & 0x7) << 6) | v;
|
||||
}
|
||||
|
||||
/*
|
||||
void Disable_940(void)
|
||||
{
|
||||
MEM_REG[0x3B42>>1];
|
||||
MEM_REG[0x3B42>>1]=0;
|
||||
MEM_REG[0x3B46>>1]=0xffff;
|
||||
MEM_REG[0x3B48>>1]|= (1 << 7);
|
||||
MEM_REG[0x904>>1]&=0xfffe;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short reg, valmask, val;
|
||||
}
|
||||
reg_setting;
|
||||
|
||||
// ~59.998, couldn't figure closer values
|
||||
static reg_setting rate_almost60[] =
|
||||
{
|
||||
{ 0x0914, 0xffff, (212<<8)|(2<<2)|1 }, /* UPLLSETVREG */
|
||||
{ 0x0924, 0xff00, (2<<14)|(36<<8) }, /* DISPCSETREG */
|
||||
{ 0x281A, 0x00ff, 1 }, /* .HSWID(T2) */
|
||||
{ 0x281C, 0x00ff, 0 }, /* .HSSTR(T8) */
|
||||
{ 0x281E, 0x00ff, 2 }, /* .HSEND(T7) */
|
||||
{ 0x2822, 0x01ff, 12 }, /* .VSEND (T9) */
|
||||
{ 0x2826, 0x0ff0, 34<<4 }, /* .DESTR(T3) */
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
// perfect 50Hz?
|
||||
static reg_setting rate_50[] =
|
||||
{
|
||||
{ 0x0914, 0xffff, (39<<8)|(0<<2)|2 }, /* UPLLSETVREG */
|
||||
{ 0x0924, 0xff00, (2<<14)|(7<<8) }, /* DISPCSETREG */
|
||||
{ 0x281A, 0x00ff, 31 }, /* .HSWID(T2) */
|
||||
{ 0x281C, 0x00ff, 16 }, /* .HSSTR(T8) */
|
||||
{ 0x281E, 0x00ff, 15 }, /* .HSEND(T7) */
|
||||
{ 0x2822, 0x01ff, 15 }, /* .VSEND (T9) */
|
||||
{ 0x2826, 0x0ff0, 37<<4 }, /* .DESTR(T3) */
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
// 16639/2 ~120.20
|
||||
static reg_setting rate_120_20[] =
|
||||
{
|
||||
{ 0x0914, 0xffff, (96<<8)|(0<<2)|2 }, /* UPLLSETVREG */
|
||||
{ 0x0924, 0xff00, (2<<14)|(7<<8) }, /* DISPCSETREG */
|
||||
{ 0x281A, 0x00ff, 19 }, /* .HSWID(T2) */
|
||||
{ 0x281C, 0x00ff, 7 }, /* .HSSTR(T8) */
|
||||
{ 0x281E, 0x00ff, 7 }, /* .HSEND(T7) */
|
||||
{ 0x2822, 0x01ff, 12 }, /* .VSEND (T9) */
|
||||
{ 0x2826, 0x0ff0, 37<<4 }, /* .DESTR(T3) */
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
// 19997/2 ~100.02
|
||||
static reg_setting rate_100_02[] =
|
||||
{
|
||||
{ 0x0914, 0xffff, (98<<8)|(0<<2)|2 }, /* UPLLSETVREG */
|
||||
{ 0x0924, 0xff00, (2<<14)|(8<<8) }, /* DISPCSETREG */
|
||||
{ 0x281A, 0x00ff, 26 }, /* .HSWID(T2) */
|
||||
{ 0x281C, 0x00ff, 6 }, /* .HSSTR(T8) */
|
||||
{ 0x281E, 0x00ff, 6 }, /* .HSEND(T7) */
|
||||
{ 0x2822, 0x01ff, 31 }, /* .VSEND (T9) */
|
||||
{ 0x2826, 0x0ff0, 37<<4 }, /* .DESTR(T3) */
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
// 120.00 97/0/2/7|25/ 7/ 7/11/37
|
||||
static reg_setting rate_120[] =
|
||||
{
|
||||
{ 0x0914, 0xffff, (97<<8)|(0<<2)|2 }, /* UPLLSETVREG */
|
||||
{ 0x0924, 0xff00, (2<<14)|(7<<8) }, /* DISPCSETREG */
|
||||
{ 0x281A, 0x00ff, 25 }, /* .HSWID(T2) */
|
||||
{ 0x281C, 0x00ff, 7 }, /* .HSSTR(T8) */
|
||||
{ 0x281E, 0x00ff, 7 }, /* .HSEND(T7) */
|
||||
{ 0x2822, 0x01ff, 11 }, /* .VSEND (T9) */
|
||||
{ 0x2826, 0x0ff0, 37<<4 }, /* .DESTR(T3) */
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
// 100.00 96/0/2/7|29/25/53/15/37
|
||||
static reg_setting rate_100[] =
|
||||
{
|
||||
{ 0x0914, 0xffff, (96<<8)|(0<<2)|2 }, /* UPLLSETVREG */
|
||||
{ 0x0924, 0xff00, (2<<14)|(7<<8) }, /* DISPCSETREG */
|
||||
{ 0x281A, 0x00ff, 29 }, /* .HSWID(T2) */
|
||||
{ 0x281C, 0x00ff, 25 }, /* .HSSTR(T8) */
|
||||
{ 0x281E, 0x00ff, 53 }, /* .HSEND(T7) */
|
||||
{ 0x2822, 0x01ff, 15 }, /* .VSEND (T9) */
|
||||
{ 0x2826, 0x0ff0, 37<<4 }, /* .DESTR(T3) */
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
|
||||
static reg_setting *possible_rates[] = { rate_almost60, rate_50, rate_120_20, rate_100_02, rate_120, rate_100 };
|
||||
|
||||
void set_LCD_custom_rate(lcd_rate_t rate)
|
||||
{
|
||||
reg_setting *set;
|
||||
|
||||
if (MEM_REG[0x2800>>1] & 0x100) // tv-out
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
printf("setting custom LCD refresh, mode=%i... ", rate); fflush(stdout);
|
||||
for (set = possible_rates[rate]; set->reg; set++)
|
||||
{
|
||||
unsigned short val = MEM_REG[set->reg >> 1];
|
||||
val &= ~set->valmask;
|
||||
val |= set->val;
|
||||
MEM_REG[set->reg >> 1] = val;
|
||||
}
|
||||
printf("done.\n");
|
||||
}
|
||||
|
||||
void unset_LCD_custom_rate(void)
|
||||
{
|
||||
printf("reset to prev LCD refresh.\n");
|
||||
MEM_REG[0x914>>1]=system_reg.UPLLVSETREG;
|
||||
MEM_REG[0x924>>1]=system_reg.DISPCSETREG;
|
||||
MEM_REG[0x281A>>1]=system_reg.DPC_HS_WIDTH;
|
||||
MEM_REG[0x281C>>1]=system_reg.DPC_HS_STR;
|
||||
MEM_REG[0x281E>>1]=system_reg.DPC_HS_END;
|
||||
MEM_REG[0x2822>>1]=system_reg.DPC_VS_END;
|
||||
MEM_REG[0x2826>>1]=system_reg.DPC_DE;
|
||||
}
|
||||
|
||||
void set_RAM_Timings(int tRC, int tRAS, int tWR, int tMRD, int tRFC, int tRP, int tRCD)
|
||||
{
|
||||
tRC -= 1; tRAS -= 1; tWR -= 1; tMRD -= 1; tRFC -= 1; tRP -= 1; tRCD -= 1; // ???
|
||||
MEM_REG[0x3802>>1] = ((tMRD & 0xF) << 12) | ((tRFC & 0xF) << 8) | ((tRP & 0xF) << 4) | (tRCD & 0xF);
|
||||
MEM_REG[0x3804>>1] = /*0x9000 |*/ ((tRC & 0xF) << 8) | ((tRAS & 0xF) << 4) | (tWR & 0xF);
|
||||
}
|
||||
|
||||
|
||||
void set_gamma(int g100, int A_SNs_curve)
|
||||
{
|
||||
float gamma = (float) g100 / 100;
|
||||
int i;
|
||||
gamma = 1/gamma;
|
||||
|
||||
//enable gamma
|
||||
MEM_REG[0x2880>>1]&=~(1<<12);
|
||||
|
||||
MEM_REG[0x295C>>1]=0;
|
||||
for(i=0; i<256; i++)
|
||||
{
|
||||
unsigned char g;
|
||||
unsigned short s;
|
||||
const unsigned short grey50=143, grey75=177, grey25=97;
|
||||
float blah;
|
||||
|
||||
if (A_SNs_curve)
|
||||
{
|
||||
// The next formula is all about gaussian interpolation
|
||||
blah = (( -128 * exp(-powf((float) i/64.0f + 2.0f , 2.0f))) +
|
||||
( -64 * exp(-powf((float) i/64.0f + 1.0f , 2.0f))) +
|
||||
(grey25 * exp(-powf((float) i/64.0f - 1.0f , 2.0f))) +
|
||||
(grey50 * exp(-powf((float) i/64.0f - 2.0f , 2.0f))) +
|
||||
(grey75 * exp(-powf((float) i/64.0f - 3.0f , 2.0f))) +
|
||||
( 256 * exp(-powf((float) i/64.0f - 4.0f , 2.0f))) +
|
||||
( 320 * exp(-powf((float) i/64.0f - 5.0f , 2.0f))) +
|
||||
( 384 * exp(-powf((float) i/64.0f - 6.0f , 2.0f)))) / (1.772637f);
|
||||
blah += 0.5f;
|
||||
}
|
||||
else
|
||||
{
|
||||
blah = i;
|
||||
}
|
||||
|
||||
g = (unsigned char)(255.0*pow(blah/255.0,gamma));
|
||||
//printf("%d : %d\n", i, g);
|
||||
s = (g<<8) | g;
|
||||
MEM_REG[0x295E>>1]= s;
|
||||
MEM_REG[0x295E>>1]= g;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,340 +0,0 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef __CPUCTRL_H__
|
||||
#define __CPUCTRL_H__
|
||||
|
||||
extern void cpuctrl_init(void); /* call this at first */
|
||||
extern void save_system_regs(void); /* save some registers */
|
||||
extern void cpuctrl_deinit(void);
|
||||
extern void set_display_clock_div(unsigned div);
|
||||
extern void set_FCLK(unsigned MHZ); /* adjust the clock frequency (in Mhz units) */
|
||||
extern void set_920_Div(unsigned short div); /* 0 to 7 divider (freq=FCLK/(1+div)) */
|
||||
extern void set_DCLK_Div(unsigned short div); /* 0 to 7 divider (freq=FCLK/(1+div)) */
|
||||
//extern void Disable_940(void); /* 940t down */
|
||||
|
||||
extern void set_RAM_Timings(int tRC, int tRAS, int tWR, int tMRD, int tRFC, int tRP, int tRCD);
|
||||
extern void set_gamma(int g100, int A_SNs_curve);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LCDR_60 = 0, /* ~59.998Hz, has interlacing problems, kills USB host */
|
||||
LCDR_50, /* 50Hz, has interlacing problems, kills USB host */
|
||||
LCDR_120_20, /* ~60.10*2Hz, used by FCE Ultra */
|
||||
LCDR_100_02, /* ~50.01*2Hz, used by FCE Ultra */
|
||||
LCDR_120, /* 120Hz */
|
||||
LCDR_100, /* 100Hz */
|
||||
} lcd_rate_t;
|
||||
|
||||
extern void set_LCD_custom_rate(lcd_rate_t rate);
|
||||
extern void unset_LCD_custom_rate(void);
|
||||
|
||||
#endif
|
37
gp2x/emu.c
37
gp2x/emu.c
|
@ -15,7 +15,7 @@
|
|||
#include <stdarg.h>
|
||||
|
||||
#include "emu.h"
|
||||
#include "gp2x.h"
|
||||
#include "plat_gp2x.h"
|
||||
#include "soc.h"
|
||||
#include "../common/menu.h"
|
||||
#include "../common/arm_utils.h"
|
||||
|
@ -24,7 +24,6 @@
|
|||
#include "../common/config.h"
|
||||
#include "../common/input.h"
|
||||
#include "../linux/sndout_oss.h"
|
||||
#include "cpuctrl.h"
|
||||
#include "version.h"
|
||||
|
||||
#include <pico/pico_int.h>
|
||||
|
@ -129,7 +128,7 @@ void emu_Deinit(void)
|
|||
|
||||
// restore gamma
|
||||
if (gp2x_old_gamma != 100)
|
||||
set_gamma(100, 0);
|
||||
set_lcd_gamma(100, 0);
|
||||
}
|
||||
|
||||
void emu_prepareDefaultConfig(void)
|
||||
|
@ -142,7 +141,7 @@ void emu_prepareDefaultConfig(void)
|
|||
defaultConfig.s_PicoAutoRgnOrder = 0x184; // US, EU, JP
|
||||
defaultConfig.s_PicoCDBuffers = 0;
|
||||
defaultConfig.Frameskip = -1; // auto
|
||||
defaultConfig.CPUclock = 200;
|
||||
defaultConfig.CPUclock = -1;
|
||||
defaultConfig.volume = 50;
|
||||
defaultConfig.gamma = 100;
|
||||
defaultConfig.scaling = 0;
|
||||
|
@ -762,7 +761,7 @@ static void tga_dump(void)
|
|||
|
||||
void emu_Loop(void)
|
||||
{
|
||||
static int gp2x_old_clock = 200, EmuOpt_old = 0;
|
||||
static int gp2x_old_clock = -1, EmuOpt_old = 0;
|
||||
char fpsbuff[24]; // fps count c string
|
||||
struct timeval tval; // timing
|
||||
int pframes_done, pframes_shown, pthissec; // "period" frames, used for sync
|
||||
|
@ -772,25 +771,41 @@ void emu_Loop(void)
|
|||
|
||||
printf("entered emu_Loop()\n");
|
||||
|
||||
if ((EmuOpt_old ^ 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(2, 6, 4, 1, 1, 1, 2, 2);
|
||||
else
|
||||
unset_ram_timings();
|
||||
}
|
||||
|
||||
if (gp2x_old_clock < 0)
|
||||
gp2x_old_clock = default_cpu_clock;
|
||||
if (currentConfig.CPUclock < 0)
|
||||
currentConfig.CPUclock = default_cpu_clock;
|
||||
if (gp2x_old_clock != currentConfig.CPUclock) {
|
||||
printf("changing clock to %i...", currentConfig.CPUclock); fflush(stdout);
|
||||
set_FCLK(currentConfig.CPUclock);
|
||||
gp2x_set_cpuclk(currentConfig.CPUclock);
|
||||
gp2x_old_clock = currentConfig.CPUclock;
|
||||
printf(" done\n");
|
||||
}
|
||||
|
||||
if (gp2x_old_gamma != currentConfig.gamma || (EmuOpt_old&0x1000) != (currentConfig.EmuOpt&0x1000)) {
|
||||
set_gamma(currentConfig.gamma, !!(currentConfig.EmuOpt&0x1000));
|
||||
set_lcd_gamma(currentConfig.gamma, !!(currentConfig.EmuOpt&0x1000));
|
||||
gp2x_old_gamma = currentConfig.gamma;
|
||||
printf("updated gamma to %i, A_SN's curve: %i\n", currentConfig.gamma, !!(currentConfig.EmuOpt&0x1000));
|
||||
}
|
||||
|
||||
if ((EmuOpt_old&0x2000) != (currentConfig.EmuOpt&0x2000)) {
|
||||
if (currentConfig.EmuOpt&0x2000)
|
||||
set_LCD_custom_rate(Pico.m.pal ? LCDR_100 : LCDR_120);
|
||||
else unset_LCD_custom_rate();
|
||||
if ((EmuOpt_old ^ currentConfig.EmuOpt) & EOPT_PSYNC) {
|
||||
if (currentConfig.EmuOpt & EOPT_PSYNC)
|
||||
set_lcd_custom_rate(Pico.m.pal);
|
||||
else
|
||||
unset_lcd_custom_rate();
|
||||
}
|
||||
|
||||
if ((EmuOpt_old ^ currentConfig.EmuOpt) & EOPT_MMUHACK)
|
||||
gp2x_make_fb_bufferable(currentConfig.EmuOpt & EOPT_MMUHACK);
|
||||
|
||||
EmuOpt_old = currentConfig.EmuOpt;
|
||||
fpsbuff[0] = 0;
|
||||
|
||||
|
|
26
gp2x/main.c
26
gp2x/main.c
|
@ -1,4 +1,4 @@
|
|||
// (c) Copyright 2006 notaz, All rights reserved.
|
||||
// (c) Copyright 2006-2009 notaz, All rights reserved.
|
||||
// Free for non-commercial use.
|
||||
|
||||
// For commercial use, separate licencing terms must be obtained.
|
||||
|
@ -6,9 +6,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <strings.h>
|
||||
#include <linux/limits.h>
|
||||
|
||||
#include "../common/menu.h"
|
||||
#include "../common/emu.h"
|
||||
|
@ -16,16 +14,11 @@
|
|||
#include "../common/input.h"
|
||||
#include "../common/plat.h"
|
||||
#include "emu.h"
|
||||
#include "940ctl.h"
|
||||
#include "version.h"
|
||||
|
||||
#include "squidgehack.h"
|
||||
#include "cpuctrl.h"
|
||||
|
||||
|
||||
extern char *PicoConfigFile;
|
||||
static int load_state_slot = -1;
|
||||
int mmuhack_status = 0;
|
||||
char **g_argv;
|
||||
|
||||
void parse_cmd_line(int argc, char *argv[])
|
||||
|
@ -83,19 +76,6 @@ int main(int argc, char *argv[])
|
|||
in_probe();
|
||||
in_debug_dump();
|
||||
|
||||
if (currentConfig.EmuOpt&0x10) {
|
||||
int ret = mmuhack();
|
||||
printf("squidge hack code finished and returned %i\n", ret); fflush(stdout);
|
||||
mmuhack_status = ret;
|
||||
}
|
||||
cpuctrl_init();
|
||||
if (currentConfig.EmuOpt&0x100) {
|
||||
printf("setting RAM timings.. "); fflush(stdout);
|
||||
// craigix: --trc 6 --tras 4 --twr 1 --tmrd 1 --trfc 1 --trp 2 --trcd 2
|
||||
set_RAM_Timings(6, 4, 1, 1, 1, 2, 2);
|
||||
printf("done.\n"); fflush(stdout);
|
||||
}
|
||||
sharedmem_init();
|
||||
emu_Init();
|
||||
menu_init();
|
||||
|
||||
|
@ -151,11 +131,7 @@ int main(int argc, char *argv[])
|
|||
endloop:
|
||||
|
||||
emu_Deinit();
|
||||
sharedmem_deinit();
|
||||
cpuctrl_deinit();
|
||||
plat_finish();
|
||||
if (mmuhack_status)
|
||||
mmuunhack();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
104
gp2x/mmuhack.c
104
gp2x/mmuhack.c
|
@ -1,104 +0,0 @@
|
|||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <asm/memory.h>
|
||||
|
||||
#define MMUHACK_MINOR 225
|
||||
#define DEVICE_NAME "mmuhack"
|
||||
|
||||
#if __GNUC__ == 3
|
||||
#include <linux/version.h>
|
||||
static const char __module_kernel_version_gcc3[] __attribute__((__used__)) __attribute__((section(".modinfo"))) =
|
||||
"kernel_version=" UTS_RELEASE;
|
||||
#endif
|
||||
|
||||
static ssize_t mmuhack_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
unsigned int *pgtable;
|
||||
unsigned int *cpt;
|
||||
int i, j;
|
||||
int ttb;
|
||||
int ret = -EFAULT;
|
||||
|
||||
// get the pointer to the translation table base...
|
||||
asm volatile(
|
||||
"stmdb sp!, {r0}\n\t"
|
||||
"mrc p15, 0, r0, c2, c0, 0\n\t"
|
||||
"mov %0, r0\n\t"
|
||||
"ldmia sp!, {r0}\n\t": "=r"(ttb)
|
||||
);
|
||||
|
||||
pgtable = __va(ttb);
|
||||
|
||||
for (i = 0; i < 4096; i ++) if ( (pgtable[i] & 3) == 1 ) {
|
||||
cpt = __va(pgtable[i] & 0xfffffc00);
|
||||
|
||||
for (j = 0; j < 256; j ++) {/*
|
||||
if ( (cpt[j] & 0xfe00000f) == 0x02000002 ) {
|
||||
// set C and B bits in upper 32MB memory area...
|
||||
printk("Set C&B bits %08x\n",cpt[j]);
|
||||
cpt[j] |= 0xFFC;
|
||||
ret = 0;
|
||||
}
|
||||
*/
|
||||
if (((cpt[j] & 0xff000000) == 0x02000000) && ((cpt[j] & 12)==0) )
|
||||
{
|
||||
//printk("Set C&B bits %08x\n",cpt[j]);
|
||||
cpt[j] |= 0xFFC;
|
||||
}
|
||||
//if ((a>=0x31 && a<=0x36) && ((cpt[i] & 12)==0))
|
||||
if (((cpt[j] & 0xff000000) == 0x03000000) && ((cpt[j] & 12)==0))
|
||||
{
|
||||
//printk("Set C&B bits %08x\n",cpt[j]);
|
||||
//printf("SDL c and b bits not set, overwriting\n");
|
||||
cpt[j] |= 0xFFC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// drain the write buffer and flush the tlb caches...
|
||||
asm volatile(
|
||||
"stmdb sp!, {r0}\n\t"
|
||||
"mov r0, #0\n\t"
|
||||
"mcr 15, 0, r0, cr7, cr10, 4\n\t"
|
||||
"mcr 15, 0, r0, cr8, cr7, 0\n\t"
|
||||
"ldmia sp!, {r0}\n\t"
|
||||
);
|
||||
|
||||
if (ret == 0)
|
||||
printk("MMU hack applied.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct file_operations mmuhack_fops = {
|
||||
owner: THIS_MODULE,
|
||||
open: mmuhack_open,
|
||||
};
|
||||
|
||||
|
||||
static struct miscdevice mmuhack = {
|
||||
MMUHACK_MINOR, DEVICE_NAME, &mmuhack_fops
|
||||
};
|
||||
|
||||
static int __init mmuhack_init(void)
|
||||
{
|
||||
misc_register(&mmuhack);
|
||||
/*
|
||||
printk("MMSP2 MMU Hack module.\n");
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit mmuhack_exit(void)
|
||||
{
|
||||
misc_deregister(&mmuhack);
|
||||
/*
|
||||
printk(KERN_ALERT "MMU Hack module removed.\n");
|
||||
*/
|
||||
}
|
||||
|
||||
module_init(mmuhack_init);
|
||||
module_exit(mmuhack_exit);
|
BIN
gp2x/mmuhack.o
BIN
gp2x/mmuhack.o
Binary file not shown.
|
@ -1,4 +0,0 @@
|
|||
Squidge's MMU Hack modularized.
|
||||
Original code by Squidge.
|
||||
Module by Annonymous?
|
||||
Slightly modified by me to suit my need.
|
31
gp2x/plat.c
31
gp2x/plat.c
|
@ -3,8 +3,9 @@
|
|||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "gp2x.h"
|
||||
#include "plat_gp2x.h"
|
||||
#include "soc.h"
|
||||
#include "warm.h"
|
||||
#include "../common/plat.h"
|
||||
#include "../common/readpng.h"
|
||||
#include "../common/menu.h"
|
||||
|
@ -12,6 +13,7 @@
|
|||
#include "../linux/sndout_oss.h"
|
||||
|
||||
/* GP2X local */
|
||||
int default_cpu_clock;
|
||||
void *gp2x_screens[4];
|
||||
|
||||
void gp2x_video_changemode(int bpp)
|
||||
|
@ -44,6 +46,22 @@ void gp2x_memset_all_buffers(int offset, int byte, int len)
|
|||
memset((char *)gp2x_screens[3] + offset, byte, len);
|
||||
}
|
||||
|
||||
void gp2x_make_fb_bufferable(int yes)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
yes = yes ? 1 : 0;
|
||||
ret |= warm_change_cb_range(WCB_B_BIT, yes, gp2x_screens[0], 320*240*2);
|
||||
ret |= warm_change_cb_range(WCB_B_BIT, yes, gp2x_screens[1], 320*240*2);
|
||||
ret |= warm_change_cb_range(WCB_B_BIT, yes, gp2x_screens[2], 320*240*2);
|
||||
ret |= warm_change_cb_range(WCB_B_BIT, yes, gp2x_screens[3], 320*240*2);
|
||||
|
||||
if (ret)
|
||||
fprintf(stderr, "could not make fb buferable.\n");
|
||||
else
|
||||
printf("made fb buferable.\n");
|
||||
}
|
||||
|
||||
/* common */
|
||||
char cpu_clk_name[16] = "GP2X CPU clocks";
|
||||
|
||||
|
@ -92,16 +110,20 @@ void plat_init(void)
|
|||
{
|
||||
case SOCID_MMSP2:
|
||||
mmsp2_init();
|
||||
default_cpu_clock = 200;
|
||||
break;
|
||||
case SOCID_POLLUX:
|
||||
pollux_init();
|
||||
strcpy(cpu_clk_name, "Wiz CPU clock");
|
||||
default_cpu_clock = 533;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "could not recognize SoC, bailing out.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
warm_init();
|
||||
|
||||
gp2x_memset_all_buffers(0, 0, 320*240*2);
|
||||
|
||||
// snd
|
||||
|
@ -110,7 +132,12 @@ void plat_init(void)
|
|||
|
||||
void plat_finish(void)
|
||||
{
|
||||
switch (gp2x_soc)
|
||||
gp2x_soc_t soc;
|
||||
|
||||
warm_finish();
|
||||
|
||||
soc = soc_detect();
|
||||
switch (soc)
|
||||
{
|
||||
case SOCID_MMSP2:
|
||||
mmsp2_finish();
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
#ifndef __GP2X_H__
|
||||
#define __GP2X_H__
|
||||
|
||||
/* video */
|
||||
void gp2x_video_changemode(int bpp);
|
||||
void gp2x_memcpy_all_buffers(void *data, int offset, int len);
|
||||
void gp2x_memset_all_buffers(int offset, int byte, int len);
|
||||
|
||||
/* input */
|
||||
int gp2x_touchpad_read(int *x, int *y);
|
||||
|
||||
#endif
|
||||
#ifndef __GP2X_H__
|
||||
#define __GP2X_H__
|
||||
|
||||
extern int default_cpu_clock;
|
||||
|
||||
/* video */
|
||||
void gp2x_video_changemode(int bpp);
|
||||
void gp2x_memcpy_all_buffers(void *data, int offset, int len);
|
||||
void gp2x_memset_all_buffers(int offset, int byte, int len);
|
||||
void gp2x_make_fb_bufferable(int yes);
|
||||
|
||||
/* input */
|
||||
int gp2x_touchpad_read(int *x, int *y);
|
||||
|
||||
#endif
|
|
@ -9,18 +9,20 @@
|
|||
#include "soc.h"
|
||||
#include "../common/emu.h"
|
||||
|
||||
gp2x_soc_t gp2x_soc = -1;
|
||||
|
||||
gp2x_soc_t soc_detect(void)
|
||||
{
|
||||
volatile unsigned short *memregs;
|
||||
volatile unsigned int *memregl;
|
||||
static gp2x_soc_t ret = -1;
|
||||
int pollux_chipname[0x30/4 + 1];
|
||||
char *pollux_chipname_c = (char *)pollux_chipname;
|
||||
gp2x_soc_t ret = -1;
|
||||
int memdev;
|
||||
int i;
|
||||
|
||||
if (ret != -1)
|
||||
/* already detected */
|
||||
return ret;
|
||||
|
||||
memdev = open("/dev/mem", O_RDONLY);
|
||||
if (memdev == -1)
|
||||
{
|
||||
|
@ -72,7 +74,6 @@ not_pollux_like:
|
|||
out:
|
||||
munmap((void *)memregs, 0x20000);
|
||||
close(memdev);
|
||||
gp2x_soc = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
13
gp2x/soc.h
13
gp2x/soc.h
|
@ -3,8 +3,6 @@ typedef enum {
|
|||
SOCID_POLLUX,
|
||||
} gp2x_soc_t;
|
||||
|
||||
extern gp2x_soc_t gp2x_soc;
|
||||
|
||||
gp2x_soc_t soc_detect(void);
|
||||
|
||||
void mmsp2_init(void);
|
||||
|
@ -13,9 +11,20 @@ void mmsp2_finish(void);
|
|||
void pollux_init(void);
|
||||
void pollux_finish(void);
|
||||
|
||||
/* SoC specific functions */
|
||||
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(int tCAS, int tRC, int tRAS, int tWR, int tMRD, int tRFC, int tRP, int tRCD);
|
||||
void unset_ram_timings(void);
|
||||
|
||||
|
|
222
gp2x/soc_mmsp2.c
222
gp2x/soc_mmsp2.c
|
@ -1,6 +1,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -9,9 +10,10 @@
|
|||
|
||||
#include "soc.h"
|
||||
#include "soc_mmsp2.h"
|
||||
#include "gp2x.h"
|
||||
#include "plat_gp2x.h"
|
||||
#include "../common/emu.h"
|
||||
#include "../common/arm_utils.h"
|
||||
#include "940ctl.h"
|
||||
|
||||
volatile unsigned short *gp2x_memregs;
|
||||
volatile unsigned long *gp2x_memregl;
|
||||
|
@ -136,6 +138,208 @@ void reset940(int yes, int bank)
|
|||
gp2x_memregs[0x3B48>>1] = ((yes&1) << 7) | (bank & 0x03);
|
||||
}
|
||||
|
||||
/*
|
||||
* CPU clock
|
||||
* Fout = (m * Fin) / (p * 2^s)
|
||||
* m = MDIV+8, p = PDIV+2, s = SDIV
|
||||
*
|
||||
* m = (Fout * p * 2^s) / Fin
|
||||
*/
|
||||
|
||||
#define SYS_CLK_FREQ 7372800
|
||||
|
||||
void gp2x_set_cpuclk(unsigned int mhz)
|
||||
{
|
||||
unsigned int mdiv, pdiv, sdiv = 0;
|
||||
unsigned int v;
|
||||
int i;
|
||||
|
||||
pdiv = 3;
|
||||
mdiv = (mhz * pdiv * 1000000) / SYS_CLK_FREQ;
|
||||
if (mdiv & ~0xff) {
|
||||
fprintf(stderr, "invalid cpuclk MHz: %u\n", mhz);
|
||||
return;
|
||||
}
|
||||
v = ((mdiv-8)<<8) | ((pdiv-2)<<2) | sdiv;
|
||||
gp2x_memregs[0x910>>1] = v;
|
||||
|
||||
for (i = 0; i < 10000; i++)
|
||||
if (!(gp2x_memregs[0x902>>1] & 1))
|
||||
break;
|
||||
}
|
||||
|
||||
/* RAM timings */
|
||||
static unsigned short memtimex[2];
|
||||
|
||||
#define TIMING_CHECK(t, adj, mask) \
|
||||
t += adj; \
|
||||
if (t & ~mask) \
|
||||
goto bad
|
||||
|
||||
void set_ram_timings(int tCAS, int tRC, int tRAS, int tWR, int tMRD, int tRFC, int tRP, int tRCD)
|
||||
{
|
||||
int i;
|
||||
TIMING_CHECK(tCAS, -2, 0x1);
|
||||
TIMING_CHECK(tRC, -1, 0xf);
|
||||
TIMING_CHECK(tRAS, -1, 0xf);
|
||||
TIMING_CHECK(tWR, -1, 0xf);
|
||||
TIMING_CHECK(tMRD, -1, 0xf);
|
||||
TIMING_CHECK(tRFC, -1, 0xf);
|
||||
TIMING_CHECK(tRP, -1, 0xf);
|
||||
TIMING_CHECK(tRCD, -1, 0xf);
|
||||
|
||||
/* get spend_cycles() into cache */
|
||||
spend_cycles(1);
|
||||
|
||||
gp2x_memregs[0x3802>>1] = ((tMRD & 0xF) << 12) | ((tRFC & 0xF) << 8) | ((tRP & 0xF) << 4) | (tRCD & 0xF);
|
||||
gp2x_memregs[0x3804>>1] = 0x8000 | ((tCAS & 1) << 12) | ((tRC & 0xF) << 8) | ((tRAS & 0xF) << 4) | (tWR & 0xF);
|
||||
|
||||
/* be sure we don't access the mem while it's being reprogrammed */
|
||||
spend_cycles(128*1024);
|
||||
for (i = 0; i < 8*1024; i++)
|
||||
if (!(gp2x_memregs[0x3804>>1] & 0x8000))
|
||||
break;
|
||||
|
||||
printf("RAM timings set.\n");
|
||||
return;
|
||||
bad:
|
||||
fprintf(stderr, "RAM timings invalid.\n");
|
||||
}
|
||||
|
||||
void unset_ram_timings(void)
|
||||
{
|
||||
gp2x_memregs[0x3802>>1] = memtimex[0];
|
||||
gp2x_memregs[0x3804>>1] = memtimex[1] | 0x8000;
|
||||
printf("RAM timings reset to startup values.\n");
|
||||
}
|
||||
|
||||
/* LCD refresh */
|
||||
typedef struct
|
||||
{
|
||||
unsigned short reg, valmask, val;
|
||||
}
|
||||
reg_setting;
|
||||
|
||||
/* 120.00 97/0/2/7|25/ 7/ 7/11/37 */
|
||||
static const reg_setting lcd_rate_120[] =
|
||||
{
|
||||
{ 0x0914, 0xffff, (97<<8)|(0<<2)|2 }, /* UPLLSETVREG */
|
||||
{ 0x0924, 0xff00, (2<<14)|(7<<8) }, /* DISPCSETREG */
|
||||
{ 0x281A, 0x00ff, 25 }, /* .HSWID(T2) */
|
||||
{ 0x281C, 0x00ff, 7 }, /* .HSSTR(T8) */
|
||||
{ 0x281E, 0x00ff, 7 }, /* .HSEND(T7) */
|
||||
{ 0x2822, 0x01ff, 11 }, /* .VSEND (T9) */
|
||||
{ 0x2826, 0x0ff0, 37<<4 }, /* .DESTR(T3) */
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
/* 100.00 96/0/2/7|29/25/53/15/37 */
|
||||
static const reg_setting lcd_rate_100[] =
|
||||
{
|
||||
{ 0x0914, 0xffff, (96<<8)|(0<<2)|2 }, /* UPLLSETVREG */
|
||||
{ 0x0924, 0xff00, (2<<14)|(7<<8) }, /* DISPCSETREG */
|
||||
{ 0x281A, 0x00ff, 29 }, /* .HSWID(T2) */
|
||||
{ 0x281C, 0x00ff, 25 }, /* .HSSTR(T8) */
|
||||
{ 0x281E, 0x00ff, 53 }, /* .HSEND(T7) */
|
||||
{ 0x2822, 0x01ff, 15 }, /* .VSEND (T9) */
|
||||
{ 0x2826, 0x0ff0, 37<<4 }, /* .DESTR(T3) */
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
static reg_setting lcd_rate_defaults[] =
|
||||
{
|
||||
{ 0x0914, 0xffff, 0 },
|
||||
{ 0x0924, 0xff00, 0 },
|
||||
{ 0x281A, 0x00ff, 0 },
|
||||
{ 0x281C, 0x00ff, 0 },
|
||||
{ 0x281E, 0x00ff, 0 },
|
||||
{ 0x2822, 0x01ff, 0 },
|
||||
{ 0x2826, 0x0ff0, 0 },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
static void get_reg_setting(reg_setting *set)
|
||||
{
|
||||
for (; set->reg; set++)
|
||||
{
|
||||
unsigned short val = gp2x_memregs[set->reg >> 1];
|
||||
val &= set->valmask;
|
||||
set->val = val;
|
||||
}
|
||||
}
|
||||
|
||||
static void set_reg_setting(const reg_setting *set)
|
||||
{
|
||||
for (; set->reg; set++)
|
||||
{
|
||||
unsigned short val = gp2x_memregs[set->reg >> 1];
|
||||
val &= ~set->valmask;
|
||||
val |= set->val;
|
||||
gp2x_memregs[set->reg >> 1] = val;
|
||||
}
|
||||
}
|
||||
|
||||
void set_lcd_custom_rate(int is_pal)
|
||||
{
|
||||
if (gp2x_memregs[0x2800>>1] & 0x100) // tv-out
|
||||
return;
|
||||
|
||||
printf("setting custom LCD refresh (%d Hz)... ", is_pal ? 100 : 120);
|
||||
fflush(stdout);
|
||||
|
||||
set_reg_setting(is_pal ? lcd_rate_100 : lcd_rate_120);
|
||||
printf("done.\n");
|
||||
}
|
||||
|
||||
void unset_lcd_custom_rate(void)
|
||||
{
|
||||
printf("reset to prev LCD refresh.\n");
|
||||
set_reg_setting(lcd_rate_defaults);
|
||||
}
|
||||
|
||||
void set_lcd_gamma(int g100, int A_SNs_curve)
|
||||
{
|
||||
float gamma = (float) g100 / 100;
|
||||
int i;
|
||||
gamma = 1 / gamma;
|
||||
|
||||
/* enable gamma */
|
||||
gp2x_memregs[0x2880>>1] &= ~(1<<12);
|
||||
|
||||
gp2x_memregs[0x295C>>1] = 0;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
unsigned char g;
|
||||
unsigned short s;
|
||||
const unsigned short grey50=143, grey75=177, grey25=97;
|
||||
double blah;
|
||||
|
||||
if (A_SNs_curve)
|
||||
{
|
||||
// The next formula is all about gaussian interpolation
|
||||
blah = (( -128 * exp(-powf((float) i/64.0f + 2.0f , 2.0f))) +
|
||||
( -64 * exp(-powf((float) i/64.0f + 1.0f , 2.0f))) +
|
||||
(grey25 * exp(-powf((float) i/64.0f - 1.0f , 2.0f))) +
|
||||
(grey50 * exp(-powf((float) i/64.0f - 2.0f , 2.0f))) +
|
||||
(grey75 * exp(-powf((float) i/64.0f - 3.0f , 2.0f))) +
|
||||
( 256 * exp(-powf((float) i/64.0f - 4.0f , 2.0f))) +
|
||||
( 320 * exp(-powf((float) i/64.0f - 5.0f , 2.0f))) +
|
||||
( 384 * exp(-powf((float) i/64.0f - 6.0f , 2.0f)))) / 1.772637;
|
||||
blah += 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
blah = i;
|
||||
}
|
||||
|
||||
g = (unsigned char)(255.0 * pow(blah/255.0, gamma));
|
||||
//printf("%d : %d\n", i, g);
|
||||
s = (g<<8) | g;
|
||||
gp2x_memregs[0x295E>>1]= s;
|
||||
gp2x_memregs[0x295E>>1]= g;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* these are not quite MMSP2 related,
|
||||
* more to GP2X F100/F200 consoles themselves. */
|
||||
|
@ -244,7 +448,14 @@ void mmsp2_init(void)
|
|||
|
||||
memcpy(gp2x_screenaddrs_use, gp2x_screenaddrs, sizeof(gp2x_screenaddrs));
|
||||
|
||||
// touchscreen
|
||||
/* default LCD refresh */
|
||||
get_reg_setting(lcd_rate_defaults);
|
||||
|
||||
/* RAM timings */
|
||||
memtimex[0] = gp2x_memregs[0x3802>>1];
|
||||
memtimex[1] = gp2x_memregs[0x3804>>1];
|
||||
|
||||
/* touchscreen */
|
||||
touchdev = open("/dev/touchscreen/wm97xx", O_RDONLY);
|
||||
if (touchdev >= 0) {
|
||||
FILE *pcf = fopen("/etc/pointercal", "r");
|
||||
|
@ -259,18 +470,25 @@ void mmsp2_init(void)
|
|||
/* disable Linux read-ahead */
|
||||
proc_set("/proc/sys/vm/max-readahead", "0\n");
|
||||
proc_set("/proc/sys/vm/min-readahead", "0\n");
|
||||
|
||||
/* code940 portion */
|
||||
sharedmem940_init();
|
||||
}
|
||||
|
||||
void mmsp2_finish(void)
|
||||
{
|
||||
reset940(1, 3);
|
||||
pause940(1);
|
||||
sharedmem940_finish();
|
||||
|
||||
gp2x_memregs[0x290E>>1] = gp2x_screenaddr_old[0];
|
||||
gp2x_memregs[0x2910>>1] = gp2x_screenaddr_old[1];
|
||||
gp2x_memregs[0x2912>>1] = gp2x_screenaddr_old[2];
|
||||
gp2x_memregs[0x2914>>1] = gp2x_screenaddr_old[3];
|
||||
|
||||
unset_ram_timings();
|
||||
unset_lcd_custom_rate();
|
||||
|
||||
munmap(gp2x_screens[0], FRAMEBUFF_WHOLESIZE);
|
||||
munmap((void *)gp2x_memregs, 0x10000);
|
||||
close(memdev);
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern char **g_argv;
|
||||
|
||||
/* Call this MMU Hack kernel module after doing mmap, and before doing memset*/
|
||||
int mmuhack(void)
|
||||
{
|
||||
char kocmd[1024];
|
||||
int i, mmufd;
|
||||
|
||||
/* some programs like some versions of gpSP use some weird version of mmuhack.o
|
||||
* which doesn't seem to work. What's even worse they leave their mmuhack loaded on exit.
|
||||
* So we must remove whatever may be left and always reload _our_ mmuhack.o */
|
||||
system("/sbin/rmmod mmuhack");
|
||||
|
||||
strcpy(kocmd, "/sbin/insmod ");
|
||||
strncpy(kocmd+13, g_argv[0], 1023-13);
|
||||
kocmd[1023] = 0;
|
||||
for (i = strlen(kocmd); i > 13; i--)
|
||||
if (kocmd[i] == '/') { i++; break; }
|
||||
strcpy(kocmd+i, "mmuhack.o");
|
||||
|
||||
printf("Installing NK's kernel module for Squidge MMU Hack (%s)...\n", kocmd);
|
||||
system(kocmd);
|
||||
mmufd = open("/dev/mmuhack", O_RDWR);
|
||||
if(mmufd < 0) return 0;
|
||||
|
||||
close(mmufd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Unload MMU Hack kernel module after closing all memory devices*/
|
||||
int mmuunhack(void)
|
||||
{
|
||||
int ret;
|
||||
printf("Removing NK's kernel module for Squidge MMU Hack... "); fflush(stdout);
|
||||
ret = system("/sbin/rmmod mmuhack");
|
||||
printf("done (%i)\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
#ifndef __MMUHACK__
|
||||
#define __MMUHACK__
|
||||
|
||||
extern int mmuhack(void);
|
||||
extern int mmuunhack(void);
|
||||
|
||||
#endif /* __MMUHACK__ */
|
254
gp2x/warm.c
Normal file
254
gp2x/warm.c
Normal file
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* wARM - exporting ARM processor specific privileged services to userspace
|
||||
* userspace part
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define WARM_CODE
|
||||
#include "warm.h"
|
||||
|
||||
/* provided by glibc */
|
||||
extern long init_module(void *, unsigned long, const char *);
|
||||
extern long delete_module(const char *, unsigned int);
|
||||
|
||||
static int warm_fd = -1;
|
||||
static int kernel_version;
|
||||
|
||||
static void sys_cacheflush(void *start, void *end)
|
||||
{
|
||||
#ifdef __ARM_EABI__
|
||||
/* EABI version */
|
||||
int num = __ARM_NR_cacheflush;
|
||||
__asm__("mov r0, %0 ;"
|
||||
"mov r1, %1 ;"
|
||||
"mov r2, #0 ;"
|
||||
"mov r7, %2 ;"
|
||||
"swi 0" : : "r" (start), "r" (end), "r" (num)
|
||||
: "r0", "r1", "r2", "r3", "r7");
|
||||
#else
|
||||
/* OABI */
|
||||
__asm__("mov r0, %0 ;"
|
||||
"mov r1, %1 ;"
|
||||
"mov r2, #0 ;"
|
||||
"swi %2" : : "r" (start), "r" (end), "i" __ARM_NR_cacheflush
|
||||
: "r0", "r1", "r2", "r3");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Those are here because system() occasionaly fails on Wiz
|
||||
* with errno 12 for some unknown reason */
|
||||
static int manual_insmod_26(const char *fname, const char *opts)
|
||||
{
|
||||
unsigned long len, read_len;
|
||||
int ret = -1;
|
||||
void *buff;
|
||||
FILE *f;
|
||||
|
||||
f = fopen(fname, "rb");
|
||||
if (f == NULL)
|
||||
return -1;
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
len = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
buff = malloc(len);
|
||||
if (buff == NULL)
|
||||
goto fail0;
|
||||
|
||||
read_len = fread(buff, 1, len, f);
|
||||
if (read_len != len) {
|
||||
fprintf(stderr, "failed to read module\n");
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
ret = init_module(buff, len, opts);
|
||||
|
||||
fail1:
|
||||
free(buff);
|
||||
fail0:
|
||||
fclose(f);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int manual_rmmod(const char *name)
|
||||
{
|
||||
return delete_module(name, O_NONBLOCK|O_EXCL);
|
||||
}
|
||||
|
||||
int warm_init(void)
|
||||
{
|
||||
struct utsname unm;
|
||||
char buff1[32], buff2[128];
|
||||
int ret;
|
||||
|
||||
memset(&unm, 0, sizeof(unm));
|
||||
uname(&unm);
|
||||
|
||||
if (strlen(unm.release) < 3 || unm.release[1] != '.') {
|
||||
fprintf(stderr, "unexpected version string: %s\n", unm.release);
|
||||
goto fail;
|
||||
}
|
||||
kernel_version = ((unm.release[0] - '0') << 4) | (unm.release[2] - '0');
|
||||
|
||||
warm_fd = open("/proc/warm", O_RDWR);
|
||||
if (warm_fd >= 0)
|
||||
return 0;
|
||||
|
||||
snprintf(buff1, sizeof(buff1), "warm_%s.%s", unm.release, kernel_version >= 0x26 ? "ko" : "o");
|
||||
snprintf(buff2, sizeof(buff2), "/sbin/insmod %s verbose=1", buff1);
|
||||
|
||||
/* try to insmod */
|
||||
ret = system(buff2);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "system/insmod failed: %d %d\n", ret, errno);
|
||||
if (kernel_version >= 0x26) {
|
||||
ret = manual_insmod_26(buff1, "verbose=1");
|
||||
if (ret != 0)
|
||||
fprintf(stderr, "manual insmod also failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
warm_fd = open("/proc/warm", O_RDWR);
|
||||
if (warm_fd >= 0)
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
fprintf(stderr, "wARM: can't init, acting as sys_cacheflush wrapper\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void warm_finish(void)
|
||||
{
|
||||
char name[32], cmd[64];
|
||||
int ret;
|
||||
|
||||
if (warm_fd < 0)
|
||||
return;
|
||||
|
||||
close(warm_fd);
|
||||
warm_fd = -1;
|
||||
|
||||
if (kernel_version < 0x26) {
|
||||
struct utsname unm;
|
||||
memset(&unm, 0, sizeof(unm));
|
||||
uname(&unm);
|
||||
snprintf(name, sizeof(name), "warm_%s", unm.release);
|
||||
}
|
||||
else
|
||||
strcpy(name, "warm");
|
||||
|
||||
snprintf(cmd, sizeof(cmd), "/sbin/rmmod %s", name);
|
||||
ret = system(cmd);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "system/rmmod failed: %d %d\n", ret, errno);
|
||||
manual_rmmod(name);
|
||||
}
|
||||
}
|
||||
|
||||
int warm_cache_op_range(int op, void *addr, unsigned long size)
|
||||
{
|
||||
struct warm_cache_op wop;
|
||||
int ret;
|
||||
|
||||
if (warm_fd < 0) {
|
||||
/* note that this won't work for warm_cache_op_all */
|
||||
sys_cacheflush(addr, (char *)addr + size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
wop.ops = op;
|
||||
wop.addr = (unsigned long)addr;
|
||||
wop.size = size;
|
||||
|
||||
ret = ioctl(warm_fd, WARMC_CACHE_OP, &wop);
|
||||
if (ret != 0) {
|
||||
perror("WARMC_CACHE_OP failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int warm_cache_op_all(int op)
|
||||
{
|
||||
return warm_cache_op_range(op, NULL, (unsigned long)-1);
|
||||
}
|
||||
|
||||
int warm_change_cb_range(int cb, int is_set, void *addr, unsigned long size)
|
||||
{
|
||||
struct warm_change_cb ccb;
|
||||
int ret;
|
||||
|
||||
if (warm_fd < 0)
|
||||
return -1;
|
||||
|
||||
ccb.addr = (unsigned long)addr;
|
||||
ccb.size = size;
|
||||
ccb.cb = cb;
|
||||
ccb.is_set = is_set;
|
||||
|
||||
ret = ioctl(warm_fd, WARMC_CHANGE_CB, &ccb);
|
||||
if (ret != 0) {
|
||||
perror("WARMC_CHANGE_CB failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int warm_change_cb_upper(int cb, int is_set)
|
||||
{
|
||||
return warm_change_cb_range(cb, is_set, 0, 0);
|
||||
}
|
||||
|
||||
unsigned long warm_virt2phys(const void *ptr)
|
||||
{
|
||||
unsigned long ptrio;
|
||||
int ret;
|
||||
|
||||
ptrio = (unsigned long)ptr;
|
||||
ret = ioctl(warm_fd, WARMC_VIRT2PHYS, &ptrio);
|
||||
if (ret != 0) {
|
||||
perror("WARMC_VIRT2PHYS failed");
|
||||
return (unsigned long)-1;
|
||||
}
|
||||
|
||||
return ptrio;
|
||||
}
|
||||
|
100
gp2x/warm.h
Normal file
100
gp2x/warm.h
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* wARM - exporting ARM processor specific privileged services to userspace
|
||||
* library functions
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __WARM_H__
|
||||
#define __WARM_H__ 1
|
||||
|
||||
/* cache operations (warm_cache_op_*):
|
||||
* o clean - write dirty data to memory, but also leave in cache.
|
||||
* o invalidate - throw away everything in cache, losing dirty data.
|
||||
*
|
||||
* Write buffer is always drained, no ops will only drain WB
|
||||
*/
|
||||
#define WOP_D_CLEAN (1 << 0)
|
||||
#define WOP_D_INVALIDATE (1 << 1)
|
||||
#define WOP_I_INVALIDATE (1 << 2)
|
||||
|
||||
/* change C and B bits (warm_change_cb_*)
|
||||
* if is_set in not zero, bits are set, else cleared.
|
||||
* the address for range function is virtual address.
|
||||
*/
|
||||
#define WCB_C_BIT (1 << 0)
|
||||
#define WCB_B_BIT (1 << 1)
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
int warm_init(void);
|
||||
|
||||
int warm_cache_op_range(int ops, void *virt_addr, unsigned long size);
|
||||
int warm_cache_op_all(int ops);
|
||||
|
||||
int warm_change_cb_upper(int cb, int is_set);
|
||||
int warm_change_cb_range(int cb, int is_set, void *virt_addr, unsigned long size);
|
||||
|
||||
unsigned long warm_virt2phys(const void *ptr);
|
||||
|
||||
void warm_finish(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* internal */
|
||||
#ifdef WARM_CODE
|
||||
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
#define WARM_IOCTL_BASE 'A'
|
||||
|
||||
struct warm_cache_op
|
||||
{
|
||||
unsigned long addr;
|
||||
unsigned long size;
|
||||
int ops;
|
||||
};
|
||||
|
||||
struct warm_change_cb
|
||||
{
|
||||
unsigned long addr;
|
||||
unsigned long size;
|
||||
int cb;
|
||||
int is_set;
|
||||
};
|
||||
|
||||
#define WARMC_CACHE_OP _IOW(WARM_IOCTL_BASE, 0, struct warm_cache_op)
|
||||
#define WARMC_CHANGE_CB _IOW(WARM_IOCTL_BASE, 1, struct warm_change_cb)
|
||||
#define WARMC_VIRT2PHYS _IOWR(WARM_IOCTL_BASE, 2, unsigned long)
|
||||
|
||||
#endif /* WARM_CODE */
|
||||
#endif /* !__ASSEMBLER__ */
|
||||
#endif /* __WARM_H__ */
|
|
@ -1,4 +1,5 @@
|
|||
/* faked 940 code just uses local copy of ym2612 */
|
||||
/* TODO: rm this */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -9,7 +10,7 @@
|
|||
#include <errno.h>
|
||||
|
||||
#include "../../pico/sound/ym2612.h"
|
||||
#include "../gp2x/gp2x.h"
|
||||
//#include "../gp2x/gp2x.h"
|
||||
#include "../gp2x/emu.h"
|
||||
#include "../gp2x/code940/940shared.h"
|
||||
#include "../common/helix/pub/mp3dec.h"
|
||||
|
|
40
linux/gp2x.c
40
linux/gp2x.c
|
@ -13,7 +13,7 @@
|
|||
#include <errno.h>
|
||||
|
||||
#include "../gp2x/emu.h"
|
||||
#include "../gp2x/gp2x.h"
|
||||
//#include "../gp2x/gp2x.h"
|
||||
#include "../gp2x/version.h"
|
||||
#include "../common/emu.h"
|
||||
#include "sndout_oss.h"
|
||||
|
@ -333,56 +333,22 @@ void reset940(int yes, int bank)
|
|||
{
|
||||
}
|
||||
|
||||
/* faking gp2x cpuctrl.c */
|
||||
void cpuctrl_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
void cpuctrl_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
void set_FCLK(unsigned MHZ)
|
||||
{
|
||||
}
|
||||
|
||||
void Disable_940(void)
|
||||
{
|
||||
}
|
||||
|
||||
void gp2x_video_wait_vsync(void)
|
||||
{
|
||||
}
|
||||
|
||||
void set_RAM_Timings(int tRC, int tRAS, int tWR, int tMRD, int tRFC, int tRP, int tRCD)
|
||||
{
|
||||
}
|
||||
|
||||
void set_gamma(int g100, int A_SNs_curve)
|
||||
{
|
||||
}
|
||||
|
||||
void set_LCD_custom_rate(int rate)
|
||||
void set_lcd_custom_rate(int rate)
|
||||
{
|
||||
}
|
||||
|
||||
void unset_LCD_custom_rate(void)
|
||||
void unset_lcd_custom_rate(void)
|
||||
{
|
||||
}
|
||||
|
||||
/* squidgehack.c */
|
||||
int mmuhack(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int mmuunhack(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* misc */
|
||||
void spend_cycles(int c)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue