1
0
Fork 0
forked from len0rd/rockbox

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... */ /* For various targets... */
#if (CONFIG_KEYPAD == RECORDER_PAD) || \ #if (CONFIG_KEYPAD == RECORDER_PAD) || \
(CONFIG_KEYPAD == IRIVER_H100_PAD) || \ (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
(CONFIG_KEYPAD == IRIVER_H300_PAD) || \ defined(HAVE_LCD_COLOR)
defined(IPOD_COLOR) || \
defined(IPOD_VIDEO) || \
defined(TOSHIBA_GIGABEAT_F) || \
defined(SANSA_E200)
rockboy rockboy
#endif #endif

View file

@ -18,11 +18,9 @@ endif
LINKFILE := $(OBJDIR)/link.lds LINKFILE := $(OBJDIR)/link.lds
DEPFILE = $(OBJDIR)/dep-rockboy DEPFILE = $(OBJDIR)/dep-rockboy
SRC = cpu.c emu.c events.c exports.c fastmem.c hw.c lcd.c lcdc.c loader.c \ SRC = cpu.c emu.c events.c fastmem.c hw.c lcd.c lcdc.c loader.c main.c \
main.c mem.c rbsound.c rccmds.c rcvars.c rtc.c save.c sound.c split.c \ mem.c menu.c rbsound.c rockboy.c rtc.c save.c sound.c sys_rockbox.c
sys_rockbox.c rockboy.c menu.c
#CFLAGS += -DGRAYSCALE
#CFLAGS += -DDYNAREC #CFLAGS += -DDYNAREC
#SRC += dynarec.c #SRC += dynarec.c
@ -30,7 +28,6 @@ SOURCES = $(SRC)
OBJS := $(SRC:%.c=$(OBJDIR)/%.o) OBJS := $(SRC:%.c=$(OBJDIR)/%.o)
DIRS = . DIRS = .
ifndef SIMVER ifndef SIMVER
ifneq (,$(findstring RECORDER,$(TARGET))) ## Archos recorder targets ifneq (,$(findstring RECORDER,$(TARGET))) ## Archos recorder targets
LDS := archos.lds 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 union reg
{ {
byte b[2][2]; byte b[2][2];
word w[2]; word w[2];
un32 d; /* padding for alignment, carry */ un32 d; /* padding for alignment, carry */
}; };
struct cpu struct cpu
{ {
#ifdef DYNAREC #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 #else
union reg pc, sp, bc, de, hl, af; union reg pc, sp, bc, de, hl, af;
#endif #endif
int ime, ima; int ime, ima;
int speed; int speed;
int halt; int halt;
int div, tim; int div, tim;
int lcdc; int lcdc;
int snd; int snd;
}; };
extern struct cpu cpu; extern struct cpu cpu;
@ -54,6 +54,6 @@ void lcdc_advance(int cnt) ICODE_ATTR;
void sound_advance(int cnt) ICODE_ATTR; void sound_advance(int cnt) ICODE_ATTR;
void cpu_timers(int cnt) ICODE_ATTR; void cpu_timers(int cnt) ICODE_ATTR;
int cpu_emulate(int cycles) ICODE_ATTR; int cpu_emulate(int cycles) ICODE_ATTR;
inline int cpu_step(int max); inline int cpu_step(int max) ICODE_ATTR;
#endif #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 = 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, 5, 2, 2, 2, 1, 1, 2, 1,
1, 3, 2, 2, 1, 1, 2, 1, 3, 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, 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, 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, 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, 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,
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, 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, 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, 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, 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 = 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, 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, 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,
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
}; };
static const byte incflag_table[256] ICONST_ATTR = 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, 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, 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 = 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, 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, 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 = static const byte swap_table[256] ICONST_ATTR =
{ {
0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F, 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF,
}; };
static const byte daa_table[4096] ICONST_ATTR= 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, 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, 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,
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,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 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,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 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,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 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 = 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, 00, 00, 00, 00, 00, 00, 00, 00,
00, 00, 00, 00, 00, 00, 00, 00, FC, FC, 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, FC, FC,
FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, FC, 00, 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 "cpu-gb.h"
#include "mem.h" #include "mem.h"
#include "lcd-gb.h" #include "lcd-gb.h"
#include "rc.h"
#include "sound.h" #include "sound.h"
#include "rtc-gb.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 * emu_reset is called to initialize the state of the emulated
* system. It should set cpu registers, hardware registers, etc. to * 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. */ * make things work in the mean time. */
void emu_run(void) 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 framesin=0,frames=0,timeten=*rb->current_tick, timehun=*rb->current_tick;
// int delay;
setvidmode(options.fullscreen); setvidmode(options.fullscreen);
vid_begin(); vid_begin();
@ -63,13 +47,12 @@ void emu_run(void)
while (R_LY > 0 && R_LY < 144) while (R_LY > 0 && R_LY < 144)
emu_step(); emu_step();
rtc_tick(); /* rtc_tick(); */ /* RTC support not implemented */
sound_mix();
if (!pcm_submit()) if(options.sound)
{ {
/* delay = framelen - sys_elapsed(timer); sound_mix();
sys_sleep(delay); pcm_submit();
sys_elapsed(timer);*/
} }
doevents(); doevents();
@ -79,8 +62,10 @@ void emu_run(void)
cpu_emulate(32832); cpu_emulate(32832);
while (R_LY > 0) /* wait for next frame */ while (R_LY > 0) /* wait for next frame */
{
emu_step(); emu_step();
rb->yield(); rb->yield();
}
frames++; frames++;
framesin++; framesin++;

View file

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

View file

@ -8,10 +8,6 @@
#include "rockmacros.h" #include "rockmacros.h"
#include "input.h" #include "input.h"
char keystates[MAX_KEYS];
int nkeysdown;
#define MAX_EVENTS 32 #define MAX_EVENTS 32
static event_t eventqueue[MAX_EVENTS]; static event_t eventqueue[MAX_EVENTS];
@ -20,34 +16,23 @@ static int eventhead, eventpos;
int ev_postevent(event_t *ev) int ev_postevent(event_t *ev)
{ {
int nextevent; int nextevent;
nextevent = (eventhead+1)%MAX_EVENTS; nextevent = (eventhead+1)%MAX_EVENTS;
if (nextevent == eventpos) if (nextevent == eventpos)
return 0; return 0;
eventqueue[eventhead] = *ev; eventqueue[eventhead] = *ev;
eventhead = nextevent; eventhead = nextevent;
return 1; return 1;
} }
int ev_getevent(event_t *ev) int ev_getevent(event_t *ev)
{ {
if (eventpos == eventhead) if (eventpos == eventhead)
{ {
ev->type = EV_NONE; ev->type = EV_NONE;
return 0; return 0;
} }
*ev = eventqueue[eventpos]; *ev = eventqueue[eventpos];
eventpos = (eventpos+1)%MAX_EVENTS; eventpos = (eventpos+1)%MAX_EVENTS;
if (ev->type == EV_PRESS) return 1;
{
keystates[ev->code] = 1;
nkeysdown++;
}
if (ev->type == EV_RELEASE)
{
keystates[ev->code] = 0;
nkeysdown--;
if (nkeysdown < 0) nkeysdown = 0;
}
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 "rockmacros.h"
#include "fastmem.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 readb(int a)
{ {
byte *p = mbc.rmap[a>>12]; byte *p = mbc.rmap[a>>12];
if (p) return p[a]; if (p) return p[a];
else return mem_read(a); else return mem_read(a);
} }
void writeb(int a, byte b) void writeb(int a, byte b)
{ {
byte *p = mbc.wmap[a>>12]; byte *p = mbc.wmap[a>>12];
if (p) p[a] = b; if (p) p[a] = b;
else mem_write(a, b); else mem_write(a, b);
} }
int readw(int a) int readw(int a)
{ {
if ((a+1) & 0xfff) if ((a+1) & 0xfff)
{ {
byte *p = mbc.rmap[a>>12]; byte *p = mbc.rmap[a>>12];
if (p) if (p)
{ {
#ifdef ROCKBOX_LITTLE_ENDIAN #ifdef ROCKBOX_LITTLE_ENDIAN
#ifndef ALLOW_UNALIGNED_IO #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 #endif
return *(word *)(p+a); return *(word *)(p+a);
#else #else
return p[a] | (p[a+1]<<8); return p[a] | (p[a+1]<<8);
#endif #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) void writew(int a, int w)
{ {
if ((a+1) & 0xfff) if ((a+1) & 0xfff)
{ {
byte *p = mbc.wmap[a>>12]; byte *p = mbc.wmap[a>>12];
if (p) if (p)
{ {
#ifdef ROCKBOX_LITTLE_ENDIAN #ifdef ROCKBOX_LITTLE_ENDIAN
#ifndef ALLOW_UNALIGNED_IO #ifndef ALLOW_UNALIGNED_IO
if (a&1) if (a&1)
{ {
p[a] = w; p[a] = w;
p[a+1] = w >> 8; p[a+1] = w >> 8;
return; return;
} }
#endif #endif
*(word *)(p+a) = w; *(word *)(p+a) = w;
return; return;
#else #else
p[a] = w; p[a] = w;
p[a+1] = w >> 8; p[a+1] = w >> 8;
return; return;
#endif #endif
} }
} }
mem_write(a, w); mem_write(a, w);
mem_write(a+1, w>>8); mem_write(a+1, w>>8);
} }
byte readhi(int a) byte readhi(int a)
{ {
return readb(a | 0xff00); return readb(a | 0xff00);
} }
void writehi(int a, byte b) 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; void writew(int a, int w) ICODE_ATTR;
byte readhi(int a) ICODE_ATTR; byte readhi(int a) ICODE_ATTR;
void writehi(int a, byte b) ICODE_ATTR; void writehi(int a, byte b) ICODE_ATTR;
#if 0
byte readhi(int a);
void writehi(int a, byte b);
#endif
#endif #endif

View file

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

View file

@ -11,7 +11,7 @@
#include "fastmem.h" #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) void hw_interrupt(byte i, byte mask)
{ {
byte oldif = R_IF; byte oldif = R_IF;
i &= 0x1F & mask; i &= 0x1F & mask;
R_IF |= i & (hw.ilines ^ i); R_IF |= i & (hw.ilines ^ i);
/* FIXME - is this correct? not sure the docs understand... */ /* FIXME - is this correct? not sure the docs understand... */
if ((R_IF & (R_IF ^ oldif) & R_IE) && cpu.ime) cpu.halt = 0; 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 & (hw.ilines ^ i) & R_IE) && cpu.ime) cpu.halt = 0; */
/* if ((i & R_IE) && cpu.ime) cpu.halt = 0; */ /* if ((i & R_IE) && cpu.ime) cpu.halt = 0; */
hw.ilines &= ~mask; hw.ilines &= ~mask;
hw.ilines |= i; hw.ilines |= i;
} }
@ -47,64 +47,65 @@ void hw_interrupt(byte i, byte mask)
void hw_dma(byte b) void hw_dma(byte b)
{ {
int i; int i;
addr a; addr a;
a = ((addr)b) << 8; a = ((addr)b) << 8;
for (i = 0; i < 160; i++, a++) for (i = 0; i < 160; i++, a++)
lcd.oam.mem[i] = readb(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) void hw_hdma(void)
{ {
int cnt; int cnt;
addr sa; addr sa;
int da; int da;
sa = ((addr)R_HDMA1 << 8) | (R_HDMA2&0xf0); sa = ((addr)R_HDMA1 << 8) | (R_HDMA2&0xf0);
da = 0x8000 | ((int)(R_HDMA3&0x1f) << 8) | (R_HDMA4&0xf0); da = 0x8000 | ((int)(R_HDMA3&0x1f) << 8) | (R_HDMA4&0xf0);
cnt = 16; cnt = 16;
while (cnt--) while (cnt--)
writeb(da++, readb(sa++)); writeb(da++, readb(sa++));
R_HDMA1 = sa >> 8; cpu_timers(16);
R_HDMA2 = sa & 0xF0; R_HDMA1 = sa >> 8;
R_HDMA3 = 0x1F & (da >> 8); R_HDMA2 = sa & 0xF0;
R_HDMA4 = da & 0xF0; R_HDMA3 = 0x1F & (da >> 8);
R_HDMA5--; R_HDMA4 = da & 0xF0;
hw.hdma--; 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() void pad_refresh()
{ {
byte oldp1; byte oldp1;
oldp1 = R_P1; oldp1 = R_P1;
R_P1 &= 0x30; R_P1 &= 0x30;
R_P1 |= 0xc0; R_P1 |= 0xc0;
if (!(R_P1 & 0x10)) if (!(R_P1 & 0x10))
R_P1 |= (hw.pad & 0x0F); R_P1 |= (hw.pad & 0x0F);
if (!(R_P1 & 0x20)) if (!(R_P1 & 0x20))
R_P1 |= (hw.pad >> 4); R_P1 |= (hw.pad >> 4);
R_P1 ^= 0x0F; R_P1 ^= 0x0F;
if (oldp1 & ~R_P1 & 0x0F) if (oldp1 & ~R_P1 & 0x0F)
{ {
hw_interrupt(IF_PAD, IF_PAD); hw_interrupt(IF_PAD, IF_PAD);
hw_interrupt(0, IF_PAD); hw_interrupt(0, IF_PAD);
} }
} }
@ -140,44 +141,37 @@ void pad_refresh()
void pad_press(byte k) void pad_press(byte k)
{ {
if (hw.pad & k) if (hw.pad & k)
return; return;
hw.pad |= k; hw.pad |= k;
pad_refresh(); pad_refresh();
} }
void pad_release(byte k) void pad_release(byte k)
{ {
if (!(hw.pad & k)) if (!(hw.pad & k))
return; return;
hw.pad &= ~k; hw.pad &= ~k;
pad_refresh(); pad_refresh();
} }
void pad_set(byte k, int st) void pad_set(byte k, int st)
{ {
st ? pad_press(k) : pad_release(k); st ? pad_press(k) : pad_release(k);
} }
void hw_reset() 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_P1 = 0xFF;
R_LCDC = 0x91; R_LCDC = 0x91;
R_BGP = 0xFC; R_BGP = 0xFC;
R_OBP0 = 0xFF; R_OBP0 = 0xFF;
R_OBP1 = 0xFF; R_OBP1 = 0xFF;
R_SVBK = 0x01; R_SVBK = 0x01;
R_HDMA5 = 0xFF; R_HDMA5 = 0xFF;
R_VBK = 0xFE; R_VBK = 0xFE;
} }

View file

@ -25,10 +25,10 @@
struct hw struct hw
{ {
byte ilines; byte ilines;
byte pad; byte pad;
int hdma; int hdma;
int cgb,gba; 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. * Definitions for input device stuff - buttons, keys, etc.
*/ */
#define MAX_KEYS 10
typedef struct event_s typedef struct event_s
{ {
int type; int type;
int code; int code;
} event_t; } event_t;
#define EV_NONE 0 #define EV_NONE 0
#define EV_PRESS 1 #define EV_PRESS 1
#define EV_RELEASE 2 #define EV_RELEASE 2
#define EV_REPEAT 3
int ev_postevent(event_t *ev) ICODE_ATTR; int ev_postevent(event_t *ev) ICODE_ATTR;
int ev_getevent(event_t *ev) ICODE_ATTR; int ev_getevent(event_t *ev) ICODE_ATTR;

View file

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

View file

@ -4,9 +4,8 @@
#include "hw.h" #include "hw.h"
#include "mem.h" #include "mem.h"
#include "lcd-gb.h" #include "lcd-gb.h"
#include "rc.h"
#include "fb.h" #include "fb.h"
#include "palette.h" #include "palette-presets.h"
#ifdef USE_ASM #ifdef USE_ASM
#include "asm.h" #include "asm.h"
#endif #endif
@ -26,9 +25,7 @@ struct scan scan IBSS_ATTR;
#define PRI (scan.pri) #define PRI (scan.pri)
#define PAL1 (scan.pal1) #define PAL (scan.pal)
#define PAL2 (scan.pal2)
#define PAL4 (scan.pal4)
#define VS (scan.vs) /* vissprites */ #define VS (scan.vs) /* vissprites */
#define NS (scan.ns) #define NS (scan.ns)
@ -53,53 +50,14 @@ byte patpix[4096][8][8]
byte patdirty[1024]; byte patdirty[1024];
byte anydirty; byte anydirty;
// static int scale = 1;
static int rgb332;
static int sprsort = 1;
static int sprdebug;
static int insync=0;
#if LCD_DEPTH < 16 #if LCD_DEPTH < 16
static int scanline_ind=0; static int scanline_ind=0;
#endif #endif
#define DEF_PAL { 0x98d0e0, 0x68a0b0, 0x60707C, 0x2C3C3C } static int dmg_pal[4][4];
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
};
fb_data *vdest; 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 #ifndef ASM_UPDATEPATPIX
void updatepatpix(void) void updatepatpix(void)
{ {
@ -506,9 +464,10 @@ void tilebuf(void)
} }
// V = vertical line /* V = vertical line
// WX = WND start (if 0, no need to do anything) -> WY * WX = WND start (if 0, no need to do anything) -> WY
// U = start...something...thingy... 7 at most * U = start...something...thingy... 7 at most
*/
void bg_scan(void) void bg_scan(void)
{ {
int cnt; int cnt;
@ -539,7 +498,7 @@ void bg_scan(void)
); );
#else #else
src = patpix[*(tile++)][V]; src = patpix[*(tile++)][V];
MEMCPY8(dest, src); memcpy(dest,src,8);
dest += 8; dest += 8;
#endif #endif
cnt -= 8; cnt -= 8;
@ -574,7 +533,7 @@ void wnd_scan(void)
); );
#else #else
src = patpix[*(tile++)][WV]; src = patpix[*(tile++)][WV];
MEMCPY8(dest, src); memcpy(dest,src,8);
dest += 8; dest += 8;
#endif #endif
cnt -= 8; cnt -= 8;
@ -752,33 +711,12 @@ static void recolor(byte *buf, byte fill, int cnt)
while (cnt--) *(buf++) |= fill; 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) void spr_enum(void)
{ {
int i, j; int i, j;
struct obj *o; struct obj *o;
struct vissprite ts[10]; struct vissprite ts;
int v, pat; int v, pat;
int l, x;
NS = 0; NS = 0;
if (!(R_LCDC & 0x02)) return; if (!(R_LCDC & 0x02)) return;
@ -818,24 +756,19 @@ void spr_enum(void)
VS[NS].buf = patpix[pat][v]; VS[NS].buf = patpix[pat][v];
if (++NS == 10) break; if (++NS == 10) break;
} }
if (!sprsort||hw.cgb) return; if (hw.cgb) return;
/* not quite optimal but it finally works! */
for (i = 0; i < NS; i++) for (i = 0; i < NS; i++)
{ {
l = 0; for (j = i + 1; j < NS; j++)
x = VS[0].x;
for (j = 1; j < NS; j++)
{ {
if (VS[j].x < x) if (VS[i].x > VS[j].x)
{ {
l = j; ts = VS[i];
x = VS[j].x; VS[i] = VS[j];
VS[j] = ts;
} }
} }
ts[i] = VS[l];
VS[l].x = 160;
} }
memcpy(VS, ts, sizeof VS);
} }
void spr_scan(void) void spr_scan(void)
@ -854,8 +787,8 @@ void spr_scan(void)
for (; ns; ns--, vs--) for (; ns; ns--, vs--)
{ {
x = vs->x; x = vs->x;
if (x >= 160) continue; if (x > 159) continue;
if (x <= -8) continue; if (x < -7) continue;
if (x < 0) if (x < 0)
{ {
src = vs->buf - x; 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] = 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 DX ((LCD_WIDTH<<16) / 160)
#define DXI ((160<<16) / LCD_WIDTH) #define DXI ((160<<16) / LCD_WIDTH)
#define DY ((LCD_HEIGHT<<16) / 144) #define DY ((LCD_HEIGHT<<16) / 144)
@ -904,18 +835,38 @@ void spr_scan(void)
void lcd_begin(void) void lcd_begin(void)
{ {
/* if (fb.indexed)
{
if (rgb332) pal_set332();
else pal_expire();
}
*/
if(options.fullscreen) #if (LCD_WIDTH>=160) && (LCD_HEIGHT>=144)
vdest = fb.ptr; #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 else
vdest=fb.ptr+((LCD_HEIGHT-144)/2)*LCD_WIDTH + ((LCD_WIDTH-160)/2); vdest=fb.ptr+S3;
WY = R_WY; WY = R_WY;
} }
@ -930,11 +881,28 @@ void setvidmode(int mode)
{ {
switch(mode) switch(mode)
{ {
case 1: /* Full screen scale */ case 1:
#if (LCD_WIDTH>=160) && (LCD_HEIGHT>=144) /* Full screen scale */
SCALEWL=DX; SCALEWL=DX;
SCALEWS=DXI; SCALEWS=DXI;
SCALEHL=DY; SCALEHL=DY;
SCALEHS=DYI; 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; break;
case 2: /* Maintain Ratio */ case 2: /* Maintain Ratio */
if (DY<DX) if (DY<DX)
@ -952,37 +920,26 @@ void setvidmode(int mode)
SCALEHS=DXI; SCALEHS=DXI;
} }
break; break;
default: /* No Scaling (or fullscreen for smaller screens) */ default:
#if LCD_WIDTH>160
SCALEWL=1<<16; SCALEWL=1<<16;
SCALEWS=1<<16; SCALEWS=1<<16;
SCALEHL=1<<16; SCALEHL=1<<16;
SCALEHS=1<<16; SCALEHS=1<<16;
#else
SCALEWL=DX;
SCALEWS=DXI;
SCALEHL=DY;
SCALEHS=DYI;
#endif
} }
swidth=(160*SCALEWL)>>16; swidth=(160*SCALEWL)>>16;
sremain=LCD_WIDTH-swidth; sremain=LCD_WIDTH-swidth;
} }
char frameout[30];
void lcd_refreshline(void) void lcd_refreshline(void)
{ {
if(!insync) { #ifdef HAVE_LCD_COLOR
if(R_LY!=0) char frameout[30];
return; #endif
else
insync=1;
}
if (!(R_LCDC & 0x80)) if (!(R_LCDC & 0x80))
return; /* should not happen... */ return; /* should not happen... */
#if LCD_HEIGHT < 144 #if (LCD_HEIGHT <= 128) && !defined(HAVE_LCD_COLOR)
if ( (fb.mode==0&&(R_LY >= 128)) || if ( (fb.mode==0&&(R_LY >= 128)) ||
(fb.mode==1&&(R_LY < 16)) || (fb.mode==1&&(R_LY < 16)) ||
(fb.mode==2&&(R_LY<8||R_LY>=136)) || (fb.mode==2&&(R_LY<8||R_LY>=136)) ||
@ -1046,8 +1003,7 @@ void lcd_refreshline(void)
vid_update(L-((int)(L/9))); vid_update(L-((int)(L/9)));
#else #else
{ {
/* Universial Scaling pulled from PrBoom and modified for rockboy */ /* Universal Scaling pulled from PrBoom and modified for rockboy */
/* Needs some thought for screens smaller than the gameboy though */
static int hpt IDATA_ATTR=0x8000; static int hpt IDATA_ATTR=0x8000;
@ -1059,9 +1015,24 @@ void lcd_refreshline(void)
register unsigned int remain=sremain; register unsigned int remain=sremain;
while(wcount--) 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; srcpt+=SCALEWS;
} }
#if LCD_HEIGHT<144
if (options.fullscreen!=0 || (hpt>>16)<(LCD_HEIGHT))
#endif
vdest+=remain; vdest+=remain;
} }
@ -1086,15 +1057,16 @@ void lcd_refreshline(void)
#endif #endif
} }
void set_pal(void)
{
memcpy(dmg_pal,palettes[options.pal], sizeof dmg_pal);
pal_dirty();
}
#if HAVE_LCD_COLOR #if HAVE_LCD_COLOR
static void updatepalette(int i) 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; c = (lcd.pal[i<<1] | ((int)lcd.pal[(i<<1)|1] << 8)) & 0x7FFF;
r = (c & 0x001F) << 3; r = (c & 0x001F) << 3;
@ -1104,38 +1076,6 @@ static void updatepalette(int i)
g |= (g >> 5); g |= (g >> 5);
b |= (b >> 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; r = (r >> fb.cc[0].r) << fb.cc[0].l;
g = (g >> fb.cc[1].r) << fb.cc[1].l; g = (g >> fb.cc[1].r) << fb.cc[1].l;
b = (b >> fb.cc[2].r) << fb.cc[2].l; b = (b >> fb.cc[2].r) << fb.cc[2].l;
@ -1145,24 +1085,7 @@ static void updatepalette(int i)
#elif LCD_PIXELFORMAT == RGB565SWAPPED #elif LCD_PIXELFORMAT == RGB565SWAPPED
c = swap16(r|g|b); c = swap16(r|g|b);
#endif #endif
PAL[i] = c;
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;
}
} }
#endif #endif
@ -1183,7 +1106,6 @@ void pal_write_dmg(int i, int mapnum, byte d)
if (hw.cgb) return; if (hw.cgb) return;
/* if (mapnum >= 2) d = 0xe4; */
for (j = 0; j < 8; j += 2) for (j = 0; j < 8; j += 2)
{ {
c = cmap[(d >> j) & 3]; 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; lcd.vbank[R_VBK&1][a] = b;
if (a >= 0x1800) return; if (a >= 0x1800) return;
@ -1235,7 +1157,6 @@ void lcd_reset(void)
memset(&lcd, 0, sizeof lcd); memset(&lcd, 0, sizeof lcd);
lcd_begin(); lcd_begin();
vram_dirty(); vram_dirty();
pal_dirty();
} }

View file

@ -23,32 +23,23 @@
void stat_trigger(void) void stat_trigger(void)
{ {
static const int condbits[4] = { 0x08, 0x30, 0x20, 0x00 }; static const int condbits[4] = { 0x08, 0x10, 0x20, 0x00 };
int flag = 0; int flag = 0;
if ((R_LY < 0x91) && (R_LY == R_LYC)) if (R_LY == R_LYC)
{ {
R_STAT |= 0x04; R_STAT |= 0x04;
if (R_STAT & 0x40) flag = IF_STAT; if (R_STAT & 0x40) flag = IF_STAT;
} }
else R_STAT &= ~0x04; 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; if (!(R_LCDC & 0x80)) flag = 0;
hw_interrupt(flag, IF_STAT); 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 * 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 * 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) static void stat_change(int stat)
{ {
stat &= 3; stat &= 3;
R_STAT = (R_STAT & 0x7C) | stat; R_STAT = (R_STAT & 0x7C) | stat;
if (stat != 1) hw_interrupt(0, IF_VBLANK); if (stat != 1) hw_interrupt(0, IF_VBLANK);
/* hw_interrupt((stat == 1) ? IF_VBLANK : 0, IF_VBLANK); */ /* hw_interrupt((stat == 1) ? IF_VBLANK : 0, IF_VBLANK); */
stat_trigger(); stat_trigger();
} }
void lcdc_change(byte b) void lcdc_change(byte b)
{ {
byte old = R_LCDC; byte old = R_LCDC;
R_LCDC = b; R_LCDC = b;
if ((R_LCDC ^ old) & 0x80) /* lcd on/off change */ if ((R_LCDC ^ old) & 0x80) /* lcd on/off change */
{ {
R_LY = 0; R_LY = 0;
stat_change(2); stat_change(2);
C = 40; C = 40;
lcd_begin(); lcd_begin();
} }
} }
void lcdc_trans(void) void lcdc_trans(void)
{ {
if (!(R_LCDC & 0x80)) if (!(R_LCDC & 0x80))
{ {
while (C <= 0) while (C <= 0)
{ {
switch ((byte)(R_STAT & 3)) switch ((byte)(R_STAT & 3))
{ {
case 0: case 0:
case 1: case 1:
stat_change(2); stat_change(2);
C += 40; C += 40;
break; break;
case 2: case 2:
stat_change(3); stat_change(3);
C += 86; C += 86;
break; break;
case 3: case 3:
stat_change(0); stat_change(0);
if (hw.hdma & 0x80) if (hw.hdma & 0x80)
hw_hdma(); hw_hdma();
else else
C += 102; C += 102;
break; break;
} }
return; return;
} }
} }
while (C <= 0) while (C <= 0)
{ {
switch ((byte)(R_STAT & 3)) switch ((byte)(R_STAT & 3))
{ {
case 1: case 1:
if (!(hw.ilines & IF_VBLANK)) if (!(hw.ilines & IF_VBLANK))
{ {
C += 218; C += 218;
hw_interrupt(IF_VBLANK, IF_VBLANK); hw_interrupt(IF_VBLANK, IF_VBLANK);
break; break;
} }
if (R_LY == 0) if (R_LY == 0)
{ {
lcd_begin(); lcd_begin();
stat_change(2); stat_change(2);
C += 40; C += 40;
break; break;
} }
else if (R_LY < 152) else if (R_LY < 152)
C += 228; C += 228;
else if (R_LY == 152) else if (R_LY == 152)
C += 28; C += 28;
else else
{ {
R_LY = -1; R_LY = -1;
C += 200; C += 200;
} }
R_LY++; R_LY++;
stat_trigger(); stat_trigger();
break; break;
case 2: case 2:
if (fb.enabled) if (fb.enabled)
lcd_refreshline(); lcd_refreshline();
stat_change(3); stat_change(3);
C += 86; C += 86;
break; break;
case 3: case 3:
stat_change(0); stat_change(0);
if (hw.hdma & 0x80) if (hw.hdma & 0x80)
hw_hdma(); hw_hdma();
/* FIXME -- how much of the hblank does hdma use?? */ /* FIXME -- how much of the hblank does hdma use?? */
/* else */ /* else */
C += 102; C += 102;
break; break;
case 0: case 0:
if (++R_LY >= 144) if (++R_LY >= 144)
{ {
if (cpu.halt) if (cpu.halt)
{ {
hw_interrupt(IF_VBLANK, IF_VBLANK); hw_interrupt(IF_VBLANK, IF_VBLANK);
C += 228; C += 228;
} }
else C += 10; else C += 10;
stat_change(1); stat_change(1);
break; break;
} }
stat_change(2); stat_change(2);
C += 40; C += 40;
break; break;
} }
} }
} }

View file

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

View file

@ -3,95 +3,42 @@
#include "rockmacros.h" #include "rockmacros.h"
#include "input.h" #include "input.h"
#include "rc.h"
#include "exports.h"
#include "emu.h" #include "emu.h"
#include "loader.h" #include "loader.h"
#include "hw.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() void doevents()
{ {
event_t ev; event_t ev;
int st; int st;
ev_poll(); ev_poll();
while (ev_getevent(&ev)) while (ev_getevent(&ev))
{ {
if (ev.type != EV_PRESS && ev.type != EV_RELEASE) if (ev.type != EV_PRESS && ev.type != EV_RELEASE)
continue; continue;
st = (ev.type != EV_RELEASE); st = (ev.type != EV_RELEASE);
pad_set(ev.code, st); 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 gnuboy_main(char *rom)
{ {
int i, w, h, y; rb->lcd_puts(0,0,"Init video");
vid_init();
y = 1; rb->lcd_puts(0,1,"Init sound");
// Avoid initializing video if we don't have to pcm_init();
// If we have special perms, drop them ASAP! rb->lcd_puts(0,2,"Loading rom");
PUTS("Init exports"); loader_init(rom);
init_exports(); if(shut)
return PLUGIN_ERROR;
PUTS("Loading default config"); rb->lcd_puts(0,3,"Emu reset");
for (i = 0; defaultconfig[i]; i++) emu_reset();
rc_command(defaultconfig[i]); rb->lcd_puts(0,4,"Emu run");
// 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_clear_display(); rb->lcd_clear_display();
// rb->lcd_drawrect((LCD_WIDTH-160)/2-1, (LCD_HEIGHT-144)/2-1, 162, 146);
rb->lcd_update(); rb->lcd_update();
#endif emu_run();
emu_run();
// never reached /* never reached */
return PLUGIN_OK; return PLUGIN_OK;
} }
#undef PUTS

View file

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

View file

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

View file

@ -13,6 +13,13 @@
#define MENU_BUTTON_DOWN BUTTON_SCROLL_FWD #define MENU_BUTTON_DOWN BUTTON_SCROLL_FWD
#define MENU_BUTTON_LEFT BUTTON_LEFT #define MENU_BUTTON_LEFT BUTTON_LEFT
#define MENU_BUTTON_RIGHT BUTTON_RIGHT #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 #else
#define MENU_BUTTON_UP BUTTON_UP #define MENU_BUTTON_UP BUTTON_UP
#define MENU_BUTTON_DOWN BUTTON_DOWN #define MENU_BUTTON_DOWN BUTTON_DOWN
@ -322,9 +329,9 @@ static void do_opt_menu(void)
}; };
static const struct opt_items fullscreen[]= { static const struct opt_items fullscreen[]= {
{ "Off", -1 }, { "Unscaled", -1 },
{ "Fullscreen", -1 }, { "Scaled", -1 },
{ "Full - Maintain Ratio", -1 }, { "Scaled - Maintain Ratio", -1 },
}; };
static const struct opt_items frameskip[]= { static const struct opt_items frameskip[]= {
@ -334,12 +341,37 @@ static void do_opt_menu(void)
{ "6 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[] = { static const struct menu_item items[] = {
{ "Max Frameskip", NULL }, { "Max Frameskip", NULL },
{ "Sound" , NULL }, { "Sound" , NULL },
{ "Stats" , NULL }, { "Stats" , NULL },
{ "Fullscreen" , NULL }, { "Screen Options" , NULL },
{ "Set Keys (Buggy)", 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); 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 */ case 1: /* Sound */
if(options.sound>1) options.sound=1; if(options.sound>1) options.sound=1;
rb->set_option(items[1].desc, &options.sound, INT, onoff, 2, NULL ); rb->set_option(items[1].desc, &options.sound, INT, onoff, 2, NULL );
if(options.sound) sound_dirty();
break; break;
case 2: /* Stats */ case 2: /* Stats */
rb->set_option(items[2].desc, &options.showstats, INT, onoff, 2, NULL ); 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 */ case 4: /* Keys */
setupkeys(); setupkeys();
break; 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: default:
done=true; done=true;
break; 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 struct pcm
{ {
int hz, len; int hz, len;
int stereo; int stereo;
byte *buf; byte *buf;
int pos; int pos;
}; };
extern struct pcm pcm; extern struct pcm pcm;

View file

@ -1,11 +1,13 @@
#include "rockmacros.h" #include "rockmacros.h"
#include "defs.h" #include "defs.h"
#include "pcm.h" #include "pcm.h"
#include "rc.h"
//#define ONEBUF // Note: I think the single buffer implementation is more responsive with sound(less lag) /*#define ONEBUF*/
// but it creates more choppyness overall to the sound. 2 buffer's don't seem to make /* Note: I think the single buffer implementation is more
// a difference, but 4 buffers is definately noticable * 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; struct pcm pcm IBSS_ATTR;
@ -17,11 +19,6 @@ bool sound = 1;
#endif #endif
#define BUF_SIZE 1024 #define BUF_SIZE 1024
rcvar_t pcm_exports[] =
{
RCV_END
};
#if CONFIG_CODEC == SWCODEC && !defined(SIMULATOR) #if CONFIG_CODEC == SWCODEC && !defined(SIMULATOR)
#ifndef ONEBUF #ifndef ONEBUF
@ -48,46 +45,45 @@ void get_more(unsigned char** start, size_t* size)
void pcm_init(void) void pcm_init(void)
{ {
if(!sound) return; newly_started = true;
newly_started = true; pcm.hz = 11025;
pcm.stereo = 1;
pcm.hz = 11025; pcm.len = BUF_SIZE;
pcm.stereo = 1; if(!buf){
pcm.len = BUF_SIZE;
if(!buf){
buf = my_malloc(pcm.len * N_BUFS); buf = my_malloc(pcm.len * N_BUFS);
gmbuf = my_malloc(pcm.len * N_BUFS*sizeof (short)); gmbuf = my_malloc(pcm.len * N_BUFS*sizeof (short));
pcm.buf = buf; pcm.buf = buf;
pcm.pos = 0; pcm.pos = 0;
#ifndef ONEBUF #ifndef ONEBUF
curbuf = gmcurbuf= 0; curbuf = gmcurbuf= 0;
#endif #endif
memset(gmbuf, 0, pcm.len * N_BUFS *sizeof(short)); memset(gmbuf, 0, pcm.len * N_BUFS *sizeof(short));
memset(buf, 0, pcm.len * N_BUFS); 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) void pcm_close(void)
{ {
memset(&pcm, 0, sizeof pcm); memset(&pcm, 0, sizeof pcm);
newly_started = true; newly_started = true;
rb->pcm_play_stop(); rb->pcm_play_stop();
rb->pcm_set_frequency(44100); rb->pcm_set_frequency(44100);
} }
int pcm_submit(void) int pcm_submit(void)
{ {
register int i; if (!options.sound) return 1;
register int i;
if (!sound) { if (!sound) {
pcm.pos = 0; pcm.pos = 0;
return 0; return 0;
} }
if (pcm.pos < pcm.len) return 1; if (pcm.pos < pcm.len) return 1;
@ -98,7 +94,7 @@ int pcm_submit(void)
#endif #endif
pcm.pos = 0; 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++) for(i=0; i<pcm.len;i++)
#ifdef ONEBUF #ifdef ONEBUF
gmbuf[i] = (pcm.buf[i]<<8)-0x8000; gmbuf[i] = (pcm.buf[i]<<8)-0x8000;
@ -112,7 +108,9 @@ int pcm_submit(void)
newly_started = false; 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 #ifdef ONEBUF
while(doneplay==0) rb->yield(); while(doneplay==0) rb->yield();
doneplay=0; doneplay=0;
@ -120,7 +118,7 @@ int pcm_submit(void)
return 1; return 1;
} }
#else #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) void pcm_init(void)
{ {
pcm.hz = 11025; 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); snprintf(optionsave, sizeof(optionsave), "%s/%s", savedir, optionname);
fd = open(optionsave, O_RDONLY); 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) #if (CONFIG_KEYPAD == IRIVER_H100_PAD)
options.A=BUTTON_ON; options.A=BUTTON_ON;
@ -136,13 +136,31 @@ void setoptions (void)
options.START=BUTTON_SCROLL_UP; options.START=BUTTON_SCROLL_UP;
options.SELECT=BUTTON_SCROLL_DOWN; options.SELECT=BUTTON_SCROLL_DOWN;
options.MENU=BUTTON_POWER; 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 #endif
options.maxskip=4; options.maxskip=4;
options.fps=0; options.fps=0;
options.showstats=0; options.showstats=0;
#if (LCD_WIDTH>=160) && (LCD_HEIGHT>=144)
options.fullscreen=0; options.fullscreen=0;
#else
options.fullscreen=1;
#endif
options.sound=1; options.sound=1;
options.pal=0;
} }
else else
read(fd,&options, sizeof(options)); 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); rb->wheel_send_events(false);
#endif #endif
/* now go ahead and have fun! */
/* rb->splash(HZ*2, true, "Rockboy v0.3"); */
/* rb->lcd_clear_display(); */
gnuboy_main(parameter); gnuboy_main(parameter);
#ifdef HAVE_WHEEL_POSITION #ifdef HAVE_WHEEL_POSITION

View file

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

View file

@ -6,12 +6,12 @@
struct rtc struct rtc
{ {
int batt; int batt;
int sel; int sel;
int latch; int latch;
int d, h, m, s, t; int d, h, m, s, t;
int stop, carry; int stop, carry;
byte regs[8]; byte regs[8];
}; };
extern struct rtc rtc; extern struct rtc rtc;

View file

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

View file

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

View file

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

View file

@ -5,20 +5,18 @@
struct sndchan struct sndchan
{ {
int on; int on;
unsigned pos; unsigned pos;
int cnt, encnt, swcnt; int cnt, encnt, swcnt;
int len, enlen, swlen; int len, enlen, swlen;
int swfreq; int freq;
int freq; int envol, endir;
int envol, endir;
}; };
struct snd struct snd
{ {
int rate; int rate;
struct sndchan ch[4]; struct sndchan ch[4];
byte wave[16];
}; };
extern struct snd snd; extern struct snd snd;
@ -31,7 +29,6 @@ extern struct snd snd;
byte sound_read(byte r) ICODE_ATTR; byte sound_read(byte r) ICODE_ATTR;
void sound_write(byte r, byte b) ICODE_ATTR; void sound_write(byte r, byte b) ICODE_ATTR;
void sound_dirty(void) ICODE_ATTR; void sound_dirty(void) ICODE_ATTR;
void sound_off(void);
void sound_reset(void); void sound_reset(void);
void sound_mix(void) ICODE_ATTR; void sound_mix(void) ICODE_ATTR;
void s1_init(void); 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 "rockmacros.h"
#include "fb.h" #include "fb.h"
#include "input.h" #include "input.h"
#include "rc.h"
#include "lcd-gb.h" #include "lcd-gb.h"
#include "hw.h" #include "hw.h"
#include "config.h" #include "config.h"
@ -32,6 +31,13 @@
#define ROCKBOY_PAD_UP BUTTON_MENU #define ROCKBOY_PAD_UP BUTTON_MENU
#define ROCKBOY_PAD_DOWN BUTTON_PLAY #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 #else
#define ROCKBOY_PAD_LEFT BUTTON_LEFT #define ROCKBOY_PAD_LEFT BUTTON_LEFT
@ -41,33 +47,10 @@
#endif #endif
rcvar_t joy_exports[] = struct fb fb IBSS_ATTR;
{
RCV_END
};
rcvar_t vid_exports[] =
{
RCV_END
};
struct fb fb;
extern int debug_trace; 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; unsigned int oldbuttonstate = 0, newbuttonstate,holdbutton;
#ifdef HAVE_WHEEL_POSITION #ifdef HAVE_WHEEL_POSITION
int oldwheel = -1, wheel; int oldwheel = -1, wheel;
@ -179,10 +162,7 @@ void ev_poll(void)
if(pressed & options.MENU) { if(pressed & options.MENU) {
#endif #endif
#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
(CONFIG_KEYPAD == IRIVER_H300_PAD) || \ defined(HAVE_LCD_COLOR)
(CONFIG_KEYPAD == IPOD_4G_PAD) || \
(CONFIG_KEYPAD == GIGABEAT_PAD) || \
(CONFIG_KEYPAD == SANSA_E200_PAD)
#ifdef HAVE_WHEEL_POSITION #ifdef HAVE_WHEEL_POSITION
rb->wheel_send_events(true); rb->wheel_send_events(true);
#endif #endif
@ -202,53 +182,36 @@ void ev_poll(void)
#endif #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; static int skip = 0;
(void)r; if (skip<options.frameskip)
(void)g; {
(void)b; skip++;
} fb.enabled=0;
}
inline void vid_begin(void) // New frameskip, makes more sense to me and performs as well else
{ {
static int skip = 0; skip=0;
if (skip<options.frameskip) { fb.enabled=1;
skip++; }
fb.enabled=0;
}
else {
skip=0;
fb.enabled=1;
}
} }
void vid_init(void) void vid_init(void)
{ {
fb.h=144;
fb.w=160;
fb.pitch=160;
fb.enabled=1; fb.enabled=1;
fb.dirty=0; fb.ptr=rb->lcd_framebuffer;
fb.mode=3;
fb.ptr=rb->lcd_framebuffer;
#if defined(HAVE_LCD_COLOR) #if defined(HAVE_LCD_COLOR)
fb.pelsize=2; // 16 bit framebuffer 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.indexed = 0; // no palette on lcd fb.cc[1].r = 2; /* 8-6 (wasted bits on green) */
fb.cc[0].r = 3; // 8-5 (wasted bits on red) fb.cc[1].l = 5; /* This is the offset to the G bits (16-5-6) */
fb.cc[0].l = 11; //this is the offset to the R bits (16-5) fb.cc[2].r = 3; /* 8-5 (wasted bits on red) */
fb.cc[1].r = 2; // 8-6 (wasted bits on green) fb.cc[2].l = 0; /* This is the offset to the B bits (16-5-6-5) */
fb.cc[1].l = 5; // This is the offset to the G bits (16-5-6) #else
fb.cc[2].r = 3; // 8-5 (wasted bits on red) fb.mode=3;
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...
#endif #endif
} }
@ -350,43 +313,29 @@ void vid_update(int scanline)
cnt++; cnt++;
} }
rb->lcd_update_rect(0, scanline & ~3, LCD_WIDTH, 4); rb->lcd_update_rect(0, scanline & ~3, LCD_WIDTH, 4);
#elif defined(HAVE_LCD_COLOR) /* iriver H3x0, colour iPod */ #elif defined(HAVE_LCD_COLOR)
// handled in lcd.c now /* handled in lcd.c now */
#endif /* LCD_HEIGHT */ #endif /* LCD_HEIGHT */
} }
#endif #endif
void vid_end(void)
{
}
long timerresult; long timerresult;
void *sys_timer(void) void *sys_timer(void)
{/* {
timerresult=*rb->current_tick; /*timerresult=*rb->current_tick;
return &timerresult;*/ return &timerresult;*/
return 0; return 0;
} }
// returns microseconds passed since sys_timer /* returns microseconds passed since sys_timer */
int sys_elapsed(long *oldtick) int sys_elapsed(long *oldtick)
{ {
/* /* int elap,mytime=microtick;
int elap,mytime=microtick;
elap=mytime-*oldtick; elap=mytime-*oldtick;
*oldtick=mytime; *oldtick=mytime;
return elap;*/ return elap; */
// return ((*rb->current_tick-(*oldtick))*1000000)/HZ; /* return ((*rb->current_tick-(*oldtick))*1000000)/HZ; */
return *oldtick; return *oldtick;
} }
void sys_sleep(int us)
{
if(us<=0) return;
int i=0;
while(i< us*11)
i++;
// if (us <= 0) return;
}