Major Rockboy update.

1) Adapt Rockboy to smaller screens (H10, X5, and iPod Nano).
2) Add the ability to use a preset palette on color targets. Choose 'Set Palette' from the main menu.
3) Clean up the code to remove any unused code and variables.
4) Changed tabs to spaces.
5) Disable reading and writing sound when sound is disabled.
6) Disbable writing to the RTC since it is not implemented yet.
7) Minor optimizations from WAC gnuboy CE and iBoy.
8) Massive clean up of code to make it appear consistent.
9) Change all C++ style comments to C style.
10) Completely reorganize dynarec. Add fixmes to all unimplemented opcodes. Add debug writes for all opcodes. Attempt to implement a few opcodes myself.
11) Silence some warnings when built using dynarec.
12) Minor reshuffling of IRAM, may or not offer a speed increase.
13) Include fixes found in the short-lived gnuboy CVS.

All in all, there's about a 10% improvement on my test roms when sound is disabled and slight improvement with sound. Especially noticable when there are few sprites on screen and less action is occurring. See FS #6567.


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12216 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Tom Ross 2007-02-06 21:41:08 +00:00
parent 1026c0f5b2
commit 2882b26a99
48 changed files with 4891 additions and 5419 deletions

View File

@ -5,11 +5,7 @@
/* For various targets... */
#if (CONFIG_KEYPAD == RECORDER_PAD) || \
(CONFIG_KEYPAD == IRIVER_H100_PAD) || \
(CONFIG_KEYPAD == IRIVER_H300_PAD) || \
defined(IPOD_COLOR) || \
defined(IPOD_VIDEO) || \
defined(TOSHIBA_GIGABEAT_F) || \
defined(SANSA_E200)
defined(HAVE_LCD_COLOR)
rockboy
#endif

View File

@ -18,11 +18,9 @@ endif
LINKFILE := $(OBJDIR)/link.lds
DEPFILE = $(OBJDIR)/dep-rockboy
SRC = cpu.c emu.c events.c exports.c fastmem.c hw.c lcd.c lcdc.c loader.c \
main.c mem.c rbsound.c rccmds.c rcvars.c rtc.c save.c sound.c split.c \
sys_rockbox.c rockboy.c menu.c
SRC = cpu.c emu.c events.c fastmem.c hw.c lcd.c lcdc.c loader.c main.c \
mem.c menu.c rbsound.c rockboy.c rtc.c save.c sound.c sys_rockbox.c
#CFLAGS += -DGRAYSCALE
#CFLAGS += -DDYNAREC
#SRC += dynarec.c
@ -30,7 +28,6 @@ SOURCES = $(SRC)
OBJS := $(SRC:%.c=$(OBJDIR)/%.o)
DIRS = .
ifndef SIMVER
ifneq (,$(findstring RECORDER,$(TARGET))) ## Archos recorder targets
LDS := archos.lds

View File

@ -1,5 +0,0 @@
#define VERSION "1.0.3" /*
VERSION = 1.0.3
# */

View File

@ -10,24 +10,24 @@
union reg
{
byte b[2][2];
word w[2];
un32 d; /* padding for alignment, carry */
byte b[2][2];
word w[2];
un32 d; /* padding for alignment, carry */
};
struct cpu
{
#ifdef DYNAREC
union reg a,b,c,d,e,hl,f,sp,pc;
union reg a,b,c,d,e,hl,f,sp,pc;
#else
union reg pc, sp, bc, de, hl, af;
union reg pc, sp, bc, de, hl, af;
#endif
int ime, ima;
int speed;
int halt;
int div, tim;
int lcdc;
int snd;
int ime, ima;
int speed;
int halt;
int div, tim;
int lcdc;
int snd;
};
extern struct cpu cpu;
@ -54,6 +54,6 @@ void lcdc_advance(int cnt) ICODE_ATTR;
void sound_advance(int cnt) ICODE_ATTR;
void cpu_timers(int cnt) ICODE_ATTR;
int cpu_emulate(int cycles) ICODE_ATTR;
inline int cpu_step(int max);
inline int cpu_step(int max) ICODE_ATTR;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -4,275 +4,254 @@
static const byte cycles_table[256]ICONST_ATTR =
{
1, 3, 2, 2, 1, 1, 2, 1, 5, 2, 2, 2, 1, 1, 2, 1,
1, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1,
3, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1,
3, 3, 2, 2, 1, 3, 3, 3, 3, 2, 2, 2, 1, 1, 2, 1,
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,
2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1,
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,
5, 3, 4, 4, 6, 4, 2, 4, 5, 4, 4, 1, 6, 6, 2, 4,
5, 3, 4, 0, 6, 4, 2, 4, 5, 4, 4, 0, 6, 0, 2, 4,
3, 3, 2, 0, 0, 4, 2, 4, 4, 1, 4, 0, 0, 0, 2, 4,
3, 3, 2, 1, 0, 4, 2, 4, 3, 2, 4, 1, 0, 0, 2, 4,
1, 3, 2, 2, 1, 1, 2, 1, 5, 2, 2, 2, 1, 1, 2, 1,
1, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1,
3, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1,
3, 3, 2, 2, 3, 3, 3, 1, 3, 2, 2, 2, 1, 1, 2, 1,
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,
2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1,
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,
5, 3, 4, 4, 6, 4, 2, 4, 5, 4, 4, 1, 6, 6, 2, 4,
5, 3, 4, 0, 6, 4, 2, 4, 5, 4, 4, 0, 6, 0, 2, 4,
3, 3, 2, 0, 0, 4, 2, 4, 4, 1, 4, 0, 0, 0, 2, 4,
3, 3, 2, 1, 0, 4, 2, 4, 3, 2, 4, 1, 0, 0, 2, 4,
};
static const byte cb_cycles_table[256] ICONST_ATTR =
{
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,
2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,
2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,
2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
};
static const byte zflag_table[256] ICONST_ATTR =
{
FZ, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,
2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,
2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,
2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,
};
static const byte incflag_table[256] ICONST_ATTR =
{
FZ|FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
FZ|FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
FH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static const byte decflag_table[256] ICONST_ATTR =
{
FZ|FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH
FZ|FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH,
FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN, FN|FH
};
static const byte swap_table[256] ICONST_ATTR =
{
0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73, 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74, 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75, 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76, 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77, 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78, 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79, 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A, 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B, 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C, 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D, 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E, 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F, 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF,
0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73, 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74, 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75, 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76, 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77, 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78, 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79, 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A, 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B, 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C, 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D, 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E, 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F, 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF,
};
static const byte daa_table[4096] ICONST_ATTR=
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A,
};
static const byte daa_carry_table[64] ICONST_ATTR =
{
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00, 00, 00, 00, 00, 00, 00, 00, FC, FC, 00, 00, 00, 00, 00, 00,
FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC,
FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, 00, FC,
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
00, 00, 00, 00, 00, 00, 00, 00, FC, FC, 00, 00, 00, 00, 00, 00,
FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC,
FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, 00, FC,
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -5,24 +5,9 @@
#include "cpu-gb.h"
#include "mem.h"
#include "lcd-gb.h"
#include "rc.h"
#include "sound.h"
#include "rtc-gb.h"
static int framelen = 16743;
static int framecount;
rcvar_t emu_exports[] =
{
RCV_INT("framelen", &framelen),
RCV_INT("framecount", &framecount),
RCV_END
};
void emu_init(void)
{
}
/*
* emu_reset is called to initialize the state of the emulated
* system. It should set cpu registers, hardware registers, etc. to
@ -47,9 +32,8 @@ void emu_step(void)
* make things work in the mean time. */
void emu_run(void)
{
// void *timer = sys_timer();
/*void *timer = sys_timer();*/
int framesin=0,frames=0,timeten=*rb->current_tick, timehun=*rb->current_tick;
// int delay;
setvidmode(options.fullscreen);
vid_begin();
@ -63,24 +47,25 @@ void emu_run(void)
while (R_LY > 0 && R_LY < 144)
emu_step();
rtc_tick();
sound_mix();
if (!pcm_submit())
/* rtc_tick(); */ /* RTC support not implemented */
if(options.sound)
{
/* delay = framelen - sys_elapsed(timer);
sys_sleep(delay);
sys_elapsed(timer);*/
sound_mix();
pcm_submit();
}
doevents();
vid_begin();
if (!(R_LCDC & 0x80))
cpu_emulate(32832);
while (R_LY > 0) /* wait for next frame */
{
emu_step();
rb->yield();
rb->yield();
}
frames++;
framesin++;

View File

@ -1,2 +1,2 @@
void emu_reset(void);
void emu_run(void);
void emu_run(void) ICODE_ATTR;

View File

@ -8,10 +8,6 @@
#include "rockmacros.h"
#include "input.h"
char keystates[MAX_KEYS];
int nkeysdown;
#define MAX_EVENTS 32
static event_t eventqueue[MAX_EVENTS];
@ -20,34 +16,23 @@ static int eventhead, eventpos;
int ev_postevent(event_t *ev)
{
int nextevent;
nextevent = (eventhead+1)%MAX_EVENTS;
if (nextevent == eventpos)
return 0;
eventqueue[eventhead] = *ev;
eventhead = nextevent;
return 1;
int nextevent;
nextevent = (eventhead+1)%MAX_EVENTS;
if (nextevent == eventpos)
return 0;
eventqueue[eventhead] = *ev;
eventhead = nextevent;
return 1;
}
int ev_getevent(event_t *ev)
{
if (eventpos == eventhead)
{
ev->type = EV_NONE;
return 0;
}
*ev = eventqueue[eventpos];
eventpos = (eventpos+1)%MAX_EVENTS;
if (ev->type == EV_PRESS)
{
keystates[ev->code] = 1;
nkeysdown++;
}
if (ev->type == EV_RELEASE)
{
keystates[ev->code] = 0;
nkeysdown--;
if (nkeysdown < 0) nkeysdown = 0;
}
return 1;
if (eventpos == eventhead)
{
ev->type = EV_NONE;
return 0;
}
*ev = eventqueue[eventpos];
eventpos = (eventpos+1)%MAX_EVENTS;
return 1;
}

View File

@ -1,42 +0,0 @@
#include "rockmacros.h"
#include "rc.h"
extern rcvar_t emu_exports[], loader_exports[],
lcd_exports[], rtc_exports[], sound_exports[],
vid_exports[], joy_exports[], pcm_exports[];
rcvar_t *sources[] =
{
emu_exports,
loader_exports,
lcd_exports,
rtc_exports,
sound_exports,
vid_exports,
joy_exports,
pcm_exports,
NULL
};
void init_exports(void)
{
rcvar_t **s = sources;
while (*s)
rc_exportvars(*(s++));
}
void show_exports(void)
{
// TODO
/*int i, j;
for (i = 0; sources[i]; i++)
for (j = 0; sources[i][j].name; j++)
printf("%s\n", sources[i][j].name);*/
}

View File

@ -1,2 +0,0 @@
void init_exports(void);
void show_exports(void);

View File

@ -3,136 +3,75 @@
#include "rockmacros.h"
#include "fastmem.h"
#define D 0 /* direct */
#define C 1 /* direct cgb-only */
#define R 2 /* io register */
#define S 3 /* sound register */
#define W 4 /* wave pattern */
#define F 0xFF /* fail */
const byte himask[256];
const byte hi_rmap[256] =
{
0, 0, R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S,
S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, C, 0, C,
0, C, C, C, C, C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, C, C, C, C, 0, 0, 0, 0,
C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
const byte hi_wmap[256] =
{
R, R, R, R, R, R, R, R, R, R, R, R, R, R, R, R,
S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S,
S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S,
S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S,
R, R, R, R, R, R, R, R, R, R, R, R, 0, R, 0, R,
0, C, C, C, C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, R, R, R, R, 0, 0, 0, 0,
R, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, R
};
byte readb(int a)
{
byte *p = mbc.rmap[a>>12];
if (p) return p[a];
else return mem_read(a);
byte *p = mbc.rmap[a>>12];
if (p) return p[a];
else return mem_read(a);
}
void writeb(int a, byte b)
{
byte *p = mbc.wmap[a>>12];
if (p) p[a] = b;
else mem_write(a, b);
byte *p = mbc.wmap[a>>12];
if (p) p[a] = b;
else mem_write(a, b);
}
int readw(int a)
{
if ((a+1) & 0xfff)
{
byte *p = mbc.rmap[a>>12];
if (p)
{
if ((a+1) & 0xfff)
{
byte *p = mbc.rmap[a>>12];
if (p)
{
#ifdef ROCKBOX_LITTLE_ENDIAN
#ifndef ALLOW_UNALIGNED_IO
if (a&1) return p[a] | (p[a+1]<<8);
if (a&1) return p[a] | (p[a+1]<<8);
#endif
return *(word *)(p+a);
return *(word *)(p+a);
#else
return p[a] | (p[a+1]<<8);
return p[a] | (p[a+1]<<8);
#endif
}
}
return mem_read(a) | (mem_read(a+1)<<8);
}
}
return mem_read(a) | (mem_read(a+1)<<8);
}
void writew(int a, int w)
{
if ((a+1) & 0xfff)
{
byte *p = mbc.wmap[a>>12];
if (p)
{
if ((a+1) & 0xfff)
{
byte *p = mbc.wmap[a>>12];
if (p)
{
#ifdef ROCKBOX_LITTLE_ENDIAN
#ifndef ALLOW_UNALIGNED_IO
if (a&1)
{
p[a] = w;
p[a+1] = w >> 8;
return;
}
if (a&1)
{
p[a] = w;
p[a+1] = w >> 8;
return;
}
#endif
*(word *)(p+a) = w;
return;
*(word *)(p+a) = w;
return;
#else
p[a] = w;
p[a+1] = w >> 8;
return;
p[a] = w;
p[a+1] = w >> 8;
return;
#endif
}
}
mem_write(a, w);
mem_write(a+1, w>>8);
}
}
mem_write(a, w);
mem_write(a+1, w>>8);
}
byte readhi(int a)
{
return readb(a | 0xff00);
return readb(a | 0xff00);
}
void writehi(int a, byte b)
{
writeb(a | 0xff00, b);
writeb(a | 0xff00, b);
}
#if 0
byte readhi(int a)
{
byte (*rd)() = hi_read[a];
return rd ? rd(a) : (ram.hi[a] | himask[a]);
}
void writehi(int a, byte b)
{
byte (*wr)() = hi_write[a];
if (wr) wr(a, b);
else ram.hi[a] = b & ~himask[a];
}
#endif

View File

@ -13,10 +13,5 @@ int readw(int a) ICODE_ATTR;
void writew(int a, int w) ICODE_ATTR;
byte readhi(int a) ICODE_ATTR;
void writehi(int a, byte b) ICODE_ATTR;
#if 0
byte readhi(int a);
void writehi(int a, byte b);
#endif
#endif

View File

@ -10,19 +10,15 @@
struct fb
{
fb_data *ptr;
int w, h;
int pelsize;
int pitch;
int indexed;
struct
{
int l, r;
} cc[4];
int yuv;
int enabled;
int dirty;
int mode;
fb_data *ptr;
struct
{
int l, r;
} cc[3];
int enabled;
#if !defined(HAVE_LCD_COLOR)
int mode;
#endif
};

View File

@ -11,7 +11,7 @@
#include "fastmem.h"
struct hw hw;
struct hw hw IBSS_ATTR;
@ -24,17 +24,17 @@ struct hw hw;
void hw_interrupt(byte i, byte mask)
{
byte oldif = R_IF;
i &= 0x1F & mask;
R_IF |= i & (hw.ilines ^ i);
byte oldif = R_IF;
i &= 0x1F & mask;
R_IF |= i & (hw.ilines ^ i);
/* FIXME - is this correct? not sure the docs understand... */
if ((R_IF & (R_IF ^ oldif) & R_IE) && cpu.ime) cpu.halt = 0;
/* if ((i & (hw.ilines ^ i) & R_IE) && cpu.ime) cpu.halt = 0; */
/* if ((i & R_IE) && cpu.ime) cpu.halt = 0; */
hw.ilines &= ~mask;
hw.ilines |= i;
/* FIXME - is this correct? not sure the docs understand... */
if ((R_IF & (R_IF ^ oldif) & R_IE) && cpu.ime) cpu.halt = 0;
/* if ((i & (hw.ilines ^ i) & R_IE) && cpu.ime) cpu.halt = 0; */
/* if ((i & R_IE) && cpu.ime) cpu.halt = 0; */
hw.ilines &= ~mask;
hw.ilines |= i;
}
@ -47,64 +47,65 @@ void hw_interrupt(byte i, byte mask)
void hw_dma(byte b)
{
int i;
addr a;
int i;
addr a;
a = ((addr)b) << 8;
for (i = 0; i < 160; i++, a++)
lcd.oam.mem[i] = readb(a);
a = ((addr)b) << 8;
for (i = 0; i < 160; i++, a++)
lcd.oam.mem[i] = readb(a);
}
void hw_hdma_cmd(byte c)
{
int cnt;
addr sa;
int da;
/* Begin or cancel HDMA */
if ((hw.hdma|c) & 0x80)
{
hw.hdma = c;
R_HDMA5 = c & 0x7f;
return;
}
/* Perform GDMA */
sa = ((addr)R_HDMA1 << 8) | (R_HDMA2&0xf0);
da = 0x8000 | ((int)(R_HDMA3&0x1f) << 8) | (R_HDMA4&0xf0);
cnt = ((int)c)+1;
/* FIXME - this should use cpu time! */
/*cpu_timers(102 * cnt);*/
cnt <<= 4;
while (cnt--)
writeb(da++, readb(sa++));
R_HDMA1 = sa >> 8;
R_HDMA2 = sa & 0xF0;
R_HDMA3 = 0x1F & (da >> 8);
R_HDMA4 = da & 0xF0;
R_HDMA5 = 0xFF;
}
void hw_hdma(void)
{
int cnt;
addr sa;
int da;
int cnt;
addr sa;
int da;
sa = ((addr)R_HDMA1 << 8) | (R_HDMA2&0xf0);
da = 0x8000 | ((int)(R_HDMA3&0x1f) << 8) | (R_HDMA4&0xf0);
cnt = 16;
while (cnt--)
writeb(da++, readb(sa++));
R_HDMA1 = sa >> 8;
R_HDMA2 = sa & 0xF0;
R_HDMA3 = 0x1F & (da >> 8);
R_HDMA4 = da & 0xF0;
R_HDMA5--;
hw.hdma--;
sa = ((addr)R_HDMA1 << 8) | (R_HDMA2&0xf0);
da = 0x8000 | ((int)(R_HDMA3&0x1f) << 8) | (R_HDMA4&0xf0);
cnt = 16;
while (cnt--)
writeb(da++, readb(sa++));
cpu_timers(16);
R_HDMA1 = sa >> 8;
R_HDMA2 = sa & 0xF0;
R_HDMA3 = 0x1F & (da >> 8);
R_HDMA4 = da & 0xF0;
R_HDMA5--;
hw.hdma--;
}
void hw_hdma_cmd(byte c)
{
int cnt;
addr sa;
int da;
/* Begin or cancel HDMA */
if ((hw.hdma|c) & 0x80)
{
hw.hdma = c;
R_HDMA5 = c & 0x7f;
if ((R_STAT&0x03) == 0x00) hw_hdma();
return;
}
/* Perform GDMA */
sa = ((addr)R_HDMA1 << 8) | (R_HDMA2&0xf0);
da = 0x8000 | ((int)(R_HDMA3&0x1f) << 8) | (R_HDMA4&0xf0);
cnt = ((int)c)+1;
/* FIXME - this should use cpu time! */
/*cpu_timers(102 * cnt);*/
cpu_timers((460>>cpu.speed)+cnt*16); /*dalias*/
/*cpu_timers(228 + (16*cnt));*/ /* this should be right according to no$ */
cnt <<= 4;
while (cnt--)
writeb(da++, readb(sa++));
R_HDMA1 = sa >> 8;
R_HDMA2 = sa & 0xF0;
R_HDMA3 = 0x1F & (da >> 8);
R_HDMA4 = da & 0xF0;
R_HDMA5 = 0xFF;
}
@ -116,20 +117,20 @@ void hw_hdma(void)
void pad_refresh()
{
byte oldp1;
oldp1 = R_P1;
R_P1 &= 0x30;
R_P1 |= 0xc0;
if (!(R_P1 & 0x10))
R_P1 |= (hw.pad & 0x0F);
if (!(R_P1 & 0x20))
R_P1 |= (hw.pad >> 4);
R_P1 ^= 0x0F;
if (oldp1 & ~R_P1 & 0x0F)
{
hw_interrupt(IF_PAD, IF_PAD);
hw_interrupt(0, IF_PAD);
}
byte oldp1;
oldp1 = R_P1;
R_P1 &= 0x30;
R_P1 |= 0xc0;
if (!(R_P1 & 0x10))
R_P1 |= (hw.pad & 0x0F);
if (!(R_P1 & 0x20))
R_P1 |= (hw.pad >> 4);
R_P1 ^= 0x0F;
if (oldp1 & ~R_P1 & 0x0F)
{
hw_interrupt(IF_PAD, IF_PAD);
hw_interrupt(0, IF_PAD);
}
}
@ -140,44 +141,37 @@ void pad_refresh()
void pad_press(byte k)
{
if (hw.pad & k)
return;
hw.pad |= k;
pad_refresh();
if (hw.pad & k)
return;
hw.pad |= k;
pad_refresh();
}
void pad_release(byte k)
{
if (!(hw.pad & k))
return;
hw.pad &= ~k;
pad_refresh();
if (!(hw.pad & k))
return;
hw.pad &= ~k;
pad_refresh();
}
void pad_set(byte k, int st)
{
st ? pad_press(k) : pad_release(k);
st ? pad_press(k) : pad_release(k);
}
void hw_reset()
{
hw.ilines = hw.pad = 0;
hw.ilines = hw.pad = 0;
memset(ram.hi, 0, sizeof ram.hi);
memset(ram.hi, 0, sizeof ram.hi);
R_P1 = 0xFF;
R_LCDC = 0x91;
R_BGP = 0xFC;
R_OBP0 = 0xFF;
R_OBP1 = 0xFF;
R_SVBK = 0x01;
R_HDMA5 = 0xFF;
R_VBK = 0xFE;
R_P1 = 0xFF;
R_LCDC = 0x91;
R_BGP = 0xFC;
R_OBP0 = 0xFF;
R_OBP1 = 0xFF;
R_SVBK = 0x01;
R_HDMA5 = 0xFF;
R_VBK = 0xFE;
}

View File

@ -25,10 +25,10 @@
struct hw
{
byte ilines;
byte pad;
int hdma;
int cgb,gba;
byte ilines;
byte pad;
int hdma;
int cgb;
};

View File

@ -1,514 +0,0 @@
/* Slightly modified from its original form so as not to exit the
* program on errors. The resulting file remains in the public
* domain for all to use. */
/* --- GZIP file format uncompression routines --- */
/* The following routines (notably the unzip()) function below
* uncompress gzipped data. They are terribly slow at the task, but
* it is presumed that they work reasonably well. They don't do any
* error checking, but they're probably not too vulnerable to buggy
* data either. Another important limitation (but it would be pretty
* easy to get around) is that the data must reside in memory, it is
* not read as a stream. They have been very little tested. Anyway,
* whatever these functions are good for, I put them in the public
* domain. -- David Madore <david.madore@ens.fr> 1999/11/21 */
#include "rockmacros.h"
static unsigned int
peek_bits (const unsigned char *data, long p, int q)
/* Read q bits starting from bit p from the data pointed to by
* data. Data is in little-endian format. */
{
unsigned int answer;
int cnt; /* Number of bits already placed in answer */
char ob, lb; /* Offset and length of bit field within current byte */
answer = 0;
for ( cnt=0 ; cnt<q ; /* cnt updated in body */ )
{
ob = (p+cnt)%8;
lb = 8-ob;
if ( cnt+lb > q )
lb = q-cnt;
answer |= ((unsigned int)((data[(p+cnt)/8]>>ob)&((1U<<lb)-1)))<<cnt;
cnt += lb;
}
return answer;
}
static unsigned int
read_bits (const unsigned char *data, long *p, int q)
/* Read q bits as per peek_bits(), but also increase p by q. */
{
unsigned int answer;
answer = peek_bits (data, *p, q);
*p += q;
return answer;
}
static void
make_code_table (const char size_table[], int table_length,
unsigned int code_table[], int maxbits)
/* Make a code table from a length table. See rfc1951, section
* 3.2.2, for details on what this means. The size_table
* contains the length of the Huffman codes for each letter, and
* the code_table receives the computed codes themselves.
* table_length is the size of the tables (alphabet length) and
* maxbits is the maximal allowed code length. */
{
int i, j;
unsigned int code;
code = 0;
for ( i=1 ; i<=maxbits ; i++ )
{
for ( j=0 ; j<table_length ; j++ )
{
if ( size_table[j]==i )
code_table[j] = code++;
}
code <<= 1;
}
}
static int
decode_one (const unsigned char *data, long *p,
const char size_table[], int table_length,
const unsigned int code_table[], int maxbits)
/* Decode one alphabet letter from the data, starting at bit p
* (which will be increased by the appropriate amount) using
* size_table and code_table to decipher the Huffman encoding. */
{
unsigned int code;
int i, j;
code = 0;
/* Read as many bits as are likely to be necessary - backward, of
* course. */
for ( i=0 ; i<maxbits ; i++ )
code = (code<<1) + peek_bits (data, (*p)+i, 1);
/* Now examine each symbol of the table to find one that matches the
* first bits of the code read. */
for ( j=0 ; j<table_length ; j++ )
{
if ( size_table[j]
&& ( (code>>(maxbits-size_table[j])) == code_table[j] ) )
{
*p += size_table[j];
return j;
}
}
return -1;
}
/* I don't know what these should be. The rfc1951 doesn't seem to say
* (it only mentions them in the last paragraph of section 3.2.1). 15
* is almost certainly safe, and it is the largest I can put given the
* constraints on the size of integers in the C standard. */
#define CLEN_MAXBITS 15
#define HLIT_MAXBITS 15
#define HDIST_MAXBITS 15
/* The magical table sizes... */
#define CLEN_TSIZE 19
#define HLIT_TSIZE 288
#define HDIST_TSIZE 30
static int
get_tables (const unsigned char *data, long *p,
char hlit_size_table[HLIT_TSIZE],
unsigned int hlit_code_table[HLIT_TSIZE],
char hdist_size_table[HDIST_TSIZE],
unsigned int hdist_code_table[HDIST_TSIZE])
/* Fill the Huffman tables (first the code lengths table, and
* then, using it, the literal/length table and the distance
* table). See section 3.2.7 of rfc1951 for details. */
{
char hlit, hdist, hclen;
const int clen_weird_tangle[CLEN_TSIZE]
= { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
char clen_size_table[CLEN_TSIZE];
unsigned int clen_code_table[CLEN_TSIZE];
int j;
unsigned int b;
int remainder; /* See note at end of section 3.2.7 of rfc1951. */
char rem_val;
hlit = read_bits (data, p, 5);
hdist = read_bits (data, p, 5);
hclen = read_bits (data, p, 4);
for ( j=0 ; j<4+hclen ; j++ )
clen_size_table[clen_weird_tangle[j]]
= read_bits (data, p, 3);
for ( ; j<CLEN_TSIZE ; j++ )
clen_size_table[clen_weird_tangle[j]] = 0;
make_code_table (clen_size_table, CLEN_TSIZE,
clen_code_table, CLEN_MAXBITS);
remainder = 0;
rem_val = 0;
for ( j=0 ; j<257+hlit ; j++ )
{
b = decode_one (data, p, clen_size_table, CLEN_TSIZE,
clen_code_table, CLEN_MAXBITS);
if ( b<0 ) return -1;
if ( b<16 )
hlit_size_table[j] = b;
else if ( b == 16 )
{
int k, l;
k = read_bits (data, p, 2);
for ( l=0 ; l<k+3 && j+l<257+hlit ; l++ )
hlit_size_table[j+l] = hlit_size_table[j-1];
j += l-1;
remainder = k+3-l; /* THIS IS SO UGLY! */
rem_val = hlit_size_table[j-1];
}
else if ( b == 17 )
{
int k, l;
k = read_bits (data, p, 3);
for ( l=0 ; l<k+3 && j+l<257+hlit ; l++ )
hlit_size_table[j+l] = 0;
j += l-1;
remainder = k+3-l;
rem_val = 0;
}
else if ( b == 18 )
{
int k, l;
k = read_bits (data, p, 7);
for ( l=0 ; l<k+11 && j+l<257+hlit ; l++ )
hlit_size_table[j+l] = 0;
j += l-1;
remainder = k+11-l;
rem_val = 0;
}
}
for ( ; j<HLIT_TSIZE ; j++ )
hlit_size_table[j] = 0;
make_code_table (hlit_size_table, HLIT_TSIZE,
hlit_code_table, HLIT_MAXBITS);
for ( j=0 ; j<remainder ; j++ )
hdist_size_table[j] = rem_val;
for ( ; j<1+hdist ; j++ )
/* Can you spell: ``copy-paste''? */
{
b = decode_one (data, p, clen_size_table, CLEN_TSIZE,
clen_code_table, CLEN_MAXBITS);
if ( b<0 ) return -1;
if ( b<16 )
hdist_size_table[j] = b;
else if ( b == 16 )
{
int k, l;
k = read_bits (data, p, 2);
for ( l=0 ; l<k+3 && j+l<1+hdist ; l++ )
hdist_size_table[j+l] = hdist_size_table[j-1];
j += l-1;
}
else if ( b == 17 )
{
int k, l;
k = read_bits (data, p, 3);
for ( l=0 ; l<k+3 && j+l<1+hdist ; l++ )
hdist_size_table[j+l] = 0;
j += l-1;
}
else if ( b == 18 )
{
int k, l;
k = read_bits (data, p, 7);
for ( l=0 ; l<k+11 && j+l<1+hdist ; l++ )
hdist_size_table[j+l] = 0;
j += l-1;
}
}
for ( ; j<HDIST_TSIZE ; j++ )
hdist_size_table[j] = 0;
make_code_table (hdist_size_table, HDIST_TSIZE,
hdist_code_table, HDIST_MAXBITS);
return 0;
}
/* The (circular) output buffer. This lets us track
* backreferences. */
/* Minimal buffer size. Also the only useful value. */
#define BUFFER_SIZE 32768
/* Pointer to the character to be added to the buffer */
static unsigned int buffer_ptr = 0;
/* The buffer itself */
static unsigned char buffer[BUFFER_SIZE];
static void
pushout (unsigned char ch)
/* Store one byte in the output buffer so it may be retrieved if
* it is referenced again. */
{
buffer[buffer_ptr++] = ch;
buffer_ptr %= BUFFER_SIZE;
}
static unsigned char
pushin (unsigned int dist)
/* Retrieve one byte, dist bytes away, from the output buffer. */
{
return buffer[(buffer_ptr+(BUFFER_SIZE-dist))%BUFFER_SIZE];
}
static int
get_data (const unsigned char *data, long *p,
const char hlit_size_table[HLIT_TSIZE],
const unsigned int hlit_code_table[HLIT_TSIZE],
const char hdist_size_table[HDIST_TSIZE],
const unsigned int hdist_code_table[HDIST_TSIZE],
void (* callback) (unsigned char d))
/* Do the actual uncompressing. Call callback on each character
* uncompressed. */
{
unsigned int b;
while ( 1 ) {
b = decode_one (data, p, hlit_size_table, HLIT_TSIZE,
hlit_code_table, HLIT_MAXBITS);
if ( b<0 ) return -1;
if ( b < 256 )
/* Literal */
{
pushout ((unsigned char) b);
callback ((unsigned char) b);
}
else if ( b == 256 )
/* End of block */
return 0;
else if ( b >= 257 )
/* Back reference */
{
unsigned int bb;
unsigned int length, dist;
unsigned int l;
switch ( b )
{
case 257: length = 3; break;
case 258: length = 4; break;
case 259: length = 5; break;
case 260: length = 6; break;
case 261: length = 7; break;
case 262: length = 8; break;
case 263: length = 9; break;
case 264: length = 10; break;
case 265: length = 11 + read_bits (data, p, 1); break;
case 266: length = 13 + read_bits (data, p, 1); break;
case 267: length = 15 + read_bits (data, p, 1); break;
case 268: length = 17 + read_bits (data, p, 1); break;
case 269: length = 19 + read_bits (data, p, 2); break;
case 270: length = 23 + read_bits (data, p, 2); break;
case 271: length = 27 + read_bits (data, p, 2); break;
case 272: length = 31 + read_bits (data, p, 2); break;
case 273: length = 35 + read_bits (data, p, 3); break;
case 274: length = 43 + read_bits (data, p, 3); break;
case 275: length = 51 + read_bits (data, p, 3); break;
case 276: length = 59 + read_bits (data, p, 3); break;
case 277: length = 67 + read_bits (data, p, 4); break;
case 278: length = 83 + read_bits (data, p, 4); break;
case 279: length = 99 + read_bits (data, p, 4); break;
case 280: length = 115 + read_bits (data, p, 4); break;
case 281: length = 131 + read_bits (data, p, 5); break;
case 282: length = 163 + read_bits (data, p, 5); break;
case 283: length = 195 + read_bits (data, p, 5); break;
case 284: length = 227 + read_bits (data, p, 5); break;
case 285: length = 258; break;
default:
return -1;
}
bb = decode_one (data, p, hdist_size_table, HDIST_TSIZE,
hdist_code_table, HDIST_MAXBITS);
switch ( bb )
{
case 0: dist = 1; break;
case 1: dist = 2; break;
case 2: dist = 3; break;
case 3: dist = 4; break;
case 4: dist = 5 + read_bits (data, p, 1); break;
case 5: dist = 7 + read_bits (data, p, 1); break;
case 6: dist = 9 + read_bits (data, p, 2); break;
case 7: dist = 13 + read_bits (data, p, 2); break;
case 8: dist = 17 + read_bits (data, p, 3); break;
case 9: dist = 25 + read_bits (data, p, 3); break;
case 10: dist = 33 + read_bits (data, p, 4); break;
case 11: dist = 49 + read_bits (data, p, 4); break;
case 12: dist = 65 + read_bits (data, p, 5); break;
case 13: dist = 97 + read_bits (data, p, 5); break;
case 14: dist = 129 + read_bits (data, p, 6); break;
case 15: dist = 193 + read_bits (data, p, 6); break;
case 16: dist = 257 + read_bits (data, p, 7); break;
case 17: dist = 385 + read_bits (data, p, 7); break;
case 18: dist = 513 + read_bits (data, p, 8); break;
case 19: dist = 769 + read_bits (data, p, 8); break;
case 20: dist = 1025 + read_bits (data, p, 9); break;
case 21: dist = 1537 + read_bits (data, p, 9); break;
case 22: dist = 2049 + read_bits (data, p, 10); break;
case 23: dist = 3073 + read_bits (data, p, 10); break;
case 24: dist = 4097 + read_bits (data, p, 11); break;
case 25: dist = 6145 + read_bits (data, p, 11); break;
case 26: dist = 8193 + read_bits (data, p, 12); break;
case 27: dist = 12289 + read_bits (data, p, 12); break;
case 28: dist = 16385 + read_bits (data, p, 13); break;
case 29: dist = 24577 + read_bits (data, p, 13); break;
default:
return -1;
}
for ( l=0 ; l<length ; l++ )
{
unsigned char ch;
ch = pushin (dist);
pushout (ch);
callback (ch);
}
}
}
return 0;
}
static int
inflate (const unsigned char *data, long *p,
void (* callback) (unsigned char d))
/* Main uncompression function for the deflate method */
{
char blast, btype;
char hlit_size_table[HLIT_TSIZE];
unsigned int hlit_code_table[HLIT_TSIZE];
char hdist_size_table[HDIST_TSIZE];
unsigned int hdist_code_table[HDIST_TSIZE];
again:
blast = read_bits (data, p, 1);
btype = read_bits (data, p, 2);
if ( btype == 1 || btype == 2 )
{
if ( btype == 2 )
{
/* Dynamic Huffman tables */
if (get_tables (data, p,
hlit_size_table, hlit_code_table,
hdist_size_table, hdist_code_table) < 0) return -1;
}
else
/* Fixed Huffman codes */
{
int j;
for ( j=0 ; j<144 ; j++ )
hlit_size_table[j] = 8;
for ( ; j<256 ; j++ )
hlit_size_table[j] = 9;
for ( ; j<280 ; j++ )
hlit_size_table[j] = 7;
for ( ; j<HLIT_TSIZE ; j++ )
hlit_size_table[j] = 8;
make_code_table (hlit_size_table, HLIT_TSIZE,
hlit_code_table, HLIT_MAXBITS);
for ( j=0 ; j<HDIST_TSIZE ; j++ )
hdist_size_table[j] = 5;
make_code_table (hdist_size_table, HDIST_TSIZE,
hdist_code_table, HDIST_MAXBITS);
}
if (get_data (data, p,
hlit_size_table, hlit_code_table,
hdist_size_table, hdist_code_table,
callback) < 0) return -1;;
}
else if ( btype == 0 )
/* Non compressed block */
{
unsigned int len, nlen;
unsigned int l;
unsigned char b;
*p = (*p+7)/8; /* Jump to next byte boundary */
len = read_bits (data, p, 16);
nlen = read_bits (data, p, 16);
for ( l=0 ; l<len ; l++ )
{
b = read_bits (data, p, 8);
pushout (b);
callback (b);
}
}
else
{
return -1;
}
if ( ! blast )
goto again;
return 0;
}
int
unzip (const unsigned char *data, long *p,
void (* callback) (unsigned char d))
/* Uncompress gzipped data. data is a pointer to the data, p is
* a pointer to a long that is initialized to 0 (unless for some
* reason you want to start uncompressing further down the data),
* and callback is a function taking an unsigned char and
* returning void that will be called successively for every
* uncompressed byte. */
{
unsigned char cm, flg;
if ( read_bits (data, p, 8) != 0x1f
|| read_bits (data, p, 8) != 0x8b )
{
return -1;
}
cm = read_bits (data, p, 8);
if ( cm != 0x8 )
{
return -1;
}
flg = read_bits (data, p, 8);
if ( flg & 0xe0 )
/* fprintf (stderr, "Warning: unknown bits are set in flags.\n") */ ;
read_bits (data, p, 32); /* Ignore modification time */
read_bits (data, p, 8); /* Ignore extra flags */
read_bits (data, p, 8); /* Ignore OS type */
if ( flg & 0x4 )
{
/* Skip over extra data */
unsigned int xlen;
xlen = read_bits (data, p, 16);
*p += ((long)xlen)*8;
}
if ( flg & 0x8 )
{
/* Skip over file name */
while ( read_bits (data, p, 8) );
}
if ( flg & 0x10 )
{
/* Skip over comment */
while ( read_bits (data, p, 8) );
}
if ( flg & 0x2 )
/* Ignore CRC16 */
read_bits (data, p, 16);
return inflate (data, p, callback);
/* CRC32 and ISIZE are at the end. We don't even bother to look at
* them. */
}

View File

@ -4,19 +4,15 @@
* Definitions for input device stuff - buttons, keys, etc.
*/
#define MAX_KEYS 10
typedef struct event_s
{
int type;
int code;
int type;
int code;
} event_t;
#define EV_NONE 0
#define EV_PRESS 1
#define EV_RELEASE 2
#define EV_REPEAT 3
int ev_postevent(event_t *ev) ICODE_ATTR;
int ev_getevent(event_t *ev) ICODE_ATTR;

View File

@ -7,15 +7,15 @@
struct vissprite
{
byte *buf;
int x;
byte pal, pri, pad[6];
byte *buf;
int x;
byte pal, pri, pad[6];
};
struct scan
{
int bg[64];
int wnd[64];
int bg[64];
int wnd[64];
#if LCD_DEPTH == 1
byte buf[8][256];
#elif LCD_DEPTH == 2
@ -23,31 +23,29 @@ struct scan
#elif LCD_DEPTH > 4
byte buf[256];
#endif
byte pal1[128];
un16 pal2[64];
un32 pal4[64];
byte pri[256];
struct vissprite vs[16];
int ns, l, x, y, s, t, u, v, wx, wy, wt, wv;
un16 pal[64];
byte pri[256];
struct vissprite vs[16];
int ns, l, x, y, s, t, u, v, wx, wy, wt, wv;
};
struct obj
{
byte y;
byte x;
byte pat;
byte flags;
byte y;
byte x;
byte pat;
byte flags;
};
struct lcd
{
byte vbank[2][8192];
union
{
byte mem[256];
struct obj obj[40];
} oam;
byte pal[128];
byte vbank[2][8192];
union
{
byte mem[256];
struct obj obj[40];
} oam;
byte pal[128];
};
extern struct lcd lcd;
@ -60,14 +58,13 @@ void bg_scan(void) ICODE_ATTR;
void wnd_scan(void) ICODE_ATTR;
void bg_scan_pri(void) ICODE_ATTR;
void wnd_scan_pri(void) ICODE_ATTR;
void spr_count(void);
void spr_enum(void) ICODE_ATTR;
void spr_scan(void) ICODE_ATTR;
void lcd_begin(void) ICODE_ATTR;
void lcd_refreshline(void) ICODE_ATTR;
void pal_write(int i, byte b) ICODE_ATTR;
void pal_write_dmg(int i, int mapnum, byte d) ICODE_ATTR;
void vram_write(int a, byte b) ICODE_ATTR;
void vram_write(addr a, byte b) ICODE_ATTR;
void vram_dirty(void) ICODE_ATTR;
void pal_dirty(void) ICODE_ATTR;
void lcd_reset(void);

View File

@ -4,9 +4,8 @@
#include "hw.h"
#include "mem.h"
#include "lcd-gb.h"
#include "rc.h"
#include "fb.h"
#include "palette.h"
#include "palette-presets.h"
#ifdef USE_ASM
#include "asm.h"
#endif
@ -26,9 +25,7 @@ struct scan scan IBSS_ATTR;
#define PRI (scan.pri)
#define PAL1 (scan.pal1)
#define PAL2 (scan.pal2)
#define PAL4 (scan.pal4)
#define PAL (scan.pal)
#define VS (scan.vs) /* vissprites */
#define NS (scan.ns)
@ -53,53 +50,14 @@ byte patpix[4096][8][8]
byte patdirty[1024];
byte anydirty;
// static int scale = 1;
static int rgb332;
static int sprsort = 1;
static int sprdebug;
static int insync=0;
#if LCD_DEPTH < 16
static int scanline_ind=0;
#endif
#define DEF_PAL { 0x98d0e0, 0x68a0b0, 0x60707C, 0x2C3C3C }
static int dmg_pal[4][4] = { DEF_PAL, DEF_PAL, DEF_PAL, DEF_PAL };
static int usefilter, filterdmg;
static int filter[3][4] = {
{ 195, 25, 0, 35 },
{ 25, 170, 25, 35 },
{ 25, 60, 125, 40 }
};
rcvar_t lcd_exports[] =
{
RCV_BOOL("rgb332", &rgb332),
RCV_VECTOR("dmg_bgp", dmg_pal[0], 4),
RCV_VECTOR("dmg_wndp", dmg_pal[1], 4),
RCV_VECTOR("dmg_obp0", dmg_pal[2], 4),
RCV_VECTOR("dmg_obp1", dmg_pal[3], 4),
RCV_BOOL("sprsort", &sprsort),
RCV_BOOL("sprdebug", &sprdebug),
RCV_BOOL("colorfilter", &usefilter),
RCV_BOOL("filterdmg", &filterdmg),
RCV_VECTOR("red", filter[0], 4),
RCV_VECTOR("green", filter[1], 4),
RCV_VECTOR("blue", filter[2], 4),
RCV_END
};
static int dmg_pal[4][4];
fb_data *vdest;
#ifdef ALLOW_UNALIGNED_IO /* long long is ok since this is i386-only anyway? */
#define MEMCPY8(d, s) ((*(long long *)(d)) = (*(long long *)(s)))
#else
#define MEMCPY8(d, s) memcpy((d), (s), 8)
#endif
#ifndef ASM_UPDATEPATPIX
void updatepatpix(void)
{
@ -506,9 +464,10 @@ void tilebuf(void)
}
// V = vertical line
// WX = WND start (if 0, no need to do anything) -> WY
// U = start...something...thingy... 7 at most
/* V = vertical line
* WX = WND start (if 0, no need to do anything) -> WY
* U = start...something...thingy... 7 at most
*/
void bg_scan(void)
{
int cnt;
@ -539,7 +498,7 @@ void bg_scan(void)
);
#else
src = patpix[*(tile++)][V];
MEMCPY8(dest, src);
memcpy(dest,src,8);
dest += 8;
#endif
cnt -= 8;
@ -574,7 +533,7 @@ void wnd_scan(void)
);
#else
src = patpix[*(tile++)][WV];
MEMCPY8(dest, src);
memcpy(dest,src,8);
dest += 8;
#endif
cnt -= 8;
@ -752,33 +711,12 @@ static void recolor(byte *buf, byte fill, int cnt)
while (cnt--) *(buf++) |= fill;
}
void spr_count(void)
{
int i;
struct obj *o;
NS = 0;
if (!(R_LCDC & 0x02)) return;
o = lcd.oam.obj;
for (i = 40; i; i--, o++)
{
if (L >= o->y || L + 16 < o->y)
continue;
if (L + 8 >= o->y && !(R_LCDC & 0x04))
continue;
if (++NS == 10) break;
}
}
void spr_enum(void)
{
int i, j;
struct obj *o;
struct vissprite ts[10];
struct vissprite ts;
int v, pat;
int l, x;
NS = 0;
if (!(R_LCDC & 0x02)) return;
@ -818,24 +756,19 @@ void spr_enum(void)
VS[NS].buf = patpix[pat][v];
if (++NS == 10) break;
}
if (!sprsort||hw.cgb) return;
/* not quite optimal but it finally works! */
if (hw.cgb) return;
for (i = 0; i < NS; i++)
{
l = 0;
x = VS[0].x;
for (j = 1; j < NS; j++)
for (j = i + 1; j < NS; j++)
{
if (VS[j].x < x)
if (VS[i].x > VS[j].x)
{
l = j;
x = VS[j].x;
ts = VS[i];
VS[i] = VS[j];
VS[j] = ts;
}
}
ts[i] = VS[l];
VS[l].x = 160;
}
memcpy(VS, ts, sizeof VS);
}
void spr_scan(void)
@ -854,8 +787,8 @@ void spr_scan(void)
for (; ns; ns--, vs--)
{
x = vs->x;
if (x >= 160) continue;
if (x <= -8) continue;
if (x > 159) continue;
if (x < -7) continue;
if (x < 0)
{
src = vs->buf - x;
@ -891,12 +824,10 @@ void spr_scan(void)
}
}
else while (i--) if (src[i]) dest[i] = pal|src[i];
/* else while (i--) if (src[i]) dest[i] = 31 + ns; */
}
// if (sprdebug) for (i = 0; i < NS; i++) BUF[i<<1] = 36;
}
// Scaling defines
/* Scaling defines */
#define DX ((LCD_WIDTH<<16) / 160)
#define DXI ((160<<16) / LCD_WIDTH)
#define DY ((LCD_HEIGHT<<16) / 144)
@ -904,18 +835,38 @@ void spr_scan(void)
void lcd_begin(void)
{
/* if (fb.indexed)
{
if (rgb332) pal_set332();
else pal_expire();
}
*/
if(options.fullscreen)
vdest = fb.ptr;
#if (LCD_WIDTH>=160) && (LCD_HEIGHT>=144)
#define S1 ((LCD_HEIGHT-144)/2)*LCD_WIDTH + ((LCD_WIDTH-160)/2)
#define S2 0
#elif (LCD_WIDTH>=160) && (LCD_HEIGHT<=144)
#define S1 ((LCD_WIDTH-160)/2)
#define S2 ((LCD_WIDTH-160)/2)
#elif (LCD_WIDTH<=160) && (LCD_HEIGHT>=144)
#define S1 ((LCD_HEIGHT-144)/2)*LCD_WIDTH
#define S2 ((LCD_HEIGHT-144)/2)*LCD_WIDTH
#else
#define S1 0
#define S2 0
#endif
#if (LCD_WIDTH>LCD_HEIGHT)
#define S3 ((LCD_WIDTH-(160*LCD_HEIGHT/144))/2)
#else
#define S3 ((LCD_HEIGHT-(144*LCD_WIDTH/160))/2)*LCD_WIDTH
#endif
set_pal();
if(options.fullscreen == 0)
vdest=fb.ptr+S1;
else if (options.fullscreen == 1)
vdest=fb.ptr+S2;
else
vdest=fb.ptr+((LCD_HEIGHT-144)/2)*LCD_WIDTH + ((LCD_WIDTH-160)/2);
vdest=fb.ptr+S3;
WY = R_WY;
}
@ -930,11 +881,28 @@ void setvidmode(int mode)
{
switch(mode)
{
case 1: /* Full screen scale */
case 1:
#if (LCD_WIDTH>=160) && (LCD_HEIGHT>=144) /* Full screen scale */
SCALEWL=DX;
SCALEWS=DXI;
SCALEHL=DY;
SCALEHS=DYI;
#elif (LCD_WIDTH>=160) && (LCD_HEIGHT<144) /* scale the height */
SCALEWL=1<<16;
SCALEWS=1<<16;
SCALEHL=DY;
SCALEHS=DYI;
#elif (LCD_WIDTH<160) && (LCD_HEIGHT>=144) /* scale the width */
SCALEWL=DX;
SCALEWS=DXI;
SCALEHL=1<<16;
SCALEHS=1<<16;
#else
SCALEWL=DX;
SCALEWS=DXI;
SCALEHL=DY;
SCALEHS=DYI;
#endif
break;
case 2: /* Maintain Ratio */
if (DY<DX)
@ -952,37 +920,26 @@ void setvidmode(int mode)
SCALEHS=DXI;
}
break;
default: /* No Scaling (or fullscreen for smaller screens) */
#if LCD_WIDTH>160
default:
SCALEWL=1<<16;
SCALEWS=1<<16;
SCALEHL=1<<16;
SCALEHS=1<<16;
#else
SCALEWL=DX;
SCALEWS=DXI;
SCALEHL=DY;
SCALEHS=DYI;
#endif
}
swidth=(160*SCALEWL)>>16;
sremain=LCD_WIDTH-swidth;
}
char frameout[30];
void lcd_refreshline(void)
{
if(!insync) {
if(R_LY!=0)
return;
else
insync=1;
}
#ifdef HAVE_LCD_COLOR
char frameout[30];
#endif
if (!(R_LCDC & 0x80))
return; /* should not happen... */
#if LCD_HEIGHT < 144
#if (LCD_HEIGHT <= 128) && !defined(HAVE_LCD_COLOR)
if ( (fb.mode==0&&(R_LY >= 128)) ||
(fb.mode==1&&(R_LY < 16)) ||
(fb.mode==2&&(R_LY<8||R_LY>=136)) ||
@ -1046,8 +1003,7 @@ void lcd_refreshline(void)
vid_update(L-((int)(L/9)));
#else
{
/* Universial Scaling pulled from PrBoom and modified for rockboy */
/* Needs some thought for screens smaller than the gameboy though */
/* Universal Scaling pulled from PrBoom and modified for rockboy */
static int hpt IDATA_ATTR=0x8000;
@ -1059,9 +1015,24 @@ void lcd_refreshline(void)
register unsigned int remain=sremain;
while(wcount--)
{
*vdest++ = scan.pal2[scan.buf[srcpt>>16]];
#if LCD_HEIGHT<144 /* cut off the bottom part of the screen that won't fit */
if (options.fullscreen==0 && (hpt>>16)>LCD_HEIGHT)
break;
#endif
#if LCD_WIDTH<160 /* cut off the right part of the screen that won't fit */
if(options.fullscreen==0 && wcount<(160-LCD_WIDTH)) {
vdest+=wcount;
wcount = 0;
}
#endif
*vdest++ = PAL[BUF[srcpt>>16]];
srcpt+=SCALEWS;
}
#if LCD_HEIGHT<144
if (options.fullscreen!=0 || (hpt>>16)<(LCD_HEIGHT))
#endif
vdest+=remain;
}
@ -1086,15 +1057,16 @@ void lcd_refreshline(void)
#endif
}
void set_pal(void)
{
memcpy(dmg_pal,palettes[options.pal], sizeof dmg_pal);
pal_dirty();
}
#if HAVE_LCD_COLOR
static void updatepalette(int i)
{
int c, r, g, b, y, u, v, rr, gg;
int c, r, g, b;
c = (lcd.pal[i<<1] | ((int)lcd.pal[(i<<1)|1] << 8)) & 0x7FFF;
r = (c & 0x001F) << 3;
@ -1104,38 +1076,6 @@ static void updatepalette(int i)
g |= (g >> 5);
b |= (b >> 5);
if (usefilter && (filterdmg||hw.cgb))
{
rr = ((r * filter[0][0] + g * filter[0][1] + b * filter[0][2]) >> 8) + filter[0][3];
gg = ((r * filter[1][0] + g * filter[1][1] + b * filter[1][2]) >> 8) + filter[1][3];
b = ((r * filter[2][0] + g * filter[2][1] + b * filter[2][2]) >> 8) + filter[2][3];
r = rr;
g = gg;
}
if (fb.yuv)
{
y = (((r * 263) + (g * 516) + (b * 100)) >> 10) + 16;
u = (((r * 450) - (g * 377) - (b * 73)) >> 10) + 128;
v = (((r * -152) - (g * 298) + (b * 450)) >> 10) + 128;
if (y < 0) y = 0; if (y > 255) y = 255;
if (u < 0) u = 0; if (u > 255) u = 255;
if (v < 0) v = 0; if (v > 255) v = 255;
PAL4[i] = (y<<fb.cc[0].l) | (y<<fb.cc[3].l)
| (u<<fb.cc[1].l) | (v<<fb.cc[2].l);
return;
}
/*
if (fb.indexed)
{
pal_release(PAL1[i]);
c = pal_getcolor(c, r, g, b);
PAL1[i] = c;
PAL2[i] = (c<<8) | c;
PAL4[i] = (c<<24) | (c<<16) | (c<<8) | c;
return;
}*/
r = (r >> fb.cc[0].r) << fb.cc[0].l;
g = (g >> fb.cc[1].r) << fb.cc[1].l;
b = (b >> fb.cc[2].r) << fb.cc[2].l;
@ -1145,24 +1085,7 @@ static void updatepalette(int i)
#elif LCD_PIXELFORMAT == RGB565SWAPPED
c = swap16(r|g|b);
#endif
switch (fb.pelsize)
{
case 1:
PAL1[i] = c;
PAL2[i] = (c<<8) | c;
PAL4[i] = (c<<24) | (c<<16) | (c<<8) | c;
break;
case 2:
PAL2[i] = c;
PAL4[i] = (c<<16) | c;
break;
case 3:
case 4:
PAL4[i] = c;
break;
}
PAL[i] = c;
}
#endif
@ -1183,7 +1106,6 @@ void pal_write_dmg(int i, int mapnum, byte d)
if (hw.cgb) return;
/* if (mapnum >= 2) d = 0xe4; */
for (j = 0; j < 8; j += 2)
{
c = cmap[(d >> j) & 3];
@ -1197,7 +1119,7 @@ void pal_write_dmg(int i, int mapnum, byte d)
}
}
void vram_write(int a, byte b)
void vram_write(addr a, byte b)
{
lcd.vbank[R_VBK&1][a] = b;
if (a >= 0x1800) return;
@ -1235,7 +1157,6 @@ void lcd_reset(void)
memset(&lcd, 0, sizeof lcd);
lcd_begin();
vram_dirty();
pal_dirty();
}

View File

@ -23,32 +23,23 @@
void stat_trigger(void)
{
static const int condbits[4] = { 0x08, 0x30, 0x20, 0x00 };
int flag = 0;
static const int condbits[4] = { 0x08, 0x10, 0x20, 0x00 };
int flag = 0;
if ((R_LY < 0x91) && (R_LY == R_LYC))
{
R_STAT |= 0x04;
if (R_STAT & 0x40) flag = IF_STAT;
}
else R_STAT &= ~0x04;
if (R_LY == R_LYC)
{
R_STAT |= 0x04;
if (R_STAT & 0x40) flag = IF_STAT;
}
else R_STAT &= ~0x04;
if (R_STAT & condbits[R_STAT&3]) flag = IF_STAT;
if (R_STAT & condbits[R_STAT&3]) flag = IF_STAT;
if (!(R_LCDC & 0x80)) flag = 0;
hw_interrupt(flag, IF_STAT);
if (!(R_LCDC & 0x80)) flag = 0;
hw_interrupt(flag, IF_STAT);
}
void stat_write(byte b)
{
R_STAT = (R_STAT & 0x07) | (b & 0x78);
if (!hw.cgb &&!(R_STAT & 2)) /* DMG STAT write bug => interrupt */
hw_interrupt(IF_STAT, IF_STAT);
stat_trigger();
}
/*
* stat_change is called when a transition results in a change to the
* LCD STAT condition (the low 2 bits of R_STAT). It raises or lowers
@ -58,118 +49,118 @@ void stat_write(byte b)
static void stat_change(int stat)
{
stat &= 3;
R_STAT = (R_STAT & 0x7C) | stat;
stat &= 3;
R_STAT = (R_STAT & 0x7C) | stat;
if (stat != 1) hw_interrupt(0, IF_VBLANK);
/* hw_interrupt((stat == 1) ? IF_VBLANK : 0, IF_VBLANK); */
stat_trigger();
if (stat != 1) hw_interrupt(0, IF_VBLANK);
/* hw_interrupt((stat == 1) ? IF_VBLANK : 0, IF_VBLANK); */
stat_trigger();
}
void lcdc_change(byte b)
{
byte old = R_LCDC;
R_LCDC = b;
if ((R_LCDC ^ old) & 0x80) /* lcd on/off change */
{
R_LY = 0;
stat_change(2);
C = 40;
lcd_begin();
}
byte old = R_LCDC;
R_LCDC = b;
if ((R_LCDC ^ old) & 0x80) /* lcd on/off change */
{
R_LY = 0;
stat_change(2);
C = 40;
lcd_begin();
}
}
void lcdc_trans(void)
{
if (!(R_LCDC & 0x80))
{
while (C <= 0)
{
switch ((byte)(R_STAT & 3))
{
case 0:
case 1:
stat_change(2);
C += 40;
break;
case 2:
stat_change(3);
C += 86;
break;
case 3:
stat_change(0);
if (hw.hdma & 0x80)
hw_hdma();
else
C += 102;
break;
}
return;
}
}
while (C <= 0)
{
switch ((byte)(R_STAT & 3))
{
case 1:
if (!(hw.ilines & IF_VBLANK))
{
C += 218;
hw_interrupt(IF_VBLANK, IF_VBLANK);
break;
}
if (R_LY == 0)
{
lcd_begin();
stat_change(2);
C += 40;
break;
}
else if (R_LY < 152)
C += 228;
else if (R_LY == 152)
C += 28;
else
{
R_LY = -1;
C += 200;
}
R_LY++;
stat_trigger();
break;
case 2:
if (!(R_LCDC & 0x80))
{
while (C <= 0)
{
switch ((byte)(R_STAT & 3))
{
case 0:
case 1:
stat_change(2);
C += 40;
break;
case 2:
stat_change(3);
C += 86;
break;
case 3:
stat_change(0);
if (hw.hdma & 0x80)
hw_hdma();
else
C += 102;
break;
}
return;
}
}
while (C <= 0)
{
switch ((byte)(R_STAT & 3))
{
case 1:
if (!(hw.ilines & IF_VBLANK))
{
C += 218;
hw_interrupt(IF_VBLANK, IF_VBLANK);
break;
}
if (R_LY == 0)
{
lcd_begin();
stat_change(2);
C += 40;
break;
}
else if (R_LY < 152)
C += 228;
else if (R_LY == 152)
C += 28;
else
{
R_LY = -1;
C += 200;
}
R_LY++;
stat_trigger();
break;
case 2:
if (fb.enabled)
lcd_refreshline();
stat_change(3);
C += 86;
break;
case 3:
stat_change(0);
if (hw.hdma & 0x80)
hw_hdma();
/* FIXME -- how much of the hblank does hdma use?? */
/* else */
C += 102;
break;
case 0:
if (++R_LY >= 144)
{
if (cpu.halt)
{
hw_interrupt(IF_VBLANK, IF_VBLANK);
C += 228;
}
else C += 10;
stat_change(1);
break;
}
stat_change(2);
C += 40;
break;
}
}
case 3:
stat_change(0);
if (hw.hdma & 0x80)
hw_hdma();
/* FIXME -- how much of the hblank does hdma use?? */
/* else */
C += 102;
break;
case 0:
if (++R_LY >= 144)
{
if (cpu.halt)
{
hw_interrupt(IF_VBLANK, IF_VBLANK);
C += 228;
}
else C += 10;
stat_change(1);
break;
}
stat_change(2);
C += 40;
break;
}
}
}

View File

@ -10,68 +10,67 @@
#include "hw.h"
#include "lcd-gb.h"
#include "rtc-gb.h"
#include "rc.h"
#include "save.h"
#include "sound.h"
static int mbc_table[256] =
{
0, 1, 1, 1, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3,
3, 3, 3, 3, 0, 0, 0, 0, 0, 5, 5, 5, MBC_RUMBLE, MBC_RUMBLE, MBC_RUMBLE, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3,
3, 3, 3, 3, 0, 0, 0, 0, 0, 5, 5, 5, MBC_RUMBLE, MBC_RUMBLE, MBC_RUMBLE, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MBC_HUC3, MBC_HUC1
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MBC_HUC3, MBC_HUC1
};
static int rtc_table[256] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0
};
static int batt_table[256] =
{
0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0,
1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0,
0
0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0,
1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0,
0
};
static int romsize_table[256] =
{
2, 4, 8, 16, 32, 64, 128, 256, 512,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 128, 128, 128
/* 0, 0, 72, 80, 96 -- actual values but bad to use these! */
2, 4, 8, 16, 32, 64, 128, 256, 512,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 128, 128, 128
/* 0, 0, 72, 80, 96 -- actual values but bad to use these! */
};
static int ramsize_table[256] =
{
1, 1, 1, 4, 16,
4 /* FIXME - what value should this be?! */
1, 1, 1, 4, 16,
4 /* FIXME - what value should this be?! */
};
@ -80,304 +79,238 @@ static char sramfile[500];
static char rtcfile[500];
static char saveprefix[500];
static char *savename;
static int saveslot;
static int forcebatt, nobatt;
static int forcedmg, gbamode;
static int forcedmg;
static int memfill = -1, memrand = -1;
//static byte romMemory[4*1025*1024];
int mp3_buffer_size;
void *bufferpos;
static void initmem(void *mem, int size)
{
char *p = mem;
if (memrand >= 0)
{
srand(memrand ? memrand : -6 ); //time(0));
while(size--) *(p++) = rand();
}
else if (memfill >= 0)
memset(p, memfill, size);
char *p = mem;
if (memrand >= 0)
{
srand(memrand ? memrand : -6 ); /* time(0)); */
while(size--) *(p++) = rand();
}
else if (memfill >= 0)
memset(p, memfill, size);
}
static byte *loadfile(int fd, int *len)
{
int c, l = 0, p = 0;
byte *d, buf[512];
d=malloc(32768);
for(;;)
{
c = read(fd, buf, sizeof buf);
if (c <= 0) break;
l += c;
memcpy(d+p, buf, c);
p += c;
}
setmallocpos(d+p+64);
*len = l;
return d;
int c, l = 0, p = 0;
byte *d, buf[512];
d=malloc(32768);
for(;;)
{
c = read(fd, buf, sizeof buf);
if (c <= 0) break;
l += c;
memcpy(d+p, buf, c);
p += c;
}
setmallocpos(d+p+64);
*len = l;
return d;
}
//static byte sram[65536];
int rom_load(void)
{
int fd;
byte c, *data, *header;
int len = 0, rlen;
int fd;
byte c, *data, *header;
int len = 0, rlen;
fd = open(romfile, O_RDONLY);
if (fd<0) {
die("cannot open rom file");
die(romfile);
return 1;
}
fd = open(romfile, O_RDONLY);
if (fd<0) {
die("cannot open rom file");
die(romfile);
return 1;
}
data = loadfile(fd, &len);
header = data; // no zip. = decompress(data, &len);
memcpy(rom.name, header+0x0134, 16);
if (rom.name[14] & 0x80) rom.name[14] = 0;
if (rom.name[15] & 0x80) rom.name[15] = 0;
rom.name[16] = 0;
data = loadfile(fd, &len);
header = data; /* no zip. = decompress(data, &len); */
memcpy(rom.name, header+0x0134, 16);
if (rom.name[14] & 0x80) rom.name[14] = 0;
if (rom.name[15] & 0x80) rom.name[15] = 0;
rom.name[16] = 0;
c = header[0x0147];
mbc.type = mbc_table[c];
mbc.batt = (batt_table[c] && !nobatt) || forcebatt;
// mbc.batt = 1; // always store savegame mem.
rtc.batt = rtc_table[c];
mbc.romsize = romsize_table[header[0x0148]];
mbc.ramsize = ramsize_table[header[0x0149]];
c = header[0x0147];
mbc.type = mbc_table[c];
mbc.batt = (batt_table[c] && !nobatt) || forcebatt;
rtc.batt = rtc_table[c];
mbc.romsize = romsize_table[header[0x0148]];
mbc.ramsize = ramsize_table[header[0x0149]];
if (!mbc.romsize) {
die("unknown ROM size %02X\n", header[0x0148]);
return 1;
}
if (!mbc.ramsize) {
die("unknown SRAM size %02X\n", header[0x0149]);
return 1;
}
if (!mbc.romsize) {
die("unknown ROM size %02X\n", header[0x0148]);
return 1;
}
if (!mbc.ramsize) {
die("unknown SRAM size %02X\n", header[0x0149]);
return 1;
}
rlen = 16384 * mbc.romsize;
rom.bank = (void *) data; //realloc(data, rlen);
if (rlen > len) memset(rom.bank[0]+len, 0xff, rlen - len);
rlen = 16384 * mbc.romsize;
rom.bank = (void *) data; /* realloc(data, rlen); */
if (rlen > len) memset(rom.bank[0]+len, 0xff, rlen - len);
ram.sbank = malloc(8192 * mbc.ramsize);
//ram.ibank = malloc(4096*8);
ram.sbank = malloc(8192 * mbc.ramsize);
/* ram.ibank = malloc(4096*8); */
initmem(ram.sbank, 8192 * mbc.ramsize);
initmem(ram.ibank, 4096 * 8);
initmem(ram.sbank, 8192 * mbc.ramsize);
initmem(ram.ibank, 4096 * 8);
mbc.rombank = 1;
mbc.rambank = 0;
mbc.rombank = 1;
mbc.rambank = 0;
c = header[0x0143];
c = header[0x0143];
hw.cgb = ((c == 0x80) || (c == 0xc0)) && !forcedmg;
hw.gba = (hw.cgb && gbamode);
close(fd);
close(fd);
return 0;
return 0;
}
int sram_load(void)
{
int fd;
char meow[500];
int fd;
char meow[500];
if (!mbc.batt || !sramfile || !*sramfile) return -1;
if (!mbc.batt || !sramfile || !*sramfile) return -1;
/* Consider sram loaded at this point, even if file doesn't exist */
ram.loaded = 1;
/* Consider sram loaded at this point, even if file doesn't exist */
ram.loaded = 1;
fd = open(sramfile, O_RDONLY);
fd = open(sramfile, O_RDONLY);
snprintf(meow,499,"Opening %s %d",sramfile,fd);
rb->splash(HZ*2, true, meow);
if (fd<0) return -1;
rb->splash(HZ*2, true, meow);
if (fd<0) return -1;
snprintf(meow,499,"Loading savedata from %s",sramfile);
rb->splash(HZ*2, true, meow);
read(fd,ram.sbank, 8192*mbc.ramsize);
close(fd);
return 0;
rb->splash(HZ*2, true, meow);
read(fd,ram.sbank, 8192*mbc.ramsize);
close(fd);
return 0;
}
int sram_save(void)
{
int fd;
char meow[500];
int fd;
char meow[500];
/* If we crash before we ever loaded sram, DO NOT SAVE! */
if (!mbc.batt || !sramfile || !ram.loaded || !mbc.ramsize)
return -1;
fd = open(sramfile, O_WRONLY|O_CREAT|O_TRUNC);
// snprintf(meow,499,"Opening %s %d",sramfile,fd);
// rb->splash(HZ*2, true, meow);
if (fd<0) return -1;
snprintf(meow,499,"Saving savedata to %s",sramfile);
rb->splash(HZ*2, true, meow);
write(fd,ram.sbank, 8192*mbc.ramsize);
close(fd);
return 0;
/* If we crash before we ever loaded sram, DO NOT SAVE! */
if (!mbc.batt || !sramfile || !ram.loaded || !mbc.ramsize)
return -1;
fd = open(sramfile, O_WRONLY|O_CREAT|O_TRUNC);
if (fd<0) return -1;
snprintf(meow,499,"Saving savedata to %s",sramfile);
rb->splash(HZ*2, true, meow);
write(fd,ram.sbank, 8192*mbc.ramsize);
close(fd);
return 0;
}
void state_save(int n)
{
int fd;
char name[500];
int fd;
char name[500];
if (n < 0) n = saveslot;
if (n < 0) n = 0;
snprintf(name, 499,"%s.%03d", saveprefix, n);
if (n < 0) n = saveslot;
if (n < 0) n = 0;
snprintf(name, 499,"%s.%03d", saveprefix, n);
if ((fd = open(name, O_WRONLY|O_CREAT|O_TRUNC)>=0))
{
savestate(fd);
close(fd);
}
if ((fd = open(name, O_WRONLY|O_CREAT|O_TRUNC)>=0))
{
savestate(fd);
close(fd);
}
}
void state_load(int n)
{
int fd;
char name[500];
int fd;
char name[500];
if (n < 0) n = saveslot;
if (n < 0) n = 0;
snprintf(name, 499, "%s.%03d", saveprefix, n);
if (n < 0) n = saveslot;
if (n < 0) n = 0;
snprintf(name, 499, "%s.%03d", saveprefix, n);
if ((fd = open(name, O_RDONLY)>=0))
{
loadstate(fd);
close(fd);
vram_dirty();
pal_dirty();
sound_dirty();
mem_updatemap();
}
if ((fd = open(name, O_RDONLY)>=0))
{
loadstate(fd);
close(fd);
vram_dirty();
pal_dirty();
sound_dirty();
mem_updatemap();
}
}
void rtc_save(void)
{
int fd;
if (!rtc.batt) return;
if ((fd = open(rtcfile, O_WRONLY|O_CREAT|O_TRUNC))<0) return;
rtc_save_internal(fd);
close(fd);
int fd;
if (!rtc.batt) return;
if ((fd = open(rtcfile, O_WRONLY|O_CREAT|O_TRUNC))<0) return;
rtc_save_internal(fd);
close(fd);
}
void rtc_load(void)
{
int fd;
if (!rtc.batt) return;
if ((fd = open(rtcfile, O_RDONLY))<0) return;
rtc_load_internal(fd);
close(fd);
int fd;
if (!rtc.batt) return;
if ((fd = open(rtcfile, O_RDONLY))<0) return;
rtc_load_internal(fd);
close(fd);
}
void loader_unload(void)
{
sram_save();
// if (romfile) free(romfile);
// if (sramfile) free(sramfile);
// if (saveprefix) free(saveprefix);
// if (rom.bank) free(rom.bank);
// if (ram.sbank) free(ram.sbank);
romfile = 0;
rom.bank = 0;
ram.sbank = 0;
mbc.type = mbc.romsize = mbc.ramsize = mbc.batt = 0;
sram_save();
/* if (romfile) free(romfile);
if (sramfile) free(sramfile);
if (saveprefix) free(saveprefix);
if (rom.bank) free(rom.bank);
if (ram.sbank) free(ram.sbank); */
romfile = 0;
rom.bank = 0;
ram.sbank = 0;
mbc.type = mbc.romsize = mbc.ramsize = mbc.batt = 0;
}
/*
static char *base(char *s)
{
char *p;
p = strrchr(s, '/');
if (p) return p+1;
return s;
}
static char *ldup(char *s)
{
int i;
char *n, *p;
p = n = malloc(strlen(s));
for (i = 0; s[i]; i++) if (isalnum(s[i])) *(p++) = tolower(s[i]);
*p = 0;
return n;
}*/
void cleanup(void)
{
sram_save();
rtc_save();
// IDEA - if error, write emergency savestate..?
sram_save();
rtc_save();
/* IDEA - if error, write emergency savestate..? */
}
void loader_init(char *s)
{
char *name;
// DIR* dir;
romfile = s;
if(rom_load())
return;
rb->splash(HZ/2, true, rom.name);
snprintf(saveprefix, 499, "%s/%s", savedir, rom.name);
// sys_checkdir(savedir, 1); /* needs to be writable */
/* dir=opendir(savedir); // should be handled when the program opens
if(!dir)
mkdir(savedir);
else
closedir(dir);*/
strcpy(sramfile, saveprefix);
strcat(sramfile, ".sav");
romfile = s;
if(rom_load())
return;
vid_settitle(rom.name);
name = rom.name;
snprintf(saveprefix, 499, "%s/%s", savedir, name);
strcpy(sramfile, saveprefix);
strcat(sramfile, ".sav");
strcpy(rtcfile, saveprefix);
strcat(rtcfile, ".rtc");
sram_load();
rtc_load();
//atexit(cleanup);
strcpy(rtcfile, saveprefix);
strcat(rtcfile, ".rtc");
sram_load();
rtc_load();
}
rcvar_t loader_exports[] =
{
RCV_STRING("savedir", &savedir),
RCV_STRING("savename", &savename),
RCV_INT("saveslot", &saveslot),
RCV_BOOL("forcebatt", &forcebatt),
RCV_BOOL("nobatt", &nobatt),
RCV_BOOL("forcedmg", &forcedmg),
RCV_INT("memfill", &memfill),
RCV_INT("memrand", &memrand),
RCV_END
};

View File

@ -6,11 +6,11 @@
typedef struct loader_s
{
char *rom;
char *base;
char *sram;
char *state;
int ramloaded;
char *rom;
char *base;
char *sram;
char *state;
int ramloaded;
} loader_t;

View File

@ -3,95 +3,42 @@
#include "rockmacros.h"
#include "input.h"
#include "rc.h"
#include "exports.h"
#include "emu.h"
#include "loader.h"
#include "hw.h"
//#include "Version"
static char *defaultconfig[] =
{
"bind up +up",
"bind down +down",
"bind left +left",
"bind right +right",
"bind joy0 +b",
"bind joy1 +a",
"bind joy2 +select",
"bind joy3 +start",
"bind ins savestate",
"bind del loadstate",
NULL
};
void doevents()
{
event_t ev;
int st;
event_t ev;
int st;
ev_poll();
while (ev_getevent(&ev))
{
if (ev.type != EV_PRESS && ev.type != EV_RELEASE)
continue;
st = (ev.type != EV_RELEASE);
pad_set(ev.code, st);
}
ev_poll();
while (ev_getevent(&ev))
{
if (ev.type != EV_PRESS && ev.type != EV_RELEASE)
continue;
st = (ev.type != EV_RELEASE);
pad_set(ev.code, st);
}
}
/* convenience macro for printing loading state */
#define PUTS(str) do { \
rb->lcd_putsxy(1, y, (unsigned char *)str); \
rb->lcd_getstringsize((unsigned char *)str, &w, &h); \
y += h + 1; \
} while (0)
int gnuboy_main(char *rom)
{
int i, w, h, y;
y = 1;
// Avoid initializing video if we don't have to
// If we have special perms, drop them ASAP!
PUTS("Init exports");
init_exports();
PUTS("Loading default config");
for (i = 0; defaultconfig[i]; i++)
rc_command(defaultconfig[i]);
// sprintf(cmd, "source %s", rom);
// s = strchr(cmd, '.');
// if (s) *s = 0;
// strcat(cmd, ".rc");
// rc_command(cmd);
// FIXME - make interface modules responsible for atexit()
PUTS("Init video");
vid_init();
PUTS("Init sound");
pcm_init();
PUTS("Loading rom");
loader_init(rom);
if(shut)
return PLUGIN_ERROR;
PUTS("Emu reset");
emu_reset();
PUTS("Emu run");
#if (LCD_HEIGHT > 144) || (LCD_WIDTH > 160)
rb->lcd_puts(0,0,"Init video");
vid_init();
rb->lcd_puts(0,1,"Init sound");
pcm_init();
rb->lcd_puts(0,2,"Loading rom");
loader_init(rom);
if(shut)
return PLUGIN_ERROR;
rb->lcd_puts(0,3,"Emu reset");
emu_reset();
rb->lcd_puts(0,4,"Emu run");
rb->lcd_clear_display();
// rb->lcd_drawrect((LCD_WIDTH-160)/2-1, (LCD_HEIGHT-144)/2-1, 162, 146);
rb->lcd_update();
#endif
emu_run();
emu_run();
// never reached
return PLUGIN_OK;
/* never reached */
return PLUGIN_OK;
}
#undef PUTS

View File

@ -12,7 +12,7 @@
#include "sound.h"
struct mbc mbc IBSS_ATTR;
struct rom rom;
struct rom rom IBSS_ATTR;
struct ram ram;
@ -31,7 +31,7 @@ struct ram ram;
void mem_updatemap()
{
int n;
byte **map;
static byte **map;
map = mbc.rmap;
map[0x0] = rom.bank[0];
@ -46,16 +46,17 @@ void mem_updatemap()
map[0x7] = rom.bank[mbc.rombank] - 0x4000;
}
else map[0x4] = map[0x5] = map[0x6] = map[0x7] = NULL;
if (0 && (R_STAT & 0x03) == 0x03)
{
map[0x8] = NULL;
map[0x9] = NULL;
}
else
{
map[0x8] = lcd.vbank[R_VBK & 1] - 0x8000;
map[0x9] = lcd.vbank[R_VBK & 1] - 0x8000;
}
if (R_VBK & 1)
{
map[0x8] = lcd.vbank[1] - 0x8000;
map[0x9] = lcd.vbank[1] - 0x8000;
}
else
{
map[0x8] = lcd.vbank[0]/*[R_VBK & 1]*/ - 0x8000;
map[0x9] = lcd.vbank[0]/*[R_VBK & 1]*/ - 0x8000;
}
if (mbc.enableram && !(rtc.sel&8))
{
map[0xA] = ram.sbank[mbc.rambank] - 0xA000;
@ -127,18 +128,18 @@ void ioreg_write(byte r, byte b)
break;
case RI_BGP:
if (R_BGP == b) break;
pal_write_dmg(0, 0, b);
pal_write_dmg(8, 1, b);
/* pal_write_dmg(0, 0, b); */ /*Disabled in iBoy and WAC-gnuboyCE */
/* pal_write_dmg(8, 1, b); */ /*Disabled in iBoy and WAC-gnuboyCE */
R_BGP = b;
break;
case RI_OBP0:
if (R_OBP0 == b) break;
pal_write_dmg(64, 2, b);
/* pal_write_dmg(64, 2, b); */ /*Disabled in iBoy and WAC-gnuboyCE */
R_OBP0 = b;
break;
case RI_OBP1:
if (R_OBP1 == b) break;
pal_write_dmg(72, 3, b);
/* pal_write_dmg(72, 3, b); */ /*Disabled in iBoy and WAC-gnuboyCE */
R_OBP1 = b;
break;
case RI_IF:
@ -166,7 +167,8 @@ void ioreg_write(byte r, byte b)
lcdc_change(b);
break;
case RI_STAT:
stat_write(b);
REG(r) = (REG(r) & 0x07) | (b & 0x78);
stat_trigger();
break;
case RI_LYC:
REG(r) = b;
@ -220,21 +222,6 @@ void ioreg_write(byte r, byte b)
hw_hdma_cmd(b);
break;
}
switch (r)
{
case RI_BGP:
case RI_OBP0:
case RI_OBP1:
/* printf("palette reg %02X write %02X at LY=%02X\n", r, b, R_LY); */
case RI_HDMA1:
case RI_HDMA2:
case RI_HDMA3:
case RI_HDMA4:
case RI_HDMA5:
/* printf("HDMA %d: %02X\n", r - RI_HDMA1 + 1, b); */
break;
}
/* printf("reg %02X => %02X (%02X)\n", r, REG(r), b); */
}
@ -410,29 +397,31 @@ void mbc_write(int a, byte b)
break;
}
break;
case MBC_HUC3:
switch (ha & 0xE)
{
case 0x0:
mbc.enableram = ((b & 0x0F) == 0x0A);
break;
case 0x2:
b &= 0x7F;
mbc.rombank = b ? b : 1;
break;
case 0x4:
rtc.sel = b & 0x0f;
mbc.rambank = b & 0x03;
break;
case 0x6:
rtc_latch(b);
break;
}
break;
}
case MBC_HUC3: /* FIXME - this is all guesswork -- is it right??? */
switch (ha & 0xE)
{
case 0x0:
mbc.enableram = ((b & 0x0F) == 0x0A);
break;
case 0x2:
if (!b) b = 1;
mbc.rombank = b;
break;
case 0x4:
if (mbc.model)
{
mbc.rambank = b & 0x03;
break;
}
break;
case 0x6:
mbc.model = b & 1;
break;
}
break;
}
mbc.rombank &= (mbc.romsize - 1);
mbc.rambank &= (mbc.ramsize - 1);
/* printf("%02X\n", mbc.rombank); */
mem_updatemap();
}
@ -494,7 +483,8 @@ void mem_write(int a, byte b)
/* return writehi(a & 0xFF, b); */
if (a >= 0xFF10 && a <= 0xFF3F)
{
sound_write(a & 0xFF, b);
if(options.sound)
sound_write(a & 0xFF, b);
break;
}
if ((a & 0xFF80) == 0xFF80 && a != 0xFFFF)
@ -530,14 +520,12 @@ byte mem_read(int a)
case 0x8:
/* if ((R_STAT & 0x03) == 0x03) return 0xFF; */
return lcd.vbank[R_VBK&1][a & 0x1FFF];
case 0xA:
if (!mbc.enableram && mbc.type == MBC_HUC3)
return 0x01;
if (!mbc.enableram)
return 0xFF;
if (rtc.sel&8)
return rtc.regs[rtc.sel&7];
return ram.sbank[mbc.rambank][a & 0x1FFF];
case 0xA:
if (!mbc.enableram)
return 0xFF;
if (rtc.sel&8)
return rtc.regs[rtc.sel&7];
return ram.sbank[mbc.rambank][a & 0x1FFF];
case 0xC:
if ((a & 0xF000) == 0xC000)
return ram.ibank[0][a & 0x0FFF];
@ -554,7 +542,12 @@ byte mem_read(int a)
/* return readhi(a & 0xFF); */
if (a == 0xFFFF) return REG(0xFF);
if (a >= 0xFF10 && a <= 0xFF3F)
return sound_read(a & 0xFF);
{
if(options.sound)
return sound_read(a & 0xFF);
else
return 1;
}
if ((a & 0xFF80) == 0xFF80)
return ram.hi[a & 0xFF];
return ioreg_read(a & 0xFF);

View File

@ -17,29 +17,29 @@
struct mbc
{
int type;
int model;
int rombank;
int rambank;
int romsize;
int ramsize;
int enableram;
int batt;
byte *rmap[0x10], *wmap[0x10];
int type;
int model;
int rombank;
int rambank;
int romsize;
int ramsize;
int enableram;
int batt;
byte *rmap[0x10], *wmap[0x10];
};
struct rom
{
byte (*bank)[16384];
char name[20];
byte (*bank)[16384];
char name[20];
};
struct ram
{
byte hi[256];
byte ibank[8][4096];
byte (*sbank)[8192];
int loaded;
byte hi[256];
byte ibank[8][4096];
byte (*sbank)[8192];
int loaded;
};

View File

@ -13,6 +13,13 @@
#define MENU_BUTTON_DOWN BUTTON_SCROLL_FWD
#define MENU_BUTTON_LEFT BUTTON_LEFT
#define MENU_BUTTON_RIGHT BUTTON_RIGHT
#elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
#define MENU_BUTTON_UP BUTTON_SCROLL_UP
#define MENU_BUTTON_DOWN BUTTON_SCROLL_DOWN
#define MENU_BUTTON_LEFT BUTTON_LEFT
#define MENU_BUTTON_RIGHT BUTTON_RIGHT
#else
#define MENU_BUTTON_UP BUTTON_UP
#define MENU_BUTTON_DOWN BUTTON_DOWN
@ -322,9 +329,9 @@ static void do_opt_menu(void)
};
static const struct opt_items fullscreen[]= {
{ "Off", -1 },
{ "Fullscreen", -1 },
{ "Full - Maintain Ratio", -1 },
{ "Unscaled", -1 },
{ "Scaled", -1 },
{ "Scaled - Maintain Ratio", -1 },
};
static const struct opt_items frameskip[]= {
@ -333,13 +340,38 @@ static void do_opt_menu(void)
{ "5 Max", -1 },
{ "6 Max", -1 },
};
#ifdef HAVE_LCD_COLOR
static const struct opt_items palette[]= {
{ "Brown (Default)", -1 },
{ "Gray", -1 },
{ "Light Gray", -1 },
{ "Multi-Color 1", -1 },
{ "Multi-Color 2", -1 },
{ "Adventure Island", -1 },
{ "Adventure Island 2", -1 },
{ "Balloon Kid", -1 },
{ "Batman", -1 },
{ "Batman: Return of Joker", -1 },
{ "Bionic Commando", -1 },
{ "Castlvania Adventure", -1 },
{ "Donkey Kong Land", -1 },
{ "Dr. Mario", -1 },
{ "Kirby", -1 },
{ "Metroid", -1 },
{ "Zelda", -1 },
};
#endif
static const struct menu_item items[] = {
{ "Max Frameskip", NULL },
{ "Sound" , NULL },
{ "Stats" , NULL },
{ "Fullscreen" , NULL },
{ "Screen Options" , NULL },
{ "Set Keys (Buggy)", NULL },
#ifdef HAVE_LCD_COLOR
{ "Set Palette" , NULL },
#endif
};
m = rb->menu_init(items, sizeof(items) / sizeof(*items), NULL, NULL, NULL, NULL);
@ -359,6 +391,7 @@ static void do_opt_menu(void)
case 1: /* Sound */
if(options.sound>1) options.sound=1;
rb->set_option(items[1].desc, &options.sound, INT, onoff, 2, NULL );
if(options.sound) sound_dirty();
break;
case 2: /* Stats */
rb->set_option(items[2].desc, &options.showstats, INT, onoff, 2, NULL );
@ -370,6 +403,12 @@ static void do_opt_menu(void)
case 4: /* Keys */
setupkeys();
break;
#ifdef HAVE_LCD_COLOR
case 5: /* Palette */
rb->set_option(items[5].desc, &options.pal, INT, palette, 17, NULL );
set_pal();
break;
#endif
default:
done=true;
break;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,151 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id: palette-presets.h $
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef __PALETTE_PRESETS_H__
#define __PALETTE_PRESETS_H__
/* The following is an array of palettes for use in Rockboy. Some were
* originally found in GoomBA for Game Boy Advance by FluBBa.
*
* The first line contains the colors for the background layer.
* The second contains the colors for the window layer.
* The third contains the colors for object 0 layer.
* The fourth contains the colors for object 1 layer.
*
* gnuboy seems to like the colors to be 0xBBGGRR */
int palettes [17][4][4] = {
{
/* Brown */ { 0x98d0e0, 0x68a0b0, 0x60707C, 0x2C3C3C },
{ 0x98d0e0, 0x68a0b0, 0x60707C, 0x2C3C3C },
{ 0x98d0e0, 0x68a0b0, 0x60707C, 0x2C3C3C },
{ 0x98d0e0, 0x68a0b0, 0x60707C, 0x2C3C3C }
},
{
/* Gray */ { 0xffffff, 0xaaaaaa, 0x555555, 0x000000 },
{ 0xffffff, 0xaaaaaa, 0x555555, 0x000000 },
{ 0xffffff, 0xaaaaaa, 0x555555, 0x000000 },
{ 0xffffff, 0xaaaaaa, 0x555555, 0x000000 }
},
{
/* Light Gray */ { 0xffffff, 0xc0c0c0, 0x808080, 0x404040 },
{ 0xffffff, 0xc0c0c0, 0x808080, 0x404040 },
{ 0xffffff, 0xc0c0c0, 0x808080, 0x404040 },
{ 0xffffff, 0xc0c0c0, 0x808080, 0x404040 }
},
{
/* Multi-Color 1 */ { 0xffffff, 0xaaaaaa, 0x555555, 0x000000 },
{ 0xffffff, 0xaaaaaa, 0x555555, 0x000000 },
{ 0xffefef, 0xe78c5a, 0x9c4a18, 0x000000 },
{ 0xefefff, 0x635aef, 0x1810ad, 0x000000 }
},
{
/* Multi-Color 2 */ { 0xffffff, 0xaaaaaa, 0x555555, 0x000000 },
{ 0xe7efd6, 0xc6de8c, 0x6b8429, 0x000000 },
{ 0xffffff, 0x635aef, 0x1810ad, 0x000000 },
{ 0xffffff, 0xe78c5a, 0x9c4a18, 0x000000 }
},
{
/* Adventure Island */ { 0xffffff, 0xffb59c, 0x009431, 0x000000 },
{ 0xffffff, 0x73cef7, 0x084a8c, 0x9c2121 },
{ 0xdeffff, 0x73c6ef, 0x5263ff, 0x290000 },
{ 0xffffff, 0xa5a5e7, 0x29297b, 0x000042 }
},
{
/* Adventure Island 2 */ { 0xffffff, 0x75eff7, 0xbd6b29, 0x000000 },
{ 0xffffff, 0x73cef7, 0x084a8c, 0x9c2121 },
{ 0xdeffff, 0x73c6ef, 0x5263ff, 0x290000 },
{ 0xffffff, 0xa5a5e7, 0x29297b, 0x000042 }
},
{
/* Balloon Kid */ { 0xa5d6ff, 0xe7efff, 0xde8c10, 0x5a1000 },
{ 0xffffff, 0x73cef7, 0x084a8c, 0x9c2121 },
{ 0xc6c6ff, 0x6b6bff, 0x0000ff, 0x000063 },
{ 0xffffff, 0xef42ef, 0x29297b, 0x000042 }
},
{
/* Batman */ { 0xeff7ff, 0xc88089, 0x445084, 0x001042 },
{ 0xffffff, 0xffa5a5, 0xbd5252, 0xa50000 },
{ 0xffffff, 0xc6a5a5, 0x8c5252, 0x5a0000 },
{ 0xffffff, 0xbdb5ad, 0x7b6b5a, 0x422108 }
},
{
/* Batman */ { 0xffffff, 0xbdada5, 0x7b5a52, 0x391000 },
/* Return of Joker */ { 0xffffff, 0xbdada5, 0x7b5a52, 0x391000 },
{ 0xffffff, 0xbdada5, 0x7b5a52, 0x391000 },
{ 0xffffff, 0xbdada5, 0x7b5a52, 0x422108 }
},
{
/* Bionic Commando */ { 0xfff7ef, 0xadb5ce, 0x2921c6, 0x000039 },
{ 0xffffff, 0xf7ce94, 0xff3910, 0x4a0000 },
{ 0xffffff, 0x84adff, 0x00395a, 0x000000 },
{ 0xefefef, 0x9ca5ad, 0x5a5a6b, 0x081042 }
},
{
/* Castlevania Adventure */ { 0xe7d6d6, 0xb5a58c, 0x6b5242, 0x181000 },
{ 0xffffff, 0xdba5a5, 0xad5252, 0x840000 },
{ 0xffffff, 0x84e7ff, 0x4252ff, 0x00005a },
{ 0xffffff, 0xceefff, 0x9cdef7, 0x6bb5f7 }
},
{
/* Donkey Kong Land */ { 0xd1ffe2, 0x89ffa9, 0x48a251, 0x032504 },
{ 0xb4b4ff, 0x4747ff, 0x000080, 0x000000 },
{ 0xb0f2ff, 0x4dc3d6, 0x115ba3, 0x00006a },
{ 0x63fff7, 0x42cec6, 0x217b73, 0x000000 }
},
{
/* Dr. Mario */ { 0xffffff, 0x66ffff, 0xff4221, 0x521000 },
{ 0xffffff, 0xd6aaaa, 0xad5555, 0x840000 },
{ 0xffffff, 0x84e7ff, 0x4252ff, 0x00008c },
{ 0xffffff, 0x8cceff, 0x5a9cf7, 0x005283 }
},
{
/* Kirby */ { 0x83ffff, 0x3ea5ff, 0x004273, 0x000933 },
{ 0xffcccc, 0xff7877, 0xc13523, 0x5a0a05 },
{ 0xc4bdff, 0x604df1, 0x29129f, 0x000000 },
{ 0xffffff, 0xaaaaaa, 0x555555, 0x000020 }
},
{
/* Metroid II */ { 0xdeffef, 0xb2ada2, 0x014284, 0x000000 },
{ 0xffcef7, 0xff6bce, 0x9c007b, 0x000000 },
{ 0x55efff, 0x1352ff, 0x001485, 0x000000 },
{ 0xffefef, 0xe78c5a, 0x9c4a18, 0x210000 }
},
{
/* Zelda */ { 0xa0ffff, 0x67d767, 0x20558c, 0x071546 },
{ 0xadffff, 0xb78080, 0x592925, 0x000000 },
{ 0x7fb0ff, 0xe78c5a, 0x9c4a18, 0x000000 },
{ 0xefefff, 0x635aef, 0x1810ad, 0x000000 }
}
};
#endif

View File

@ -1,153 +0,0 @@
#include "rockmacros.h"
#include "defs.h"
#include "fb.h"
#include "palette.h"
static byte palmap[32768];
static byte pallock[256];
static int palrev[256];
/* Course color mapping, for when palette is exhausted. */
static byte crsmap[4][32768];
static int crsrev[4][256];
static const int crsmask[4] = { 0x7BDE, 0x739C, 0x6318, 0x4210 };
enum plstatus
{
pl_unused = 0,
pl_linger,
pl_active,
pl_locked
};
/*
static byte bestmatch(int c)
{
byte n, best;
int r, g, b;
int r2, g2, b2, c2;
int err, besterr;
r = (c & 0x001F) << 3;
g = (c & 0x03E0) >> 2;
b = (c & 0x7C00) >> 7;
best = 0;
besterr = 1024;
for (n = 1; n; n++)
{
c2 = palrev[n];
r2 = (c2 & 0x001F) << 3;
g2 = (c2 & 0x03E0) >> 2;
b2 = (c2 & 0x7C00) >> 7;
err = abs(r-r2) + abs(b-b2) + abs(g-g2);
if (err < besterr)
{
besterr = err;
best = n;
}
}
return best;
}
*/
static void makecourse(int c, byte n)
{
int i;
for (i = 0; i < 4; i++)
{
c &= crsmask[i];
crsmap[i][c] = n;
crsrev[i][n] = c;
}
}
static byte findcourse(int c)
{
int i;
byte n;
for (i = 0; i < 4; i++)
{
c &= crsmask[i];
n = crsmap[i][c];
if (crsrev[i][n] == c)
return n;
}
return 0;
}
void pal_lock(byte n)
{
if (!n) return;
if (pallock[n] >= pl_locked)
pallock[n]++;
else pallock[n] = pl_locked;
}
byte pal_getcolor(int c, int r, int g, int b)
{
byte n;
static byte l;
n = palmap[c];
if (n && pallock[n] && palrev[n] == c)
{
pal_lock(n);
return n;
}
for (n = l+1; n != l; n++)
{
if (!n || pallock[n] /* || n < 16 */) continue;
pal_lock(n);
palmap[c] = n;
palrev[n] = c;
makecourse(c, n);
vid_setpal(n, r, g, b);
return (l = n);
}
n = findcourse(c);
pal_lock(n);
return n;
}
void pal_release(byte n)
{
if (pallock[n] >= pl_locked)
pallock[n]--;
}
void pal_expire(void)
{
int i;
for (i = 0; i < 256; i++)
if (pallock[i] && pallock[i] < pl_locked)
pallock[i]--;
}
void pal_set332(void)
{
int i, r, g, b;
fb.indexed = 0;
fb.cc[0].r = 5;
fb.cc[1].r = 5;
fb.cc[2].r = 6;
fb.cc[0].l = 0;
fb.cc[1].l = 3;
fb.cc[2].l = 6;
i = 0;
for (b = 0; b < 4; b++) for (g = 0; g < 8; g++) for (r = 0; r < 8; r++)
vid_setpal(i++, (r<<5)|(r<<2)|(r>>1),
(g<<5)|(g<<2)|(g>>1), (b<<6)|(b<<4)|(b<<2)|b);
}

View File

@ -1,6 +0,0 @@
void pal_lock(byte n) ICODE_ATTR;
byte pal_getcolor(int c, int r, int g, int b) ICODE_ATTR;
void pal_release(byte n) ICODE_ATTR;
void pal_expire(void) ICODE_ATTR;
void pal_set332(void) ICODE_ATTR;
void vid_setpal(int i, int r, int g, int b) ICODE_ATTR;

View File

@ -7,10 +7,10 @@
struct pcm
{
int hz, len;
int stereo;
byte *buf;
int pos;
int hz, len;
int stereo;
byte *buf;
int pos;
};
extern struct pcm pcm;

View File

@ -1,11 +1,13 @@
#include "rockmacros.h"
#include "defs.h"
#include "pcm.h"
#include "rc.h"
//#define ONEBUF // Note: I think the single buffer implementation is more responsive with sound(less lag)
// but it creates more choppyness overall to the sound. 2 buffer's don't seem to make
// a difference, but 4 buffers is definately noticable
/*#define ONEBUF*/
/* Note: I think the single buffer implementation is more
* responsive with sound(less lag) but it creates more
* choppyness overall to the sound. 2 buffer's don't seem to
* make a difference, but 4 buffers is definately noticable
*/
struct pcm pcm IBSS_ATTR;
@ -17,11 +19,6 @@ bool sound = 1;
#endif
#define BUF_SIZE 1024
rcvar_t pcm_exports[] =
{
RCV_END
};
#if CONFIG_CODEC == SWCODEC && !defined(SIMULATOR)
#ifndef ONEBUF
@ -48,46 +45,45 @@ void get_more(unsigned char** start, size_t* size)
void pcm_init(void)
{
if(!sound) return;
newly_started = true;
newly_started = true;
pcm.hz = 11025;
pcm.stereo = 1;
pcm.hz = 11025;
pcm.stereo = 1;
pcm.len = BUF_SIZE;
if(!buf){
pcm.len = BUF_SIZE;
if(!buf){
buf = my_malloc(pcm.len * N_BUFS);
gmbuf = my_malloc(pcm.len * N_BUFS*sizeof (short));
pcm.buf = buf;
pcm.pos = 0;
gmbuf = my_malloc(pcm.len * N_BUFS*sizeof (short));
pcm.buf = buf;
pcm.pos = 0;
#ifndef ONEBUF
curbuf = gmcurbuf= 0;
#endif
memset(gmbuf, 0, pcm.len * N_BUFS *sizeof(short));
memset(buf, 0, pcm.len * N_BUFS);
}
}
rb->pcm_play_stop();
rb->pcm_play_stop();
rb->pcm_set_frequency(11025); // 44100 22050 11025
rb->pcm_set_frequency(11025); /* 44100 22050 11025 */
}
void pcm_close(void)
{
memset(&pcm, 0, sizeof pcm);
newly_started = true;
rb->pcm_play_stop();
rb->pcm_set_frequency(44100);
memset(&pcm, 0, sizeof pcm);
newly_started = true;
rb->pcm_play_stop();
rb->pcm_set_frequency(44100);
}
int pcm_submit(void)
{
register int i;
if (!options.sound) return 1;
register int i;
if (!sound) {
pcm.pos = 0;
return 0;
if (!sound) {
pcm.pos = 0;
return 0;
}
if (pcm.pos < pcm.len) return 1;
@ -98,7 +94,7 @@ int pcm_submit(void)
#endif
pcm.pos = 0;
// gotta convert the 8 bit buffer to 16
/* gotta convert the 8 bit buffer to 16 */
for(i=0; i<pcm.len;i++)
#ifdef ONEBUF
gmbuf[i] = (pcm.buf[i]<<8)-0x8000;
@ -112,7 +108,9 @@ int pcm_submit(void)
newly_started = false;
}
// this while loop and done play are in place to make sure the sound timing is correct(although it's not)
/* this while loop and done play are in place to make sure the sound timing
* is correct(although it's not)
*/
#ifdef ONEBUF
while(doneplay==0) rb->yield();
doneplay=0;
@ -120,7 +118,7 @@ int pcm_submit(void)
return 1;
}
#else
static byte buf1_unal[(BUF_SIZE / sizeof(short)) + 2]; // to make sure 4 byte aligned
static byte buf1_unal[(BUF_SIZE / sizeof(short)) + 2]; /* 4 byte aligned */
void pcm_init(void)
{
pcm.hz = 11025;

View File

@ -1,62 +0,0 @@
#ifndef __RC_H__
#define __RC_H__
typedef enum rctype
{
rcv_end,
rcv_int,
rcv_string,
rcv_vector,
rcv_bool
} rcvtype_t;
typedef struct rcvar_s
{
char *name;
int type;
int len;
void *mem;
} rcvar_t;
#define RCV_END { 0, rcv_end, 0, 0 }
#define RCV_INT(n,v) { (n), rcv_int, 1, (v) }
#define RCV_STRING(n,v) { (n), rcv_string, 0, (v) }
#define RCV_VECTOR(n,v,l) { (n), rcv_vector, (l), (v) }
#define RCV_BOOL(n,v) { (n), rcv_bool, 1, (v) }
typedef struct rccmd_s
{
char *name;
int (*func)(int, char **);
} rccmd_t;
#define RCC(n,f) { (n), (f) }
#define RCC_END { 0, 0 }
void rc_export(rcvar_t *v);
void rc_exportvars(rcvar_t *vars);
int rc_findvar(char *name);
int rc_setvar_n(int i, int c, char **v);
int rc_setvar(char *name, int c, char **v);
int rc_getint_n(int i);
int *rc_getvec_n(int i);
char *rc_getstr_n(int i);
int rc_getint(char *name);
int *rc_getvec(char *name);
char *rc_getstr(char *name);
int rc_bindkey(char *keyname, char *cmd);
int rc_unbindkey(char *keyname);
void rc_unbindall(void);
int rc_sourcefile(char *filename);
void rc_dokey(int key, int st);
int rc_command(char *line);
#endif

View File

@ -1,122 +0,0 @@
#include "rockmacros.h"
#include "defs.h"
#include "rc.h"
#include "hw.h"
#include "emu.h"
#include "save.h"
#include "split.h"
/*
* the set command is used to set rc-exported variables.
*/
static int cmd_set(int argc, char **argv)
{
if (argc < 3)
return -1;
return rc_setvar(argv[1], argc-2, argv+2);
}
/*
* the following commands allow keys to be bound to perform rc commands.
*/
static int cmd_reset(int argc, char **argv)
{
(void)argc;
(void)argv;
emu_reset();
return 0;
}
static int cmd_savestate(int argc, char **argv)
{
state_save(argc > 1 ? atoi(argv[1]) : -1);
return 0;
}
static int cmd_loadstate(int argc, char **argv)
{
state_load(argc > 1 ? atoi(argv[1]) : -1);
return 0;
}
/*
* table of command names and the corresponding functions to be called
*/
rccmd_t rccmds[] =
{
RCC("set", cmd_set),
RCC("reset", cmd_reset),
RCC("savestate", cmd_savestate),
RCC("loadstate", cmd_loadstate),
RCC_END
};
int rc_command(char *line)
{
int i, argc, ret;
char *argv[128], linecopy[500];
// linecopy = malloc(strlen(line)+1);
strcpy(linecopy, line);
argc = splitline(argv, (sizeof argv)/(sizeof argv[0]), linecopy);
if (!argc)
{
// free(linecopy);
return -1;
}
for (i = 0; rccmds[i].name; i++)
{
if (!strcmp(argv[0], rccmds[i].name))
{
ret = rccmds[i].func(argc, argv);
// free(linecopy);
return ret;
}
}
/* printf("unknown command: %s\n", argv[0]); */
// free(linecopy);
return -1;
}

View File

@ -1,211 +0,0 @@
#include "rockmacros.h"
#include "defs.h"
#include "rc.h"
static rcvar_t rcvars[150];
static int nvars;
void rc_export(rcvar_t *v)
{
const rcvar_t end = RCV_END;
if (!v) return;
nvars++;
// rcvars = realloc(rcvars, sizeof (rcvar_t) * (nvars+1));
// if (!rcvars)
// die("out of memory adding rcvar %s\n", v->name);
rcvars[nvars-1] = *v;
rcvars[nvars] = end;
}
void rc_exportvars(rcvar_t *vars)
{
while(vars->type)
rc_export(vars++);
}
int rc_findvar(char *name)
{
int i;
if (!rcvars) return -1;
for (i = 0; rcvars[i].name; i++)
if (!strcmp(rcvars[i].name, name))
break;
if (!rcvars[i].name)
return -1;
return i;
}
int my_atoi(const char *s)
{
int a = 0;
if (*s == '0')
{
s++;
if (*s == 'x' || *s == 'X')
{
s++;
while (*s)
{
if (isdigit(*s))
a = (a<<4) + *s - '0';
else if (strchr("ABCDEF", *s))
a = (a<<4) + *s - 'A' + 10;
else if (strchr("abcdef", *s))
a = (a<<4) + *s - 'a' + 10;
else return a;
s++;
}
return a;
}
while (*s)
{
if (strchr("01234567", *s))
a = (a<<3) + *s - '0';
else return a;
s++;
}
return a;
}
if (*s == '-')
{
s++;
for (;;)
{
if (isdigit(*s))
a = (a*10) + *s - '0';
else return -a;
s++;
}
}
while (*s)
{
if (isdigit(*s))
a = (a*10) + *s - '0';
else return a;
s++;
}
return a;
}
int rc_setvar_n(int i, int c, char **v)
{
int j;
int *n;
char **s;
switch (rcvars[i].type)
{
case rcv_int:
if (c < 1) return -1;
n = (int *)rcvars[i].mem;
*n = my_atoi(v[0]);
return 0;
case rcv_string:
if (c < 1) return -1;
s = (char **)rcvars[i].mem;
// if (*s) free(*s);
strcpy(*s,v[0]);
if (!*s)
die("out of memory setting rcvar %s\n", rcvars[i].name);
return 0;
case rcv_vector:
if (c > rcvars[i].len)
c = rcvars[i].len;
for (j = 0; j < c ; j++)
((int *)rcvars[i].mem)[j] = my_atoi(v[j]);
return 0;
case rcv_bool:
if (c < 1 || atoi(v[0]) || strchr("yYtT", v[0][0]))
*(int *)rcvars[i].mem = 1;
else if (strchr("0nNfF", v[0][0]))
*(int *)rcvars[i].mem = 0;
else
return -1;
return 0;
}
return -1;
}
int rc_setvar(char *name, int c, char **v)
{
int i;
i = rc_findvar(name);
if (i < 0) return i;
return rc_setvar_n(i, c, v);
}
void *rc_getmem_n(int i)
{
return rcvars[i].mem;
}
void *rc_getmem(char *name)
{
int i;
i = rc_findvar(name);
if (i < 0) return NULL;
return rcvars[i].mem;
}
int rc_getint_n(int i)
{
if (i < 0) return 0;
switch (rcvars[i].type)
{
case rcv_int:
case rcv_bool:
return *(int *)rcvars[i].mem;
}
return 0;
}
int *rc_getvec_n(int i)
{
if (i < 0) return NULL;
switch (rcvars[i].type)
{
case rcv_int:
case rcv_bool:
case rcv_vector:
return (int *)rcvars[i].mem;
}
return NULL;
}
char *rc_getstr_n(int i)
{
if (i < 0) return 0;
switch (rcvars[i].type)
{
case rcv_string:
return *(char **)rcvars[i].mem;
}
return 0;
}
int rc_getint(char *name)
{
return rc_getint_n(rc_findvar(name));
}
int *rc_getvec(char *name)
{
return rc_getvec_n(rc_findvar(name));
}
char *rc_getstr(char *name)
{
return rc_getstr_n(rc_findvar(name));
}

View File

@ -86,7 +86,7 @@ void setoptions (void)
snprintf(optionsave, sizeof(optionsave), "%s/%s", savedir, optionname);
fd = open(optionsave, O_RDONLY);
if(fd < 0) // no options to read, set defaults
if(fd < 0) /* no options to read, set defaults */
{
#if (CONFIG_KEYPAD == IRIVER_H100_PAD)
options.A=BUTTON_ON;
@ -136,13 +136,31 @@ void setoptions (void)
options.START=BUTTON_SCROLL_UP;
options.SELECT=BUTTON_SCROLL_DOWN;
options.MENU=BUTTON_POWER;
#elif CONFIG_KEYPAD == IAUDIO_X5_PAD
options.A=BUTTON_PLAY;
options.B=BUTTON_REC;
options.START=BUTTON_SELECT;
options.SELECT=BUTTON_NONE;
options.MENU=BUTTON_POWER;
#elif CONFIG_KEYPAD == IRIVER_H10_PAD
options.A=BUTTON_PLAY;
options.B=BUTTON_FF;
options.START=BUTTON_REW;
options.SELECT=BUTTON_NONE;
options.MENU=BUTTON_POWER;
#endif
options.maxskip=4;
options.fps=0;
options.showstats=0;
#if (LCD_WIDTH>=160) && (LCD_HEIGHT>=144)
options.fullscreen=0;
#else
options.fullscreen=1;
#endif
options.sound=1;
options.pal=0;
}
else
read(fd,&options, sizeof(options));
@ -197,9 +215,6 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
rb->wheel_send_events(false);
#endif
/* now go ahead and have fun! */
/* rb->splash(HZ*2, true, "Rockboy v0.3"); */
/* rb->lcd_clear_display(); */
gnuboy_main(parameter);
#ifdef HAVE_WHEEL_POSITION

View File

@ -28,24 +28,30 @@ void *my_malloc(size_t size);
extern struct plugin_api* rb;
extern int shut,cleanshut;
void vid_update(int scanline);
void vid_init(void);
inline void vid_begin(void);
void vid_end(void);
void die(char *message, ...);
void setmallocpos(void *pointer);
void vid_settitle(char *title);
void *sys_timer(void);
int sys_elapsed(long *oldtick);
void sys_sleep(int us);
int pcm_submit(void);
void pcm_init(void);
void sound_dirty(void);
void doevents(void) ICODE_ATTR;
void ev_poll(void);
int do_user_menu(void);
void loadstate(int fd);
void savestate(int fd);
void setvidmode(int mode);
void set_pal(void);
#if !defined(HAVE_LCD_COLOR)
void vid_update(int scanline);
#endif
#ifdef DYNAREC
extern struct dynarec_block newblock;
void dynamic_recompile (struct dynarec_block *newblock);
#endif
#define USER_MENU_QUIT -2
/* Disable ICODE for the ARMs */
@ -54,6 +60,12 @@ void setvidmode(int mode);
#define ICODE_ATTR
#endif
/* Disable IBSS when using dynarec since it won't fit */
#ifdef DYNAREC
#undef IBSS_ATTR
#define IBSS_ATTR
#endif
/* libc functions */
#define isdigit(c) ((c) >= '0' && (c) <= '9')
#define isalpha(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && ((c) <= 'Z')))
@ -101,12 +113,13 @@ void setvidmode(int mode);
#define tolower(_A_) (isupper(_A_) ? (_A_ - 'A' + 'a') : _A_)
/* Using #define isn't enough with GCC 4.0.1 */
void* memcpy(void* dst, const void* src, size_t size);
void* memcpy(void* dst, const void* src, size_t size) ICODE_ATTR;
struct options {
int A, B, START, SELECT, MENU;
int frameskip, fps, maxskip;
int sound, fullscreen, showstats;
int pal;
};
extern struct options options;

View File

@ -6,12 +6,12 @@
struct rtc
{
int batt;
int sel;
int latch;
int d, h, m, s, t;
int stop, carry;
byte regs[8];
int batt;
int sel;
int latch;
int d, h, m, s, t;
int stop, carry;
byte regs[8];
};
extern struct rtc rtc;
@ -21,5 +21,5 @@ void rtc_write(byte b);
void rtc_tick(void);
void rtc_save_internal(int fd);
void rtc_load_internal(int fd);
#endif

View File

@ -7,119 +7,109 @@
#include "defs.h"
#include "mem.h"
#include "rtc-gb.h"
#include "rc.h"
struct rtc rtc IBSS_ATTR;
static int syncrtc = 1;
rcvar_t rtc_exports[] =
{
RCV_BOOL("syncrtc", &syncrtc),
RCV_END
};
struct rtc rtc;
void rtc_latch(byte b)
{
if ((rtc.latch ^ b) & b & 1)
{
rtc.regs[0] = rtc.s;
rtc.regs[1] = rtc.m;
rtc.regs[2] = rtc.h;
rtc.regs[3] = rtc.d;
rtc.regs[4] = (rtc.d>>9) | (rtc.stop<<6) | (rtc.carry<<7);
rtc.regs[5] = 0xff;
rtc.regs[6] = 0xff;
rtc.regs[7] = 0xff;
}
rtc.latch = b;
if ((rtc.latch ^ b) & b & 1)
{
rtc.regs[0] = rtc.s;
rtc.regs[1] = rtc.m;
rtc.regs[2] = rtc.h;
rtc.regs[3] = rtc.d;
rtc.regs[4] = (rtc.d>>9) | (rtc.stop<<6) | (rtc.carry<<7);
rtc.regs[5] = 0xff;
rtc.regs[6] = 0xff;
rtc.regs[7] = 0xff;
}
rtc.latch = b;
}
void rtc_write(byte b)
{
/* printf("write %02X: %02X (%d)\n", rtc.sel, b, b); */
if (!(rtc.sel & 8)) return;
switch (rtc.sel & 7)
{
case 0:
rtc.s = rtc.regs[0] = b;
while (rtc.s >= 60) rtc.s -= 60;
break;
case 1:
rtc.m = rtc.regs[1] = b;
while (rtc.m >= 60) rtc.m -= 60;
break;
case 2:
rtc.h = rtc.regs[2] = b;
while (rtc.h >= 24) rtc.h -= 24;
break;
case 3:
rtc.regs[3] = b;
rtc.d = (rtc.d & 0x100) | b;
break;
case 4:
rtc.regs[4] = b;
rtc.d = (rtc.d & 0xff) | ((b&1)<<9);
rtc.stop = (b>>6)&1;
rtc.carry = (b>>7)&1;
break;
}
/* printf("write %02X: %02X (%d)\n", rtc.sel, b, b); */
if (!(rtc.sel & 8)) return;
switch (rtc.sel & 7)
{
case 0:
rtc.s = rtc.regs[0] = b;
while (rtc.s >= 60) rtc.s -= 60;
break;
case 1:
rtc.m = rtc.regs[1] = b;
while (rtc.m >= 60) rtc.m -= 60;
break;
case 2:
rtc.h = rtc.regs[2] = b;
while (rtc.h >= 24) rtc.h -= 24;
break;
case 3:
rtc.regs[3] = b;
rtc.d = (rtc.d & 0x100) | b;
break;
case 4:
rtc.regs[4] = b;
rtc.d = (rtc.d & 0xff) | ((b&1)<<9);
rtc.stop = (b>>6)&1;
rtc.carry = (b>>7)&1;
break;
}
}
void rtc_tick()
{
if (rtc.stop) return;
if (++rtc.t == 60)
{
if (++rtc.s == 60)
{
if (++rtc.m == 60)
{
if (++rtc.h == 24)
{
if (++rtc.d == 365)
{
rtc.d = 0;
rtc.carry = 1;
}
rtc.h = 0;
}
rtc.m = 0;
}
rtc.s = 0;
}
rtc.t = 0;
}
if (rtc.stop) return;
if (++rtc.t == 60)
{
if (++rtc.s == 60)
{
if (++rtc.m == 60)
{
if (++rtc.h == 24)
{
if (++rtc.d == 365)
{
rtc.d = 0;
rtc.carry = 1;
}
rtc.h = 0;
}
rtc.m = 0;
}
rtc.s = 0;
}
rtc.t = 0;
}
}
void rtc_save_internal(int fd)
{
(void)fd; // stop compiler complaining
// TODO
// fprintf(f, "%d %d %d %02d %02d %02d %02d\n%d\n",
// rtc.carry, rtc.stop, rtc.d, rtc.h, rtc.m, rtc.s, rtc.t,
// time(0));
(void)fd; /* stop compiler complaining */
/* TODO */
/* fprintf(f, "%d %d %d %02d %02d %02d %02d\n%d\n",
rtc.carry, rtc.stop, rtc.d, rtc.h, rtc.m, rtc.s, rtc.t,
time(0)); */
}
void rtc_load_internal(int fd)
{
//int rt = 0;
(void)fd; // stop compiler complaining
// TODO
/* fscanf(
f, "%d %d %d %02d %02d %02d %02d\n%d\n",
&rtc.carry, &rtc.stop, &rtc.d,
&rtc.h, &rtc.m, &rtc.s, &rtc.t, &rt);
while (rtc.t >= 60) rtc.t -= 60;
while (rtc.s >= 60) rtc.s -= 60;
while (rtc.m >= 60) rtc.m -= 60;
while (rtc.h >= 24) rtc.h -= 24;
while (rtc.d >= 365) rtc.d -= 365;
rtc.stop &= 1;
rtc.carry &= 1;
if (rt) rt = (time(0) - rt) * 60;
if (syncrtc) while (rt-- > 0) rtc_tick(); */
/* int rt = 0; */
(void)fd; /* stop compiler complaining */
/* TODO */
/* fscanf(
f, "%d %d %d %02d %02d %02d %02d\n%d\n",
&rtc.carry, &rtc.stop, &rtc.d,
&rtc.h, &rtc.m, &rtc.s, &rtc.t, &rt);
while (rtc.t >= 60) rtc.t -= 60;
while (rtc.s >= 60) rtc.s -= 60;
while (rtc.m >= 60) rtc.m -= 60;
while (rtc.h >= 24) rtc.h -= 24;
while (rtc.d >= 365) rtc.d -= 365;
rtc.stop &= 1;
rtc.carry &= 1;
if (rt) rt = (time(0) - rt) * 60;
if (syncrtc) while (rt-- > 0) rtc_tick(); */
}

View File

@ -30,9 +30,9 @@
struct svar
{
int len;
char key[4];
void *ptr;
int len;
char key[4];
void *ptr;
};
static int ver;
@ -41,247 +41,243 @@ static int hramofs, hiofs, palofs, oamofs, wavofs;
struct svar svars[] =
{
I4("GbSs", &ver),
I2("PC ", &PC),
I2("SP ", &SP),
I2("HL ", &HL),
I4("GbSs", &ver),
I2("PC ", &PC),
I2("SP ", &SP),
I2("HL ", &HL),
#ifdef DYNAREC
I1("A ", &A),
I1("B ", &A),
I1("C ", &A),
I1("D ", &A),
I1("E ", &A),
I1("F ", &A),
I1("A ", &A),
I1("B ", &A),
I1("C ", &A),
I1("D ", &A),
I1("E ", &A),
I1("F ", &A),
#else
I2("BC ", &BC),
I2("DE ", &DE),
I2("AF ", &AF),
#endif
I4("IME ", &cpu.ime),
I4("ima ", &cpu.ima),
I4("spd ", &cpu.speed),
I4("halt", &cpu.halt),
I4("div ", &cpu.div),
I4("tim ", &cpu.tim),
I4("lcdc", &cpu.lcdc),
I4("snd ", &cpu.snd),
I1("ints", &hw.ilines),
I1("pad ", &hw.pad),
I4("cgb ", &hw.cgb),
I4("gba ", &hw.gba),
I4("mbcm", &mbc.model),
I4("romb", &mbc.rombank),
I4("ramb", &mbc.rambank),
I4("enab", &mbc.enableram),
I4("batt", &mbc.batt),
I4("rtcR", &rtc.sel),
I4("rtcL", &rtc.latch),
I4("rtcC", &rtc.carry),
I4("rtcS", &rtc.stop),
I4("rtcd", &rtc.d),
I4("rtch", &rtc.h),
I4("rtcm", &rtc.m),
I4("rtcs", &rtc.s),
I4("rtct", &rtc.t),
I1("rtR8", &rtc.regs[0]),
I1("rtR9", &rtc.regs[1]),
I1("rtRA", &rtc.regs[2]),
I1("rtRB", &rtc.regs[3]),
I1("rtRC", &rtc.regs[4]),
I2("BC ", &BC),
I2("DE ", &DE),
I2("AF ", &AF),
#endif
I4("IME ", &cpu.ime),
I4("ima ", &cpu.ima),
I4("spd ", &cpu.speed),
I4("halt", &cpu.halt),
I4("div ", &cpu.div),
I4("tim ", &cpu.tim),
I4("lcdc", &cpu.lcdc),
I4("snd ", &cpu.snd),
I1("ints", &hw.ilines),
I1("pad ", &hw.pad),
I4("cgb ", &hw.cgb),
I4("mbcm", &mbc.model),
I4("romb", &mbc.rombank),
I4("ramb", &mbc.rambank),
I4("enab", &mbc.enableram),
I4("batt", &mbc.batt),
I4("rtcR", &rtc.sel),
I4("rtcL", &rtc.latch),
I4("rtcC", &rtc.carry),
I4("rtcS", &rtc.stop),
I4("rtcd", &rtc.d),
I4("rtch", &rtc.h),
I4("rtcm", &rtc.m),
I4("rtcs", &rtc.s),
I4("rtct", &rtc.t),
I1("rtR8", &rtc.regs[0]),
I1("rtR9", &rtc.regs[1]),
I1("rtRA", &rtc.regs[2]),
I1("rtRB", &rtc.regs[3]),
I1("rtRC", &rtc.regs[4]),
I4("S1on", &snd.ch[0].on),
I4("S1p ", &snd.ch[0].pos),
I4("S1c ", &snd.ch[0].cnt),
I4("S1ec", &snd.ch[0].encnt),
I4("S1sc", &snd.ch[0].swcnt),
I4("S1sf", &snd.ch[0].swfreq),
I4("S1on", &snd.ch[0].on),
I4("S1p ", &snd.ch[0].pos),
I4("S1c ", &snd.ch[0].cnt),
I4("S1ec", &snd.ch[0].encnt),
I4("S1sc", &snd.ch[0].swcnt),
I4("S2on", &snd.ch[1].on),
I4("S2p ", &snd.ch[1].pos),
I4("S2c ", &snd.ch[1].cnt),
I4("S2ec", &snd.ch[1].encnt),
I4("S3on", &snd.ch[2].on),
I4("S3p ", &snd.ch[2].pos),
I4("S3c ", &snd.ch[2].cnt),
I4("S4on", &snd.ch[3].on),
I4("S4p ", &snd.ch[3].pos),
I4("S4c ", &snd.ch[3].cnt),
I4("S4ec", &snd.ch[3].encnt),
I4("hdma", &hw.hdma),
I4("sram", &sramblock),
I4("iram", &iramblock),
I4("vram", &vramblock),
I4("hi ", &hiofs),
I4("pal ", &palofs),
I4("oam ", &oamofs),
I4("wav ", &wavofs),
/* NOSAVE is a special code to prevent the rest of the table
* from being saved, used to support old stuff for backwards
* compatibility... */
NOSAVE,
I4("S2on", &snd.ch[1].on),
I4("S2p ", &snd.ch[1].pos),
I4("S2c ", &snd.ch[1].cnt),
I4("S2ec", &snd.ch[1].encnt),
I4("S3on", &snd.ch[2].on),
I4("S3p ", &snd.ch[2].pos),
I4("S3c ", &snd.ch[2].cnt),
I4("S4on", &snd.ch[3].on),
I4("S4p ", &snd.ch[3].pos),
I4("S4c ", &snd.ch[3].cnt),
I4("S4ec", &snd.ch[3].encnt),
I4("hdma", &hw.hdma),
I4("sram", &sramblock),
I4("iram", &iramblock),
I4("vram", &vramblock),
I4("hi ", &hiofs),
I4("pal ", &palofs),
I4("oam ", &oamofs),
/* NOSAVE is a special code to prevent the rest of the table
* from being saved, used to support old stuff for backwards
* compatibility... */
NOSAVE,
/* the following are obsolete as of 0x104 */
I4("hram", &hramofs),
R(P1), R(SB), R(SC),
R(DIV), R(TIMA), R(TMA), R(TAC),
R(IE), R(IF),
R(LCDC), R(STAT), R(LY), R(LYC),
R(SCX), R(SCY), R(WX), R(WY),
R(BGP), R(OBP0), R(OBP1),
R(DMA),
/* the following are obsolete as of 0x104 */
I4("hram", &hramofs),
/* I4("gba ", &hw.gba), */
/* I4("S1sf", &snd.ch[0].swfreq), */
I4("wav ", &wavofs),
R(P1), R(SB), R(SC),
R(DIV), R(TIMA), R(TMA), R(TAC),
R(IE), R(IF),
R(LCDC), R(STAT), R(LY), R(LYC),
R(SCX), R(SCY), R(WX), R(WY),
R(BGP), R(OBP0), R(OBP1),
R(DMA),
R(VBK), R(SVBK), R(KEY1),
R(BCPS), R(BCPD), R(OCPS), R(OCPD),
R(VBK), R(SVBK), R(KEY1),
R(BCPS), R(BCPD), R(OCPS), R(OCPD),
R(NR10), R(NR11), R(NR12), R(NR13), R(NR14),
R(NR21), R(NR22), R(NR23), R(NR24),
R(NR30), R(NR31), R(NR32), R(NR33), R(NR34),
R(NR41), R(NR42), R(NR43), R(NR44),
R(NR50), R(NR51), R(NR52),
R(NR10), R(NR11), R(NR12), R(NR13), R(NR14),
R(NR21), R(NR22), R(NR23), R(NR24),
R(NR30), R(NR31), R(NR32), R(NR33), R(NR34),
R(NR41), R(NR42), R(NR43), R(NR44),
R(NR50), R(NR51), R(NR52),
I1("DMA1", &R_HDMA1),
I1("DMA2", &R_HDMA2),
I1("DMA3", &R_HDMA3),
I1("DMA4", &R_HDMA4),
I1("DMA5", &R_HDMA5),
END
I1("DMA1", &R_HDMA1),
I1("DMA2", &R_HDMA2),
I1("DMA3", &R_HDMA3),
I1("DMA4", &R_HDMA4),
I1("DMA5", &R_HDMA5),
END
};
void loadstate(int fd)
{
int i, j;
byte buf[4096];
un32 (*header)[2] = (un32 (*)[2])buf;
un32 d;
int irl = hw.cgb ? 8 : 2;
int vrl = hw.cgb ? 4 : 2;
int srl = mbc.ramsize << 1;
size_t base_offset;
int i, j;
byte buf[4096];
un32 (*header)[2] = (un32 (*)[2])buf;
un32 d;
int irl = hw.cgb ? 8 : 2;
int vrl = hw.cgb ? 4 : 2;
int srl = mbc.ramsize << 1;
size_t base_offset;
ver = hramofs = hiofs = palofs = oamofs = wavofs = 0;
ver = hramofs = hiofs = palofs = oamofs = wavofs = 0;
base_offset = lseek(fd, 0, SEEK_CUR);
base_offset = lseek(fd, 0, SEEK_CUR);
read(fd,buf, 4096);
for (j = 0; header[j][0]; j++)
{
for (i = 0; svars[i].ptr; i++)
{
if (header[j][0] != *(un32 *)svars[i].key)
continue;
d = LIL(header[j][1]);
switch (svars[i].len)
{
case 1:
*(byte *)svars[i].ptr = d;
break;
case 2:
*(un16 *)svars[i].ptr = d;
break;
case 4:
*(un32 *)svars[i].ptr = d;
break;
}
break;
}
}
read(fd,buf, 4096);
for (j = 0; header[j][0]; j++)
{
for (i = 0; svars[i].ptr; i++)
{
if (header[j][0] != *(un32 *)svars[i].key)
continue;
d = LIL(header[j][1]);
switch (svars[i].len)
{
case 1:
*(byte *)svars[i].ptr = d;
break;
case 2:
*(un16 *)svars[i].ptr = d;
break;
case 4:
*(un32 *)svars[i].ptr = d;
break;
}
break;
}
}
/* obsolete as of version 0x104 */
if (hramofs) memcpy(ram.hi+128, buf+hramofs, 127);
if (hiofs) memcpy(ram.hi, buf+hiofs, sizeof ram.hi);
if (palofs) memcpy(lcd.pal, buf+palofs, sizeof lcd.pal);
if (oamofs) memcpy(lcd.oam.mem, buf+oamofs, sizeof lcd.oam);
/* obsolete as of version 0x104 */
if (hramofs) memcpy(ram.hi+128, buf+hramofs, 127);
if (wavofs) memcpy(ram.hi+48, buf+wavofs, 16);
if (hiofs) memcpy(ram.hi, buf+hiofs, sizeof ram.hi);
if (palofs) memcpy(lcd.pal, buf+palofs, sizeof lcd.pal);
if (oamofs) memcpy(lcd.oam.mem, buf+oamofs, sizeof lcd.oam);
if (wavofs) memcpy(snd.wave, buf+wavofs, sizeof snd.wave);
else memcpy(snd.wave, ram.hi+0x30, 16); /* patch data from older files */
lseek(fd, base_offset + (iramblock << 12), SEEK_SET);
read(fd,ram.ibank, 4096*irl);
lseek(fd, base_offset + (vramblock << 12), SEEK_SET);
read(fd,lcd.vbank, 4096*vrl);
lseek(fd, base_offset + (sramblock << 12), SEEK_SET);
read(fd,ram.sbank, 4096*srl);
vram_dirty();
pal_dirty();
sound_dirty();
mem_updatemap();
lseek(fd, base_offset + (iramblock << 12), SEEK_SET);
read(fd,ram.ibank, 4096*irl);
lseek(fd, base_offset + (vramblock << 12), SEEK_SET);
read(fd,lcd.vbank, 4096*vrl);
lseek(fd, base_offset + (sramblock << 12), SEEK_SET);
read(fd,ram.sbank, 4096*srl);
vram_dirty();
pal_dirty();
sound_dirty();
mem_updatemap();
}
void savestate(int fd)
{
int i;
byte buf[4096];
un32 (*header)[2] = (un32 (*)[2])buf;
un32 d = 0;
int irl = hw.cgb ? 8 : 2;
int vrl = hw.cgb ? 4 : 2;
int srl = mbc.ramsize << 1;
size_t base_offset;
int i;
byte buf[4096];
un32 (*header)[2] = (un32 (*)[2])buf;
un32 d = 0;
int irl = hw.cgb ? 8 : 2;
int vrl = hw.cgb ? 4 : 2;
int srl = mbc.ramsize << 1;
size_t base_offset;
ver = 0x105;
iramblock = 1;
vramblock = 1+irl;
sramblock = 1+irl+vrl;
wavofs = 4096 - 784;
hiofs = 4096 - 768;
palofs = 4096 - 512;
oamofs = 4096 - 256;
memset(buf, 0, sizeof buf);
ver = 0x104;
iramblock = 1;
vramblock = 1+irl;
sramblock = 1+irl+vrl;
hiofs = 4096 - 768;
palofs = 4096 - 512;
oamofs = 4096 - 256;
memset(buf, 0, sizeof buf);
for (i = 0; svars[i].len > 0; i++)
{
header[i][0] = *(un32 *)svars[i].key;
switch (svars[i].len)
{
case 1:
d = *(byte *)svars[i].ptr;
break;
case 2:
d = *(un16 *)svars[i].ptr;
break;
case 4:
d = *(un32 *)svars[i].ptr;
break;
}
header[i][1] = LIL(d);
}
header[i][0] = header[i][1] = 0;
for (i = 0; svars[i].len > 0; i++)
{
header[i][0] = *(un32 *)svars[i].key;
switch (svars[i].len)
{
case 1:
d = *(byte *)svars[i].ptr;
break;
case 2:
d = *(un16 *)svars[i].ptr;
break;
case 4:
d = *(un32 *)svars[i].ptr;
break;
}
header[i][1] = LIL(d);
}
header[i][0] = header[i][1] = 0;
memcpy(buf+hiofs, ram.hi, sizeof ram.hi);
memcpy(buf+palofs, lcd.pal, sizeof lcd.pal);
memcpy(buf+oamofs, lcd.oam.mem, sizeof lcd.oam);
memcpy(buf+wavofs, snd.wave, sizeof snd.wave);
memcpy(buf+hiofs, ram.hi, sizeof ram.hi);
memcpy(buf+palofs, lcd.pal, sizeof lcd.pal);
memcpy(buf+oamofs, lcd.oam.mem, sizeof lcd.oam);
/* calculate base offset for output file */
/* (we'll seek relative to that from now on) */
base_offset = lseek(fd, 0, SEEK_CUR);
write(fd,buf, 4096);
lseek(fd, base_offset + (iramblock << 12), SEEK_SET);
write(fd,ram.ibank, 4096*irl);
lseek(fd, base_offset + (vramblock << 12), SEEK_SET);
write(fd,lcd.vbank, 4096*vrl);
lseek(fd, base_offset + (sramblock << 12), SEEK_SET);
write(fd,ram.sbank, 4096*srl);
/* calculate base offset for output file */
/* (we'll seek relative to that from now on) */
base_offset = lseek(fd, 0, SEEK_CUR);
write(fd,buf, 4096);
lseek(fd, base_offset + (iramblock << 12), SEEK_SET);
write(fd,ram.ibank, 4096*irl);
lseek(fd, base_offset + (vramblock << 12), SEEK_SET);
write(fd,lcd.vbank, 4096*vrl);
lseek(fd, base_offset + (sramblock << 12), SEEK_SET);
write(fd,ram.sbank, 4096*srl);
}

View File

@ -8,63 +8,38 @@
#include "cpu-gb.h"
#include "hw.h"
#include "regs.h"
#include "rc.h"
#include "noise.h"
static const byte dmgwave[16] =
{
0xac, 0xdd, 0xda, 0x48,
0x36, 0x02, 0xcf, 0x16,
0x2c, 0x04, 0xe5, 0x2c,
0xac, 0xdd, 0xda, 0x48
};
static const byte cgbwave[16] =
{
0x00, 0xff, 0x00, 0xff,
0x00, 0xff, 0x00, 0xff,
0x00, 0xff, 0x00, 0xff,
0x00, 0xff, 0x00, 0xff,
};
static const byte sqwave[4][8] =
{
{ 0, 0,-1, 0, 0, 0, 0, 0 },
{ 0,-1,-1, 0, 0, 0, 0, 0 },
{ -1,-1,-1,-1, 0, 0, 0, 0 },
{ 0,-1,-1,-1,-1, 0, 0, 0 },
{ -1, 0, 0,-1,-1,-1,-1,-1 }
};
static const int freqtab[8] =
{
(1<<14)*2,
(1<<14),
(1<<14)/2,
(1<<14)/3,
(1<<14)/4,
(1<<14)/5,
(1<<14)/6,
(1<<14)/7
(1<<18)*2,
(1<<18),
(1<<18)/2,
(1<<18)/3,
(1<<18)/4,
(1<<18)/5,
(1<<18)/6,
(1<<18)/7
};
struct snd snd IBSS_ATTR;
int pcm_submit(void);
#define RATE (snd.rate)
#define WAVE (snd.wave) /* ram.hi+0x30 */
#define WAVE (ram.hi+0x30)
#define S1 (snd.ch[0])
#define S2 (snd.ch[1])
#define S3 (snd.ch[2])
#define S4 (snd.ch[3])
rcvar_t sound_exports[] =
{
RCV_END
};
static void s1_freq_d(int d)
{
if (RATE > (d<<4)) S1.freq = 0;
@ -86,14 +61,13 @@ static void s2_freq(void)
static void s3_freq(void)
{
int d = 2048 - (((R_NR34&7)<<8) + R_NR33);
if (RATE > (d<<3)) S3.freq = 0;
if (RATE > d) S3.freq = 0;
else S3.freq = (RATE << 21)/d;
}
static void s4_freq(void)
{
S4.freq = (freqtab[R_NR43&7] >> (R_NR43 >> 4)) * RATE;
if (S4.freq >> 18) S4.freq = 1<<18;
}
void sound_dirty(void)
@ -103,13 +77,13 @@ void sound_dirty(void)
S1.envol = R_NR12 >> 4;
S1.endir = (R_NR12>>3) & 1;
S1.endir |= S1.endir - 1;
S1.enlen = (R_NR12 & 7) << 15;
S1.enlen = (R_NR12 & 3) << 15;
s1_freq();
S2.len = (64-(R_NR21&63)) << 13;
S2.envol = R_NR22 >> 4;
S2.endir = (R_NR22>>3) & 1;
S2.endir |= S2.endir - 1;
S2.enlen = (R_NR22 & 7) << 15;
S2.enlen = (R_NR22 & 3) << 15;
s2_freq();
S3.len = (256-R_NR31) << 20;
s3_freq();
@ -117,16 +91,16 @@ void sound_dirty(void)
S4.envol = R_NR42 >> 4;
S4.endir = (R_NR42>>3) & 1;
S4.endir |= S4.endir - 1;
S4.enlen = (R_NR42 & 7) << 15;
S4.enlen = (R_NR42 & 3) << 15;
s4_freq();
}
void sound_off(void)
void sound_reset(void)
{
memset(&S1, 0, sizeof S1);
memset(&S2, 0, sizeof S2);
memset(&S3, 0, sizeof S3);
memset(&S4, 0, sizeof S4);
int i;
memset(&snd, 0, sizeof snd);
if (pcm.hz) snd.rate = (1<<21) / pcm.hz;
else snd.rate = 0;
R_NR10 = 0x80;
R_NR11 = 0xBF;
R_NR12 = 0xF3;
@ -137,7 +111,7 @@ void sound_off(void)
R_NR30 = 0x7F;
R_NR31 = 0xFF;
R_NR32 = 0x9F;
R_NR33 = 0xBF;
R_NR34 = 0xBF;
R_NR41 = 0xFF;
R_NR42 = 0x00;
R_NR43 = 0x00;
@ -145,23 +119,13 @@ void sound_off(void)
R_NR50 = 0x77;
R_NR51 = 0xF3;
R_NR52 = 0xF1;
for (i = 0; i < 16; i++) WAVE[i] = -(i&1);
sound_dirty();
}
void sound_reset(void)
{
memset(&snd, 0, sizeof snd);
if (pcm.hz) snd.rate = (1<<21) / pcm.hz;
else snd.rate = 0;
memcpy(WAVE, hw.cgb ? cgbwave : dmgwave, 16);
memcpy(ram.hi+0x30, WAVE, 16);
sound_off();
}
void sound_mix(void)
{
if (!options.sound) return;
if(!options.sound) return;
int s, l, r, f, n;
if (!RATE || cpu.snd < RATE) return;
@ -185,8 +149,7 @@ void sound_mix(void)
}
if (S1.swlen && (S1.swcnt += RATE) >= S1.swlen)
{
S1.swcnt -= S1.swlen;
f = S1.swfreq;
f = ((R_NR14 & 7) << 8) + R_NR13;
n = (R_NR10 & 7);
if (R_NR10 & 8) f -= (f >> n);
else f += (f >> n);
@ -194,15 +157,14 @@ void sound_mix(void)
S1.on = 0;
else
{
S1.swfreq = f;
R_NR13 = f;
R_NR14 = (R_NR14 & 0xF8) | (f>>8);
s1_freq_d(2048 - f);
}
}
s <<= 2;
if (R_NR51 & 1) r += s;
if (R_NR51 & 16) l += s;
if (R_NR51 & 1) l += s;
if (R_NR51 & 16) r += s;
}
if (S2.on)
@ -219,8 +181,8 @@ void sound_mix(void)
if (S2.envol > 15) S2.envol = 15;
}
s <<= 2;
if (R_NR51 & 2) r += s;
if (R_NR51 & 32) l += s;
if (R_NR51 & 2) l += s;
if (R_NR51 & 32) r += s;
}
if (S3.on)
@ -234,16 +196,16 @@ void sound_mix(void)
S3.on = 0;
if (R_NR32 & 96) s <<= (3 - ((R_NR32>>5)&3));
else s = 0;
if (R_NR51 & 4) r += s;
if (R_NR51 & 64) l += s;
if (R_NR51 & 4) l += s;
if (R_NR51 & 64) r += s;
}
if (S4.on)
{
if (R_NR43 & 8) s = 1 & (noise7[
(S4.pos>>20)&15] >> (7-((S4.pos>>17)&7)));
(S4.pos>>24)&15] >> ((S4.pos>>21)&7));
else s = 1 & (noise15[
(S4.pos>>20)&4095] >> (7-((S4.pos>>17)&7)));
(S4.pos>>24)&4095] >> ((S4.pos>>21)&7));
s = (-s) & S4.envol;
S4.pos += S4.freq;
if ((R_NR44 & 64) && ((S4.cnt += RATE) >= S4.len))
@ -255,9 +217,9 @@ void sound_mix(void)
if (S4.envol < 0) S4.envol = 0;
if (S4.envol > 15) S4.envol = 15;
}
s += s << 1;
if (R_NR51 & 8) r += s;
if (R_NR51 & 128) l += s;
s <<= 2;
if (R_NR51 & 8) l += s;
if (R_NR51 & 128) r += s;
}
l *= (R_NR50 & 0x07);
@ -276,10 +238,10 @@ void sound_mix(void)
pcm_submit();
if (pcm.stereo)
{
pcm.buf[pcm.pos++] = l+128;
pcm.buf[pcm.pos++] = r+128;
pcm.buf[pcm.pos++] = l+128;
pcm.buf[pcm.pos++] = r+128;
}
else pcm.buf[pcm.pos++] = ((l+r)>>1)+128;
else pcm.buf[pcm.pos++] = ((l+r)>>1)+128;
}
}
R_NR52 = (R_NR52&0xf0) | S1.on | (S2.on<<1) | (S3.on<<2) | (S4.on<<3);
@ -289,7 +251,7 @@ void sound_mix(void)
byte sound_read(byte r)
{
if(!options.sound) return 0;
if(!options.sound) return 0;
sound_mix();
/* printf("read %02X: %02X\n", r, REG(r)); */
return REG(r);
@ -298,13 +260,12 @@ byte sound_read(byte r)
void s1_init(void)
{
S1.swcnt = 0;
S1.swfreq = ((R_NR14&7)<<8) + R_NR13;
S1.envol = R_NR12 >> 4;
S1.endir = (R_NR12>>3) & 1;
S1.endir |= S1.endir - 1;
S1.enlen = (R_NR12 & 7) << 15;
if (!S1.on) S1.pos = 0;
S1.on = 1;
S1.pos = 0;
S1.cnt = 0;
S1.encnt = 0;
}
@ -315,20 +276,17 @@ void s2_init(void)
S2.endir = (R_NR22>>3) & 1;
S2.endir |= S2.endir - 1;
S2.enlen = (R_NR22 & 7) << 15;
if (!S2.on) S2.pos = 0;
S2.on = 1;
S2.pos = 0;
S2.cnt = 0;
S2.encnt = 0;
}
void s3_init(void)
{
int i;
if (!S3.on) S3.pos = 0;
S3.pos = 0;
S3.cnt = 0;
S3.on = R_NR30 >> 7;
if (S3.on) for (i = 0; i < 16; i++)
ram.hi[i+0x30] = 0x13 ^ ram.hi[i+0x31];
}
void s4_init(void)
@ -346,19 +304,13 @@ void s4_init(void)
void sound_write(byte r, byte b)
{
if(!options.sound) return;
#if 0
static void *timer;
if (!timer) timer = sys_timer();
printf("write %02X: %02X @ %d\n", r, b, sys_elapsed(timer));
#endif
if(!options.sound) return;
if (!(R_NR52 & 128) && r != RI_NR52) return;
if ((r & 0xF0) == 0x30)
{
if (S3.on) sound_mix();
if (!S3.on)
WAVE[r-0x30] = ram.hi[r] = b;
if (!S3.on) WAVE[r - 0x30] = b;
return;
}
sound_mix();
@ -366,8 +318,6 @@ void sound_write(byte r, byte b)
{
case RI_NR10:
R_NR10 = b;
S1.swlen = ((R_NR10>>4) & 7) << 14;
S1.swfreq = ((R_NR14&7)<<8) + R_NR13;
break;
case RI_NR11:
R_NR11 = b;
@ -415,7 +365,7 @@ void sound_write(byte r, byte b)
break;
case RI_NR31:
R_NR31 = b;
S3.len = (256-R_NR31) << 13;
S3.len = (256-R_NR31) << 20;
break;
case RI_NR32:
R_NR32 = b;
@ -457,7 +407,7 @@ void sound_write(byte r, byte b)
case RI_NR52:
R_NR52 = b;
if (!(R_NR52 & 128))
sound_off();
sound_reset();
break;
default:
return;

View File

@ -5,20 +5,18 @@
struct sndchan
{
int on;
unsigned pos;
int cnt, encnt, swcnt;
int len, enlen, swlen;
int swfreq;
int freq;
int envol, endir;
int on;
unsigned pos;
int cnt, encnt, swcnt;
int len, enlen, swlen;
int freq;
int envol, endir;
};
struct snd
{
int rate;
struct sndchan ch[4];
byte wave[16];
int rate;
struct sndchan ch[4];
};
extern struct snd snd;
@ -31,7 +29,6 @@ extern struct snd snd;
byte sound_read(byte r) ICODE_ATTR;
void sound_write(byte r, byte b) ICODE_ATTR;
void sound_dirty(void) ICODE_ATTR;
void sound_off(void);
void sound_reset(void);
void sound_mix(void) ICODE_ATTR;
void s1_init(void);

View File

@ -1,59 +0,0 @@
#include "rockmacros.h"
/*
* splitline is a destructive argument parser, much like a very primitive
* form of a shell parser. it supports quotes for embedded spaces and
* literal quotes with the backslash escape.
*/
char *splitnext(char **pos)
{
char *a, *d, *s;
d = s = *pos;
while (*s == ' ' || *s == '\t') s++;
a = s;
while (*s && *s != ' ' && *s != '\t')
{
if (*s == '"')
{
s++;
while (*s && *s != '"')
{
if (*s == '\\')
s++;
if (*s)
*(d++) = *(s++);
}
if (*s == '"') s++;
}
else
{
if (*s == '\\')
s++;
*(d++) = *(s++);
}
}
while (*s == ' ' || *s == '\t') s++;
*d = 0;
*pos = s;
return a;
}
int splitline(char **argv, int max, char *line)
{
char *s;
int i;
s = line;
for (i = 0; *s && i < max + 1; i++)
argv[i] = splitnext(&s);
argv[i] = 0;
return i;
}

View File

@ -1 +0,0 @@
int splitline(char **argv, int max, char *line);

View File

@ -20,7 +20,6 @@
#include "rockmacros.h"
#include "fb.h"
#include "input.h"
#include "rc.h"
#include "lcd-gb.h"
#include "hw.h"
#include "config.h"
@ -32,6 +31,13 @@
#define ROCKBOY_PAD_UP BUTTON_MENU
#define ROCKBOY_PAD_DOWN BUTTON_PLAY
#elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
#define ROCKBOY_PAD_LEFT BUTTON_LEFT
#define ROCKBOY_PAD_RIGHT BUTTON_RIGHT
#define ROCKBOY_PAD_UP BUTTON_SCROLL_UP
#define ROCKBOY_PAD_DOWN BUTTON_SCROLL_DOWN
#else
#define ROCKBOY_PAD_LEFT BUTTON_LEFT
@ -41,33 +47,10 @@
#endif
rcvar_t joy_exports[] =
{
RCV_END
};
rcvar_t vid_exports[] =
{
RCV_END
};
struct fb fb;
struct fb fb IBSS_ATTR;
extern int debug_trace;
void vid_settitle(char *title)
{
rb->splash(HZ/2, true, title);
}
void joy_init(void)
{
}
void joy_close(void)
{
}
unsigned int oldbuttonstate = 0, newbuttonstate,holdbutton;
#ifdef HAVE_WHEEL_POSITION
int oldwheel = -1, wheel;
@ -179,10 +162,7 @@ void ev_poll(void)
if(pressed & options.MENU) {
#endif
#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
(CONFIG_KEYPAD == IRIVER_H300_PAD) || \
(CONFIG_KEYPAD == IPOD_4G_PAD) || \
(CONFIG_KEYPAD == GIGABEAT_PAD) || \
(CONFIG_KEYPAD == SANSA_E200_PAD)
defined(HAVE_LCD_COLOR)
#ifdef HAVE_WHEEL_POSITION
rb->wheel_send_events(true);
#endif
@ -202,53 +182,36 @@ void ev_poll(void)
#endif
}
void vid_setpal(int i, int r, int g, int b)
/* New frameskip, makes more sense to me and performs as well */
inline void vid_begin(void)
{
(void)i;
(void)r;
(void)g;
(void)b;
}
inline void vid_begin(void) // New frameskip, makes more sense to me and performs as well
{
static int skip = 0;
if (skip<options.frameskip) {
skip++;
fb.enabled=0;
}
else {
skip=0;
fb.enabled=1;
}
static int skip = 0;
if (skip<options.frameskip)
{
skip++;
fb.enabled=0;
}
else
{
skip=0;
fb.enabled=1;
}
}
void vid_init(void)
{
fb.h=144;
fb.w=160;
fb.pitch=160;
fb.enabled=1;
fb.dirty=0;
fb.mode=3;
fb.ptr=rb->lcd_framebuffer;
fb.ptr=rb->lcd_framebuffer;
#if defined(HAVE_LCD_COLOR)
fb.pelsize=2; // 16 bit framebuffer
fb.indexed = 0; // no palette on lcd
fb.cc[0].r = 3; // 8-5 (wasted bits on red)
fb.cc[0].l = 11; //this is the offset to the R bits (16-5)
fb.cc[1].r = 2; // 8-6 (wasted bits on green)
fb.cc[1].l = 5; // This is the offset to the G bits (16-5-6)
fb.cc[2].r = 3; // 8-5 (wasted bits on red)
fb.cc[2].l = 0; // This is the offset to the B bits (16-5-6-5)
fb.cc[3].r = 0; // no alpha
fb.cc[3].l = 0;
fb.yuv = 0; // not in yuv format
#else // ***** NEED TO LOOK INTO THIS MORE FOR THE H100 (Should be able to get rid of some IFDEF's elsewhere)
fb.pelsize=1; // 8 bit framebuffer.. (too much.. but lowest gnuboy will support.. so yea...
fb.cc[0].r = 3; /* 8-5 (wasted bits on red) */
fb.cc[0].l = 11; /* this is the offset to the R bits (16-5) */
fb.cc[1].r = 2; /* 8-6 (wasted bits on green) */
fb.cc[1].l = 5; /* This is the offset to the G bits (16-5-6) */
fb.cc[2].r = 3; /* 8-5 (wasted bits on red) */
fb.cc[2].l = 0; /* This is the offset to the B bits (16-5-6-5) */
#else
fb.mode=3;
#endif
}
@ -350,43 +313,29 @@ void vid_update(int scanline)
cnt++;
}
rb->lcd_update_rect(0, scanline & ~3, LCD_WIDTH, 4);
#elif defined(HAVE_LCD_COLOR) /* iriver H3x0, colour iPod */
// handled in lcd.c now
#elif defined(HAVE_LCD_COLOR)
/* handled in lcd.c now */
#endif /* LCD_HEIGHT */
}
#endif
void vid_end(void)
{
}
long timerresult;
void *sys_timer(void)
{/*
timerresult=*rb->current_tick;
{
/*timerresult=*rb->current_tick;
return &timerresult;*/
return 0;
}
// returns microseconds passed since sys_timer
/* returns microseconds passed since sys_timer */
int sys_elapsed(long *oldtick)
{
/*
int elap,mytime=microtick;
/* int elap,mytime=microtick;
elap=mytime-*oldtick;
*oldtick=mytime;
return elap;*/
// return ((*rb->current_tick-(*oldtick))*1000000)/HZ;
return elap; */
/* return ((*rb->current_tick-(*oldtick))*1000000)/HZ; */
return *oldtick;
}
void sys_sleep(int us)
{
if(us<=0) return;
int i=0;
while(i< us*11)
i++;
// if (us <= 0) return;
}