upgrade core, fix frameskipping bug

This commit is contained in:
dborth 2008-09-22 23:00:10 +00:00
parent e1c493fed1
commit c711145d1d
83 changed files with 29032 additions and 36431 deletions

View File

@ -18,17 +18,17 @@ include $(DEVKITPPC)/gamecube_rules
TARGET := vbagx_gc TARGET := vbagx_gc
TARGETDIR := executables TARGETDIR := executables
BUILD := build_gc BUILD := build_gc
SOURCES := source/vba source/vba/gb source/ngc SOURCES := source/vba source/vba/agb source/vba/dmg source/ngc
INCLUDES := source/vba source/vba/gb source/ngc INCLUDES := source/vba source/ngc
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# options for code generation # options for code generation
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE) -maltivec \ CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) \
-DNGC -DWORDS_BIGENDIAN -DC_CORE \ -DNGC -DWORDS_BIGENDIAN -DC_CORE -DFINAL_VERSION \
-DCHANFFS -DSDL -DHAVE_ZUTIL_H -DSDL -DNO_PNG -DHAVE_ZUTIL_H
CXXFLAGS = -save-temps -Xassembler -aln=$@.lst $(CFLAGS) CXXFLAGS = $(CFLAGS)
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------

View File

@ -18,17 +18,17 @@ include $(DEVKITPPC)/wii_rules
TARGET := vbagx_wii TARGET := vbagx_wii
TARGETDIR := executables TARGETDIR := executables
BUILD := build_wii BUILD := build_wii
SOURCES := source/vba source/vba/gb source/ngc SOURCES := source/vba source/vba/agb source/vba/dmg source/ngc
INCLUDES := source/vba source/vba/gb source/ngc INCLUDES := source/vba source/ngc
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# options for code generation # options for code generation
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE) -maltivec \ CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) \
-DNGC -DWORDS_BIGENDIAN -DC_CORE \ -DNGC -DWORDS_BIGENDIAN -DC_CORE -DFINAL_VERSION \
-DCHANFFS -DSDL -DHAVE_ZUTIL_H -DSDL -DNO_PNG -DHAVE_ZUTIL_H
CXXFLAGS = -save-temps -Xassembler -aln=$@.lst $(CFLAGS) CXXFLAGS = $(CFLAGS)
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------

View File

@ -1,7 +1,7 @@
¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤ ¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤
- Visual Boy Advance GX - - Visual Boy Advance GX -
Version 1.0.1 Version 1.0.2
(Under GPL License) (Under GPL License)
¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤ ¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤
@ -22,6 +22,16 @@ With it you can play GBA/Game Boy Color/Game Boy games on your Wii/GameCube.
|0O×øo· UPDATE HISTORY ·oø×O0| |0O×øo· UPDATE HISTORY ·oø×O0|
`¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨' `¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨'
[What's New 1.0.2]
* New core! The core is a modified version of VBA-M and VBA 1.80 beta 3
* Better emulation speeds. Should now be nearly full speed all the time
* Turbo speed feature. Mapped to right C-stick (classic controller &
Gamecube controller), and A+B for wiimote
* Controller mapping preferences bug fixed. Your preferences will reset
automatically to correct any problems in your preferences file
* Fix a frameskipping bug
* Some tweaks behind the scenes
[What's New 1.0.1] [What's New 1.0.1]
* GBA games now run at full speed * GBA games now run at full speed
* Menu improvements, with spiffy new background - thanks brakken! * Menu improvements, with spiffy new background - thanks brakken!

View File

@ -13,23 +13,21 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "GBA.h" #include "agb/GBA.h"
#include "agbprint.h" #include "agb/agbprint.h"
#include "Flash.h" #include "Flash.h"
#include "Port.h" #include "Port.h"
#include "RTC.h" #include "RTC.h"
#include "Sound.h" #include "Sound.h"
#include "Text.h"
#include "unzip.h" #include "unzip.h"
#include "Util.h" #include "Util.h"
#include "gb/GB.h" #include "dmg/GB.h"
#include "gb/gbGlobals.h" #include "dmg/gbGlobals.h"
#include "vba.h" #include "vba.h"
#include "fileop.h" #include "fileop.h"
#include "audio.h" #include "audio.h"
#include "vmmem.h" #include "vmmem.h"
#include "pal60.h"
#include "input.h" #include "input.h"
#include "video.h" #include "video.h"
#include "menudraw.h" #include "menudraw.h"
@ -44,9 +42,6 @@ static tb_t start, now;
u32 loadtimeradjust; u32 loadtimeradjust;
int throttle = 100;
u32 throttleLastTime = 0;
static u32 autoFrameSkipLastTime = 0; static u32 autoFrameSkipLastTime = 0;
static int frameskipadjust = 0; static int frameskipadjust = 0;
@ -122,7 +117,7 @@ bool systemPauseOnFrame()
{ {
return false; return false;
} }
/*
void GC_Sleep(u32 dwMiliseconds) void GC_Sleep(u32 dwMiliseconds)
{ {
int nVBlanks = (dwMiliseconds / 16); int nVBlanks = (dwMiliseconds / 16);
@ -131,7 +126,7 @@ void GC_Sleep(u32 dwMiliseconds)
VIDEO_WaitVSync(); VIDEO_WaitVSync();
} }
} }
*/
void system10Frames(int rate) void system10Frames(int rate)
{ {
if ( cartridgeType == 1 ) if ( cartridgeType == 1 )
@ -181,8 +176,8 @@ void system10Frames(int rate)
****************************************************************************/ ****************************************************************************/
void systemGbPrint(u8 *data,int pages,int feed,int palette, int contrast) {} void systemGbPrint(u8 *data,int pages,int feed,int palette, int contrast) {}
void debuggerOutput(char *, u32) {} void debuggerOutput(const char *s, u32 addr) {}
void (*dbgOutput)(char *, u32) = debuggerOutput; void (*dbgOutput)(const char *s, u32 addr) = debuggerOutput;
void systemMessage(int num, const char *msg, ...) {} void systemMessage(int num, const char *msg, ...) {}
/**************************************************************************** /****************************************************************************
@ -397,7 +392,7 @@ int loadVBAROM(char filename[])
} }
// Set defaults // Set defaults
flashSetSize(0x10000); flashSetSize(0x20000); // 128K saves
rtcEnable(true); rtcEnable(true);
agbPrintEnable(false); agbPrintEnable(false);
soundOffFlag = false; soundOffFlag = false;
@ -425,6 +420,9 @@ int loadVBAROM(char filename[])
emulating = 1; emulating = 1;
// reset frameskip variables
autoFrameSkipLastTime = frameskipadjust = systemFrameSkip = 0;
// Start system clock // Start system clock
mftb(&start); mftb(&start);

View File

@ -17,7 +17,7 @@
#include <fat.h> #include <fat.h>
#include <sys/dir.h> #include <sys/dir.h>
#include "GBA.h" #include "agb/GBA.h"
#include "Globals.h" #include "Globals.h"
#include "Util.h" #include "Util.h"
#include "Port.h" #include "Port.h"
@ -104,20 +104,16 @@ static void VMClose( void )
int VMCPULoadROM( char *filename ) int VMCPULoadROM( char *filename )
{ {
int res=0; int res=0;
char temp[512]; //char temp[512];
VMClose(); VMClose();
VMAllocGBA(); VMAllocGBA();
GBAROMSize = 0; GBAROMSize = 0;
sprintf(temp,"Filename %s\n", filename);
//WaitPrompt(temp);
romfile = gen_fopen(filename, "rb"); romfile = gen_fopen(filename, "rb");
if ( romfile == NULL ) if ( romfile == NULL )
{ {
WaitPrompt((char*) "Error opening file!"); WaitPrompt((char*) "Error opening file!");
//while(1);
VMClose(); VMClose();
return 0; return 0;
} }
@ -126,7 +122,7 @@ int VMCPULoadROM( char *filename )
GBAROMSize = ftell(romfile); GBAROMSize = ftell(romfile);
fseek(romfile, 0, SEEK_SET); fseek(romfile, 0, SEEK_SET);
sprintf(temp,"ROM Size %dMb (%dMBit)", GBAROMSize/1024/1024,(GBAROMSize*8)/1024/1024); //sprintf(temp,"ROM Size %dMb (%dMBit)", GBAROMSize/1024/1024,(GBAROMSize*8)/1024/1024);
//WaitPrompt(temp); //WaitPrompt(temp);
rom = (u8 *)MEM2Storage; rom = (u8 *)MEM2Storage;
@ -137,7 +133,8 @@ int VMCPULoadROM( char *filename )
if ( (u32)res != GBAROMSize ) if ( (u32)res != GBAROMSize )
{ {
WaitPrompt((char*) "Error reading file!"); WaitPrompt((char*) "Error reading file!");
while(1); VMClose();
return 0;
} }
strcpy( romfilename, filename ); strcpy( romfilename, filename );
@ -208,7 +205,7 @@ u8 VMRead8( u32 address )
#include <string.h> #include <string.h>
#include <malloc.h> #include <malloc.h>
#include "GBA.h" #include "agb/GBA.h"
#include "Globals.h" #include "Globals.h"
#include "Util.h" #include "Util.h"
#include "Port.h" #include "Port.h"
@ -389,13 +386,12 @@ int VMCPULoadROM( char *filename )
loadtimeradjust = useVM = GBAROMSize = 0; loadtimeradjust = useVM = GBAROMSize = 0;
printf("Filename %s\n", filename); //printf("Filename %s\n", filename);
romfile = gen_fopen(filename, "rb"); romfile = gen_fopen(filename, "rb");
if ( romfile == NULL ) if ( romfile == NULL )
{ {
WaitPrompt((char*) "Error opening file!"); WaitPrompt((char*) "Error opening file!");
while(1);
VMClose(); VMClose();
return 0; return 0;
} }
@ -408,7 +404,8 @@ int VMCPULoadROM( char *filename )
{ {
sprintf(msg, "Error reading file! %i \n",res); sprintf(msg, "Error reading file! %i \n",res);
WaitPrompt(msg); WaitPrompt(msg);
while(1); VMClose();
return 0;
} }
fseek(romfile, 0, SEEK_END); fseek(romfile, 0, SEEK_END);
@ -446,7 +443,8 @@ static void VMNewPage( int pageid )
{ {
sprintf(msg, "Seek error! - Offset %08x %d\n", pageid << VMSHIFTBITS, res); sprintf(msg, "Seek error! - Offset %08x %d\n", pageid << VMSHIFTBITS, res);
WaitPrompt(msg); WaitPrompt(msg);
while(1); VMClose();
return;
} }
VMAllocate( pageid ); VMAllocate( pageid );
@ -456,7 +454,8 @@ static void VMNewPage( int pageid )
{ {
sprintf(msg, "Error reading! %d bytes only\n", res); sprintf(msg, "Error reading! %d bytes only\n", res);
WaitPrompt(msg); WaitPrompt(msg);
while(1); VMClose();
return;
} }
mftb(&end); mftb(&end);
@ -516,7 +515,8 @@ u32 VMRead32( u32 address )
default: default:
sprintf(msg, "VM32 : Unknown page type! (%d) [%d]", vmpage[pageid].pagetype, pageid); sprintf(msg, "VM32 : Unknown page type! (%d) [%d]", vmpage[pageid].pagetype, pageid);
WaitPrompt(msg); WaitPrompt(msg);
while(1); VMClose();
return 0;
} }
/* Can never get here ... but stops gcc bitchin' */ /* Can never get here ... but stops gcc bitchin' */
@ -555,7 +555,8 @@ u16 VMRead16( u32 address )
default: default:
WaitPrompt((char*) "VM16 : Unknown page type!"); WaitPrompt((char*) "VM16 : Unknown page type!");
while(1); VMClose();
return 0;
} }
/* Can never get here ... but stops gcc bitchin' */ /* Can never get here ... but stops gcc bitchin' */
@ -594,7 +595,8 @@ u8 VMRead8( u32 address )
default: default:
WaitPrompt((char*) "VM8 : Unknown page type!"); WaitPrompt((char*) "VM8 : Unknown page type!");
while(1); VMClose();
return 0;
} }
/* Can never get here ... but stops gcc bitchin' */ /* Can never get here ... but stops gcc bitchin' */

View File

@ -1,362 +1,329 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "CheatSearch.h" #include "CheatSearch.h"
CheatSearchBlock cheatSearchBlocks[4]; CheatSearchBlock cheatSearchBlocks[4];
CheatSearchData cheatSearchData = { CheatSearchData cheatSearchData = {
0, 0,
cheatSearchBlocks cheatSearchBlocks
}; };
static bool cheatSearchEQ(u32 a, u32 b) static bool cheatSearchEQ(u32 a, u32 b)
{ {
return a == b; return a == b;
} }
static bool cheatSearchNE(u32 a, u32 b) static bool cheatSearchNE(u32 a, u32 b)
{ {
return a != b; return a != b;
} }
static bool cheatSearchLT(u32 a, u32 b) static bool cheatSearchLT(u32 a, u32 b)
{ {
return a < b; return a < b;
} }
static bool cheatSearchLE(u32 a, u32 b) static bool cheatSearchLE(u32 a, u32 b)
{ {
return a <= b; return a <= b;
} }
static bool cheatSearchGT(u32 a, u32 b) static bool cheatSearchGT(u32 a, u32 b)
{ {
return a > b; return a > b;
} }
static bool cheatSearchGE(u32 a, u32 b) static bool cheatSearchGE(u32 a, u32 b)
{ {
return a >= b; return a >= b;
} }
static bool cheatSearchSignedEQ(s32 a, s32 b) static bool cheatSearchSignedEQ(s32 a, s32 b)
{ {
return a == b; return a == b;
} }
static bool cheatSearchSignedNE(s32 a, s32 b) static bool cheatSearchSignedNE(s32 a, s32 b)
{ {
return a != b; return a != b;
} }
static bool cheatSearchSignedLT(s32 a, s32 b) static bool cheatSearchSignedLT(s32 a, s32 b)
{ {
return a < b; return a < b;
} }
static bool cheatSearchSignedLE(s32 a, s32 b) static bool cheatSearchSignedLE(s32 a, s32 b)
{ {
return a <= b; return a <= b;
} }
static bool cheatSearchSignedGT(s32 a, s32 b) static bool cheatSearchSignedGT(s32 a, s32 b)
{ {
return a > b; return a > b;
} }
static bool cheatSearchSignedGE(s32 a, s32 b) static bool cheatSearchSignedGE(s32 a, s32 b)
{ {
return a >= b; return a >= b;
} }
static bool (*cheatSearchFunc[])(u32,u32) = { static bool (*cheatSearchFunc[])(u32,u32) = {
cheatSearchEQ, cheatSearchEQ,
cheatSearchNE, cheatSearchNE,
cheatSearchLT, cheatSearchLT,
cheatSearchLE, cheatSearchLE,
cheatSearchGT, cheatSearchGT,
cheatSearchGE cheatSearchGE
}; };
static bool (*cheatSearchSignedFunc[])(s32,s32) = { static bool (*cheatSearchSignedFunc[])(s32,s32) = {
cheatSearchSignedEQ, cheatSearchSignedEQ,
cheatSearchSignedNE, cheatSearchSignedNE,
cheatSearchSignedLT, cheatSearchSignedLT,
cheatSearchSignedLE, cheatSearchSignedLE,
cheatSearchSignedGT, cheatSearchSignedGT,
cheatSearchSignedGE cheatSearchSignedGE
}; };
void cheatSearchCleanup(CheatSearchData *cs) void cheatSearchCleanup(CheatSearchData *cs)
{ {
int count = cs->count; int count = cs->count;
for(int i = 0; i < count; i++) for(int i = 0; i < count; i++) {
{ free(cs->blocks[i].saved);
free(cs->blocks[i].saved); free(cs->blocks[i].bits);
free(cs->blocks[i].bits); }
} cs->count = 0;
cs->count = 0; }
}
void cheatSearchStart(const CheatSearchData *cs)
void cheatSearchStart(const CheatSearchData *cs) {
{ int count = cs->count;
int count = cs->count;
for(int i = 0; i < count; i++) {
for(int i = 0; i < count; i++) CheatSearchBlock *block = &cs->blocks[i];
{
CheatSearchBlock *block = &cs->blocks[i]; memset(block->bits, 0xff, block->size >> 3);
memcpy(block->saved, block->data, block->size);
memset(block->bits, 0xff, block->size >> 3); }
memcpy(block->saved, block->data, block->size); }
}
} s32 cheatSearchSignedRead(u8 *data, int off, int size)
{
s32 cheatSearchSignedRead(u8 *data, int off, int size) u32 res = data[off++];
{
u32 res = data[off++]; switch(size) {
case BITS_8:
switch(size) res <<= 24;
{ return ((s32)res) >> 24;
case BITS_8: case BITS_16:
res <<= 24; res |= ((u32)data[off++])<<8;
return ((s32)res) >> 24; res <<= 16;
case BITS_16: return ((s32)res) >> 16;
res |= ((u32)data[off++])<<8; case BITS_32:
res <<= 16; res |= ((u32)data[off++])<<8;
return ((s32)res) >> 16; res |= ((u32)data[off++])<<16;
case BITS_32: res |= ((u32)data[off++])<<24;
res |= ((u32)data[off++])<<8; return (s32)res;
res |= ((u32)data[off++])<<16; }
res |= ((u32)data[off++])<<24; return (s32)res;
return (s32)res; }
}
return (s32)res; u32 cheatSearchRead(u8 *data, int off, int size)
} {
u32 res = data[off++];
u32 cheatSearchRead(u8 *data, int off, int size) if(size == BITS_16)
{ res |= ((u32)data[off++])<<8;
u32 res = data[off++]; else if(size == BITS_32) {
if(size == BITS_16) res |= ((u32)data[off++])<<8;
res |= ((u32)data[off++])<<8; res |= ((u32)data[off++])<<16;
else if(size == BITS_32) res |= ((u32)data[off++])<<24;
{ }
res |= ((u32)data[off++])<<8; return res;
res |= ((u32)data[off++])<<16; }
res |= ((u32)data[off++])<<24;
} void cheatSearch(const CheatSearchData *cs, int compare, int size,
return res; bool isSigned)
} {
if(compare < 0 || compare > SEARCH_GE)
void cheatSearch(const CheatSearchData *cs, int compare, int size, return;
bool isSigned) int inc = 1;
{ if(size == BITS_16)
if(compare < 0 || compare > SEARCH_GE) inc = 2;
return; else if(size == BITS_32)
int inc = 1; inc = 4;
if(size == BITS_16)
inc = 2; if(isSigned) {
else if(size == BITS_32) bool (*func)(s32,s32) = cheatSearchSignedFunc[compare];
inc = 4;
for(int i = 0; i < cs->count; i++) {
if(isSigned) CheatSearchBlock *block = &cs->blocks[i];
{ int size2 = block->size;
bool (*func)(s32,s32) = cheatSearchSignedFunc[compare]; u8 *bits = block->bits;
u8 *data = block->data;
for(int i = 0; i < cs->count; i++) u8 *saved = block->saved;
{
CheatSearchBlock *block = &cs->blocks[i]; for(int j = 0; j < size2; j += inc) {
int size2 = block->size; if(IS_BIT_SET(bits, j)) {
u8 *bits = block->bits; s32 a = cheatSearchSignedRead(data, j, size);
u8 *data = block->data; s32 b = cheatSearchSignedRead(saved,j, size);
u8 *saved = block->saved;
if(!func(a, b)) {
for(int j = 0; j < size2; j += inc) CLEAR_BIT(bits, j);
{ if(size == BITS_16)
if(IS_BIT_SET(bits, j)) CLEAR_BIT(bits, j+1);
{ if(size == BITS_32) {
s32 a = cheatSearchSignedRead(data, j, size); CLEAR_BIT(bits, j+2);
s32 b = cheatSearchSignedRead(saved,j, size); CLEAR_BIT(bits, j+3);
}
if(!func(a, b)) }
{ }
CLEAR_BIT(bits, j); }
if(size == BITS_16) }
CLEAR_BIT(bits, j+1); } else {
if(size == BITS_32) bool (*func)(u32,u32) = cheatSearchFunc[compare];
{
CLEAR_BIT(bits, j+2); for(int i = 0; i < cs->count; i++) {
CLEAR_BIT(bits, j+3); CheatSearchBlock *block = &cs->blocks[i];
} int size2 = block->size;
} u8 *bits = block->bits;
} u8 *data = block->data;
} u8 *saved = block->saved;
}
} for(int j = 0; j < size2; j += inc) {
else if(IS_BIT_SET(bits, j)) {
{ u32 a = cheatSearchRead(data, j, size);
bool (*func)(u32,u32) = cheatSearchFunc[compare]; u32 b = cheatSearchRead(saved,j, size);
for(int i = 0; i < cs->count; i++) if(!func(a, b)) {
{ CLEAR_BIT(bits, j);
CheatSearchBlock *block = &cs->blocks[i]; if(size == BITS_16)
int size2 = block->size; CLEAR_BIT(bits, j+1);
u8 *bits = block->bits; if(size == BITS_32) {
u8 *data = block->data; CLEAR_BIT(bits, j+2);
u8 *saved = block->saved; CLEAR_BIT(bits, j+3);
}
for(int j = 0; j < size2; j += inc) }
{ }
if(IS_BIT_SET(bits, j)) }
{ }
u32 a = cheatSearchRead(data, j, size); }
u32 b = cheatSearchRead(saved,j, size); }
if(!func(a, b)) void cheatSearchValue(const CheatSearchData *cs, int compare, int size,
{ bool isSigned, u32 value)
CLEAR_BIT(bits, j); {
if(size == BITS_16) if(compare < 0 || compare > SEARCH_GE)
CLEAR_BIT(bits, j+1); return;
if(size == BITS_32) int inc = 1;
{ if(size == BITS_16)
CLEAR_BIT(bits, j+2); inc = 2;
CLEAR_BIT(bits, j+3); else if(size == BITS_32)
} inc = 4;
}
} if(isSigned) {
} bool (*func)(s32,s32) = cheatSearchSignedFunc[compare];
}
} for(int i = 0; i < cs->count; i++) {
} CheatSearchBlock *block = &cs->blocks[i];
int size2 = block->size;
void cheatSearchValue(const CheatSearchData *cs, int compare, int size, u8 *bits = block->bits;
bool isSigned, u32 value) u8 *data = block->data;
{
if(compare < 0 || compare > SEARCH_GE) for(int j = 0; j < size2; j += inc) {
return; if(IS_BIT_SET(bits, j)) {
int inc = 1; s32 a = cheatSearchSignedRead(data, j, size);
if(size == BITS_16) s32 b = (s32)value;
inc = 2;
else if(size == BITS_32) if(!func(a, b)) {
inc = 4; CLEAR_BIT(bits, j);
if(size == BITS_16)
if(isSigned) CLEAR_BIT(bits, j+1);
{ if(size == BITS_32) {
bool (*func)(s32,s32) = cheatSearchSignedFunc[compare]; CLEAR_BIT(bits, j+2);
CLEAR_BIT(bits, j+3);
for(int i = 0; i < cs->count; i++) }
{ }
CheatSearchBlock *block = &cs->blocks[i]; }
int size2 = block->size; }
u8 *bits = block->bits; }
u8 *data = block->data; } else {
bool (*func)(u32,u32) = cheatSearchFunc[compare];
for(int j = 0; j < size2; j += inc)
{ for(int i = 0; i < cs->count; i++) {
if(IS_BIT_SET(bits, j)) CheatSearchBlock *block = &cs->blocks[i];
{ int size2 = block->size;
s32 a = cheatSearchSignedRead(data, j, size); u8 *bits = block->bits;
s32 b = (s32)value; u8 *data = block->data;
if(!func(a, b)) for(int j = 0; j < size2; j += inc) {
{ if(IS_BIT_SET(bits, j)) {
CLEAR_BIT(bits, j); u32 a = cheatSearchRead(data, j, size);
if(size == BITS_16)
CLEAR_BIT(bits, j+1); if(!func(a, value)) {
if(size == BITS_32) CLEAR_BIT(bits, j);
{ if(size == BITS_16)
CLEAR_BIT(bits, j+2); CLEAR_BIT(bits, j+1);
CLEAR_BIT(bits, j+3); if(size == BITS_32) {
} CLEAR_BIT(bits, j+2);
} CLEAR_BIT(bits, j+3);
} }
} }
} }
} }
else }
{ }
bool (*func)(u32,u32) = cheatSearchFunc[compare]; }
for(int i = 0; i < cs->count; i++) int cheatSearchGetCount(const CheatSearchData *cs, int size)
{ {
CheatSearchBlock *block = &cs->blocks[i]; int res = 0;
int size2 = block->size; int inc = 1;
u8 *bits = block->bits; if(size == BITS_16)
u8 *data = block->data; inc = 2;
else if(size == BITS_32)
for(int j = 0; j < size2; j += inc) inc = 4;
{
if(IS_BIT_SET(bits, j)) for(int i = 0; i < cs->count; i++) {
{ CheatSearchBlock *block = &cs->blocks[i];
u32 a = cheatSearchRead(data, j, size);
int size2 = block->size;
if(!func(a, value)) u8 *bits = block->bits;
{ for(int j = 0; j < size2; j += inc) {
CLEAR_BIT(bits, j); if(IS_BIT_SET(bits, j))
if(size == BITS_16) res++;
CLEAR_BIT(bits, j+1); }
if(size == BITS_32) }
{ return res;
CLEAR_BIT(bits, j+2); }
CLEAR_BIT(bits, j+3);
} void cheatSearchUpdateValues(const CheatSearchData *cs)
} {
} for(int i = 0; i < cs->count; i++) {
} CheatSearchBlock *block = &cs->blocks[i];
}
} memcpy(block->saved, block->data, block->size);
} }
}
int cheatSearchGetCount(const CheatSearchData *cs, int size)
{
int res = 0;
int inc = 1;
if(size == BITS_16)
inc = 2;
else if(size == BITS_32)
inc = 4;
for(int i = 0; i < cs->count; i++)
{
CheatSearchBlock *block = &cs->blocks[i];
int size2 = block->size;
u8 *bits = block->bits;
for(int j = 0; j < size2; j += inc)
{
if(IS_BIT_SET(bits, j))
res++;
}
}
return res;
}
void cheatSearchUpdateValues(const CheatSearchData *cs)
{
for(int i = 0; i < cs->count; i++)
{
CheatSearchBlock *block = &cs->blocks[i];
memcpy(block->saved, block->data, block->size);
}
}

View File

@ -1,75 +1,73 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef VBA_CHEATSEARCH_H #ifndef VBA_CHEATSEARCH_H
#define VBA_CHEATSEARCH_H #define VBA_CHEATSEARCH_H
#include "System.h" #include "System.h"
struct CheatSearchBlock struct CheatSearchBlock {
{ int size;
int size; u32 offset;
u32 offset; u8 *bits;
u8 *bits; u8 *data;
u8 *data; u8 *saved;
u8 *saved; };
};
struct CheatSearchData {
struct CheatSearchData int count;
{ CheatSearchBlock *blocks;
int count; };
CheatSearchBlock *blocks;
}; enum {
SEARCH_EQ,
enum { SEARCH_NE,
SEARCH_EQ, SEARCH_LT,
SEARCH_NE, SEARCH_LE,
SEARCH_LT, SEARCH_GT,
SEARCH_LE, SEARCH_GE
SEARCH_GT, };
SEARCH_GE
}; enum {
BITS_8,
enum { BITS_16,
BITS_8, BITS_32
BITS_16, };
BITS_32
}; #define SET_BIT(bits,off) \
(bits)[(off) >> 3] |= (1 << ((off) & 7))
#define SET_BIT(bits,off) \
(bits)[(off) >> 3] |= (1 << ((off) & 7)) #define CLEAR_BIT(bits, off) \
(bits)[(off) >> 3] &= ~(1 << ((off) & 7))
#define CLEAR_BIT(bits, off) \
(bits)[(off) >> 3] &= ~(1 << ((off) & 7)) #define IS_BIT_SET(bits, off) \
(bits)[(off) >> 3] & (1 << ((off) & 7))
#define IS_BIT_SET(bits, off) \
(bits)[(off) >> 3] & (1 << ((off) & 7)) extern CheatSearchData cheatSearchData;
extern void cheatSearchCleanup(CheatSearchData *cs);
extern CheatSearchData cheatSearchData; extern void cheatSearchStart(const CheatSearchData *cs);
extern void cheatSearchCleanup(CheatSearchData *cs); extern void cheatSearch(const CheatSearchData *cs, int compare, int size,
extern void cheatSearchStart(const CheatSearchData *cs); bool isSigned);
extern void cheatSearch(const CheatSearchData *cs, int compare, int size, extern void cheatSearchValue(const CheatSearchData *cs, int compare, int size,
bool isSigned); bool isSigned, u32 value);
extern void cheatSearchValue(const CheatSearchData *cs, int compare, int size, extern int cheatSearchGetCount(const CheatSearchData *cs, int size);
bool isSigned, u32 value); extern void cheatSearchUpdateValues(const CheatSearchData *cs);
extern int cheatSearchGetCount(const CheatSearchData *cs, int size); extern s32 cheatSearchSignedRead(u8 *data, int off, int size);
extern void cheatSearchUpdateValues(const CheatSearchData *cs); extern u32 cheatSearchRead(u8 *data, int off, int size);
extern s32 cheatSearchSignedRead(u8 *data, int off, int size); #endif
extern u32 cheatSearchRead(u8 *data, int off, int size);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,55 +1,55 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004-2006 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef GBA_CHEATS_H #ifndef GBA_CHEATS_H
#define GBA_CHEATS_H #define GBA_CHEATS_H
struct CheatsData struct CheatsData {
{ int code;
int code; int size;
int size; int status;
int status; bool enabled;
bool enabled; u32 rawaddress;
u32 address; u32 address;
u32 value; u32 value;
u32 oldValue; u32 oldValue;
char codestring[20]; char codestring[20];
char desc[32]; char desc[32];
}; };
extern void cheatsAdd(const char *,const char *,u32,u32,int,int); extern void cheatsAdd(const char *,const char *,u32, u32,u32,int,int);
extern void cheatsAddCheatCode(const char *code, const char *desc); extern void cheatsAddCheatCode(const char *code, const char *desc);
extern void cheatsAddGSACode(const char *code, const char *desc, bool v3); extern void cheatsAddGSACode(const char *code, const char *desc, bool v3);
extern void cheatsAddCBACode(const char *code, const char *desc); extern void cheatsAddCBACode(const char *code, const char *desc);
extern bool cheatsImportGSACodeFile(const char *name, int game, bool v3); extern bool cheatsImportGSACodeFile(const char *name, int game, bool v3);
extern void cheatsDelete(int number, bool restore); extern void cheatsDelete(int number, bool restore);
extern void cheatsDeleteAll(bool restore); extern void cheatsDeleteAll(bool restore);
extern void cheatsEnable(int number); extern void cheatsEnable(int number);
extern void cheatsDisable(int number); extern void cheatsDisable(int number);
extern void cheatsSaveGame(gzFile file); extern void cheatsSaveGame(gzFile file);
extern void cheatsReadGame(gzFile file); extern void cheatsReadGame(gzFile file, int version);
extern void cheatsSaveCheatList(const char *file); extern void cheatsSaveCheatList(const char *file);
extern bool cheatsLoadCheatList(const char *file); extern bool cheatsLoadCheatList(const char *file);
extern void cheatsWriteMemory(u32 *, u32, u32); extern void cheatsWriteMemory(u32, u32);
extern void cheatsWriteHalfWord(u16 *, u16, u16); extern void cheatsWriteHalfWord(u32, u16);
extern void cheatsWriteByte(u8 *, u8); extern void cheatsWriteByte(u32, u8);
extern int cheatsCheckKeys(u32,u32); extern int cheatsCheckKeys(u32,u32);
extern int cheatsNumber; extern int cheatsNumber;
extern CheatsData cheatsList[100]; extern CheatsData cheatsList[100];
#endif // GBA_CHEATS_H #endif // GBA_CHEATS_H

View File

@ -1,214 +1,206 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "GBA.h" #include <string.h>
#include "EEprom.h" #include "agb/GBA.h"
#include "Util.h" #include "EEprom.h"
#include "Util.h"
extern int cpuDmaCount;
extern int cpuDmaCount;
int eepromMode = EEPROM_IDLE;
int eepromByte = 0; int eepromMode = EEPROM_IDLE;
int eepromBits = 0; int eepromByte = 0;
int eepromAddress = 0; int eepromBits = 0;
u8 eepromData[0x2000]; int eepromAddress = 0;
u8 eepromBuffer[16]; u8 eepromData[0x2000];
bool eepromInUse = false; u8 eepromBuffer[16];
int eepromSize = 512; bool eepromInUse = false;
int eepromSize = 512;
variable_desc eepromSaveData[] = {
{ &eepromMode, sizeof(int) }, variable_desc eepromSaveData[] = {
{ &eepromByte, sizeof(int) }, { &eepromMode, sizeof(int) },
{ &eepromBits , sizeof(int) }, { &eepromByte, sizeof(int) },
{ &eepromAddress , sizeof(int) }, { &eepromBits , sizeof(int) },
{ &eepromInUse, sizeof(bool) }, { &eepromAddress , sizeof(int) },
{ &eepromData[0], 512 }, { &eepromInUse, sizeof(bool) },
{ &eepromBuffer[0], 16 }, { &eepromData[0], 512 },
{ NULL, 0 } { &eepromBuffer[0], 16 },
}; { NULL, 0 }
};
void eepromReset()
{ void eepromInit()
eepromMode = EEPROM_IDLE; {
eepromByte = 0; memset(eepromData, 255, sizeof(eepromData));
eepromBits = 0; }
eepromAddress = 0;
eepromInUse = false; void eepromReset()
eepromSize = 512; {
} eepromMode = EEPROM_IDLE;
eepromByte = 0;
void eepromSaveGame(gzFile gzFile) eepromBits = 0;
{ eepromAddress = 0;
utilWriteData(gzFile, eepromSaveData); eepromInUse = false;
utilWriteInt(gzFile, eepromSize); eepromSize = 512;
utilGzWrite(gzFile, eepromData, 0x2000); }
}
void eepromSaveGame(gzFile gzFile)
void eepromReadGame(gzFile gzFile, int version) {
{ utilWriteData(gzFile, eepromSaveData);
utilReadData(gzFile, eepromSaveData); utilWriteInt(gzFile, eepromSize);
if(version >= SAVE_GAME_VERSION_3) utilGzWrite(gzFile, eepromData, 0x2000);
{ }
eepromSize = utilReadInt(gzFile);
utilGzRead(gzFile, eepromData, 0x2000); void eepromReadGame(gzFile gzFile, int version)
} {
else utilReadData(gzFile, eepromSaveData);
{ if(version >= SAVE_GAME_VERSION_3) {
// prior to 0.7.1, only 4K EEPROM was supported eepromSize = utilReadInt(gzFile);
eepromSize = 512; utilGzRead(gzFile, eepromData, 0x2000);
} } else {
} // prior to 0.7.1, only 4K EEPROM was supported
eepromSize = 512;
}
int eepromRead(u32 /* address */) }
{
switch(eepromMode) void eepromReadGameSkip(gzFile gzFile, int version)
{ {
case EEPROM_IDLE: // skip the eeprom data in a save game
case EEPROM_READADDRESS: utilReadDataSkip(gzFile, eepromSaveData);
case EEPROM_WRITEDATA: if(version >= SAVE_GAME_VERSION_3) {
return 1; utilGzSeek(gzFile, sizeof(int), SEEK_CUR);
case EEPROM_READDATA: utilGzSeek(gzFile, 0x2000, SEEK_CUR);
{ }
eepromBits++; }
if(eepromBits == 4)
{ int eepromRead(u32 /* address */)
eepromMode = EEPROM_READDATA2; {
eepromBits = 0; switch(eepromMode) {
eepromByte = 0; case EEPROM_IDLE:
} case EEPROM_READADDRESS:
return 0; case EEPROM_WRITEDATA:
} return 1;
case EEPROM_READDATA2: case EEPROM_READDATA:
{ {
int data = 0; eepromBits++;
int address = eepromAddress << 3; if(eepromBits == 4) {
int mask = 1 << (7 - (eepromBits & 7)); eepromMode = EEPROM_READDATA2;
data = (eepromData[address+eepromByte] & mask) ? 1 : 0; eepromBits = 0;
eepromBits++; eepromByte = 0;
if((eepromBits & 7) == 0) }
eepromByte++; return 0;
if(eepromBits == 0x40) }
eepromMode = EEPROM_IDLE; case EEPROM_READDATA2:
return data; {
} int data = 0;
default: int address = eepromAddress << 3;
return 0; int mask = 1 << (7 - (eepromBits & 7));
} data = (eepromData[address+eepromByte] & mask) ? 1 : 0;
return 1; eepromBits++;
} if((eepromBits & 7) == 0)
eepromByte++;
void eepromWrite(u32 /* address */, u8 value) if(eepromBits == 0x40)
{ eepromMode = EEPROM_IDLE;
if(cpuDmaCount == 0) return data;
return; }
int bit = value & 1; default:
switch(eepromMode) return 0;
{ }
case EEPROM_IDLE: return 1;
eepromByte = 0; }
eepromBits = 1;
eepromBuffer[eepromByte] = bit; void eepromWrite(u32 /* address */, u8 value)
eepromMode = EEPROM_READADDRESS; {
break; if(cpuDmaCount == 0)
case EEPROM_READADDRESS: return;
eepromBuffer[eepromByte] <<= 1; int bit = value & 1;
eepromBuffer[eepromByte] |= bit; switch(eepromMode) {
eepromBits++; case EEPROM_IDLE:
if((eepromBits & 7) == 0) eepromByte = 0;
{ eepromBits = 1;
eepromByte++; eepromBuffer[eepromByte] = bit;
} eepromMode = EEPROM_READADDRESS;
if(cpuDmaCount == 0x11 || cpuDmaCount == 0x51) break;
{ case EEPROM_READADDRESS:
if(eepromBits == 0x11) eepromBuffer[eepromByte] <<= 1;
{ eepromBuffer[eepromByte] |= bit;
eepromInUse = true; eepromBits++;
eepromSize = 0x2000; if((eepromBits & 7) == 0) {
eepromAddress = ((eepromBuffer[0] & 0x3F) << 8) | eepromByte++;
((eepromBuffer[1] & 0xFF)); }
if(!(eepromBuffer[0] & 0x40)) if(cpuDmaCount == 0x11 || cpuDmaCount == 0x51) {
{ if(eepromBits == 0x11) {
eepromBuffer[0] = bit; eepromInUse = true;
eepromBits = 1; eepromSize = 0x2000;
eepromByte = 0; eepromAddress = ((eepromBuffer[0] & 0x3F) << 8) |
eepromMode = EEPROM_WRITEDATA; ((eepromBuffer[1] & 0xFF));
} if(!(eepromBuffer[0] & 0x40)) {
else eepromBuffer[0] = bit;
{ eepromBits = 1;
eepromMode = EEPROM_READDATA; eepromByte = 0;
eepromByte = 0; eepromMode = EEPROM_WRITEDATA;
eepromBits = 0; } else {
} eepromMode = EEPROM_READDATA;
} eepromByte = 0;
} eepromBits = 0;
else }
{ }
if(eepromBits == 9) } else {
{ if(eepromBits == 9) {
eepromInUse = true; eepromInUse = true;
eepromAddress = (eepromBuffer[0] & 0x3F); eepromAddress = (eepromBuffer[0] & 0x3F);
if(!(eepromBuffer[0] & 0x40)) if(!(eepromBuffer[0] & 0x40)) {
{ eepromBuffer[0] = bit;
eepromBuffer[0] = bit; eepromBits = 1;
eepromBits = 1; eepromByte = 0;
eepromByte = 0; eepromMode = EEPROM_WRITEDATA;
eepromMode = EEPROM_WRITEDATA; } else {
} eepromMode = EEPROM_READDATA;
else eepromByte = 0;
{ eepromBits = 0;
eepromMode = EEPROM_READDATA; }
eepromByte = 0; }
eepromBits = 0; }
} break;
} case EEPROM_READDATA:
} case EEPROM_READDATA2:
break; // should we reset here?
case EEPROM_READDATA: eepromMode = EEPROM_IDLE;
case EEPROM_READDATA2: break;
// should we reset here? case EEPROM_WRITEDATA:
eepromMode = EEPROM_IDLE; eepromBuffer[eepromByte] <<= 1;
break; eepromBuffer[eepromByte] |= bit;
case EEPROM_WRITEDATA: eepromBits++;
eepromBuffer[eepromByte] <<= 1; if((eepromBits & 7) == 0) {
eepromBuffer[eepromByte] |= bit; eepromByte++;
eepromBits++; }
if((eepromBits & 7) == 0) if(eepromBits == 0x40) {
{ eepromInUse = true;
eepromByte++; // write data;
} for(int i = 0; i < 8; i++) {
if(eepromBits == 0x40) eepromData[(eepromAddress << 3) + i] = eepromBuffer[i];
{ }
eepromInUse = true; systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
// write data; } else if(eepromBits == 0x41) {
for(int i = 0; i < 8; i++) eepromMode = EEPROM_IDLE;
{ eepromByte = 0;
eepromData[(eepromAddress << 3) + i] = eepromBuffer[i]; eepromBits = 0;
} }
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED; break;
} }
else if(eepromBits == 0x41) }
{
eepromMode = EEPROM_IDLE;
eepromByte = 0;
eepromBits = 0;
}
break;
}
}

View File

@ -1,38 +1,40 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef VBA_EEPROM_H #ifndef VBA_EEPROM_H
#define VBA_EEPROM_H #define VBA_EEPROM_H
extern void eepromSaveGame(gzFile gzFile); extern void eepromSaveGame(gzFile _gzFile);
extern void eepromReadGame(gzFile gzFile, int version); extern void eepromReadGame(gzFile _gzFile, int version);
extern int eepromRead(u32 address); extern void eepromReadGameSkip(gzFile _gzFile, int version);
extern void eepromWrite(u32 address, u8 value); extern int eepromRead(u32 address);
extern void eepromReset(); extern void eepromWrite(u32 address, u8 value);
extern u8 eepromData[0x2000]; extern void eepromInit();
extern bool eepromInUse; extern void eepromReset();
extern int eepromSize; extern u8 eepromData[0x2000];
extern bool eepromInUse;
#define EEPROM_IDLE 0 extern int eepromSize;
#define EEPROM_READADDRESS 1
#define EEPROM_READDATA 2 #define EEPROM_IDLE 0
#define EEPROM_READDATA2 3 #define EEPROM_READADDRESS 1
#define EEPROM_WRITEDATA 4 #define EEPROM_READDATA 2
#define EEPROM_READDATA2 3
#endif // VBA_EEPROM_H #define EEPROM_WRITEDATA 4
#endif // VBA_EEPROM_H

View File

@ -1,288 +1,275 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004-2006 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "GBA.h" #include "agb/GBA.h"
#include "Globals.h" #include "Globals.h"
#include "Flash.h" #include "Flash.h"
#include "Sram.h" #include "Sram.h"
#include "Util.h" #include "Util.h"
#define FLASH_READ_ARRAY 0 #define FLASH_READ_ARRAY 0
#define FLASH_CMD_1 1 #define FLASH_CMD_1 1
#define FLASH_CMD_2 2 #define FLASH_CMD_2 2
#define FLASH_AUTOSELECT 3 #define FLASH_AUTOSELECT 3
#define FLASH_CMD_3 4 #define FLASH_CMD_3 4
#define FLASH_CMD_4 5 #define FLASH_CMD_4 5
#define FLASH_CMD_5 6 #define FLASH_CMD_5 6
#define FLASH_ERASE_COMPLETE 7 #define FLASH_ERASE_COMPLETE 7
#define FLASH_PROGRAM 8 #define FLASH_PROGRAM 8
#define FLASH_SETBANK 9 #define FLASH_SETBANK 9
u8 flashSaveMemory[0x20000]; u8 flashSaveMemory[0x20000];
int flashState = FLASH_READ_ARRAY; int flashState = FLASH_READ_ARRAY;
int flashReadState = FLASH_READ_ARRAY; int flashReadState = FLASH_READ_ARRAY;
int flashSize = 0x10000; int flashSize = 0x10000;
int flashDeviceID = 0x1b; int flashDeviceID = 0x1b;
int flashManufacturerID = 0x32; int flashManufacturerID = 0x32;
int flashBank = 0; int flashBank = 0;
static variable_desc flashSaveData[] = { static variable_desc flashSaveData[] = {
{ &flashState, sizeof(int) }, { &flashState, sizeof(int) },
{ &flashReadState, sizeof(int) }, { &flashReadState, sizeof(int) },
{ &flashSaveMemory[0], 0x10000 }, { &flashSaveMemory[0], 0x10000 },
{ NULL, 0 } { NULL, 0 }
}; };
static variable_desc flashSaveData2[] = { static variable_desc flashSaveData2[] = {
{ &flashState, sizeof(int) }, { &flashState, sizeof(int) },
{ &flashReadState, sizeof(int) }, { &flashReadState, sizeof(int) },
{ &flashSize, sizeof(int) }, { &flashSize, sizeof(int) },
{ &flashSaveMemory[0], 0x20000 }, { &flashSaveMemory[0], 0x20000 },
{ NULL, 0 } { NULL, 0 }
}; };
static variable_desc flashSaveData3[] = { static variable_desc flashSaveData3[] = {
{ &flashState, sizeof(int) }, { &flashState, sizeof(int) },
{ &flashReadState, sizeof(int) }, { &flashReadState, sizeof(int) },
{ &flashSize, sizeof(int) }, { &flashSize, sizeof(int) },
{ &flashBank, sizeof(int) }, { &flashBank, sizeof(int) },
{ &flashSaveMemory[0], 0x20000 }, { &flashSaveMemory[0], 0x20000 },
{ NULL, 0 } { NULL, 0 }
}; };
void flashReset() void flashInit()
{ {
flashState = FLASH_READ_ARRAY; memset(flashSaveMemory, 0xff, sizeof(flashSaveMemory));
flashReadState = FLASH_READ_ARRAY; }
flashBank = 0;
} void flashReset()
{
void flashSaveGame(gzFile gzFile) flashState = FLASH_READ_ARRAY;
{ flashReadState = FLASH_READ_ARRAY;
utilWriteData(gzFile, flashSaveData3); flashBank = 0;
} }
void flashReadGame(gzFile gzFile, int version) void flashSaveGame(gzFile gzFile)
{ {
if(version < SAVE_GAME_VERSION_5) utilWriteData(gzFile, flashSaveData3);
utilReadData(gzFile, flashSaveData); }
else if(version < SAVE_GAME_VERSION_7)
{ void flashReadGame(gzFile gzFile, int version)
utilReadData(gzFile, flashSaveData2); {
flashBank = 0; if(version < SAVE_GAME_VERSION_5)
flashSetSize(flashSize); utilReadData(gzFile, flashSaveData);
} else if(version < SAVE_GAME_VERSION_7) {
else utilReadData(gzFile, flashSaveData2);
{ flashBank = 0;
utilReadData(gzFile, flashSaveData3); flashSetSize(flashSize);
} } else {
} utilReadData(gzFile, flashSaveData3);
}
void flashSetSize(int size) }
{
// log("Setting flash size to %d\n", size); void flashReadGameSkip(gzFile gzFile, int version)
flashSize = size; {
if(size == 0x10000) // skip the flash data in a save game
{ if(version < SAVE_GAME_VERSION_5)
flashDeviceID = 0x1b; utilReadDataSkip(gzFile, flashSaveData);
flashManufacturerID = 0x32; else if(version < SAVE_GAME_VERSION_7) {
} utilReadDataSkip(gzFile, flashSaveData2);
else } else {
{ utilReadDataSkip(gzFile, flashSaveData3);
flashDeviceID = 0x13; //0x09; }
flashManufacturerID = 0x62; //0xc2; }
}
} void flashSetSize(int size)
{
u8 flashRead(u32 address) // log("Setting flash size to %d\n", size);
{ if(size == 0x10000) {
// log("Reading %08x from %08x\n", address, reg[15].I); flashDeviceID = 0x1b;
// log("Current read state is %d\n", flashReadState); flashManufacturerID = 0x32;
address &= 0xFFFF; } else {
flashDeviceID = 0x13; //0x09;
switch(flashReadState) flashManufacturerID = 0x62; //0xc2;
{ }
case FLASH_READ_ARRAY: // Added to make 64k saves compatible with 128k ones
return flashSaveMemory[(flashBank << 16) + address]; // (allow wrongfuly set 64k saves to work for Pokemon games)
case FLASH_AUTOSELECT: if ((size == 0x20000) && (flashSize == 0x10000))
switch(address & 0xFF) memcpy((u8 *)(flashSaveMemory+0x10000), (u8 *)(flashSaveMemory), 0x10000);
{ flashSize = size;
case 0: }
// manufacturer ID
return flashManufacturerID; u8 flashRead(u32 address)
case 1: {
// device ID // log("Reading %08x from %08x\n", address, reg[15].I);
return flashDeviceID; // log("Current read state is %d\n", flashReadState);
} address &= 0xFFFF;
break;
case FLASH_ERASE_COMPLETE: switch(flashReadState) {
flashState = FLASH_READ_ARRAY; case FLASH_READ_ARRAY:
flashReadState = FLASH_READ_ARRAY; return flashSaveMemory[(flashBank << 16) + address];
return 0xFF; case FLASH_AUTOSELECT:
}; switch(address & 0xFF) {
return 0; case 0:
} // manufacturer ID
return flashManufacturerID;
void flashSaveDecide(u32 address, u8 byte) case 1:
{ // device ID
// log("Deciding save type %08x\n", address); return flashDeviceID;
if(address == 0x0e005555) }
{ break;
saveType = 2; case FLASH_ERASE_COMPLETE:
cpuSaveGameFunc = flashWrite; flashState = FLASH_READ_ARRAY;
} flashReadState = FLASH_READ_ARRAY;
else return 0xFF;
{ };
saveType = 1; return 0;
cpuSaveGameFunc = sramWrite; }
}
void flashSaveDecide(u32 address, u8 byte)
(*cpuSaveGameFunc)(address, byte); {
} // log("Deciding save type %08x\n", address);
if(address == 0x0e005555) {
void flashWrite(u32 address, u8 byte) saveType = 2;
{ cpuSaveGameFunc = flashWrite;
// log("Writing %02x at %08x\n", byte, address); } else {
// log("Current state is %d\n", flashState); saveType = 1;
address &= 0xFFFF; cpuSaveGameFunc = sramWrite;
switch(flashState) }
{
case FLASH_READ_ARRAY: (*cpuSaveGameFunc)(address, byte);
if(address == 0x5555 && byte == 0xAA) }
flashState = FLASH_CMD_1;
break; void flashDelayedWrite(u32 address, u8 byte)
case FLASH_CMD_1: {
if(address == 0x2AAA && byte == 0x55) saveType = 2;
flashState = FLASH_CMD_2; cpuSaveGameFunc = flashWrite;
else flashWrite(address, byte);
flashState = FLASH_READ_ARRAY; }
break;
case FLASH_CMD_2: void flashWrite(u32 address, u8 byte)
if(address == 0x5555) {
{ // log("Writing %02x at %08x\n", byte, address);
if(byte == 0x90) // log("Current state is %d\n", flashState);
{ address &= 0xFFFF;
flashState = FLASH_AUTOSELECT; switch(flashState) {
flashReadState = FLASH_AUTOSELECT; case FLASH_READ_ARRAY:
} if(address == 0x5555 && byte == 0xAA)
else if(byte == 0x80) flashState = FLASH_CMD_1;
{ break;
flashState = FLASH_CMD_3; case FLASH_CMD_1:
} if(address == 0x2AAA && byte == 0x55)
else if(byte == 0xF0) flashState = FLASH_CMD_2;
{ else
flashState = FLASH_READ_ARRAY; flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY; break;
} case FLASH_CMD_2:
else if(byte == 0xA0) if(address == 0x5555) {
{ if(byte == 0x90) {
flashState = FLASH_PROGRAM; flashState = FLASH_AUTOSELECT;
} flashReadState = FLASH_AUTOSELECT;
else if(byte == 0xB0 && flashSize == 0x20000) } else if(byte == 0x80) {
{ flashState = FLASH_CMD_3;
flashState = FLASH_SETBANK; } else if(byte == 0xF0) {
} flashState = FLASH_READ_ARRAY;
else flashReadState = FLASH_READ_ARRAY;
{ } else if(byte == 0xA0) {
flashState = FLASH_READ_ARRAY; flashState = FLASH_PROGRAM;
flashReadState = FLASH_READ_ARRAY; } else if(byte == 0xB0 && flashSize == 0x20000) {
} flashState = FLASH_SETBANK;
} } else {
else flashState = FLASH_READ_ARRAY;
{ flashReadState = FLASH_READ_ARRAY;
flashState = FLASH_READ_ARRAY; }
flashReadState = FLASH_READ_ARRAY; } else {
} flashState = FLASH_READ_ARRAY;
break; flashReadState = FLASH_READ_ARRAY;
case FLASH_CMD_3: }
if(address == 0x5555 && byte == 0xAA) break;
{ case FLASH_CMD_3:
flashState = FLASH_CMD_4; if(address == 0x5555 && byte == 0xAA) {
} flashState = FLASH_CMD_4;
else } else {
{ flashState = FLASH_READ_ARRAY;
flashState = FLASH_READ_ARRAY; flashReadState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY; }
} break;
break; case FLASH_CMD_4:
case FLASH_CMD_4: if(address == 0x2AAA && byte == 0x55) {
if(address == 0x2AAA && byte == 0x55) flashState = FLASH_CMD_5;
{ } else {
flashState = FLASH_CMD_5; flashState = FLASH_READ_ARRAY;
} flashReadState = FLASH_READ_ARRAY;
else }
{ break;
flashState = FLASH_READ_ARRAY; case FLASH_CMD_5:
flashReadState = FLASH_READ_ARRAY; if(byte == 0x30) {
} // SECTOR ERASE
break; memset(&flashSaveMemory[(flashBank << 16) + (address & 0xF000)],
case FLASH_CMD_5: 0,
if(byte == 0x30) 0x1000);
{ systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
// SECTOR ERASE flashReadState = FLASH_ERASE_COMPLETE;
memset(&flashSaveMemory[(flashBank << 16) + (address & 0xF000)], } else if(byte == 0x10) {
0, // CHIP ERASE
0x1000); memset(flashSaveMemory, 0, flashSize);
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED; systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
flashReadState = FLASH_ERASE_COMPLETE; flashReadState = FLASH_ERASE_COMPLETE;
} } else {
else if(byte == 0x10) flashState = FLASH_READ_ARRAY;
{ flashReadState = FLASH_READ_ARRAY;
// CHIP ERASE }
memset(flashSaveMemory, 0, flashSize); break;
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED; case FLASH_AUTOSELECT:
flashReadState = FLASH_ERASE_COMPLETE; if(byte == 0xF0) {
} flashState = FLASH_READ_ARRAY;
else flashReadState = FLASH_READ_ARRAY;
{ } else if(address == 0x5555 && byte == 0xAA)
flashState = FLASH_READ_ARRAY; flashState = FLASH_CMD_1;
flashReadState = FLASH_READ_ARRAY; else {
} flashState = FLASH_READ_ARRAY;
break; flashReadState = FLASH_READ_ARRAY;
case FLASH_AUTOSELECT: }
if(byte == 0xF0) break;
{ case FLASH_PROGRAM:
flashState = FLASH_READ_ARRAY; flashSaveMemory[(flashBank<<16)+address] = byte;
flashReadState = FLASH_READ_ARRAY; systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
} flashState = FLASH_READ_ARRAY;
else if(address == 0x5555 && byte == 0xAA) flashReadState = FLASH_READ_ARRAY;
flashState = FLASH_CMD_1; break;
else case FLASH_SETBANK:
{ if(address == 0) {
flashState = FLASH_READ_ARRAY; flashBank = (byte & 1);
flashReadState = FLASH_READ_ARRAY; }
} flashState = FLASH_READ_ARRAY;
break; flashReadState = FLASH_READ_ARRAY;
case FLASH_PROGRAM: break;
flashSaveMemory[(flashBank<<16)+address] = byte; }
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED; }
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
break;
case FLASH_SETBANK:
if(address == 0)
{
flashBank = (byte & 1);
}
flashState = FLASH_READ_ARRAY;
flashReadState = FLASH_READ_ARRAY;
break;
}
}

View File

@ -1,33 +1,36 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef VBA_FLASH_H #ifndef VBA_FLASH_H
#define VBA_FLASH_H #define VBA_FLASH_H
extern void flashSaveGame(gzFile gzFile); extern void flashSaveGame(gzFile _gzFile);
extern void flashReadGame(gzFile gzFile, int version); extern void flashReadGame(gzFile _gzFile, int version);
extern u8 flashRead(u32 address); extern void flashReadGameSkip(gzFile _gzFile, int version);
extern void flashWrite(u32 address, u8 byte); extern u8 flashRead(u32 address);
extern u8 flashSaveMemory[0x20000]; extern void flashWrite(u32 address, u8 byte);
extern void flashSaveDecide(u32 address, u8 byte); extern void flashDelayedWrite(u32 address, u8 byte);
extern void flashReset(); extern u8 flashSaveMemory[0x20000];
extern void flashSetSize(int size); extern void flashSaveDecide(u32 address, u8 byte);
extern void flashReset();
extern int flashSize; extern void flashSetSize(int size);
#endif // VBA_FLASH_H extern void flashInit();
extern int flashSize;
#endif // VBA_FLASH_H

File diff suppressed because it is too large Load Diff

View File

@ -1,556 +0,0 @@
// -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef VBA_GBAinline_H
#define VBA_GBAinline_H
#include "System.h"
#include "Port.h"
#include "RTC.h"
#include "vmmem.h"
extern bool cpuSramEnabled;
extern bool cpuFlashEnabled;
extern bool cpuEEPROMEnabled;
extern bool cpuEEPROMSensorEnabled;
#define VM_USED 1
#define CPUReadByteQuickDef(addr) \
map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]
#define CPUReadHalfWordQuickDef(addr) \
READ16LE(((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
#define CPUReadMemoryQuickDef(addr) \
READ32LE(((u32*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
u8 inline CPUReadByteQuick( u32 addr )
{
switch(addr >> 24 )
{
case 8:
case 9:
case 10:
case 12:
return VMRead8( addr & 0x1FFFFFF );
default:
return CPUReadByteQuickDef(addr);
}
return 0;
}
u16 inline CPUReadHalfWordQuick( u32 addr )
{
switch(addr >> 24)
{
case 8:
case 9:
case 10:
case 12:
return VMRead16( addr & 0x1FFFFFF );
default:
return CPUReadHalfWordQuickDef(addr);
}
return 0;
}
u32 inline CPUReadMemoryQuick( u32 addr )
{
switch(addr >> 24)
{
case 8:
case 9:
case 10:
case 12:
return VMRead32( addr & 0x1FFFFFF );
default:
return CPUReadMemoryQuickDef(addr);
}
return 0;
}
inline u32 CPUReadMemory(u32 address)
{
#ifdef DEV_VERSION
if(address & 3)
{
if(systemVerbose & VERBOSE_UNALIGNED_MEMORY)
{
log("Unaligned word read: %08x at %08x\n", address, armMode ?
armNextPC - 4 : armNextPC - 2);
}
}
#endif
u32 value;
switch(address >> 24)
{
case 0:
if(reg[15].I >> 24)
{
if(address < 0x4000)
{
#ifdef DEV_VERSION
if(systemVerbose & VERBOSE_ILLEGAL_READ)
{
log("Illegal word read: %08x at %08x\n", address, armMode ?
armNextPC - 4 : armNextPC - 2);
}
#endif
value = READ32LE(((u32 *)&biosProtected));
}
else goto unreadable;
}
else
value = READ32LE(((u32 *)&bios[address & 0x3FFC]));
break;
case 2:
value = READ32LE(((u32 *)&workRAM[address & 0x3FFFC]));
break;
case 3:
value = READ32LE(((u32 *)&internalRAM[address & 0x7ffC]));
break;
case 4:
if((address < 0x4000400) && ioReadable[address & 0x3fc])
{
if(ioReadable[(address & 0x3fc) + 2])
value = READ32LE(((u32 *)&ioMem[address & 0x3fC]));
else
value = READ16LE(((u16 *)&ioMem[address & 0x3fc]));
}
else goto unreadable;
break;
case 5:
value = READ32LE(((u32 *)&paletteRAM[address & 0x3fC]));
break;
case 6:
value = READ32LE(((u32 *)&vram[address & 0x1fffc]));
break;
case 7:
value = READ32LE(((u32 *)&oam[address & 0x3FC]));
break;
case 8:
case 9:
case 10:
case 11:
case 12:
/** Need NGC VM here **/
//value = READ32LE(((u32 *)&rom[address&0x1FFFFFC]));
value = VMRead32( address & 0x1FFFFFC );
break;
case 13:
if(cpuEEPROMEnabled)
// no need to swap this
return eepromRead(address);
goto unreadable;
case 14:
if(cpuFlashEnabled | cpuSramEnabled)
// no need to swap this
return flashRead(address);
// default
default:
unreadable:
#ifdef DEV_VERSION
if(systemVerbose & VERBOSE_ILLEGAL_READ)
{
log("Illegal word read: %08x at %08x\n", address, armMode ?
armNextPC - 4 : armNextPC - 2);
}
#endif
// if(ioMem[0x205] & 0x40) {
if(armState)
{
#if VM_USED
value = CPUReadMemoryQuick(reg[15].I);
#else
value = CPUReadMemoryQuickDef(reg[15].I);
#endif
//value = VMRead32(reg[15].I);
}
else
{
#if VM_USED
value = CPUReadHalfWordQuick(reg[15].I) |
CPUReadHalfWordQuick(reg[15].I) << 16;
#else
value = CPUReadHalfWordQuickDef(reg[15].I) |
CPUReadHalfWordQuickDef(reg[15].I) << 16;
#endif
//value = VMRead16(reg[15].I) | VMRead16(reg[15].I) << 16;
}
// } else {
// value = *((u32 *)&bios[address & 0x3ffc]);
// }
// return 0xFFFFFFFF;
}
if(address & 3)
{
#ifdef C_CORE
int shift = (address & 3) << 3;
value = (value >> shift) | (value << (32 - shift));
#else
#ifdef __GNUC__
asm("and $3, %%ecx;"
"shl $3 ,%%ecx;"
"ror %%cl, %0"
: "=r" (value)
: "r" (value), "c" (address));
#else
__asm {
mov ecx, address;
and ecx, 3;
shl ecx, 3;
ror [dword ptr value], cl;
}
#endif
#endif
}
return value;
}
extern u32 myROM[];
inline u32 CPUReadHalfWord(u32 address)
{
#ifdef DEV_VERSION
if(address & 1)
{
if(systemVerbose & VERBOSE_UNALIGNED_MEMORY)
{
log("Unaligned halfword read: %08x at %08x\n", address, armMode ?
armNextPC - 4 : armNextPC - 2);
}
}
#endif
u32 value;
switch(address >> 24)
{
case 0:
if (reg[15].I >> 24)
{
if(address < 0x4000)
{
#ifdef DEV_VERSION
if(systemVerbose & VERBOSE_ILLEGAL_READ)
{
log("Illegal halfword read: %08x at %08x\n", address, armMode ?
armNextPC - 4 : armNextPC - 2);
}
#endif
value = READ16LE(((u16 *)&biosProtected[address&2]));
}
else goto unreadable;
}
else
value = READ16LE(((u16 *)&bios[address & 0x3FFE]));
break;
case 2:
value = READ16LE(((u16 *)&workRAM[address & 0x3FFFE]));
break;
case 3:
value = READ16LE(((u16 *)&internalRAM[address & 0x7ffe]));
break;
case 4:
if((address < 0x4000400) && ioReadable[address & 0x3fe])
value = READ16LE(((u16 *)&ioMem[address & 0x3fe]));
else goto unreadable;
break;
case 5:
value = READ16LE(((u16 *)&paletteRAM[address & 0x3fe]));
break;
case 6:
value = READ16LE(((u16 *)&vram[address & 0x1fffe]));
break;
case 7:
value = READ16LE(((u16 *)&oam[address & 0x3fe]));
break;
case 8:
case 9:
case 10:
case 11:
case 12:
if(address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8)
value = rtcRead(address);
else
/** Need NGC VM Here **/
//value = READ16LE(((u16 *)&rom[address & 0x1FFFFFE]));
value = VMRead16( address & 0x1FFFFFE );
break;
case 13:
if(cpuEEPROMEnabled)
// no need to swap this
return eepromRead(address);
goto unreadable;
case 14:
if(cpuFlashEnabled | cpuSramEnabled)
// no need to swap this
return flashRead(address);
// default
default:
unreadable:
#ifdef DEV_VERSION
if(systemVerbose & VERBOSE_ILLEGAL_READ)
{
log("Illegal halfword read: %08x at %08x\n", address, armMode ?
armNextPC - 4 : armNextPC - 2);
}
#endif
extern bool cpuDmaHack;
extern u32 cpuDmaLast;
extern int cpuDmaCount;
if(cpuDmaHack && cpuDmaCount)
{
value = (u16)cpuDmaLast;
}
else
{
if(armState)
{
#if VM_USED
value = CPUReadHalfWordQuick(reg[15].I + (address & 2));
#else
value = CPUReadHalfWordQuickDef(reg[15].I + (address & 2));
#endif
//value = VMRead16(reg[15].I + (address & 2));
}
else
{
#if VM_USED
value = CPUReadHalfWordQuick(reg[15].I);
#else
value = CPUReadHalfWordQuickDef(reg[15].I);
#endif
//value = VMRead16(reg[15].I);
}
}
// return value;
// if(address & 1)
// value = (value >> 8) | ((value & 0xFF) << 24);
// return 0xFFFF;
break;
}
if(address & 1)
{
value = (value >> 8) | (value << 24);
}
return value;
}
inline u16 CPUReadHalfWordSigned(u32 address)
{
u16 value = CPUReadHalfWord(address);
if((address & 1))
value = (s8)value;
return value;
}
inline u8 CPUReadByte(u32 address)
{
switch(address >> 24)
{
case 0:
if (reg[15].I >> 24)
{
if(address < 0x4000)
{
#ifdef DEV_VERSION
if(systemVerbose & VERBOSE_ILLEGAL_READ)
{
log("Illegal byte read: %08x at %08x\n", address, armMode ?
armNextPC - 4 : armNextPC - 2);
}
#endif
return biosProtected[address & 3];
}
else goto unreadable;
}
return bios[address & 0x3FFF];
case 2:
return workRAM[address & 0x3FFFF];
case 3:
return internalRAM[address & 0x7fff];
case 4:
if((address < 0x4000400) && ioReadable[address & 0x3ff])
return ioMem[address & 0x3ff];
else goto unreadable;
case 5:
return paletteRAM[address & 0x3ff];
case 6:
return vram[address & 0x1ffff];
case 7:
return oam[address & 0x3ff];
case 8:
case 9:
case 10:
case 11:
case 12:
/** Need NGC VM Here **/
//return rom[address & 0x1FFFFFF];
return VMRead8( address & 0x1FFFFFF );
case 13:
if(cpuEEPROMEnabled)
return eepromRead(address);
goto unreadable;
case 14:
if(cpuSramEnabled | cpuFlashEnabled)
return flashRead(address);
if(cpuEEPROMSensorEnabled)
{
switch(address & 0x00008f00)
{
case 0x8200:
return systemGetSensorX() & 255;
case 0x8300:
return (systemGetSensorX() >> 8)|0x80;
case 0x8400:
return systemGetSensorY() & 255;
case 0x8500:
return systemGetSensorY() >> 8;
}
}
// default
default:
unreadable:
#ifdef DEV_VERSION
if(systemVerbose & VERBOSE_ILLEGAL_READ)
{
log("Illegal byte read: %08x at %08x\n", address, armMode ?
armNextPC - 4 : armNextPC - 2);
}
#endif
if(armState)
{
#if VM_USED
return CPUReadByteQuick(reg[15].I+(address & 3));
#else
return CPUReadByteQuickDef(reg[15].I+(address & 3));
#endif
//return VMRead8(reg[15].I+(address & 3));
}
else
{
#if VM_USED
return CPUReadByteQuick(reg[15].I+(address & 1));
#else
return CPUReadByteQuickDef(reg[15].I+(address & 1));
#endif
//return VMRead8(reg[15].I+(address & 1));
}
// return 0xFF;
break;
}
}
inline void CPUWriteMemory(u32 address, u32 value)
{
#ifdef DEV_VERSION
if(address & 3)
{
if(systemVerbose & VERBOSE_UNALIGNED_MEMORY)
{
log("Unaliagned word write: %08x to %08x from %08x\n",
value,
address,
armMode ? armNextPC - 4 : armNextPC - 2);
}
}
#endif
switch(address >> 24)
{
case 0x02:
#ifdef SDL
if(*((u32 *)&freezeWorkRAM[address & 0x3FFFC]))
cheatsWriteMemory((u32 *)&workRAM[address & 0x3FFFC],
value,
*((u32 *)&freezeWorkRAM[address & 0x3FFFC]));
else
#endif
WRITE32LE(((u32 *)&workRAM[address & 0x3FFFC]), value);
break;
case 0x03:
#ifdef SDL
if(*((u32 *)&freezeInternalRAM[address & 0x7ffc]))
cheatsWriteMemory((u32 *)&internalRAM[address & 0x7FFC],
value,
*((u32 *)&freezeInternalRAM[address & 0x7ffc]));
else
#endif
WRITE32LE(((u32 *)&internalRAM[address & 0x7ffC]), value);
break;
case 0x04:
CPUUpdateRegister((address & 0x3FC), value & 0xFFFF);
CPUUpdateRegister((address & 0x3FC) + 2, (value >> 16));
break;
case 0x05:
WRITE32LE(((u32 *)&paletteRAM[address & 0x3FC]), value);
break;
case 0x06:
if(address & 0x10000)
WRITE32LE(((u32 *)&vram[address & 0x17ffc]), value);
else
WRITE32LE(((u32 *)&vram[address & 0x1fffc]), value);
break;
case 0x07:
WRITE32LE(((u32 *)&oam[address & 0x3fc]), value);
break;
case 0x0D:
if(cpuEEPROMEnabled)
{
eepromWrite(address, value);
break;
}
goto unwritable;
case 0x0E:
if(!eepromInUse | cpuSramEnabled | cpuFlashEnabled)
{
(*cpuSaveGameFunc)(address, (u8)value);
break;
}
// default
default:
unwritable:
#ifdef DEV_VERSION
if(systemVerbose & VERBOSE_ILLEGAL_WRITE)
{
log("Illegal word write: %08x to %08x from %08x\n",
value,
address,
armMode ? armNextPC - 4 : armNextPC - 2);
}
#endif
break;
}
}
#endif //VBA_GBAinline_H

File diff suppressed because it is too large Load Diff

View File

@ -1,135 +1,141 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "GBA.h" #include "agb/GBA.h"
reg_pair reg[45]; #ifdef BKPT_SUPPORT
memoryMap map[256]; int oldreg[17];
bool ioReadable[0x400]; char oldbuffer[10];
bool N_FLAG = 0; #endif
bool C_FLAG = 0;
bool Z_FLAG = 0; reg_pair reg[45];
bool V_FLAG = 0; memoryMap map[256];
bool armState = true; bool ioReadable[0x400];
bool armIrqEnable = true; bool N_FLAG = 0;
u32 armNextPC = 0x00000000; bool C_FLAG = 0;
int armMode = 0x1f; bool Z_FLAG = 0;
u32 stop = 0x08000568; bool V_FLAG = 0;
int saveType = 0; bool armState = true;
bool useBios = false; bool armIrqEnable = true;
bool skipBios = false; u32 armNextPC = 0x00000000;
int frameSkip = 1; int armMode = 0x1f;
bool speedup = false; u32 stop = 0x08000568;
bool synchronize = true; int saveType = 0;
bool cpuDisableSfx = false; bool useBios = false;
bool cpuIsMultiBoot = false; bool skipBios = false;
bool parseDebug = true; int frameSkip = 1;
int layerSettings = 0xff00; bool speedup = false;
int layerEnable = 0xff00; bool synchronize = true;
bool speedHack = false; bool cpuDisableSfx = false;
int cpuSaveType = 0; bool cpuIsMultiBoot = false;
bool cpuEnhancedDetection = true; bool parseDebug = true;
bool cheatsEnabled = true; int layerSettings = 0xff00;
int layerEnable = 0xff00;
u8 *bios = NULL; bool speedHack = false;
u8 *rom = NULL; int cpuSaveType = 0;
u8 *internalRAM = NULL; bool cheatsEnabled = true;
u8 *workRAM = NULL; bool mirroringEnable = false;
u8 *paletteRAM = NULL; bool skipSaveGameBattery = false;
u8 *vram = NULL;
u8 *pix = NULL; u8 *bios = NULL;
u8 *oam = NULL; u8 *rom = NULL;
u8 *ioMem = NULL; u8 *internalRAM = NULL;
u8 *workRAM = NULL;
u16 DISPCNT = 0x0080; u8 *paletteRAM = NULL;
u16 DISPSTAT = 0x0000; u8 *vram = NULL;
u16 VCOUNT = 0x0000; u8 *pix = NULL;
u16 BG0CNT = 0x0000; u8 *oam = NULL;
u16 BG1CNT = 0x0000; u8 *ioMem = NULL;
u16 BG2CNT = 0x0000;
u16 BG3CNT = 0x0000; u16 DISPCNT = 0x0080;
u16 BG0HOFS = 0x0000; u16 DISPSTAT = 0x0000;
u16 BG0VOFS = 0x0000; u16 VCOUNT = 0x0000;
u16 BG1HOFS = 0x0000; u16 BG0CNT = 0x0000;
u16 BG1VOFS = 0x0000; u16 BG1CNT = 0x0000;
u16 BG2HOFS = 0x0000; u16 BG2CNT = 0x0000;
u16 BG2VOFS = 0x0000; u16 BG3CNT = 0x0000;
u16 BG3HOFS = 0x0000; u16 BG0HOFS = 0x0000;
u16 BG3VOFS = 0x0000; u16 BG0VOFS = 0x0000;
u16 BG2PA = 0x0100; u16 BG1HOFS = 0x0000;
u16 BG2PB = 0x0000; u16 BG1VOFS = 0x0000;
u16 BG2PC = 0x0000; u16 BG2HOFS = 0x0000;
u16 BG2PD = 0x0100; u16 BG2VOFS = 0x0000;
u16 BG2X_L = 0x0000; u16 BG3HOFS = 0x0000;
u16 BG2X_H = 0x0000; u16 BG3VOFS = 0x0000;
u16 BG2Y_L = 0x0000; u16 BG2PA = 0x0100;
u16 BG2Y_H = 0x0000; u16 BG2PB = 0x0000;
u16 BG3PA = 0x0100; u16 BG2PC = 0x0000;
u16 BG3PB = 0x0000; u16 BG2PD = 0x0100;
u16 BG3PC = 0x0000; u16 BG2X_L = 0x0000;
u16 BG3PD = 0x0100; u16 BG2X_H = 0x0000;
u16 BG3X_L = 0x0000; u16 BG2Y_L = 0x0000;
u16 BG3X_H = 0x0000; u16 BG2Y_H = 0x0000;
u16 BG3Y_L = 0x0000; u16 BG3PA = 0x0100;
u16 BG3Y_H = 0x0000; u16 BG3PB = 0x0000;
u16 WIN0H = 0x0000; u16 BG3PC = 0x0000;
u16 WIN1H = 0x0000; u16 BG3PD = 0x0100;
u16 WIN0V = 0x0000; u16 BG3X_L = 0x0000;
u16 WIN1V = 0x0000; u16 BG3X_H = 0x0000;
u16 WININ = 0x0000; u16 BG3Y_L = 0x0000;
u16 WINOUT = 0x0000; u16 BG3Y_H = 0x0000;
u16 MOSAIC = 0x0000; u16 WIN0H = 0x0000;
u16 BLDMOD = 0x0000; u16 WIN1H = 0x0000;
u16 COLEV = 0x0000; u16 WIN0V = 0x0000;
u16 COLY = 0x0000; u16 WIN1V = 0x0000;
u16 DM0SAD_L = 0x0000; u16 WININ = 0x0000;
u16 DM0SAD_H = 0x0000; u16 WINOUT = 0x0000;
u16 DM0DAD_L = 0x0000; u16 MOSAIC = 0x0000;
u16 DM0DAD_H = 0x0000; u16 BLDMOD = 0x0000;
u16 DM0CNT_L = 0x0000; u16 COLEV = 0x0000;
u16 DM0CNT_H = 0x0000; u16 COLY = 0x0000;
u16 DM1SAD_L = 0x0000; u16 DM0SAD_L = 0x0000;
u16 DM1SAD_H = 0x0000; u16 DM0SAD_H = 0x0000;
u16 DM1DAD_L = 0x0000; u16 DM0DAD_L = 0x0000;
u16 DM1DAD_H = 0x0000; u16 DM0DAD_H = 0x0000;
u16 DM1CNT_L = 0x0000; u16 DM0CNT_L = 0x0000;
u16 DM1CNT_H = 0x0000; u16 DM0CNT_H = 0x0000;
u16 DM2SAD_L = 0x0000; u16 DM1SAD_L = 0x0000;
u16 DM2SAD_H = 0x0000; u16 DM1SAD_H = 0x0000;
u16 DM2DAD_L = 0x0000; u16 DM1DAD_L = 0x0000;
u16 DM2DAD_H = 0x0000; u16 DM1DAD_H = 0x0000;
u16 DM2CNT_L = 0x0000; u16 DM1CNT_L = 0x0000;
u16 DM2CNT_H = 0x0000; u16 DM1CNT_H = 0x0000;
u16 DM3SAD_L = 0x0000; u16 DM2SAD_L = 0x0000;
u16 DM3SAD_H = 0x0000; u16 DM2SAD_H = 0x0000;
u16 DM3DAD_L = 0x0000; u16 DM2DAD_L = 0x0000;
u16 DM3DAD_H = 0x0000; u16 DM2DAD_H = 0x0000;
u16 DM3CNT_L = 0x0000; u16 DM2CNT_L = 0x0000;
u16 DM3CNT_H = 0x0000; u16 DM2CNT_H = 0x0000;
u16 TM0D = 0x0000; u16 DM3SAD_L = 0x0000;
u16 TM0CNT = 0x0000; u16 DM3SAD_H = 0x0000;
u16 TM1D = 0x0000; u16 DM3DAD_L = 0x0000;
u16 TM1CNT = 0x0000; u16 DM3DAD_H = 0x0000;
u16 TM2D = 0x0000; u16 DM3CNT_L = 0x0000;
u16 TM2CNT = 0x0000; u16 DM3CNT_H = 0x0000;
u16 TM3D = 0x0000; u16 TM0D = 0x0000;
u16 TM3CNT = 0x0000; u16 TM0CNT = 0x0000;
u16 P1 = 0xFFFF; u16 TM1D = 0x0000;
u16 IE = 0x0000; u16 TM1CNT = 0x0000;
u16 IF = 0x0000; u16 TM2D = 0x0000;
u16 IME = 0x0000; u16 TM2CNT = 0x0000;
u16 TM3D = 0x0000;
u16 TM3CNT = 0x0000;
u16 P1 = 0xFFFF;
u16 IE = 0x0000;
u16 IF = 0x0000;
u16 IME = 0x0000;

View File

@ -1,149 +1,153 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef VBA_GLOBALS_H #ifndef VBA_GLOBALS_H
#define VBA_GLOBALS_H #define VBA_GLOBALS_H
#define VERBOSE_SWI 1 #include "agb/GBA.h"
#define VERBOSE_UNALIGNED_MEMORY 2
#define VERBOSE_ILLEGAL_WRITE 4 #define VERBOSE_SWI 1
#define VERBOSE_ILLEGAL_READ 8 #define VERBOSE_UNALIGNED_MEMORY 2
#define VERBOSE_DMA0 16 #define VERBOSE_ILLEGAL_WRITE 4
#define VERBOSE_DMA1 32 #define VERBOSE_ILLEGAL_READ 8
#define VERBOSE_DMA2 64 #define VERBOSE_DMA0 16
#define VERBOSE_DMA3 128 #define VERBOSE_DMA1 32
#define VERBOSE_UNDEFINED 256 #define VERBOSE_DMA2 64
#define VERBOSE_AGBPRINT 512 #define VERBOSE_DMA3 128
#define VERBOSE_UNDEFINED 256
extern reg_pair reg[45]; #define VERBOSE_AGBPRINT 512
extern bool ioReadable[0x400]; #define VERBOSE_SOUNDOUTPUT 1024
extern bool N_FLAG;
extern bool C_FLAG; extern reg_pair reg[45];
extern bool Z_FLAG; extern bool ioReadable[0x400];
extern bool V_FLAG; extern bool N_FLAG;
extern bool armState; extern bool C_FLAG;
extern bool armIrqEnable; extern bool Z_FLAG;
extern u32 armNextPC; extern bool V_FLAG;
extern int armMode; extern bool armState;
extern u32 stop; extern bool armIrqEnable;
extern int saveType; extern u32 armNextPC;
extern bool useBios; extern int armMode;
extern bool skipBios; extern u32 stop;
extern int frameSkip; extern int saveType;
extern bool speedup; extern bool useBios;
extern bool synchronize; extern bool skipBios;
extern bool cpuDisableSfx; extern int frameSkip;
extern bool cpuIsMultiBoot; extern bool speedup;
extern bool parseDebug; extern bool synchronize;
extern int layerSettings; extern bool cpuDisableSfx;
extern int layerEnable; extern bool cpuIsMultiBoot;
extern bool speedHack; extern bool parseDebug;
extern int cpuSaveType; extern int layerSettings;
extern bool cpuEnhancedDetection; extern int layerEnable;
extern bool cheatsEnabled; extern bool speedHack;
extern int cpuSaveType;
extern u8 *bios; extern bool cheatsEnabled;
extern u8 *rom; extern bool mirroringEnable;
extern u8 *internalRAM; extern bool skipSaveGameBattery;
extern u8 *workRAM;
extern u8 *paletteRAM; extern u8 *bios;
extern u8 *vram; extern u8 *rom;
extern u8 *pix; extern u8 *internalRAM;
extern u8 *oam; extern u8 *workRAM;
extern u8 *ioMem; extern u8 *paletteRAM;
extern u8 *vram;
extern u16 DISPCNT; extern u8 *pix;
extern u16 DISPSTAT; extern u8 *oam;
extern u16 VCOUNT; extern u8 *ioMem;
extern u16 BG0CNT;
extern u16 BG1CNT; extern u16 DISPCNT;
extern u16 BG2CNT; extern u16 DISPSTAT;
extern u16 BG3CNT; extern u16 VCOUNT;
extern u16 BG0HOFS; extern u16 BG0CNT;
extern u16 BG0VOFS; extern u16 BG1CNT;
extern u16 BG1HOFS; extern u16 BG2CNT;
extern u16 BG1VOFS; extern u16 BG3CNT;
extern u16 BG2HOFS; extern u16 BG0HOFS;
extern u16 BG2VOFS; extern u16 BG0VOFS;
extern u16 BG3HOFS; extern u16 BG1HOFS;
extern u16 BG3VOFS; extern u16 BG1VOFS;
extern u16 BG2PA; extern u16 BG2HOFS;
extern u16 BG2PB; extern u16 BG2VOFS;
extern u16 BG2PC; extern u16 BG3HOFS;
extern u16 BG2PD; extern u16 BG3VOFS;
extern u16 BG2X_L; extern u16 BG2PA;
extern u16 BG2X_H; extern u16 BG2PB;
extern u16 BG2Y_L; extern u16 BG2PC;
extern u16 BG2Y_H; extern u16 BG2PD;
extern u16 BG3PA; extern u16 BG2X_L;
extern u16 BG3PB; extern u16 BG2X_H;
extern u16 BG3PC; extern u16 BG2Y_L;
extern u16 BG3PD; extern u16 BG2Y_H;
extern u16 BG3X_L; extern u16 BG3PA;
extern u16 BG3X_H; extern u16 BG3PB;
extern u16 BG3Y_L; extern u16 BG3PC;
extern u16 BG3Y_H; extern u16 BG3PD;
extern u16 WIN0H; extern u16 BG3X_L;
extern u16 WIN1H; extern u16 BG3X_H;
extern u16 WIN0V; extern u16 BG3Y_L;
extern u16 WIN1V; extern u16 BG3Y_H;
extern u16 WININ; extern u16 WIN0H;
extern u16 WINOUT; extern u16 WIN1H;
extern u16 MOSAIC; extern u16 WIN0V;
extern u16 BLDMOD; extern u16 WIN1V;
extern u16 COLEV; extern u16 WININ;
extern u16 COLY; extern u16 WINOUT;
extern u16 DM0SAD_L; extern u16 MOSAIC;
extern u16 DM0SAD_H; extern u16 BLDMOD;
extern u16 DM0DAD_L; extern u16 COLEV;
extern u16 DM0DAD_H; extern u16 COLY;
extern u16 DM0CNT_L; extern u16 DM0SAD_L;
extern u16 DM0CNT_H; extern u16 DM0SAD_H;
extern u16 DM1SAD_L; extern u16 DM0DAD_L;
extern u16 DM1SAD_H; extern u16 DM0DAD_H;
extern u16 DM1DAD_L; extern u16 DM0CNT_L;
extern u16 DM1DAD_H; extern u16 DM0CNT_H;
extern u16 DM1CNT_L; extern u16 DM1SAD_L;
extern u16 DM1CNT_H; extern u16 DM1SAD_H;
extern u16 DM2SAD_L; extern u16 DM1DAD_L;
extern u16 DM2SAD_H; extern u16 DM1DAD_H;
extern u16 DM2DAD_L; extern u16 DM1CNT_L;
extern u16 DM2DAD_H; extern u16 DM1CNT_H;
extern u16 DM2CNT_L; extern u16 DM2SAD_L;
extern u16 DM2CNT_H; extern u16 DM2SAD_H;
extern u16 DM3SAD_L; extern u16 DM2DAD_L;
extern u16 DM3SAD_H; extern u16 DM2DAD_H;
extern u16 DM3DAD_L; extern u16 DM2CNT_L;
extern u16 DM3DAD_H; extern u16 DM2CNT_H;
extern u16 DM3CNT_L; extern u16 DM3SAD_L;
extern u16 DM3CNT_H; extern u16 DM3SAD_H;
extern u16 TM0D; extern u16 DM3DAD_L;
extern u16 TM0CNT; extern u16 DM3DAD_H;
extern u16 TM1D; extern u16 DM3CNT_L;
extern u16 TM1CNT; extern u16 DM3CNT_H;
extern u16 TM2D; extern u16 TM0D;
extern u16 TM2CNT; extern u16 TM0CNT;
extern u16 TM3D; extern u16 TM1D;
extern u16 TM3CNT; extern u16 TM1CNT;
extern u16 P1; extern u16 TM2D;
extern u16 IE; extern u16 TM2CNT;
extern u16 IF; extern u16 TM3D;
extern u16 IME; extern u16 TM3CNT;
extern u16 P1;
#endif // VBA_GLOBALS_H extern u16 IE;
extern u16 IF;
extern u16 IME;
#endif // VBA_GLOBALS_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,550 +1,446 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "GBA.h" #include "agb/GBA.h"
#include "Globals.h" #include "Globals.h"
#include "Gfx.h" #include "agb/GBAGfx.h"
void mode2RenderLine() void mode2RenderLine()
{ {
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x80) if(DISPCNT & 0x80) {
{ for(int x = 0; x < 240; x++) {
for(int x = 0; x < 240; x++) lineMix[x] = 0x7fff;
{ }
lineMix[x] = 0x7fff; gfxLastVCOUNT = VCOUNT;
} return;
gfxLastVCOUNT = VCOUNT; }
return;
} if(layerEnable & 0x0400) {
int changed = gfxBG2Changed;
if(layerEnable & 0x0400) if(gfxLastVCOUNT > VCOUNT)
{ changed = 3;
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT) gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
changed = 3; BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
changed, line2);
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, }
BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
changed, line2); if(layerEnable & 0x0800) {
} int changed = gfxBG3Changed;
if(gfxLastVCOUNT > VCOUNT)
if(layerEnable & 0x0800) changed = 3;
{
int changed = gfxBG3Changed; gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
if(gfxLastVCOUNT > VCOUNT) BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
changed = 3; changed, line3);
}
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y, gfxDrawSprites(lineOBJ);
changed, line3);
} u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
gfxDrawSprites(lineOBJ); for(int x = 0; x < 240; x++) {
u32 color = backdrop;
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000); u8 top = 0x20;
for(int x = 0; x < 240; x++)
{ if((u8)(line2[x]>>24) < (u8)(color >> 24)) {
u32 color = backdrop; color = line2[x];
u8 top = 0x20; top = 0x04;
}
if((u8)(line2[x]>>24) < (u8)(color >> 24)) if((u8)(line3[x]>>24) < (u8)(color >> 24)) {
{ color = line3[x];
color = line2[x]; top = 0x08;
top = 0x04; }
}
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
if((u8)(line3[x]>>24) < (u8)(color >> 24)) color = lineOBJ[x];
{ top = 0x10;
color = line3[x]; }
top = 0x08;
} if((top & 0x10) && (color & 0x00010000)) {
// semi-transparent OBJ
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) u32 back = backdrop;
{ u8 top2 = 0x20;
color = lineOBJ[x];
top = 0x10; if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
} back = line2[x];
top2 = 0x04;
if((top & 0x10) && (color & 0x00010000)) }
{
// semi-transparent OBJ if((u8)(line3[x]>>24) < (u8)(back >> 24)) {
u32 back = backdrop; back = line3[x];
u8 top2 = 0x20; top2 = 0x08;
}
if((u8)(line2[x]>>24) < (u8)(back >> 24))
{ if(top2 & (BLDMOD>>8))
back = line2[x]; color = gfxAlphaBlend(color, back,
top2 = 0x04; coeff[COLEV & 0x1F],
} coeff[(COLEV >> 8) & 0x1F]);
else {
if((u8)(line3[x]>>24) < (u8)(back >> 24)) switch((BLDMOD >> 6) & 3) {
{ case 2:
back = line3[x]; if(BLDMOD & top)
top2 = 0x08; color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
} break;
case 3:
if(top2 & (BLDMOD>>8)) if(BLDMOD & top)
color = gfxAlphaBlend(color, back, color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
coeff[COLEV & 0x1F], break;
coeff[(COLEV >> 8) & 0x1F]); }
else }
{ }
switch((BLDMOD >> 6) & 3)
{ lineMix[x] = color;
case 2: }
if(BLDMOD & top) gfxBG2Changed = 0;
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); gfxBG3Changed = 0;
break; gfxLastVCOUNT = VCOUNT;
case 3: }
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); void mode2RenderLineNoWindow()
break; {
} u16 *palette = (u16 *)paletteRAM;
}
} if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) {
lineMix[x] = color; lineMix[x] = 0x7fff;
} }
gfxBG2Changed = 0; gfxLastVCOUNT = VCOUNT;
gfxBG3Changed = 0; return;
gfxLastVCOUNT = VCOUNT; }
}
if(layerEnable & 0x0400) {
void mode2RenderLineNoWindow() int changed = gfxBG2Changed;
{ if(gfxLastVCOUNT > VCOUNT)
u16 *palette = (u16 *)paletteRAM; changed = 3;
if(DISPCNT & 0x80) gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
{ BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
for(int x = 0; x < 240; x++) changed, line2);
{ }
lineMix[x] = 0x7fff;
} if(layerEnable & 0x0800) {
gfxLastVCOUNT = VCOUNT; int changed = gfxBG3Changed;
return; if(gfxLastVCOUNT > VCOUNT)
} changed = 3;
if(layerEnable & 0x0400) gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
{ BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
int changed = gfxBG2Changed; changed, line3);
if(gfxLastVCOUNT > VCOUNT) }
changed = 3;
gfxDrawSprites(lineOBJ);
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y, u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
changed, line2);
} for(int x = 0; x < 240; x++) {
u32 color = backdrop;
if(layerEnable & 0x0800) u8 top = 0x20;
{
int changed = gfxBG3Changed;
if(gfxLastVCOUNT > VCOUNT) if((u8)(line2[x]>>24) < (u8)(color >> 24)) {
changed = 3; color = line2[x];
top = 0x04;
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H, }
BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
changed, line3); if((u8)(line3[x]>>24) < (u8)(color >> 24)) {
} color = line3[x];
top = 0x08;
gfxDrawSprites(lineOBJ); }
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000); if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
color = lineOBJ[x];
for(int x = 0; x < 240; x++) top = 0x10;
{ }
u32 color = backdrop;
u8 top = 0x20; if(!(color & 0x00010000)) {
switch((BLDMOD >> 6) & 3) {
case 0:
if((u8)(line2[x]>>24) < (u8)(color >> 24)) break;
{ case 1:
color = line2[x]; {
top = 0x04; if(top & BLDMOD) {
} u32 back = backdrop;
u8 top2 = 0x20;
if((u8)(line3[x]>>24) < (u8)(color >> 24))
{ if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
color = line3[x]; if(top != 0x04) {
top = 0x08; back = line2[x];
} top2 = 0x04;
}
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) }
{
color = lineOBJ[x]; if((u8)(line3[x]>>24) < (u8)(back >> 24)) {
top = 0x10; if(top != 0x08) {
} back = line3[x];
top2 = 0x08;
if(!(color & 0x00010000)) }
{ }
switch((BLDMOD >> 6) & 3)
{ if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
case 0: if(top != 0x10) {
break; back = lineOBJ[x];
case 1: top2 = 0x10;
{ }
if(top & BLDMOD) }
{
u32 back = backdrop; if(top2 & (BLDMOD>>8))
u8 top2 = 0x20; color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
if((u8)(line2[x]>>24) < (u8)(back >> 24)) coeff[(COLEV >> 8) & 0x1F]);
{ }
if(top != 0x04) }
{ break;
back = line2[x]; case 2:
top2 = 0x04; if(BLDMOD & top)
} color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
} break;
case 3:
if((u8)(line3[x]>>24) < (u8)(back >> 24)) if(BLDMOD & top)
{ color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
if(top != 0x08) break;
{ }
back = line3[x]; } else {
top2 = 0x08; // semi-transparent OBJ
} u32 back = backdrop;
} u8 top2 = 0x20;
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) if((u8)(line2[x]>>24) < (u8)(back >> 24)) {
{ back = line2[x];
if(top != 0x10) top2 = 0x04;
{ }
back = lineOBJ[x];
top2 = 0x10; if((u8)(line3[x]>>24) < (u8)(back >> 24)) {
} back = line3[x];
} top2 = 0x08;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back, if(top2 & (BLDMOD>>8))
coeff[COLEV & 0x1F], color = gfxAlphaBlend(color, back,
coeff[(COLEV >> 8) & 0x1F]); coeff[COLEV & 0x1F],
} coeff[(COLEV >> 8) & 0x1F]);
} else {
break; switch((BLDMOD >> 6) & 3) {
case 2: case 2:
if(BLDMOD & top) if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break; break;
case 3: case 3:
if(BLDMOD & top) if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break; break;
} }
} }
else }
{
// semi-transparent OBJ lineMix[x] = color;
u32 back = backdrop; }
u8 top2 = 0x20; gfxBG2Changed = 0;
gfxBG3Changed = 0;
if((u8)(line2[x]>>24) < (u8)(back >> 24)) gfxLastVCOUNT = VCOUNT;
{ }
back = line2[x];
top2 = 0x04; void mode2RenderLineAll()
} {
u16 *palette = (u16 *)paletteRAM;
if((u8)(line3[x]>>24) < (u8)(back >> 24))
{ if(DISPCNT & 0x80) {
back = line3[x]; for(int x = 0; x < 240; x++) {
top2 = 0x08; lineMix[x] = 0x7fff;
} }
gfxLastVCOUNT = VCOUNT;
if(top2 & (BLDMOD>>8)) return;
color = gfxAlphaBlend(color, back, }
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]); bool inWindow0 = false;
else bool inWindow1 = false;
{
switch((BLDMOD >> 6) & 3) if(layerEnable & 0x2000) {
{ u8 v0 = WIN0V >> 8;
case 2: u8 v1 = WIN0V & 255;
if(BLDMOD & top) inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); if(v1 >= v0)
break; inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
case 3: else
if(BLDMOD & top) inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); }
break; if(layerEnable & 0x4000) {
} u8 v0 = WIN1V >> 8;
} u8 v1 = WIN1V & 255;
} inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
if(v1 >= v0)
lineMix[x] = color; inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
} else
gfxBG2Changed = 0; inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
gfxBG3Changed = 0; }
gfxLastVCOUNT = VCOUNT;
} if(layerEnable & 0x0400) {
int changed = gfxBG2Changed;
void mode2RenderLineAll() if(gfxLastVCOUNT > VCOUNT)
{ changed = 3;
u16 *palette = (u16 *)paletteRAM;
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
if(DISPCNT & 0x80) BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y,
{ changed, line2);
for(int x = 0; x < 240; x++) }
{
lineMix[x] = 0x7fff; if(layerEnable & 0x0800) {
} int changed = gfxBG3Changed;
gfxLastVCOUNT = VCOUNT; if(gfxLastVCOUNT > VCOUNT)
return; changed = 3;
}
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H,
bool inWindow0 = false; BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
bool inWindow1 = false; changed, line3);
}
if(layerEnable & 0x2000)
{ gfxDrawSprites(lineOBJ);
u8 v0 = WIN0V >> 8; gfxDrawOBJWin(lineOBJWin);
u8 v1 = WIN0V & 255;
inWindow0 = ((v0 == v1) && (v0 >= 0xe8)); u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
if(v1 >= v0)
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1); u8 inWin0Mask = WININ & 0xFF;
else u8 inWin1Mask = WININ >> 8;
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1); u8 outMask = WINOUT & 0xFF;
}
if(layerEnable & 0x4000) for(int x = 0; x < 240; x++) {
{ u32 color = backdrop;
u8 v0 = WIN1V >> 8; u8 top = 0x20;
u8 v1 = WIN1V & 255; u8 mask = outMask;
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
if(v1 >= v0) if(!(lineOBJWin[x] & 0x80000000)) {
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1); mask = WINOUT >> 8;
else }
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
} if(inWindow1) {
if(gfxInWin1[x])
if(layerEnable & 0x0400) mask = inWin1Mask;
{ }
int changed = gfxBG2Changed;
if(gfxLastVCOUNT > VCOUNT) if(inWindow0) {
changed = 3; if(gfxInWin0[x]) {
mask = inWin0Mask;
gfxDrawRotScreen(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, }
BG2PA, BG2PB, BG2PC, BG2PD, gfxBG2X, gfxBG2Y, }
changed, line2);
} if(line2[x] < color && (mask & 4)) {
color = line2[x];
if(layerEnable & 0x0800) top = 0x04;
{ }
int changed = gfxBG3Changed;
if(gfxLastVCOUNT > VCOUNT) if((u8)(line3[x]>>24) < (u8)(color >> 24) && (mask & 8)) {
changed = 3; color = line3[x];
top = 0x08;
gfxDrawRotScreen(BG3CNT, BG3X_L, BG3X_H, BG3Y_L, BG3Y_H, }
BG3PA, BG3PB, BG3PC, BG3PD, gfxBG3X, gfxBG3Y,
changed, line3); if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24) && (mask & 16)) {
} color = lineOBJ[x];
top = 0x10;
gfxDrawSprites(lineOBJ); }
gfxDrawOBJWin(lineOBJWin);
if(color & 0x00010000) {
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000); // semi-transparent OBJ
u32 back = backdrop;
u8 inWin0Mask = WININ & 0xFF; u8 top2 = 0x20;
u8 inWin1Mask = WININ >> 8;
u8 outMask = WINOUT & 0xFF; if((mask & 4) && line2[x] < back) {
back = line2[x];
for(int x = 0; x < 240; x++) top2 = 0x04;
{ }
u32 color = backdrop;
u8 top = 0x20; if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24)) {
u8 mask = outMask; back = line3[x];
top2 = 0x08;
if(!(lineOBJWin[x] & 0x80000000)) }
{
mask = WINOUT >> 8; if(top2 & (BLDMOD>>8))
} color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
if(inWindow1) coeff[(COLEV >> 8) & 0x1F]);
{ else {
if(gfxInWin1[x]) switch((BLDMOD >> 6) & 3) {
mask = inWin1Mask; case 2:
} if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
if(inWindow0) break;
{ case 3:
if(gfxInWin0[x]) if(BLDMOD & top)
{ color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
mask = inWin0Mask; break;
} }
} }
} else if(mask & 32) {
if(line2[x] < color && (mask & 4)) // special FX on the window
{ switch((BLDMOD >> 6) & 3) {
color = line2[x]; case 0:
top = 0x04; break;
} case 1:
{
if((u8)(line3[x]>>24) < (u8)(color >> 24) && (mask & 8)) if(top & BLDMOD) {
{ u32 back = backdrop;
color = line3[x]; u8 top2 = 0x20;
top = 0x08;
} if((mask & 4) && line2[x] < back) {
if(top != 0x04) {
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24) && (mask & 16)) back = line2[x];
{ top2 = 0x04;
color = lineOBJ[x]; }
top = 0x10; }
}
if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24)) {
if(mask & 32) if(top != 0x08) {
{ back = line3[x];
if(!(color & 0x00010000)) top2 = 0x08;
{ }
switch((BLDMOD >> 6) & 3) }
{
case 0: if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
break; if(top != 0x10) {
case 1: back = lineOBJ[x];
{ top2 = 0x10;
if(top & BLDMOD) }
{ }
u32 back = backdrop;
u8 top2 = 0x20; if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
if((mask & 4) && line2[x] < back) coeff[COLEV & 0x1F],
{ coeff[(COLEV >> 8) & 0x1F]);
if(top != 0x04) }
{ }
back = line2[x]; break;
top2 = 0x04; case 2:
} if(BLDMOD & top)
} color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24)) case 3:
{ if(BLDMOD & top)
if(top != 0x08) color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
{ break;
back = line3[x]; }
top2 = 0x08; }
}
} lineMix[x] = color;
}
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) gfxBG2Changed = 0;
{ gfxBG3Changed = 0;
if(top != 0x10) gfxLastVCOUNT = VCOUNT;
{ }
back = lineOBJ[x];
top2 = 0x10;
}
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
}
break;
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
else
{
// semi-transparent OBJ
u32 back = backdrop;
u8 top2 = 0x20;
if((mask & 4) && line2[x] < back)
{
back = line2[x];
top2 = 0x04;
}
if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24))
{
back = line3[x];
top2 = 0x08;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else
{
switch((BLDMOD >> 6) & 3)
{
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
}
}
else if(color & 0x00010000)
{
// semi-transparent OBJ
u32 back = backdrop;
u8 top2 = 0x20;
if((mask & 4) && line2[x] < back)
{
back = line2[x];
top2 = 0x04;
}
if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24))
{
back = line3[x];
top2 = 0x08;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else
{
switch((BLDMOD >> 6) & 3)
{
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
}
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxBG3Changed = 0;
gfxLastVCOUNT = VCOUNT;
}

View File

@ -1,463 +1,377 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "GBA.h" #include "agb/GBA.h"
#include "Globals.h" #include "Globals.h"
#include "Gfx.h" #include "agb/GBAGfx.h"
void mode3RenderLine() void mode3RenderLine()
{ {
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x80) if(DISPCNT & 0x80) {
{ for(int x = 0; x < 240; x++) {
for(int x = 0; x < 240; x++) lineMix[x] = 0x7fff;
{ }
lineMix[x] = 0x7fff; gfxLastVCOUNT = VCOUNT;
} return;
gfxLastVCOUNT = VCOUNT; }
return;
} if(layerEnable & 0x0400) {
int changed = gfxBG2Changed;
if(layerEnable & 0x0400)
{ if(gfxLastVCOUNT > VCOUNT)
int changed = gfxBG2Changed; changed = 3;
if(gfxLastVCOUNT > VCOUNT) gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
changed = 3; BG2Y_L, BG2Y_H, BG2PA, BG2PB,
BG2PC, BG2PD,
gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H, gfxBG2X, gfxBG2Y, changed,
BG2Y_L, BG2Y_H, BG2PA, BG2PB, line2);
BG2PC, BG2PD, }
gfxBG2X, gfxBG2Y, changed,
line2); gfxDrawSprites(lineOBJ);
}
u32 background = (READ16LE(&palette[0]) | 0x30000000);
gfxDrawSprites(lineOBJ);
for(int x = 0; x < 240; x++) {
u32 background = (READ16LE(&palette[0]) | 0x30000000); u32 color = background;
u8 top = 0x20;
for(int x = 0; x < 240; x++)
{ if(line2[x] < color) {
u32 color = background; color = line2[x];
u8 top = 0x20; top = 0x04;
}
if(line2[x] < color)
{ if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
color = line2[x]; color = lineOBJ[x];
top = 0x04; top = 0x10;
} }
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) if((top & 0x10) && (color & 0x00010000)) {
{ // semi-transparent OBJ
color = lineOBJ[x]; u32 back = background;
top = 0x10; u8 top2 = 0x20;
}
if(line2[x] < back) {
if((top & 0x10) && (color & 0x00010000)) back = line2[x];
{ top2 = 0x04;
// semi-transparent OBJ }
u32 back = background;
u8 top2 = 0x20; if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
if(line2[x] < back) coeff[COLEV & 0x1F],
{ coeff[(COLEV >> 8) & 0x1F]);
back = line2[x]; else {
top2 = 0x04; switch((BLDMOD >> 6) & 3) {
} case 2:
if(BLDMOD & top)
if(top2 & (BLDMOD>>8)) color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
color = gfxAlphaBlend(color, back, break;
coeff[COLEV & 0x1F], case 3:
coeff[(COLEV >> 8) & 0x1F]); if(BLDMOD & top)
else color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
{ break;
switch((BLDMOD >> 6) & 3) }
{ }
case 2: }
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); lineMix[x] = color;
break; }
case 3: gfxBG2Changed = 0;
if(BLDMOD & top) gfxLastVCOUNT = VCOUNT;
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); }
break;
} void mode3RenderLineNoWindow()
} {
} u16 *palette = (u16 *)paletteRAM;
lineMix[x] = color; if(DISPCNT & 0x80) {
} for(int x = 0; x < 240; x++) {
gfxBG2Changed = 0; lineMix[x] = 0x7fff;
gfxLastVCOUNT = VCOUNT; }
} gfxLastVCOUNT = VCOUNT;
return;
void mode3RenderLineNoWindow() }
{
u16 *palette = (u16 *)paletteRAM; if(layerEnable & 0x0400) {
int changed = gfxBG2Changed;
if(DISPCNT & 0x80)
{ if(gfxLastVCOUNT > VCOUNT)
for(int x = 0; x < 240; x++) changed = 3;
{
lineMix[x] = 0x7fff; gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
} BG2Y_L, BG2Y_H, BG2PA, BG2PB,
gfxLastVCOUNT = VCOUNT; BG2PC, BG2PD,
return; gfxBG2X, gfxBG2Y, changed,
} line2);
}
if(layerEnable & 0x0400)
{ gfxDrawSprites(lineOBJ);
int changed = gfxBG2Changed;
u32 background = (READ16LE(&palette[0]) | 0x30000000);
if(gfxLastVCOUNT > VCOUNT)
changed = 3; for(int x = 0; x < 240; x++) {
u32 color = background;
gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H, u8 top = 0x20;
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
BG2PC, BG2PD, if(line2[x] < color) {
gfxBG2X, gfxBG2Y, changed, color = line2[x];
line2); top = 0x04;
} }
gfxDrawSprites(lineOBJ); if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
color = lineOBJ[x];
u32 background = (READ16LE(&palette[0]) | 0x30000000); top = 0x10;
}
for(int x = 0; x < 240; x++)
{ if(!(color & 0x00010000)) {
u32 color = background; switch((BLDMOD >> 6) & 3) {
u8 top = 0x20; case 0:
break;
if(line2[x] < color) case 1:
{ {
color = line2[x]; if(top & BLDMOD) {
top = 0x04; u32 back = background;
} u8 top2 = 0x20;
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) if(line2[x] < back) {
{ if(top != 0x04) {
color = lineOBJ[x]; back = line2[x];
top = 0x10; top2 = 0x04;
} }
}
if(!(color & 0x00010000))
{ if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
switch((BLDMOD >> 6) & 3) if(top != 0x10) {
{ back = lineOBJ[x];
case 0: top2 = 0x10;
break; }
case 1: }
{
if(top & BLDMOD) if(top2 & (BLDMOD>>8))
{ color = gfxAlphaBlend(color, back,
u32 back = background; coeff[COLEV & 0x1F],
u8 top2 = 0x20; coeff[(COLEV >> 8) & 0x1F]);
if(line2[x] < back) }
{ }
if(top != 0x04) break;
{ case 2:
back = line2[x]; if(BLDMOD & top)
top2 = 0x04; color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
} break;
} case 3:
if(BLDMOD & top)
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
{ break;
if(top != 0x10) }
{ } else {
back = lineOBJ[x]; // semi-transparent OBJ
top2 = 0x10; u32 back = background;
} u8 top2 = 0x20;
}
if(line2[x] < back) {
if(top2 & (BLDMOD>>8)) back = line2[x];
color = gfxAlphaBlend(color, back, top2 = 0x04;
coeff[COLEV & 0x1F], }
coeff[(COLEV >> 8) & 0x1F]);
if(top2 & (BLDMOD>>8))
} color = gfxAlphaBlend(color, back,
} coeff[COLEV & 0x1F],
break; coeff[(COLEV >> 8) & 0x1F]);
case 2: else {
if(BLDMOD & top) switch((BLDMOD >> 6) & 3) {
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); case 2:
break; if(BLDMOD & top)
case 3: color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
if(BLDMOD & top) break;
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); case 3:
break; if(BLDMOD & top)
} color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
} break;
else }
{ }
// semi-transparent OBJ }
u32 back = background;
u8 top2 = 0x20; lineMix[x] = color;
}
if(line2[x] < back) gfxBG2Changed = 0;
{ gfxLastVCOUNT = VCOUNT;
back = line2[x]; }
top2 = 0x04;
} void mode3RenderLineAll()
{
if(top2 & (BLDMOD>>8)) u16 *palette = (u16 *)paletteRAM;
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F], if(DISPCNT & 0x80) {
coeff[(COLEV >> 8) & 0x1F]); for(int x = 0; x < 240; x++) {
else lineMix[x] = 0x7fff;
{ }
switch((BLDMOD >> 6) & 3) gfxLastVCOUNT = VCOUNT;
{ return;
case 2: }
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); bool inWindow0 = false;
break; bool inWindow1 = false;
case 3:
if(BLDMOD & top) if(layerEnable & 0x2000) {
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); u8 v0 = WIN0V >> 8;
break; u8 v1 = WIN0V & 255;
} inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
} if(v1 >= v0)
} inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
else
lineMix[x] = color; inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
} }
gfxBG2Changed = 0; if(layerEnable & 0x4000) {
gfxLastVCOUNT = VCOUNT; u8 v0 = WIN1V >> 8;
} u8 v1 = WIN1V & 255;
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
void mode3RenderLineAll() if(v1 >= v0)
{ inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
u16 *palette = (u16 *)paletteRAM; else
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
if(DISPCNT & 0x80) }
{
for(int x = 0; x < 240; x++) if(layerEnable & 0x0400) {
{ int changed = gfxBG2Changed;
lineMix[x] = 0x7fff;
} if(gfxLastVCOUNT > VCOUNT)
gfxLastVCOUNT = VCOUNT; changed = 3;
return;
} gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H,
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
bool inWindow0 = false; BG2PC, BG2PD,
bool inWindow1 = false; gfxBG2X, gfxBG2Y, changed,
line2);
if(layerEnable & 0x2000) }
{
u8 v0 = WIN0V >> 8; gfxDrawSprites(lineOBJ);
u8 v1 = WIN0V & 255; gfxDrawOBJWin(lineOBJWin);
inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
if(v1 >= v0) u8 inWin0Mask = WININ & 0xFF;
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1); u8 inWin1Mask = WININ >> 8;
else u8 outMask = WINOUT & 0xFF;
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
} u32 background = (READ16LE(&palette[0]) | 0x30000000);
if(layerEnable & 0x4000)
{ for(int x = 0; x < 240; x++) {
u8 v0 = WIN1V >> 8; u32 color = background;
u8 v1 = WIN1V & 255; u8 top = 0x20;
inWindow1 = ((v0 == v1) && (v0 >= 0xe8)); u8 mask = outMask;
if(v1 >= v0)
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1); if(!(lineOBJWin[x] & 0x80000000)) {
else mask = WINOUT >> 8;
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1); }
}
if(inWindow1) {
if(layerEnable & 0x0400) if(gfxInWin1[x])
{ mask = inWin1Mask;
int changed = gfxBG2Changed; }
if(gfxLastVCOUNT > VCOUNT) if(inWindow0) {
changed = 3; if(gfxInWin0[x]) {
mask = inWin0Mask;
gfxDrawRotScreen16Bit(BG2CNT, BG2X_L, BG2X_H, }
BG2Y_L, BG2Y_H, BG2PA, BG2PB, }
BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed, if((mask & 4) && (line2[x] < color)) {
line2); color = line2[x];
} top = 0x04;
}
gfxDrawSprites(lineOBJ);
gfxDrawOBJWin(lineOBJWin); if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))) {
color = lineOBJ[x];
u8 inWin0Mask = WININ & 0xFF; top = 0x10;
u8 inWin1Mask = WININ >> 8; }
u8 outMask = WINOUT & 0xFF;
if(color & 0x00010000) {
u32 background = (READ16LE(&palette[0]) | 0x30000000); // semi-transparent OBJ
u32 back = background;
for(int x = 0; x < 240; x++) u8 top2 = 0x20;
{
u32 color = background; if((mask & 4) && line2[x] < back) {
u8 top = 0x20; back = line2[x];
u8 mask = outMask; top2 = 0x04;
}
if(!(lineOBJWin[x] & 0x80000000))
{ if(top2 & (BLDMOD>>8))
mask = WINOUT >> 8; color = gfxAlphaBlend(color, back,
} coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
if(inWindow1) else {
{ switch((BLDMOD >> 6) & 3) {
if(gfxInWin1[x]) case 2:
mask = inWin1Mask; if(BLDMOD & top)
} color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
if(inWindow0) case 3:
{ if(BLDMOD & top)
if(gfxInWin0[x]) color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
{ break;
mask = inWin0Mask; }
} }
} } else if(mask & 32) {
switch((BLDMOD >> 6) & 3) {
if((mask & 4) && (line2[x] < color)) case 0:
{ break;
color = line2[x]; case 1:
top = 0x04; {
} if(top & BLDMOD) {
u32 back = background;
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))) u8 top2 = 0x20;
{
color = lineOBJ[x]; if((mask & 4) && line2[x] < back) {
top = 0x10; if(top != 0x04) {
} back = line2[x];
top2 = 0x04;
if(mask & 32) }
{ }
if(!(color & 0x00010000))
{ if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
switch((BLDMOD >> 6) & 3) if(top != 0x10) {
{ back = lineOBJ[x];
case 0: top2 = 0x10;
break; }
case 1: }
{
if(top & BLDMOD) if(top2 & (BLDMOD>>8))
{ color = gfxAlphaBlend(color, back,
u32 back = background; coeff[COLEV & 0x1F],
u8 top2 = 0x20; coeff[(COLEV >> 8) & 0x1F]);
if((mask & 4) && line2[x] < back) }
{ }
if(top != 0x04) break;
{ case 2:
back = line2[x]; if(BLDMOD & top)
top2 = 0x04; color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
} break;
} case 3:
if(BLDMOD & top)
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
{ break;
if(top != 0x10) }
{ }
back = lineOBJ[x];
top2 = 0x10; lineMix[x] = color;
} }
} gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
if(top2 & (BLDMOD>>8)) }
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
}
break;
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
else
{
// semi-transparent OBJ
u32 back = background;
u8 top2 = 0x20;
if((mask & 4) && line2[x] < back)
{
back = line2[x];
top2 = 0x04;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else
{
switch((BLDMOD >> 6) & 3)
{
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
}
}
else if(color & 0x00010000)
{
// semi-transparent OBJ
u32 back = background;
u8 top2 = 0x20;
if((mask & 4) && line2[x] < back)
{
back = line2[x];
top2 = 0x04;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else
{
switch((BLDMOD >> 6) & 3)
{
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
}
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
}

View File

@ -1,460 +1,374 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "GBA.h" #include "agb/GBA.h"
#include "Gfx.h" #include "agb/GBAGfx.h"
#include "Globals.h" #include "Globals.h"
void mode4RenderLine() void mode4RenderLine()
{ {
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x0080) if(DISPCNT & 0x0080) {
{ for(int x = 0; x < 240; x++) {
for(int x = 0; x < 240; x++) lineMix[x] = 0x7fff;
{ }
lineMix[x] = 0x7fff; gfxLastVCOUNT = VCOUNT;
} return;
gfxLastVCOUNT = VCOUNT; }
return;
} if(layerEnable & 0x400) {
int changed = gfxBG2Changed;
if(layerEnable & 0x400)
{ if(gfxLastVCOUNT > VCOUNT)
int changed = gfxBG2Changed; changed = 3;
if(gfxLastVCOUNT > VCOUNT) gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
changed = 3; BG2PA, BG2PB, BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed,
gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, line2);
BG2PA, BG2PB, BG2PC, BG2PD, }
gfxBG2X, gfxBG2Y, changed,
line2); gfxDrawSprites(lineOBJ);
}
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
gfxDrawSprites(lineOBJ);
for(int x = 0; x < 240; x++) {
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000); u32 color = backdrop;
u8 top = 0x20;
for(int x = 0; x < 240; x++)
{ if(line2[x] < color) {
u32 color = backdrop; color = line2[x];
u8 top = 0x20; top = 0x04;
}
if(line2[x] < color)
{ if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
color = line2[x]; color = lineOBJ[x];
top = 0x04; top = 0x10;
} }
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) if((top & 0x10) && (color & 0x00010000)) {
{ // semi-transparent OBJ
color = lineOBJ[x]; u32 back = backdrop;
top = 0x10; u8 top2 = 0x20;
}
if(line2[x] < back) {
if((top & 0x10) && (color & 0x00010000)) back = line2[x];
{ top2 = 0x04;
// semi-transparent OBJ }
u32 back = backdrop;
u8 top2 = 0x20; if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
if(line2[x] < back) coeff[COLEV & 0x1F],
{ coeff[(COLEV >> 8) & 0x1F]);
back = line2[x]; else {
top2 = 0x04; switch((BLDMOD >> 6) & 3) {
} case 2:
if(BLDMOD & top)
if(top2 & (BLDMOD>>8)) color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
color = gfxAlphaBlend(color, back, break;
coeff[COLEV & 0x1F], case 3:
coeff[(COLEV >> 8) & 0x1F]); if(BLDMOD & top)
else color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
{ break;
switch((BLDMOD >> 6) & 3) }
{ }
case 2: }
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); lineMix[x] = color;
break; }
case 3: gfxBG2Changed = 0;
if(BLDMOD & top) gfxLastVCOUNT = VCOUNT;
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); }
break;
} void mode4RenderLineNoWindow()
} {
} u16 *palette = (u16 *)paletteRAM;
lineMix[x] = color; if(DISPCNT & 0x0080) {
} for(int x = 0; x < 240; x++) {
gfxBG2Changed = 0; lineMix[x] = 0x7fff;
gfxLastVCOUNT = VCOUNT; }
} gfxLastVCOUNT = VCOUNT;
return;
void mode4RenderLineNoWindow() }
{
u16 *palette = (u16 *)paletteRAM; if(layerEnable & 0x400) {
int changed = gfxBG2Changed;
if(DISPCNT & 0x0080)
{ if(gfxLastVCOUNT > VCOUNT)
for(int x = 0; x < 240; x++) changed = 3;
{
lineMix[x] = 0x7fff; gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
} BG2PA, BG2PB, BG2PC, BG2PD,
gfxLastVCOUNT = VCOUNT; gfxBG2X, gfxBG2Y, changed,
return; line2);
} }
if(layerEnable & 0x400) gfxDrawSprites(lineOBJ);
{
int changed = gfxBG2Changed; u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
if(gfxLastVCOUNT > VCOUNT) for(int x = 0; x < 240; x++) {
changed = 3; u32 color = backdrop;
u8 top = 0x20;
gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD, if(line2[x] < color) {
gfxBG2X, gfxBG2Y, changed, color = line2[x];
line2); top = 0x04;
} }
gfxDrawSprites(lineOBJ); if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
color = lineOBJ[x];
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000); top = 0x10;
}
for(int x = 0; x < 240; x++)
{ if(!(color & 0x00010000)) {
u32 color = backdrop; switch((BLDMOD >> 6) & 3) {
u8 top = 0x20; case 0:
break;
if(line2[x] < color) case 1:
{ {
color = line2[x]; if(top & BLDMOD) {
top = 0x04; u32 back = backdrop;
} u8 top2 = 0x20;
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) if(line2[x] < back) {
{ if(top != 0x04) {
color = lineOBJ[x]; back = line2[x];
top = 0x10; top2 = 0x04;
} }
}
if(!(color & 0x00010000))
{ if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
switch((BLDMOD >> 6) & 3) if(top != 0x10) {
{ back = lineOBJ[x];
case 0: top2 = 0x10;
break; }
case 1: }
{
if(top & BLDMOD) if(top2 & (BLDMOD>>8))
{ color = gfxAlphaBlend(color, back,
u32 back = backdrop; coeff[COLEV & 0x1F],
u8 top2 = 0x20; coeff[(COLEV >> 8) & 0x1F]);
if(line2[x] < back) }
{ }
if(top != 0x04) break;
{ case 2:
back = line2[x]; if(BLDMOD & top)
top2 = 0x04; color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
} break;
} case 3:
if(BLDMOD & top)
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
{ break;
if(top != 0x10) }
{ } else {
back = lineOBJ[x]; // semi-transparent OBJ
top2 = 0x10; u32 back = backdrop;
} u8 top2 = 0x20;
}
if(line2[x] < back) {
if(top2 & (BLDMOD>>8)) back = line2[x];
color = gfxAlphaBlend(color, back, top2 = 0x04;
coeff[COLEV & 0x1F], }
coeff[(COLEV >> 8) & 0x1F]);
if(top2 & (BLDMOD>>8))
} color = gfxAlphaBlend(color, back,
} coeff[COLEV & 0x1F],
break; coeff[(COLEV >> 8) & 0x1F]);
case 2: else {
if(BLDMOD & top) switch((BLDMOD >> 6) & 3) {
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); case 2:
break; if(BLDMOD & top)
case 3: color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
if(BLDMOD & top) break;
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); case 3:
break; if(BLDMOD & top)
} color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
} break;
else }
{ }
// semi-transparent OBJ }
u32 back = backdrop;
u8 top2 = 0x20; lineMix[x] = color;
}
if(line2[x] < back) gfxBG2Changed = 0;
{ gfxLastVCOUNT = VCOUNT;
back = line2[x]; }
top2 = 0x04;
} void mode4RenderLineAll()
{
if(top2 & (BLDMOD>>8)) u16 *palette = (u16 *)paletteRAM;
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F], if(DISPCNT & 0x0080) {
coeff[(COLEV >> 8) & 0x1F]); for(int x = 0; x < 240; x++) {
else lineMix[x] = 0x7fff;
{ }
switch((BLDMOD >> 6) & 3) gfxLastVCOUNT = VCOUNT;
{ return;
case 2: }
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); bool inWindow0 = false;
break; bool inWindow1 = false;
case 3:
if(BLDMOD & top) if(layerEnable & 0x2000) {
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); u8 v0 = WIN0V >> 8;
break; u8 v1 = WIN0V & 255;
} inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
} if(v1 >= v0)
} inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
else
lineMix[x] = color; inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
} }
gfxBG2Changed = 0; if(layerEnable & 0x4000) {
gfxLastVCOUNT = VCOUNT; u8 v0 = WIN1V >> 8;
} u8 v1 = WIN1V & 255;
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
void mode4RenderLineAll() if(v1 >= v0)
{ inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
u16 *palette = (u16 *)paletteRAM; else
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
if(DISPCNT & 0x0080) }
{
for(int x = 0; x < 240; x++) if(layerEnable & 0x400) {
{ int changed = gfxBG2Changed;
lineMix[x] = 0x7fff;
} if(gfxLastVCOUNT > VCOUNT)
gfxLastVCOUNT = VCOUNT; changed = 3;
return;
} gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H,
BG2PA, BG2PB, BG2PC, BG2PD,
bool inWindow0 = false; gfxBG2X, gfxBG2Y, changed,
bool inWindow1 = false; line2);
}
if(layerEnable & 0x2000)
{ gfxDrawSprites(lineOBJ);
u8 v0 = WIN0V >> 8; gfxDrawOBJWin(lineOBJWin);
u8 v1 = WIN0V & 255;
inWindow0 = ((v0 == v1) && (v0 >= 0xe8)); u32 backdrop = (READ16LE(&palette[0]) | 0x30000000);
if(v1 >= v0)
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1); u8 inWin0Mask = WININ & 0xFF;
else u8 inWin1Mask = WININ >> 8;
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1); u8 outMask = WINOUT & 0xFF;
}
if(layerEnable & 0x4000) for(int x = 0; x < 240; x++) {
{ u32 color = backdrop;
u8 v0 = WIN1V >> 8; u8 top = 0x20;
u8 v1 = WIN1V & 255; u8 mask = outMask;
inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
if(v1 >= v0) if(!(lineOBJWin[x] & 0x80000000)) {
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1); mask = WINOUT >> 8;
else }
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
} if(inWindow1) {
if(gfxInWin1[x])
if(layerEnable & 0x400) mask = inWin1Mask;
{ }
int changed = gfxBG2Changed;
if(inWindow0) {
if(gfxLastVCOUNT > VCOUNT) if(gfxInWin0[x]) {
changed = 3; mask = inWin0Mask;
}
gfxDrawRotScreen256(BG2CNT, BG2X_L, BG2X_H, BG2Y_L, BG2Y_H, }
BG2PA, BG2PB, BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed, if((mask & 4) && (line2[x] < color)) {
line2); color = line2[x];
} top = 0x04;
}
gfxDrawSprites(lineOBJ);
gfxDrawOBJWin(lineOBJWin); if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))) {
color = lineOBJ[x];
u32 backdrop = (READ16LE(&palette[0]) | 0x30000000); top = 0x10;
}
u8 inWin0Mask = WININ & 0xFF;
u8 inWin1Mask = WININ >> 8; if(color & 0x00010000) {
u8 outMask = WINOUT & 0xFF; // semi-transparent OBJ
u32 back = backdrop;
for(int x = 0; x < 240; x++) u8 top2 = 0x20;
{
u32 color = backdrop; if((mask & 4) && line2[x] < back) {
u8 top = 0x20; back = line2[x];
u8 mask = outMask; top2 = 0x04;
}
if(!(lineOBJWin[x] & 0x80000000))
{ if(top2 & (BLDMOD>>8))
mask = WINOUT >> 8; color = gfxAlphaBlend(color, back,
} coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
if(inWindow1) else {
{ switch((BLDMOD >> 6) & 3) {
if(gfxInWin1[x]) case 2:
mask = inWin1Mask; if(BLDMOD & top)
} color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
if(inWindow0) case 3:
{ if(BLDMOD & top)
if(gfxInWin0[x]) color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
{ break;
mask = inWin0Mask; }
} }
} } else if(mask & 32) {
switch((BLDMOD >> 6) & 3) {
if((mask & 4) && (line2[x] < color)) case 0:
{ break;
color = line2[x]; case 1:
top = 0x04; {
} if(top & BLDMOD) {
u32 back = backdrop;
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))) u8 top2 = 0x20;
{
color = lineOBJ[x]; if((mask & 4) && line2[x] < back) {
top = 0x10; if(top != 0x04) {
} back = line2[x];
top2 = 0x04;
if(mask & 32) }
{ }
if(!(color & 0x00010000))
{ if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
switch((BLDMOD >> 6) & 3) if(top != 0x10) {
{ back = lineOBJ[x];
case 0: top2 = 0x10;
break; }
case 1: }
{
if(top & BLDMOD) if(top2 & (BLDMOD>>8))
{ color = gfxAlphaBlend(color, back,
u32 back = backdrop; coeff[COLEV & 0x1F],
u8 top2 = 0x20; coeff[(COLEV >> 8) & 0x1F]);
if((mask & 4) && line2[x] < back) }
{ }
if(top != 0x04) break;
{ case 2:
back = line2[x]; if(BLDMOD & top)
top2 = 0x04; color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
} break;
} case 3:
if(BLDMOD & top)
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
{ break;
if(top != 0x10) }
{ }
back = lineOBJ[x];
top2 = 0x10; lineMix[x] = color;
} }
} gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
if(top2 & (BLDMOD>>8)) }
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
}
break;
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
else
{
// semi-transparent OBJ
u32 back = backdrop;
u8 top2 = 0x20;
if((mask & 4) && line2[x] < back)
{
back = line2[x];
top2 = 0x04;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else
{
switch((BLDMOD >> 6) & 3)
{
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
}
}
else if(color & 0x00010000)
{
// semi-transparent OBJ
u32 back = backdrop;
u8 top2 = 0x20;
if((mask & 4) && line2[x] < back)
{
back = line2[x];
top2 = 0x04;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else
{
switch((BLDMOD >> 6) & 3)
{
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
}
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
}

View File

@ -1,463 +1,377 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "GBA.h" #include "agb/GBA.h"
#include "Globals.h" #include "Globals.h"
#include "Gfx.h" #include "agb/GBAGfx.h"
void mode5RenderLine() void mode5RenderLine()
{ {
if(DISPCNT & 0x0080) if(DISPCNT & 0x0080) {
{ for(int x = 0; x < 240; x++) {
for(int x = 0; x < 240; x++) lineMix[x] = 0x7fff;
{ }
lineMix[x] = 0x7fff; gfxLastVCOUNT = VCOUNT;
} return;
gfxLastVCOUNT = VCOUNT; }
return;
} u16 *palette = (u16 *)paletteRAM;
u16 *palette = (u16 *)paletteRAM; if(layerEnable & 0x0400) {
int changed = gfxBG2Changed;
if(layerEnable & 0x0400)
{ if(gfxLastVCOUNT > VCOUNT)
int changed = gfxBG2Changed; changed = 3;
if(gfxLastVCOUNT > VCOUNT) gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
changed = 3; BG2Y_L, BG2Y_H, BG2PA, BG2PB,
BG2PC, BG2PD,
gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H, gfxBG2X, gfxBG2Y, changed,
BG2Y_L, BG2Y_H, BG2PA, BG2PB, line2);
BG2PC, BG2PD, }
gfxBG2X, gfxBG2Y, changed,
line2); gfxDrawSprites(lineOBJ);
}
u32 background = (READ16LE(&palette[0]) | 0x30000000);
gfxDrawSprites(lineOBJ);
for(int x = 0; x < 240; x++) {
u32 background = (READ16LE(&palette[0]) | 0x30000000); u32 color = background;
u8 top = 0x20;
for(int x = 0; x < 240; x++)
{ if(line2[x] < color) {
u32 color = background; color = line2[x];
u8 top = 0x20; top = 0x04;
}
if(line2[x] < color)
{ if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
color = line2[x]; color = lineOBJ[x];
top = 0x04; top = 0x10;
} }
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) if((top & 0x10) && (color & 0x00010000)) {
{ // semi-transparent OBJ
color = lineOBJ[x]; u32 back = background;
top = 0x10; u8 top2 = 0x20;
}
if(line2[x] < back) {
if((top & 0x10) && (color & 0x00010000)) back = line2[x];
{ top2 = 0x04;
// semi-transparent OBJ }
u32 back = background;
u8 top2 = 0x20; if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
if(line2[x] < back) coeff[COLEV & 0x1F],
{ coeff[(COLEV >> 8) & 0x1F]);
back = line2[x]; else {
top2 = 0x04; switch((BLDMOD >> 6) & 3) {
} case 2:
if(BLDMOD & top)
if(top2 & (BLDMOD>>8)) color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
color = gfxAlphaBlend(color, back, break;
coeff[COLEV & 0x1F], case 3:
coeff[(COLEV >> 8) & 0x1F]); if(BLDMOD & top)
else color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
{ break;
switch((BLDMOD >> 6) & 3) }
{ }
case 2: }
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); lineMix[x] = color;
break; }
case 3: gfxBG2Changed = 0;
if(BLDMOD & top) gfxLastVCOUNT = VCOUNT;
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); }
break;
} void mode5RenderLineNoWindow()
} {
} if(DISPCNT & 0x0080) {
for(int x = 0; x < 240; x++) {
lineMix[x] = color; lineMix[x] = 0x7fff;
} }
gfxBG2Changed = 0; gfxLastVCOUNT = VCOUNT;
gfxLastVCOUNT = VCOUNT; return;
} }
void mode5RenderLineNoWindow() u16 *palette = (u16 *)paletteRAM;
{
if(DISPCNT & 0x0080) if(layerEnable & 0x0400) {
{ int changed = gfxBG2Changed;
for(int x = 0; x < 240; x++)
{ if(gfxLastVCOUNT > VCOUNT)
lineMix[x] = 0x7fff; changed = 3;
}
gfxLastVCOUNT = VCOUNT; gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
return; BG2Y_L, BG2Y_H, BG2PA, BG2PB,
} BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed,
u16 *palette = (u16 *)paletteRAM; line2);
}
if(layerEnable & 0x0400)
{ gfxDrawSprites(lineOBJ);
int changed = gfxBG2Changed;
u32 background = ( READ16LE(&palette[0]) | 0x30000000);
if(gfxLastVCOUNT > VCOUNT)
changed = 3; for(int x = 0; x < 240; x++) {
u32 color = background;
gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H, u8 top = 0x20;
BG2Y_L, BG2Y_H, BG2PA, BG2PB,
BG2PC, BG2PD, if(line2[x] < color) {
gfxBG2X, gfxBG2Y, changed, color = line2[x];
line2); top = 0x04;
} }
gfxDrawSprites(lineOBJ); if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) {
color = lineOBJ[x];
u32 background = ( READ16LE(&palette[0]) | 0x30000000); top = 0x10;
}
for(int x = 0; x < 240; x++)
{ if(!(color & 0x00010000)) {
u32 color = background; switch((BLDMOD >> 6) & 3) {
u8 top = 0x20; case 0:
break;
if(line2[x] < color) case 1:
{ {
color = line2[x]; if(top & BLDMOD) {
top = 0x04; u32 back = background;
} u8 top2 = 0x20;
if((u8)(lineOBJ[x]>>24) < (u8)(color >>24)) if(line2[x] < back) {
{ if(top != 0x04) {
color = lineOBJ[x]; back = line2[x];
top = 0x10; top2 = 0x04;
} }
}
if(!(color & 0x00010000))
{ if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
switch((BLDMOD >> 6) & 3) if(top != 0x10) {
{ back = lineOBJ[x];
case 0: top2 = 0x10;
break; }
case 1: }
{
if(top & BLDMOD) if(top2 & (BLDMOD>>8))
{ color = gfxAlphaBlend(color, back,
u32 back = background; coeff[COLEV & 0x1F],
u8 top2 = 0x20; coeff[(COLEV >> 8) & 0x1F]);
if(line2[x] < back) }
{ }
if(top != 0x04) break;
{ case 2:
back = line2[x]; if(BLDMOD & top)
top2 = 0x04; color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
} break;
} case 3:
if(BLDMOD & top)
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
{ break;
if(top != 0x10) }
{ } else {
back = lineOBJ[x]; // semi-transparent OBJ
top2 = 0x10; u32 back = background;
} u8 top2 = 0x20;
}
if(line2[x] < back) {
if(top2 & (BLDMOD>>8)) back = line2[x];
color = gfxAlphaBlend(color, back, top2 = 0x04;
coeff[COLEV & 0x1F], }
coeff[(COLEV >> 8) & 0x1F]);
if(top2 & (BLDMOD>>8))
} color = gfxAlphaBlend(color, back,
} coeff[COLEV & 0x1F],
break; coeff[(COLEV >> 8) & 0x1F]);
case 2: else {
if(BLDMOD & top) switch((BLDMOD >> 6) & 3) {
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); case 2:
break; if(BLDMOD & top)
case 3: color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
if(BLDMOD & top) break;
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); case 3:
break; if(BLDMOD & top)
} color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
} break;
else }
{ }
// semi-transparent OBJ }
u32 back = background;
u8 top2 = 0x20; lineMix[x] = color;
}
if(line2[x] < back) gfxBG2Changed = 0;
{ gfxLastVCOUNT = VCOUNT;
back = line2[x]; }
top2 = 0x04;
} void mode5RenderLineAll()
{
if(top2 & (BLDMOD>>8)) if(DISPCNT & 0x0080) {
color = gfxAlphaBlend(color, back, for(int x = 0; x < 240; x++) {
coeff[COLEV & 0x1F], lineMix[x] = 0x7fff;
coeff[(COLEV >> 8) & 0x1F]); }
else gfxLastVCOUNT = VCOUNT;
{ return;
switch((BLDMOD >> 6) & 3) }
{
case 2: u16 *palette = (u16 *)paletteRAM;
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]); if(layerEnable & 0x0400) {
break; int changed = gfxBG2Changed;
case 3:
if(BLDMOD & top) if(gfxLastVCOUNT > VCOUNT)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]); changed = 3;
break;
} gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
} BG2Y_L, BG2Y_H, BG2PA, BG2PB,
} BG2PC, BG2PD,
gfxBG2X, gfxBG2Y, changed,
lineMix[x] = color; line2);
} }
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT; gfxDrawSprites(lineOBJ);
} gfxDrawOBJWin(lineOBJWin);
void mode5RenderLineAll() bool inWindow0 = false;
{ bool inWindow1 = false;
if(DISPCNT & 0x0080)
{ if(layerEnable & 0x2000) {
for(int x = 0; x < 240; x++) u8 v0 = WIN0V >> 8;
{ u8 v1 = WIN0V & 255;
lineMix[x] = 0x7fff; inWindow0 = ((v0 == v1) && (v0 >= 0xe8));
} if(v1 >= v0)
gfxLastVCOUNT = VCOUNT; inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1);
return; else
} inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1);
}
u16 *palette = (u16 *)paletteRAM; if(layerEnable & 0x4000) {
u8 v0 = WIN1V >> 8;
if(layerEnable & 0x0400) u8 v1 = WIN1V & 255;
{ inWindow1 = ((v0 == v1) && (v0 >= 0xe8));
int changed = gfxBG2Changed; if(v1 >= v0)
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1);
if(gfxLastVCOUNT > VCOUNT) else
changed = 3; inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
}
gfxDrawRotScreen16Bit160(BG2CNT, BG2X_L, BG2X_H,
BG2Y_L, BG2Y_H, BG2PA, BG2PB, u8 inWin0Mask = WININ & 0xFF;
BG2PC, BG2PD, u8 inWin1Mask = WININ >> 8;
gfxBG2X, gfxBG2Y, changed, u8 outMask = WINOUT & 0xFF;
line2);
} u32 background = (READ16LE(&palette[0]) | 0x30000000);
gfxDrawSprites(lineOBJ); for(int x = 0; x < 240; x++) {
gfxDrawOBJWin(lineOBJWin); u32 color = background;
u8 top = 0x20;
bool inWindow0 = false; u8 mask = outMask;
bool inWindow1 = false;
if(!(lineOBJWin[x] & 0x80000000)) {
if(layerEnable & 0x2000) mask = WINOUT >> 8;
{ }
u8 v0 = WIN0V >> 8;
u8 v1 = WIN0V & 255; if(inWindow1) {
inWindow0 = ((v0 == v1) && (v0 >= 0xe8)); if(gfxInWin1[x])
if(v1 >= v0) mask = inWin1Mask;
inWindow0 |= (VCOUNT >= v0 && VCOUNT < v1); }
else
inWindow0 |= (VCOUNT >= v0 || VCOUNT < v1); if(inWindow0) {
} if(gfxInWin0[x]) {
if(layerEnable & 0x4000) mask = inWin0Mask;
{ }
u8 v0 = WIN1V >> 8; }
u8 v1 = WIN1V & 255;
inWindow1 = ((v0 == v1) && (v0 >= 0xe8)); if((mask & 4) && (line2[x] < color)) {
if(v1 >= v0) color = line2[x];
inWindow1 |= (VCOUNT >= v0 && VCOUNT < v1); top = 0x04;
else }
inWindow1 |= (VCOUNT >= v0 || VCOUNT < v1);
} if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))) {
color = lineOBJ[x];
u8 inWin0Mask = WININ & 0xFF; top = 0x10;
u8 inWin1Mask = WININ >> 8; }
u8 outMask = WINOUT & 0xFF;
if(color & 0x00010000) {
u32 background = (READ16LE(&palette[0]) | 0x30000000); // semi-transparent OBJ
u32 back = background;
for(int x = 0; x < 240; x++) u8 top2 = 0x20;
{
u32 color = background; if((mask & 4) && line2[x] < back) {
u8 top = 0x20; back = line2[x];
u8 mask = outMask; top2 = 0x04;
}
if(!(lineOBJWin[x] & 0x80000000))
{ if(top2 & (BLDMOD>>8))
mask = WINOUT >> 8; color = gfxAlphaBlend(color, back,
} coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
if(inWindow1) else {
{ switch((BLDMOD >> 6) & 3) {
if(gfxInWin1[x]) case 2:
mask = inWin1Mask; if(BLDMOD & top)
} color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
if(inWindow0) case 3:
{ if(BLDMOD & top)
if(gfxInWin0[x]) color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
{ break;
mask = inWin0Mask; }
} }
} } else if(mask & 32) {
switch((BLDMOD >> 6) & 3) {
if((mask & 4) && (line2[x] < color)) case 0:
{ break;
color = line2[x]; case 1:
top = 0x04; {
} if(top & BLDMOD) {
u32 back = background;
if((mask & 16) && ((u8)(lineOBJ[x]>>24) < (u8)(color >>24))) u8 top2 = 0x20;
{
color = lineOBJ[x]; if((mask & 4) && line2[x] < back) {
top = 0x10; if(top != 0x04) {
} back = line2[x];
top2 = 0x04;
if(mask & 32) }
{ }
if(!(color & 0x00010000))
{ if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
switch((BLDMOD >> 6) & 3) if(top != 0x10) {
{ back = lineOBJ[x];
case 0: top2 = 0x10;
break; }
case 1: }
{
if(top & BLDMOD) if(top2 & (BLDMOD>>8))
{ color = gfxAlphaBlend(color, back,
u32 back = background; coeff[COLEV & 0x1F],
u8 top2 = 0x20; coeff[(COLEV >> 8) & 0x1F]);
if((mask & 4) && line2[x] < back) }
{ }
if(top != 0x04) break;
{ case 2:
back = line2[x]; if(BLDMOD & top)
top2 = 0x04; color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
} break;
} case 3:
if(BLDMOD & top)
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
{ break;
if(top != 0x10) }
{ }
back = lineOBJ[x];
top2 = 0x10; lineMix[x] = color;
} }
} gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
if(top2 & (BLDMOD>>8)) }
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
}
}
break;
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
else
{
// semi-transparent OBJ
u32 back = background;
u8 top2 = 0x20;
if((mask & 4) && line2[x] < back)
{
back = line2[x];
top2 = 0x04;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else
{
switch((BLDMOD >> 6) & 3)
{
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
}
}
else if(color & 0x00010000)
{
// semi-transparent OBJ
u32 back = background;
u8 top2 = 0x20;
if((mask & 4) && line2[x] < back)
{
back = line2[x];
top2 = 0x04;
}
if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]);
else
{
switch((BLDMOD >> 6) & 3)
{
case 2:
if(BLDMOD & top)
color = gfxIncreaseBrightness(color, coeff[COLY & 0x1F]);
break;
case 3:
if(BLDMOD & top)
color = gfxDecreaseBrightness(color, coeff[COLY & 0x1F]);
break;
}
}
}
lineMix[x] = color;
}
gfxBG2Changed = 0;
gfxLastVCOUNT = VCOUNT;
}

View File

@ -1,62 +1,64 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define N_(String) (String) #define N_(String) (String)
#define MSG_UNSUPPORTED_VBA_SGM 1 #define MSG_UNSUPPORTED_VBA_SGM 1
#define MSG_CANNOT_LOAD_SGM 2 #define MSG_CANNOT_LOAD_SGM 2
#define MSG_SAVE_GAME_NOT_USING_BIOS 3 #define MSG_SAVE_GAME_NOT_USING_BIOS 3
#define MSG_SAVE_GAME_USING_BIOS 4 #define MSG_SAVE_GAME_USING_BIOS 4
#define MSG_UNSUPPORTED_SAVE_TYPE 5 #define MSG_UNSUPPORTED_SAVE_TYPE 5
#define MSG_CANNOT_OPEN_FILE 6 #define MSG_CANNOT_OPEN_FILE 6
#define MSG_BAD_ZIP_FILE 7 #define MSG_BAD_ZIP_FILE 7
#define MSG_NO_IMAGE_ON_ZIP 8 #define MSG_NO_IMAGE_ON_ZIP 8
#define MSG_ERROR_OPENING_IMAGE 9 #define MSG_ERROR_OPENING_IMAGE 9
#define MSG_ERROR_READING_IMAGE 10 #define MSG_ERROR_READING_IMAGE 10
#define MSG_UNSUPPORTED_BIOS_FUNCTION 11 #define MSG_UNSUPPORTED_BIOS_FUNCTION 11
#define MSG_INVALID_BIOS_FILE_SIZE 12 #define MSG_INVALID_BIOS_FILE_SIZE 12
#define MSG_INVALID_CHEAT_CODE 13 #define MSG_INVALID_CHEAT_CODE 13
#define MSG_UNKNOWN_ARM_OPCODE 14 #define MSG_UNKNOWN_ARM_OPCODE 14
#define MSG_UNKNOWN_THUMB_OPCODE 15 #define MSG_UNKNOWN_THUMB_OPCODE 15
#define MSG_ERROR_CREATING_FILE 16 #define MSG_ERROR_CREATING_FILE 16
#define MSG_FAILED_TO_READ_SGM 17 #define MSG_FAILED_TO_READ_SGM 17
#define MSG_FAILED_TO_READ_RTC 18 #define MSG_FAILED_TO_READ_RTC 18
#define MSG_UNSUPPORTED_VB_SGM 19 #define MSG_UNSUPPORTED_VB_SGM 19
#define MSG_CANNOT_LOAD_SGM_FOR 20 #define MSG_CANNOT_LOAD_SGM_FOR 20
#define MSG_ERROR_OPENING_IMAGE_FROM 21 #define MSG_ERROR_OPENING_IMAGE_FROM 21
#define MSG_ERROR_READING_IMAGE_FROM 22 #define MSG_ERROR_READING_IMAGE_FROM 22
#define MSG_UNSUPPORTED_ROM_SIZE 23 #define MSG_UNSUPPORTED_ROM_SIZE 23
#define MSG_UNSUPPORTED_RAM_SIZE 24 #define MSG_UNSUPPORTED_RAM_SIZE 24
#define MSG_UNKNOWN_CARTRIDGE_TYPE 25 #define MSG_UNKNOWN_CARTRIDGE_TYPE 25
#define MSG_MAXIMUM_NUMBER_OF_CHEATS 26 #define MSG_MAXIMUM_NUMBER_OF_CHEATS 26
#define MSG_INVALID_GAMESHARK_CODE 27 #define MSG_INVALID_GAMESHARK_CODE 27
#define MSG_INVALID_GAMEGENIE_CODE 28 #define MSG_INVALID_GAMEGENIE_CODE 28
#define MSG_INVALID_CHEAT_TO_REMOVE 29 #define MSG_INVALID_CHEAT_TO_REMOVE 29
#define MSG_INVALID_CHEAT_CODE_ADDRESS 30 #define MSG_INVALID_CHEAT_CODE_ADDRESS 30
#define MSG_UNSUPPORTED_CHEAT_LIST_VERSION 31 #define MSG_UNSUPPORTED_CHEAT_LIST_VERSION 31
#define MSG_UNSUPPORTED_CHEAT_LIST_TYPE 32 #define MSG_UNSUPPORTED_CHEAT_LIST_TYPE 32
#define MSG_INVALID_GSA_CODE 33 #define MSG_INVALID_GSA_CODE 33
#define MSG_CANNOT_IMPORT_SNAPSHOT_FOR 34 #define MSG_CANNOT_IMPORT_SNAPSHOT_FOR 34
#define MSG_UNSUPPORTED_SNAPSHOT_FILE 35 #define MSG_UNSUPPORTED_SNAPSHOT_FILE 35
#define MSG_UNSUPPORTED_ARM_MODE 36 #define MSG_UNSUPPORTED_ARM_MODE 36
#define MSG_UNSUPPORTED_CODE_FILE 37 #define MSG_UNSUPPORTED_CODE_FILE 37
#define MSG_GBA_CODE_WARNING 38 #define MSG_GBA_CODE_WARNING 38
#define MSG_INVALID_CBA_CODE 39 #define MSG_INVALID_CBA_CODE 39
#define MSG_CBA_CODE_WARNING 40 #define MSG_CBA_CODE_WARNING 40
#define MSG_OUT_OF_MEMORY 41 #define MSG_OUT_OF_MEMORY 41
#define MSG_WRONG_GAMESHARK_CODE 42
#define MSG_UNSUPPORTED_GAMESHARK_CODE 43

View File

@ -1,77 +1,75 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef VBA_PORT_H #ifndef VBA_PORT_H
#define VBA_PORT_H #define VBA_PORT_H
// swaps a 16-bit value // swaps a 16-bit value
static inline u16 swap16(u16 v) static inline u16 swap16(u16 v)
{ {
return (v<<8)|(v>>8); return (v<<8)|(v>>8);
} }
// swaps a 32-bit value // swaps a 32-bit value
static inline u32 swap32(u32 v) static inline u32 swap32(u32 v)
{ {
return (v<<24)|((v<<8)&0xff0000)|((v>>8)&0xff00)|(v>>24); return (v<<24)|((v<<8)&0xff0000)|((v>>8)&0xff00)|(v>>24);
} }
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
#define __ppc__ #if defined(__GNUC__) && defined(__ppc__)
#if defined(__GNUC__) && defined(__ppc__) #define READ16LE(base) \
({ unsigned short lhbrxResult; \
#define READ16LE(base) \ __asm__ ("lhbrx %0, 0, %1" : "=r" (lhbrxResult) : "r" (base) : "memory"); \
({ unsigned short lhbrxResult; \ lhbrxResult; })
__asm__ ("lhbrx %0, 0, %1" : "=r" (lhbrxResult) : "r" (base) : "memory"); \
lhbrxResult; }) #define READ32LE(base) \
({ unsigned long lwbrxResult; \
#define READ32LE(base) \ __asm__ ("lwbrx %0, 0, %1" : "=r" (lwbrxResult) : "r" (base) : "memory"); \
({ unsigned long lwbrxResult; \ lwbrxResult; })
__asm__ ("lwbrx %0, 0, %1" : "=r" (lwbrxResult) : "r" (base) : "memory"); \
lwbrxResult; }) #define WRITE16LE(base, value) \
__asm__ ("sthbrx %0, 0, %1" : : "r" (value), "r" (base) : "memory")
#define WRITE16LE(base, value) \
__asm__ ("sthbrx %0, 0, %1" : : "r" (value), "r" (base) : "memory") #define WRITE32LE(base, value) \
__asm__ ("stwbrx %0, 0, %1" : : "r" (value), "r" (base) : "memory")
#define WRITE32LE(base, value) \
__asm__ ("stwbrx %0, 0, %1" : : "r" (value), "r" (base) : "memory") #else
#define READ16LE(x) \
#else swap16(*((u16 *)(x)))
#define READ16LE(x) \ #define READ32LE(x) \
swap16(*((u16 *)(x))) swap32(*((u32 *)(x)))
#define READ32LE(x) \ #define WRITE16LE(x,v) \
swap32(*((u32 *)(x))) *((u16 *)x) = swap16((v))
#define WRITE16LE(x,v) \ #define WRITE32LE(x,v) \
*((u16 *)x) = swap16((v)) *((u32 *)x) = swap32((v))
#define WRITE32LE(x,v) \ #endif
*((u32 *)x) = swap32((v)) #else
#endif #define READ16LE(x) \
#else *((u16 *)x)
#define READ16LE(x) \ #define READ32LE(x) \
*((u16 *)x) *((u32 *)x)
#define READ32LE(x) \ #define WRITE16LE(x,v) \
*((u32 *)x) *((u16 *)x) = (v)
#define WRITE16LE(x,v) \ #define WRITE32LE(x,v) \
*((u16 *)x) = (v) *((u32 *)x) = (v)
#define WRITE32LE(x,v) \ #endif
*((u32 *)x) = (v)
#endif #endif
#endif

View File

@ -1,245 +1,227 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "System.h" #include "System.h"
#include "GBA.h" #include "agb/GBA.h"
#include "Globals.h" #include "Globals.h"
#include "Port.h" #include "Port.h"
#include "Util.h" #include "Util.h"
#include "NLS.h" #include "NLS.h"
#include "vmmem.h" #include "vmmem.h"
#include <time.h> #include <time.h>
#include <string.h> #include <string.h>
enum RTCSTATE { IDLE, COMMAND, DATA, READDATA }; enum RTCSTATE { IDLE, COMMAND, DATA, READDATA };
typedef struct typedef struct {
{ u8 byte0;
u8 byte0; u8 byte1;
u8 byte1; u8 byte2;
u8 byte2; u8 command;
u8 command; int dataLen;
int dataLen; int bits;
int bits; RTCSTATE state;
RTCSTATE state; u8 data[12];
u8 data[12]; // reserved variables for future
// reserved variables for future u8 reserved[12];
u8 reserved[12]; bool reserved2;
bool reserved2; u32 reserved3;
u32 reserved3; } RTCCLOCKDATA;
}
RTCCLOCKDATA; static RTCCLOCKDATA rtcClockData;
static bool rtcEnabled = false;
static RTCCLOCKDATA rtcClockData;
static bool rtcEnabled = false; void rtcEnable(bool e)
{
void rtcEnable(bool e) rtcEnabled = e;
{ }
rtcEnabled = e;
} bool rtcIsEnabled()
{
bool rtcIsEnabled() return rtcEnabled;
{ }
return rtcEnabled;
} u16 rtcRead(u32 address)
{
u16 rtcRead(u32 address) if(rtcEnabled) {
{ switch(address){
if(rtcEnabled) case 0x80000c8:
{ return rtcClockData.byte2;
if(address == 0x80000c8) break;
return rtcClockData.byte2; case 0x80000c6:
else if(address == 0x80000c6) return rtcClockData.byte1;
return rtcClockData.byte1; break;
else if(address == 0x80000c4) case 0x80000c4:
{ return rtcClockData.byte0;
return rtcClockData.byte0; break;
} }
} }
//return READ16LE((&rom[address & 0x1FFFFFE]));
//return READ16LE((&rom[address & 0x1FFFFFE])); return VMRead16( address & 0x1FFFFFE );
return VMRead16( address & 0x1FFFFFE ); }
}
static u8 toBCD(u8 value)
static u8 toBCD(u8 value) {
{ value = value % 100;
value = value % 100; int l = value % 10;
int l = value % 10; int h = value / 10;
int h = value / 10; return h * 16 + l;
return h * 16 + l; }
}
bool rtcWrite(u32 address, u16 value)
bool rtcWrite(u32 address, u16 value) {
{ if(!rtcEnabled)
if(!rtcEnabled) return false;
return false;
if(address == 0x80000c8) {
if(address == 0x80000c8) rtcClockData.byte2 = (u8)value; // enable ?
{ } else if(address == 0x80000c6) {
rtcClockData.byte2 = (u8)value; // enable ? rtcClockData.byte1 = (u8)value; // read/write
} } else if(address == 0x80000c4) {
else if(address == 0x80000c6) if(rtcClockData.byte2 & 1) {
{ if(rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5) {
rtcClockData.byte1 = (u8)value; // read/write rtcClockData.state = COMMAND;
} rtcClockData.bits = 0;
else if(address == 0x80000c4) rtcClockData.command = 0;
{ } else if(!(rtcClockData.byte0 & 1) && (value & 1)) { // bit transfer
if(rtcClockData.byte2 & 1) rtcClockData.byte0 = (u8)value;
{ switch(rtcClockData.state) {
if(rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5) case COMMAND:
{ rtcClockData.command |= ((value & 2) >> 1) << (7-rtcClockData.bits);
rtcClockData.state = COMMAND; rtcClockData.bits++;
rtcClockData.bits = 0; if(rtcClockData.bits == 8) {
rtcClockData.command = 0; rtcClockData.bits = 0;
} switch(rtcClockData.command) {
else if(!(rtcClockData.byte0 & 1) && (value & 1)) case 0x60:
{ // bit transfer // not sure what this command does but it doesn't take parameters
rtcClockData.byte0 = (u8)value; // maybe it is a reset or stop
switch(rtcClockData.state) rtcClockData.state = IDLE;
{ rtcClockData.bits = 0;
case COMMAND: break;
rtcClockData.command |= ((value & 2) >> 1) << (7-rtcClockData.bits); case 0x62:
rtcClockData.bits++; // this sets the control state but not sure what those values are
if(rtcClockData.bits == 8) rtcClockData.state = READDATA;
{ rtcClockData.dataLen = 1;
rtcClockData.bits = 0; break;
switch(rtcClockData.command) case 0x63:
{ rtcClockData.dataLen = 1;
case 0x60: rtcClockData.data[0] = 0x40;
// not sure what this command does but it doesn't take parameters rtcClockData.state = DATA;
// maybe it is a reset or stop break;
rtcClockData.state = IDLE; case 0x64:
rtcClockData.bits = 0; break;
break; case 0x65:
case 0x62: {
// this sets the control state but not sure what those values are struct tm *newtime;
rtcClockData.state = READDATA; time_t long_time;
rtcClockData.dataLen = 1;
break; time( &long_time ); /* Get time as long integer. */
case 0x63: newtime = localtime( &long_time ); /* Convert to local time. */
rtcClockData.dataLen = 1;
rtcClockData.data[0] = 0x40; rtcClockData.dataLen = 7;
rtcClockData.state = DATA; rtcClockData.data[0] = toBCD(newtime->tm_year);
break; rtcClockData.data[1] = toBCD(newtime->tm_mon+1);
case 0x65: rtcClockData.data[2] = toBCD(newtime->tm_mday);
{ rtcClockData.data[3] = toBCD(newtime->tm_wday);
struct tm *newtime; rtcClockData.data[4] = toBCD(newtime->tm_hour);
time_t long_time; rtcClockData.data[5] = toBCD(newtime->tm_min);
rtcClockData.data[6] = toBCD(newtime->tm_sec);
time( &long_time ); /* Get time as long integer. */ rtcClockData.state = DATA;
newtime = localtime( &long_time ); /* Convert to local time. */ }
break;
rtcClockData.dataLen = 7; case 0x67:
rtcClockData.data[0] = toBCD(newtime->tm_year); {
rtcClockData.data[1] = toBCD(newtime->tm_mon+1); struct tm *newtime;
rtcClockData.data[2] = toBCD(newtime->tm_mday); time_t long_time;
rtcClockData.data[3] = 0;
rtcClockData.data[4] = toBCD(newtime->tm_hour); time( &long_time ); /* Get time as long integer. */
rtcClockData.data[5] = toBCD(newtime->tm_min); newtime = localtime( &long_time ); /* Convert to local time. */
rtcClockData.data[6] = toBCD(newtime->tm_sec);
rtcClockData.state = DATA; rtcClockData.dataLen = 3;
} rtcClockData.data[0] = toBCD(newtime->tm_hour);
break; rtcClockData.data[1] = toBCD(newtime->tm_min);
case 0x67: rtcClockData.data[2] = toBCD(newtime->tm_sec);
{ rtcClockData.state = DATA;
struct tm *newtime; }
time_t long_time; break;
default:
time( &long_time ); /* Get time as long integer. */ systemMessage(0, N_("Unknown RTC command %02x"), rtcClockData.command);
newtime = localtime( &long_time ); /* Convert to local time. */ rtcClockData.state = IDLE;
break;
rtcClockData.dataLen = 3; }
rtcClockData.data[0] = toBCD(newtime->tm_hour); }
rtcClockData.data[1] = toBCD(newtime->tm_min); break;
rtcClockData.data[2] = toBCD(newtime->tm_sec); case DATA:
rtcClockData.state = DATA; if(rtcClockData.byte1 & 2) {
} } else {
break; rtcClockData.byte0 = (rtcClockData.byte0 & ~2) |
default: ((rtcClockData.data[rtcClockData.bits >> 3] >>
systemMessage(0, N_("Unknown RTC command %02x"), rtcClockData.command); (rtcClockData.bits & 7)) & 1)*2;
rtcClockData.state = IDLE; rtcClockData.bits++;
break; if(rtcClockData.bits == 8*rtcClockData.dataLen) {
} rtcClockData.bits = 0;
} rtcClockData.state = IDLE;
break; }
case DATA: }
if(rtcClockData.byte1 & 2) break;
{} case READDATA:
else if(!(rtcClockData.byte1 & 2)) {
{ } else {
rtcClockData.byte0 = (rtcClockData.byte0 & ~2) | rtcClockData.data[rtcClockData.bits >> 3] =
((rtcClockData.data[rtcClockData.bits >> 3] >> (rtcClockData.data[rtcClockData.bits >> 3] >> 1) |
(rtcClockData.bits & 7)) & 1)*2; ((value << 6) & 128);
rtcClockData.bits++; rtcClockData.bits++;
if(rtcClockData.bits == 8*rtcClockData.dataLen) if(rtcClockData.bits == 8*rtcClockData.dataLen) {
{ rtcClockData.bits = 0;
rtcClockData.bits = 0; rtcClockData.state = IDLE;
rtcClockData.state = IDLE; }
} }
} break;
break; default:
case READDATA: break;
if(!(rtcClockData.byte1 & 2)) }
{} } else
else rtcClockData.byte0 = (u8)value;
{ }
rtcClockData.data[rtcClockData.bits >> 3] = }
(rtcClockData.data[rtcClockData.bits >> 3] >> 1) | return true;
((value << 6) & 128); }
rtcClockData.bits++;
if(rtcClockData.bits == 8*rtcClockData.dataLen) void rtcReset()
{ {
rtcClockData.bits = 0; memset(&rtcClockData, 0, sizeof(rtcClockData));
rtcClockData.state = IDLE;
} rtcClockData.byte0 = 0;
} rtcClockData.byte1 = 0;
break; rtcClockData.byte2 = 0;
default: rtcClockData.command = 0;
break; rtcClockData.dataLen = 0;
} rtcClockData.bits = 0;
} rtcClockData.state = IDLE;
else }
rtcClockData.byte0 = (u8)value;
} void rtcSaveGame(gzFile gzFile)
} {
return true; utilGzWrite(gzFile, &rtcClockData, sizeof(rtcClockData));
} }
void rtcReset() void rtcReadGame(gzFile gzFile)
{ {
memset(&rtcClockData, 0, sizeof(rtcClockData)); utilGzRead(gzFile, &rtcClockData, sizeof(rtcClockData));
}
rtcClockData.byte0 = 0;
rtcClockData.byte1 = 0;
rtcClockData.byte2 = 0;
rtcClockData.command = 0;
rtcClockData.dataLen = 0;
rtcClockData.bits = 0;
rtcClockData.state = IDLE;
}
void rtcSaveGame(gzFile gzFile)
{
utilGzWrite(gzFile, &rtcClockData, sizeof(rtcClockData));
}
void rtcReadGame(gzFile gzFile)
{
utilGzRead(gzFile, &rtcClockData, sizeof(rtcClockData));
}

View File

@ -1,31 +1,31 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef VBA_RTC_H #ifndef VBA_RTC_H
#define VBA_RTC_H #define VBA_RTC_H
extern u16 rtcRead(u32 address); extern u16 rtcRead(u32 address);
extern bool rtcWrite(u32 address, u16 value); extern bool rtcWrite(u32 address, u16 value);
extern void rtcEnable(bool); extern void rtcEnable(bool);
extern bool rtcIsEnabled(); extern bool rtcIsEnabled();
extern void rtcReset(); extern void rtcReset();
extern void rtcReadGame(gzFile gzFile); extern void rtcReadGame(gzFile gzFile);
extern void rtcSaveGame(gzFile gzFile); extern void rtcSaveGame(gzFile gzFile);
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -1,82 +1,84 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// Copyright (C) 2004-2006 VBA development team
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // This program is free software; you can redistribute it and/or modify
// the Free Software Foundation; either version 2, or(at your option) // it under the terms of the GNU General Public License as published by
// any later version. // the Free Software Foundation; either version 2, or(at your option)
// // any later version.
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of // This program is distributed in the hope that it will be useful,
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // but WITHOUT ANY WARRANTY; without even the implied warranty of
// GNU General Public License for more details. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// // GNU General Public License for more details.
// You should have received a copy of the GNU General Public License //
// along with this program; if not, write to the Free Software Foundation, // You should have received a copy of the GNU General Public License
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef VBA_SOUND_H
#define VBA_SOUND_H #ifndef VBA_SOUND_H
#define VBA_SOUND_H
#define NR10 0x60
#define NR11 0x62 #include "System.h"
#define NR12 0x63
#define NR13 0x64 #define NR10 0x60
#define NR14 0x65 #define NR11 0x62
#define NR21 0x68 #define NR12 0x63
#define NR22 0x69 #define NR13 0x64
#define NR23 0x6c #define NR14 0x65
#define NR24 0x6d #define NR21 0x68
#define NR30 0x70 #define NR22 0x69
#define NR31 0x72 #define NR23 0x6c
#define NR32 0x73 #define NR24 0x6d
#define NR33 0x74 #define NR30 0x70
#define NR34 0x75 #define NR31 0x72
#define NR41 0x78 #define NR32 0x73
#define NR42 0x79 #define NR33 0x74
#define NR43 0x7c #define NR34 0x75
#define NR44 0x7d #define NR41 0x78
#define NR50 0x80 #define NR42 0x79
#define NR51 0x81 #define NR43 0x7c
#define NR52 0x84 #define NR44 0x7d
#define SGCNT0_H 0x82 #define NR50 0x80
#define FIFOA_L 0xa0 #define NR51 0x81
#define FIFOA_H 0xa2 #define NR52 0x84
#define FIFOB_L 0xa4 #define SGCNT0_H 0x82
#define FIFOB_H 0xa6 #define FIFOA_L 0xa0
#define FIFOA_H 0xa2
extern void soundTick(); #define FIFOB_L 0xa4
extern void soundShutdown(); #define FIFOB_H 0xa6
extern bool soundInit();
extern void soundPause(); void soundTick();
extern void soundResume(); void soundShutdown();
extern void soundEnable(int); bool soundInit();
extern void soundDisable(int); void soundPause();
extern int soundGetEnable(); void soundResume();
extern void soundReset(); void soundEnable(int);
extern void soundSaveGame(gzFile); void soundDisable(int);
extern void soundReadGame(gzFile, int); int soundGetEnable();
extern void soundEvent(u32, u8); void soundReset();
extern void soundEvent(u32, u16); void soundSaveGame(gzFile);
extern void soundTimerOverflow(int); void soundReadGame(gzFile, int);
extern void soundSetQuality(int); void soundEvent(u32, u8);
void soundEvent(u32, u16);
//extern int SOUND_TICKS; void soundTimerOverflow(int);
extern int SOUND_CLOCK_TICKS; void soundSetQuality(int);
extern int soundTicks;
extern int soundPaused; extern int SOUND_CLOCK_TICKS;
extern bool soundOffFlag; extern int soundTicks;
extern int soundQuality; extern int soundPaused;
extern int soundBufferLen; extern bool soundOffFlag;
extern int soundBufferTotalLen; extern int soundQuality;
extern u32 soundNextPosition; extern int soundBufferLen;
extern u16 soundFinalWave[1470]; extern int soundBufferTotalLen;
extern int soundVolume; extern u32 soundNextPosition;
extern u16 soundFinalWave[1470];
extern bool soundEcho; extern int soundVolume;
extern bool soundLowPass;
extern bool soundReverse; extern bool soundEcho;
extern bool soundLowPass;
#endif // VBA_SOUND_H extern bool soundReverse;
#endif // VBA_SOUND_H

View File

@ -1,32 +1,39 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "GBA.h" #include "agb/GBA.h"
#include "Flash.h" #include "Globals.h"
#include "Sram.h" #include "Flash.h"
#include "Sram.h"
u8 sramRead(u32 address)
{ u8 sramRead(u32 address)
return flashSaveMemory[address & 0xFFFF]; {
} return flashSaveMemory[address & 0xFFFF];
}
void sramWrite(u32 address, u8 byte) void sramDelayedWrite(u32 address, u8 byte)
{ {
flashSaveMemory[address & 0xFFFF] = byte; saveType = 1;
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED; cpuSaveGameFunc = sramWrite;
} sramWrite(address, byte);
}
void sramWrite(u32 address, u8 byte)
{
flashSaveMemory[address & 0xFFFF] = byte;
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
}

View File

@ -1,26 +1,27 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef VBA_SRAM_H #ifndef VBA_SRAM_H
#define VBA_SRAM_H #define VBA_SRAM_H
extern u8 sramRead(u32 address); extern u8 sramRead(u32 address);
extern void sramWrite(u32 address, u8 byte); extern void sramWrite(u32 address, u8 byte);
extern void sramDelayedWrite(u32 address, u8 byte);
#endif // VBA_SRAM_H
#endif // VBA_SRAM_H

View File

@ -1,127 +1,135 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef VBA_SYSTEM_H #ifndef VBA_SYSTEM_H
#define VBA_SYSTEM_H #define VBA_SYSTEM_H
#include "unzip.h" #include <stdint.h>
#include "unzip.h"
#ifndef NULL
#define NULL 0 #ifndef NULL
#endif #define NULL 0
#endif
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32; typedef uint8_t u8;
typedef uint16_t u16;
#ifdef _MSC_VER typedef uint32_t u32;
typedef unsigned __int64 u64; typedef uint64_t u64;
#else
typedef unsigned long long u64; typedef int8_t s8;
#endif typedef int16_t s16;
typedef int32_t s32;
typedef signed char s8; typedef int64_t s64;
typedef signed short s16;
typedef signed int s32;
#ifdef _MSC_VER typedef unsigned char u8;
typedef signed __int64 s64; typedef unsigned short u16;
#else typedef unsigned int u32;
typedef signed long long s64;
#endif struct EmulatedSystem {
// main emulation function
struct EmulatedSystem void (*emuMain)(int);
{ // reset emulator
// main emulation function void (*emuReset)();
void (*emuMain)(int); // clean up memory
// reset emulator void (*emuCleanUp)();
void (*emuReset)(); // load battery file
// clean up memory bool (*emuReadBattery)(const char *);
void (*emuCleanUp)(); // write battery file
// load battery file bool (*emuWriteBattery)(const char *);
bool (*emuReadBattery)(const char *); // load state
// write battery file bool (*emuReadState)(const char *);
bool (*emuWriteBattery)(const char *); // save state
// load state bool (*emuWriteState)(const char *);
bool (*emuReadState)(const char *); // load memory state (rewind)
// save state bool (*emuReadMemState)(char *, int);
bool (*emuWriteState)(const char *); // write memory state (rewind)
// load memory state (rewind) bool (*emuWriteMemState)(char *, int);
bool (*emuReadMemState)(char *, int); // write PNG file
// write memory state (rewind) bool (*emuWritePNG)(const char *);
bool (*emuWriteMemState)(char *, int); // write BMP file
// write PNG file bool (*emuWriteBMP)(const char *);
bool (*emuWritePNG)(const char *); // emulator update CPSR (ARM only)
// write BMP file void (*emuUpdateCPSR)();
bool (*emuWriteBMP)(const char *); // emulator has debugger
// emulator update CPSR (ARM only) bool emuHasDebugger;
void (*emuUpdateCPSR)(); // clock ticks to emulate
// emulator has debugger int emuCount;
bool emuHasDebugger; };
// clock ticks to emulate
int emuCount; extern void log(const char *,...);
};
extern bool systemPauseOnFrame();
extern void log(const char *,...); extern void systemGbPrint(u8 *,int,int,int,int);
extern void systemScreenCapture(int);
extern bool systemPauseOnFrame(); extern void systemDrawScreen();
extern void systemGbPrint(u8 *,int,int,int,int); // updates the joystick data
extern void systemScreenCapture(int); extern bool systemReadJoypads();
extern void systemDrawScreen(); // return information about the given joystick, -1 for default joystick
// updates the joystick data extern u32 systemReadJoypad(int);
extern bool systemReadJoypads(); extern u32 systemGetClock();
// return information about the given joystick, -1 for default joystick extern void systemMessage(int, const char *, ...);
extern u32 systemReadJoypad(int); extern void systemSetTitle(const char *);
extern u32 systemGetClock(); extern void systemWriteDataToSoundBuffer();
extern void systemMessage(int, const char *, ...); extern void systemSoundShutdown();
extern void systemSetTitle(const char *); extern void systemSoundPause();
extern void systemWriteDataToSoundBuffer(); extern void systemSoundResume();
extern void systemSoundShutdown(); extern void systemSoundReset();
extern void systemSoundPause(); extern bool systemSoundInit();
extern void systemSoundResume(); extern void systemScreenMessage(const char *);
extern void systemSoundReset(); extern void systemUpdateMotionSensor();
extern bool systemSoundInit(); extern int systemGetSensorX();
extern void systemScreenMessage(const char *); extern int systemGetSensorY();
extern void systemUpdateMotionSensor(); extern bool systemCanChangeSoundQuality();
extern int systemGetSensorX(); extern void systemShowSpeed(int);
extern int systemGetSensorY(); extern void system10Frames(int);
extern bool systemCanChangeSoundQuality(); extern void systemFrame();
extern void systemShowSpeed(int); extern void systemGbBorderOn();
extern void system10Frames(int);
extern void systemFrame(); extern void Sm60FPS_Init();
extern void systemGbBorderOn(); extern bool Sm60FPS_CanSkipFrame();
extern void Sm60FPS_Sleep();
extern bool systemSoundOn; extern void DbgMsg(const char *msg, ...);
extern u16 systemColorMap16[0x10000]; extern void winlog(const char *,...);
//extern u32 systemColorMap32[0x10000];
extern u32 *systemColorMap32; extern void (*dbgOutput)(const char *s, u32 addr);
extern u16 systemGbPalette[24]; extern void (*dbgSignal)(int sig,int number);
extern int systemRedShift;
extern int systemGreenShift; extern bool systemSoundOn; // old sound system
extern int systemBlueShift; extern u16 systemColorMap16[0x10000];
extern int systemColorDepth; //extern u32 systemColorMap32[0x10000];
extern int systemDebug; extern u32 *systemColorMap32;
extern int systemVerbose; extern u16 systemGbPalette[24];
extern int systemFrameSkip; extern int systemRedShift;
extern int systemSaveUpdateCounter; extern int systemGreenShift;
extern int systemBlueShift;
#define SYSTEM_SAVE_UPDATED 30 extern int systemColorDepth;
#define SYSTEM_SAVE_NOT_UPDATED 0 extern int systemDebug;
extern int systemVerbose;
#endif //VBA_SYSTEM_H extern int systemFrameSkip;
extern int systemSaveUpdateCounter;
extern int systemSpeed;
extern int systemThrottle;
#define SYSTEM_SAVE_UPDATED 30
#define SYSTEM_SAVE_NOT_UPDATED 0
#endif //VBA_SYSTEM_H

View File

@ -1,180 +0,0 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2002 Ben Parnell
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Code originally from fceu/drawing.h file, adapted by Forgotten
*/
#include "System.h"
extern int RGB_LOW_BITS_MASK;
static const u8 fontdata2[2048] =
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x81,0xa5,0x81,0xbd,0x99,0x81,0x7e,0x7e,0xff,0xdb,0xff,0xc3,0xe7,0xff,0x7e,0x36,0x7f,0x7f,0x7f,0x3e,0x1c,0x08,0x00,0x08,0x1c,0x3e,0x7f,0x3e,0x1c,0x08,0x00,0x1c,0x3e,0x1c,0x7f,0x7f,0x3e,0x1c,0x3e,0x08,0x08,0x1c,0x3e,0x7f,0x3e,0x1c,0x3e,0x00,0x00,0x18,0x3c,0x3c,0x18,0x00,0x00,0xff,0xff,0xe7,0xc3,0xc3,0xe7,0xff,0xff,0x00,0x3c,0x66,0x42,0x42,0x66,0x3c,0x00,0xff,0xc3,0x99,0xbd,0xbd,0x99,0xc3,0xff,0xf0,0xe0,0xf0,0xbe,0x33,0x33,0x33,0x1e,0x3c,0x66,0x66,0x66,0x3c,0x18,0x7e,0x18,0xfc,0xcc,0xfc,0x0c,0x0c,0x0e,0x0f,0x07,0xfe,0xc6,0xfe,0xc6,0xc6,0xe6,0x67,0x03,0x99,0x5a,0x3c,0xe7,0xe7,0x3c,0x5a,0x99,0x01,0x07,0x1f,0x7f,0x1f,0x07,0x01,0x00,0x40,0x70,0x7c,0x7f,0x7c,0x70,0x40,0x00,0x18,0x3c,0x7e,0x18,0x18,0x7e,0x3c,0x18,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x00,0xfe,0xdb,0xdb,0xde,0xd8,0xd8,0xd8,0x00,0x7c,0xc6,0x1c,0x36,0x36,0x1c,0x33,0x1e,0x00,0x00,0x00,0x00,0x7e,0x7e,0x7e,0x00,0x18,0x3c,0x7e,0x18,0x7e,0x3c,0x18,0xff,0x18,0x3c,0x7e,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x18,0x30,0x7f,0x30,0x18,0x00,0x00,0x00,0x0c,0x06,0x7f,0x06,0x0c,0x00,0x00,0x00,0x00,0x03,0x03,0x03,0x7f,0x00,0x00,0x00,0x24,0x66,0xff,0x66,0x24,0x00,0x00,0x00,0x18,0x3c,0x7e,0xff,0xff,0x00,0x00,0x00,0xff,0xff,0x7e,0x3c,0x18,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x1e,0x1e,0x0c,0x0c,0x00,0x0c,0x00,0x36,0x36,0x36,0x00,0x00,0x00,0x00,0x00,0x36,0x36,0x7f,0x36,0x7f,0x36,0x36,0x00,0x0c,0x3e,0x03,0x1e,0x30,0x1f,0x0c,0x00,0x00,0x63,0x33,0x18,0x0c,0x66,0x63,0x00,0x1c,0x36,0x1c,0x6e,0x3b,0x33,0x6e,0x00,0x06,0x06,0x03,0x00,0x00,0x00,0x00,0x00,0x18,0x0c,0x06,0x06,0x06,0x0c,0x18,0x00,0x06,0x0c,0x18,0x18,0x18,0x0c,0x06,0x00,0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00,0x00,0x0c,0x0c,0x3f,0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x0c,0x06,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x0c,0x00,0x60,0x30,0x18,0x0c,0x06,0x03,0x01,0x00,0x3e,0x63,0x73,0x7b,0x6f,0x67,0x3e,0x00,0x0c,0x0e,0x0c,0x0c,0x0c,0x0c,0x3f,0x00,0x1e,0x33,0x30,0x1c,0x06,0x33,0x3f,0x00,0x1e,0x33,0x30,0x1c,0x30,0x33,0x1e,0x00,0x38,0x3c,0x36,0x33,0x7f,0x30,0x78,0x00,0x3f,0x03,0x1f,0x30,0x30,0x33,0x1e,0x00,0x1c,0x06,0x03,0x1f,0x33,0x33,0x1e,0x00,0x3f,0x33,0x30,0x18,0x0c,0x0c,0x0c,0x00,0x1e,0x33,0x33,0x1e,0x33,0x33,0x1e,0x00,0x1e,0x33,0x33,0x3e,0x30,0x18,0x0e,0x00,0x00,0x0c,0x0c,0x00,0x00,0x0c,0x0c,0x00,0x00,0x0c,0x0c,0x00,0x00,0x0c,0x0c,0x06,0x18,0x0c,0x06,0x03,0x06,0x0c,0x18,0x00,0x00,0x00,0x3f,0x00,0x00,0x3f,0x00,0x00,0x06,0x0c,0x18,0x30,0x18,0x0c,0x06,0x00,0x1e,0x33,0x30,0x18,0x0c,0x00,0x0c,0x00,
0x3e,0x63,0x7b,0x7b,0x7b,0x03,0x1e,0x00,0x0c,0x1e,0x33,0x33,0x3f,0x33,0x33,0x00,0x3f,0x66,0x66,0x3e,0x66,0x66,0x3f,0x00,0x3c,0x66,0x03,0x03,0x03,0x66,0x3c,0x00,0x1f,0x36,0x66,0x66,0x66,0x36,0x1f,0x00,0x7f,0x46,0x16,0x1e,0x16,0x46,0x7f,0x00,0x7f,0x46,0x16,0x1e,0x16,0x06,0x0f,0x00,0x3c,0x66,0x03,0x03,0x73,0x66,0x7c,0x00,0x33,0x33,0x33,0x3f,0x33,0x33,0x33,0x00,0x1e,0x0c,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x78,0x30,0x30,0x30,0x33,0x33,0x1e,0x00,0x67,0x66,0x36,0x1e,0x36,0x66,0x67,0x00,0x0f,0x06,0x06,0x06,0x46,0x66,0x7f,0x00,0x63,0x77,0x7f,0x7f,0x6b,0x63,0x63,0x00,0x63,0x67,0x6f,0x7b,0x73,0x63,0x63,0x00,0x1c,0x36,0x63,0x63,0x63,0x36,0x1c,0x00,0x3f,0x66,0x66,0x3e,0x06,0x06,0x0f,0x00,0x1e,0x33,0x33,0x33,0x3b,0x1e,0x38,0x00,0x3f,0x66,0x66,0x3e,0x36,0x66,0x67,0x00,0x1e,0x33,0x07,0x0e,0x38,0x33,0x1e,0x00,0x3f,0x2d,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x33,0x33,0x33,0x33,0x33,0x33,0x3f,0x00,0x33,0x33,0x33,0x33,0x33,0x1e,0x0c,0x00,0x63,0x63,0x63,0x6b,0x7f,0x77,0x63,0x00,0x63,0x63,0x36,0x1c,0x1c,0x36,0x63,0x00,0x33,0x33,0x33,0x1e,0x0c,0x0c,0x1e,0x00,0x7f,0x63,0x31,0x18,0x4c,0x66,0x7f,0x00,0x1e,0x06,0x06,0x06,0x06,0x06,0x1e,0x00,0x03,0x06,0x0c,0x18,0x30,0x60,0x40,0x00,0x1e,0x18,0x18,0x18,0x18,0x18,0x1e,0x00,0x08,0x1c,0x36,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,
0x0c,0x0c,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x30,0x3e,0x33,0x6e,0x00,0x07,0x06,0x06,0x3e,0x66,0x66,0x3b,0x00,0x00,0x00,0x1e,0x33,0x03,0x33,0x1e,0x00,0x38,0x30,0x30,0x3e,0x33,0x33,0x6e,0x00,0x00,0x00,0x1e,0x33,0x3f,0x03,0x1e,0x00,0x1c,0x36,0x06,0x0f,0x06,0x06,0x0f,0x00,0x00,0x00,0x6e,0x33,0x33,0x3e,0x30,0x1f,0x07,0x06,0x36,0x6e,0x66,0x66,0x67,0x00,0x0c,0x00,0x0e,0x0c,0x0c,0x0c,0x1e,0x00,0x30,0x00,0x30,0x30,0x30,0x33,0x33,0x1e,0x07,0x06,0x66,0x36,0x1e,0x36,0x67,0x00,0x0e,0x0c,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x33,0x7f,0x7f,0x6b,0x63,0x00,0x00,0x00,0x1f,0x33,0x33,0x33,0x33,0x00,0x00,0x00,0x1e,0x33,0x33,0x33,0x1e,0x00,0x00,0x00,0x3b,0x66,0x66,0x3e,0x06,0x0f,0x00,0x00,0x6e,0x33,0x33,0x3e,0x30,0x78,0x00,0x00,0x3b,0x6e,0x66,0x06,0x0f,0x00,0x00,0x00,0x3e,0x03,0x1e,0x30,0x1f,0x00,0x08,0x0c,0x3e,0x0c,0x0c,0x2c,0x18,0x00,0x00,0x00,0x33,0x33,0x33,0x33,0x6e,0x00,0x00,0x00,0x33,0x33,0x33,0x1e,0x0c,0x00,0x00,0x00,0x63,0x6b,0x7f,0x7f,0x36,0x00,0x00,0x00,0x63,0x36,0x1c,0x36,0x63,0x00,0x00,0x00,0x33,0x33,0x33,0x3e,0x30,0x1f,0x00,0x00,0x3f,0x19,0x0c,0x26,0x3f,0x00,0x38,0x0c,0x0c,0x07,0x0c,0x0c,0x38,0x00,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x00,0x07,0x0c,0x0c,0x38,0x0c,0x0c,0x07,0x00,0x6e,0x3b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x1c,0x36,0x63,0x63,0x7f,0x00,
0x1e,0x33,0x03,0x33,0x1e,0x18,0x30,0x1e,0x00,0x33,0x00,0x33,0x33,0x33,0x7e,0x00,0x38,0x00,0x1e,0x33,0x3f,0x03,0x1e,0x00,0x7e,0xc3,0x3c,0x60,0x7c,0x66,0xfc,0x00,0x33,0x00,0x1e,0x30,0x3e,0x33,0x7e,0x00,0x07,0x00,0x1e,0x30,0x3e,0x33,0x7e,0x00,0x0c,0x0c,0x1e,0x30,0x3e,0x33,0x7e,0x00,0x00,0x00,0x1e,0x03,0x03,0x1e,0x30,0x1c,0x7e,0xc3,0x3c,0x66,0x7e,0x06,0x3c,0x00,0x33,0x00,0x1e,0x33,0x3f,0x03,0x1e,0x00,0x07,0x00,0x1e,0x33,0x3f,0x03,0x1e,0x00,0x33,0x00,0x0e,0x0c,0x0c,0x0c,0x1e,0x00,0x3e,0x63,0x1c,0x18,0x18,0x18,0x3c,0x00,0x07,0x00,0x0e,0x0c,0x0c,0x0c,0x1e,0x00,0x63,0x1c,0x36,0x63,0x7f,0x63,0x63,0x00,0x0c,0x0c,0x00,0x1e,0x33,0x3f,0x33,0x00,0x38,0x00,0x3f,0x06,0x1e,0x06,0x3f,0x00,0x00,0x00,0xfe,0x30,0xfe,0x33,0xfe,0x00,0x7c,0x36,0x33,0x7f,0x33,0x33,0x73,0x00,0x1e,0x33,0x00,0x1e,0x33,0x33,0x1e,0x00,0x00,0x33,0x00,0x1e,0x33,0x33,0x1e,0x00,0x00,0x07,0x00,0x1e,0x33,0x33,0x1e,0x00,0x1e,0x33,0x00,0x33,0x33,0x33,0x7e,0x00,0x00,0x07,0x00,0x33,0x33,0x33,0x7e,0x00,0x00,0x33,0x00,0x33,0x33,0x3e,0x30,0x1f,0xc3,0x18,0x3c,0x66,0x66,0x3c,0x18,0x00,0x33,0x00,0x33,0x33,0x33,0x33,0x1e,0x00,0x18,0x18,0x7e,0x03,0x03,0x7e,0x18,0x18,0x1c,0x36,0x26,0x0f,0x06,0x67,0x3f,0x00,0x33,0x33,0x1e,0x3f,0x0c,0x3f,0x0c,0x0c,0x1f,0x33,0x33,0x5f,0x63,0xf3,0x63,0xe3,0x70,0xd8,0x18,0x3c,0x18,0x18,0x1b,0x0e,
0x38,0x00,0x1e,0x30,0x3e,0x33,0x7e,0x00,0x1c,0x00,0x0e,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x38,0x00,0x1e,0x33,0x33,0x1e,0x00,0x00,0x38,0x00,0x33,0x33,0x33,0x7e,0x00,0x00,0x1f,0x00,0x1f,0x33,0x33,0x33,0x00,0x3f,0x00,0x33,0x37,0x3f,0x3b,0x33,0x00,0x3c,0x36,0x36,0x7c,0x00,0x7e,0x00,0x00,0x1c,0x36,0x36,0x1c,0x00,0x3e,0x00,0x00,0x0c,0x00,0x0c,0x06,0x03,0x33,0x1e,0x00,0x00,0x00,0x00,0x3f,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x3f,0x30,0x30,0x00,0x00,0xc3,0x63,0x33,0x7b,0xcc,0x66,0x33,0xf0,0xc3,0x63,0x33,0xdb,0xec,0xf6,0xf3,0xc0,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x00,0x00,0xcc,0x66,0x33,0x66,0xcc,0x00,0x00,0x00,0x33,0x66,0xcc,0x66,0x33,0x00,0x00,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xdb,0xee,0xdb,0x77,0xdb,0xee,0xdb,0x77,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x18,0x18,0x18,0x6c,0x6c,0x6c,0x6c,0x6f,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00,0x7f,0x6c,0x6c,0x6c,0x00,0x00,0x1f,0x18,0x1f,0x18,0x18,0x18,0x6c,0x6c,0x6f,0x60,0x6f,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x7f,0x60,0x6f,0x6c,0x6c,0x6c,0x6c,0x6c,0x6f,0x60,0x7f,0x00,0x00,0x00,0x6c,0x6c,0x6c,0x6c,0x7f,0x00,0x00,0x00,0x18,0x18,0x1f,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x18,0x18,
0x18,0x18,0x18,0x18,0xf8,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x18,0x18,0x18,0x6c,0x6c,0x6c,0x6c,0xec,0x6c,0x6c,0x6c,0x6c,0x6c,0xec,0x0c,0xfc,0x00,0x00,0x00,0x00,0x00,0xfc,0x0c,0xec,0x6c,0x6c,0x6c,0x6c,0x6c,0xef,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xef,0x6c,0x6c,0x6c,0x6c,0x6c,0xec,0x0c,0xec,0x6c,0x6c,0x6c,0x00,0x00,0xff,0x00,0xff,0x00,0x00,0x00,0x6c,0x6c,0xef,0x00,0xef,0x6c,0x6c,0x6c,0x18,0x18,0xff,0x00,0xff,0x00,0x00,0x00,0x6c,0x6c,0x6c,0x6c,0xff,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0xff,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0xfc,0x00,0x00,0x00,0x18,0x18,0xf8,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0xf8,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0xfc,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0xff,0x6c,0x6c,0x6c,0x18,0x18,0xff,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0x18,0x18,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
0x00,0x00,0x6e,0x3b,0x13,0x3b,0x6e,0x00,0x00,0x1e,0x33,0x1f,0x33,0x1f,0x03,0x03,0x00,0x3f,0x33,0x03,0x03,0x03,0x03,0x00,0x00,0x7f,0x36,0x36,0x36,0x36,0x36,0x00,0x3f,0x33,0x06,0x0c,0x06,0x33,0x3f,0x00,0x00,0x00,0x7e,0x1b,0x1b,0x1b,0x0e,0x00,0x00,0x66,0x66,0x66,0x66,0x3e,0x06,0x03,0x00,0x6e,0x3b,0x18,0x18,0x18,0x18,0x00,0x3f,0x0c,0x1e,0x33,0x33,0x1e,0x0c,0x3f,0x1c,0x36,0x63,0x7f,0x63,0x36,0x1c,0x00,0x1c,0x36,0x63,0x63,0x36,0x36,0x77,0x00,0x38,0x0c,0x18,0x3e,0x33,0x33,0x1e,0x00,0x00,0x00,0x7e,0xdb,0xdb,0x7e,0x00,0x00,0x60,0x30,0x7e,0xdb,0xdb,0x7e,0x06,0x03,0x1c,0x06,0x03,0x1f,0x03,0x06,0x1c,0x00,0x1e,0x33,0x33,0x33,0x33,0x33,0x33,0x00,0x00,0x3f,0x00,0x3f,0x00,0x3f,0x00,0x00,0x0c,0x0c,0x3f,0x0c,0x0c,0x00,0x3f,0x00,0x06,0x0c,0x18,0x0c,0x06,0x00,0x3f,0x00,0x18,0x0c,0x06,0x0c,0x18,0x00,0x3f,0x00,0x70,0xd8,0xd8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1b,0x1b,0x0e,0x0c,0x0c,0x00,0x3f,0x00,0x0c,0x0c,0x00,0x00,0x6e,0x3b,0x00,0x6e,0x3b,0x00,0x00,0x1c,0x36,0x36,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0xf0,0x30,0x30,0x30,0x37,0x36,0x3c,0x38,0x1e,0x36,0x36,0x36,0x36,0x00,0x00,0x00,0x0e,0x18,0x0c,0x06,0x1e,0x00,0x00,0x00,0x00,0x00,0x3c,0x3c,0x3c,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
static void drawTextInternal(u8 *screen, int pitch, int x, int y,
const char *string, bool trans)
{
screen += y*pitch;
int inc = 2;
switch(systemColorDepth)
{
case 24:
inc = 3;
break;
case 32:
inc = 4;
break;
}
screen += x*inc;
switch(systemColorDepth)
{
case 16:
{
while(*string)
{
char c = *string++;
u8 *scr = screen;
u16 mask = ~RGB_LOW_BITS_MASK;
int h, w;
u16 *s = (u16 *)scr;
for (h = 0; h < 8; h++)
{
for (w = 0; w < 8; w++, s++)
{
int on = (fontdata2[(c<<3)+h]>>w)&1;
if(trans)
{
if(on)
*s = ((0xf) << systemRedShift) +
((*s & mask) >>1);
}
else
{
if(on)
*s = (0x1f) << systemRedShift;
}
}
scr += pitch;
s = (u16 *)scr;
}
screen += inc*8;
}
}
break;
case 24:
{
while(*string)
{
char c = *string++;
u8 *scr = screen;
int h, w;
u8 *s = (u8 *)scr;
for (h = 0; h < 8; h++)
{
for (w = 0; w < 8; w++, s+=3)
{
int on = (fontdata2[(c<<3)+h]>>w)&1;
if(trans)
{
if(on)
{
u32 color = (0x1f) << systemRedShift;
*s = ((color & 255)>>1)+(*s>>1);
*(s+1) = (((color >> 8) & 255)>>1)+(*(s+1)>>1);
*(s+2) = (((color >> 16) & 255)>>1)+(*(s+2)>>1);
}
}
else
{
if(on)
{
u32 color = (0x1f) << systemRedShift;
*s = (color & 255);
*(s+1) = (color >> 8) & 255;
*(s+2) = (color >> 16) & 255;
}
}
}
scr += pitch;
s = (u8 *)scr;
}
screen += inc*8;
}
}
break;
case 32:
{
while(*string)
{
char c = *string++;
u8 *scr = screen;
int h, w;
u32 mask = 0xfefefe;
u32 *s = (u32 *)scr;
for (h = 0; h < 8; h++)
{
for (w = 0; w < 8; w++, s++)
{
int on = (fontdata2[(c<<3)+h]>>w)&1;
if(trans)
{
if(on)
*s = ((0xf) << systemRedShift) + ((*s & mask)>>1);
}
else
{
if(on)
*s = (0x1f) << systemRedShift;
}
}
scr += pitch;
s = (u32 *)scr;
}
screen += inc*8;
}
}
break;
}
}
void drawText(u8 *screen, int pitch, int x, int y, const char *string)
{
drawTextInternal(screen, pitch, x, y, string, false);
}
void drawTextTransp(u8 *screen, int pitch, int x, int y, const char *string)
{
drawTextInternal(screen, pitch, x, y, string, true);
}

View File

@ -1,21 +0,0 @@
// -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
extern void drawText(u8 *, int, int, int, const char *);
extern void drawTextTransp(u8 *, int, int, int, const char *);

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,9 @@
#ifndef VBA_UTIL_H #ifndef VBA_UTIL_H
#define VBA_UTIL_H #define VBA_UTIL_H
#include "System.h"
enum IMAGE_TYPE { enum IMAGE_TYPE {
IMAGE_UNKNOWN = -1, IMAGE_UNKNOWN = -1,
IMAGE_GBA = 0, IMAGE_GBA = 0,
@ -27,40 +30,38 @@ enum IMAGE_TYPE {
// save game // save game
typedef struct typedef struct {
{ void *address;
void *address; int size;
int size; } variable_desc;
}
variable_desc;
extern bool utilWritePNGFile(const char *, int, int, u8 *); extern bool utilWritePNGFile(const char *, int, int, u8 *);
extern bool utilWriteBMPFile(const char *, int, int, u8 *); extern bool utilWriteBMPFile(const char *, int, int, u8 *);
extern void utilApplyIPS(const char *ips, u8 **rom, int *size); extern void utilApplyIPS(const char *ips, u8 **rom, int *size);
extern void utilWriteBMP(char *, int, int, u8 *);
extern bool utilIsGBAImage(const char *); extern bool utilIsGBAImage(const char *);
extern bool utilIsGBImage(const char *); extern bool utilIsGBImage(const char *);
extern bool utilIsZipFile(const char *);
extern bool utilIsGzipFile(const char *); extern bool utilIsGzipFile(const char *);
extern bool utilIsRarFile(const char *); extern void utilStripDoubleExtension(const char *, char *);
extern void utilGetBaseName(const char *, char *);
extern IMAGE_TYPE utilFindType(const char *); extern IMAGE_TYPE utilFindType(const char *);
extern u8 *utilLoad(const char *, extern u8 *utilLoad(const char *,
bool (*)(const char*), bool (*)(const char*),
u8 *, u8 *,
int &); int &);
extern void utilPutDword(u8 *, u32); extern void utilPutDword(u8 *, u32);
extern void utilPutWord(u8 *, u16); extern void utilPutWord(u8 *, u16);
extern void utilWriteData(gzFile, variable_desc *); extern void utilWriteData(gzFile, variable_desc *);
extern void utilReadData(gzFile, variable_desc *); extern void utilReadData(gzFile, variable_desc *);
extern void utilReadDataSkip(gzFile, variable_desc *);
extern int utilReadInt(gzFile); extern int utilReadInt(gzFile);
extern void utilWriteInt(gzFile, int); extern void utilWriteInt(gzFile, int);
extern gzFile utilGzOpen(const char *file, const char *mode); extern gzFile utilGzOpen(const char *file, const char *mode);
extern gzFile utilMemGzOpen(char *memory, int available, char *mode); extern gzFile utilMemGzOpen(char *memory, int available, const char *mode);
extern int utilGzWrite(gzFile file, const voidp buffer, unsigned int len); extern int utilGzWrite(gzFile file, const voidp buffer, unsigned int len);
extern int utilGzRead(gzFile file, voidp buffer, unsigned int len); extern int utilGzRead(gzFile file, voidp buffer, unsigned int len);
extern int utilGzClose(gzFile file); extern int utilGzClose(gzFile file);
extern z_off_t utilGzSeek(gzFile file, z_off_t offset, int whence);
extern long utilGzMemTell(gzFile file); extern long utilGzMemTell(gzFile file);
extern void utilGBAFindSave(const u8 *, const int); extern void utilGBAFindSave(const u8 *, const int);
extern void utilUpdateSystemColorMaps();
#endif #endif

File diff suppressed because it is too large Load Diff

2967
source/vba/agb/GBA-arm.cpp Normal file

File diff suppressed because it is too large Load Diff

2343
source/vba/agb/GBA-thumb.cpp Normal file

File diff suppressed because it is too large Load Diff

3994
source/vba/agb/GBA.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,153 +1,160 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef VBA_GBA_H #ifndef VBA_GBA_H
#define VBA_GBA_H #define VBA_GBA_H
#include "System.h" #include "../System.h"
#define SAVE_GAME_VERSION_1 1 #define SAVE_GAME_VERSION_1 1
#define SAVE_GAME_VERSION_2 2 #define SAVE_GAME_VERSION_2 2
#define SAVE_GAME_VERSION_3 3 #define SAVE_GAME_VERSION_3 3
#define SAVE_GAME_VERSION_4 4 #define SAVE_GAME_VERSION_4 4
#define SAVE_GAME_VERSION_5 5 #define SAVE_GAME_VERSION_5 5
#define SAVE_GAME_VERSION_6 6 #define SAVE_GAME_VERSION_6 6
#define SAVE_GAME_VERSION_7 7 #define SAVE_GAME_VERSION_7 7
#define SAVE_GAME_VERSION_8 8 #define SAVE_GAME_VERSION_8 8
#define SAVE_GAME_VERSION SAVE_GAME_VERSION_8 #define SAVE_GAME_VERSION_9 9
#define SAVE_GAME_VERSION_10 10
typedef struct #define SAVE_GAME_VERSION SAVE_GAME_VERSION_10
{
u8 *address; typedef struct {
u32 mask; u8 *address;
} u32 mask;
memoryMap; } memoryMap;
typedef union { typedef union {
struct struct {
{ #ifdef WORDS_BIGENDIAN
#ifdef WORDS_BIGENDIAN u8 B3;
u8 B3; u8 B2;
u8 B2; u8 B1;
u8 B1; u8 B0;
u8 B0; #else
#else u8 B0;
u8 B0; u8 B1;
u8 B1; u8 B2;
u8 B2; u8 B3;
u8 B3; #endif
#endif } B;
} struct {
B; #ifdef WORDS_BIGENDIAN
struct u16 W1;
{ u16 W0;
#ifdef WORDS_BIGENDIAN #else
u16 W1; u16 W0;
u16 W0; u16 W1;
#else #endif
u16 W0; } W;
u16 W1; #ifdef WORDS_BIGENDIAN
#endif volatile u32 I;
} #else
W; u32 I;
#ifdef WORDS_BIGENDIAN #endif
volatile u32 I; } reg_pair;
#else
u32 I; #ifndef NO_GBA_MAP
#endif extern memoryMap map[256];
} reg_pair; #endif
#ifndef NO_GBA_MAP extern reg_pair reg[45];
extern memoryMap map[256]; extern u8 biosProtected[4];
#endif
extern bool N_FLAG;
extern reg_pair reg[45]; extern bool Z_FLAG;
extern u8 biosProtected[4]; extern bool C_FLAG;
extern bool V_FLAG;
extern bool N_FLAG; extern bool armIrqEnable;
extern bool Z_FLAG; extern bool armState;
extern bool C_FLAG; extern int armMode;
extern bool V_FLAG; extern void (*cpuSaveGameFunc)(u32,u8);
extern bool armIrqEnable;
extern bool armState; #ifdef BKPT_SUPPORT
extern int armMode; extern u8 freezeWorkRAM[0x40000];
extern void (*cpuSaveGameFunc)(u32,u8); extern u8 freezeInternalRAM[0x8000];
extern u8 freezeVRAM[0x18000];
extern bool freezeWorkRAM[0x40000]; extern u8 freezeOAM[0x400];
extern bool freezeInternalRAM[0x8000]; extern u8 freezePRAM[0x400];
extern bool CPUReadGSASnapshot(const char *); extern bool debugger_last;
extern bool CPUWriteGSASnapshot(const char *, const char *, const char *, const char *); extern int oldreg[17];
extern bool CPUWriteBatteryFile(const char *); extern char oldbuffer[10];
extern bool CPUReadBatteryFile(const char *); #endif
extern bool CPUExportEepromFile(const char *);
extern bool CPUImportEepromFile(const char *); extern bool CPUReadGSASnapshot(const char *);
extern bool CPUWritePNGFile(const char *); extern bool CPUWriteGSASnapshot(const char *, const char *, const char *, const char *);
extern bool CPUWriteBMPFile(const char *); extern bool CPUWriteBatteryFile(const char *);
extern void CPUCleanUp(); extern bool CPUReadBatteryFile(const char *);
extern void CPUUpdateRender(); extern bool CPUExportEepromFile(const char *);
extern bool CPUReadMemState(char *, int); extern bool CPUImportEepromFile(const char *);
extern bool CPUReadState(const char *); extern bool CPUWritePNGFile(const char *);
extern bool CPUWriteMemState(char *, int); extern bool CPUWriteBMPFile(const char *);
extern bool CPUWriteState(const char *); extern void CPUCleanUp();
extern int CPULoadRom(const char *); extern void CPUUpdateRender();
extern void CPUUpdateRegister(u32, u16); extern void CPUUpdateRenderBuffers(bool);
extern void CPUWriteHalfWord(u32, u16); extern bool CPUReadMemState(char *, int);
extern void CPUWriteByte(u32, u8); extern bool CPUReadState(const char *);
extern void CPUInit(const char *,bool); extern bool CPUWriteMemState(char *, int);
extern void CPUReset(); extern bool CPUWriteState(const char *);
extern void CPULoop(int); extern int CPULoadRom(const char *);
extern void CPUCheckDMA(int,int); extern void doMirroring(bool);
extern bool CPUIsGBAImage(const char *); extern void CPUUpdateRegister(u32, u16);
extern bool CPUIsZipFile(const char *); extern void applyTimer ();
#ifdef PROFILING extern void CPUInit(const char *,bool);
extern void cpuProfil(char *buffer, int, u32, int); extern void CPUReset();
extern void cpuEnableProfiling(int hz); extern void CPULoop(int);
#endif extern void CPUCheckDMA(int,int);
extern bool CPUIsGBAImage(const char *);
extern struct EmulatedSystem GBASystem; extern bool CPUIsZipFile(const char *);
#ifdef PROFILING
#define R13_IRQ 18 #include "prof/prof.h"
#define R14_IRQ 19 extern void cpuProfil(profile_segment *seg);
#define SPSR_IRQ 20 extern void cpuEnableProfiling(int hz);
#define R13_USR 26 #endif
#define R14_USR 27
#define R13_SVC 28 extern struct EmulatedSystem GBASystem;
#define R14_SVC 29
#define SPSR_SVC 30 #define R13_IRQ 18
#define R13_ABT 31 #define R14_IRQ 19
#define R14_ABT 32 #define SPSR_IRQ 20
#define SPSR_ABT 33 #define R13_USR 26
#define R13_UND 34 #define R14_USR 27
#define R14_UND 35 #define R13_SVC 28
#define SPSR_UND 36 #define R14_SVC 29
#define R8_FIQ 37 #define SPSR_SVC 30
#define R9_FIQ 38 #define R13_ABT 31
#define R10_FIQ 39 #define R14_ABT 32
#define R11_FIQ 40 #define SPSR_ABT 33
#define R12_FIQ 41 #define R13_UND 34
#define R13_FIQ 42 #define R14_UND 35
#define R14_FIQ 43 #define SPSR_UND 36
#define SPSR_FIQ 44 #define R8_FIQ 37
#define R9_FIQ 38
#include "Cheats.h" #define R10_FIQ 39
#include "Globals.h" #define R11_FIQ 40
#include "EEprom.h" #define R12_FIQ 41
#include "Flash.h" #define R13_FIQ 42
#define R14_FIQ 43
#endif //VBA_GBA_H #define SPSR_FIQ 44
#include "../Cheats.h"
#include "../Globals.h"
#include "../EEprom.h"
#include "../Flash.h"
#endif //VBA_GBA_H

View File

@ -1,47 +1,47 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "System.h" #include "../System.h"
int coeff[32] = { int coeff[32] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}; 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
u32 line0[240];
u32 line0[240]; u32 line1[240];
u32 line1[240]; u32 line2[240];
u32 line2[240]; u32 line3[240];
u32 line3[240]; u32 lineOBJ[240];
u32 lineOBJ[240]; u32 lineOBJWin[240];
u32 lineOBJWin[240]; u32 lineMix[240];
u32 lineMix[240]; bool gfxInWin0[240];
bool gfxInWin0[240]; bool gfxInWin1[240];
bool gfxInWin1[240]; int lineOBJpixleft[128];
int gfxBG2Changed = 0; int gfxBG2Changed = 0;
int gfxBG3Changed = 0; int gfxBG3Changed = 0;
int gfxBG2X = 0; int gfxBG2X = 0;
int gfxBG2Y = 0; int gfxBG2Y = 0;
int gfxBG2LastX = 0; int gfxBG2LastX = 0;
int gfxBG2LastY = 0; int gfxBG2LastY = 0;
int gfxBG3X = 0; int gfxBG3X = 0;
int gfxBG3Y = 0; int gfxBG3Y = 0;
int gfxBG3LastX = 0; int gfxBG3LastX = 0;
int gfxBG3LastY = 0; int gfxBG3LastY = 0;
int gfxLastVCOUNT = 0; int gfxLastVCOUNT = 0;

1601
source/vba/agb/GBAGfx.h Normal file

File diff suppressed because it is too large Load Diff

302
source/vba/agb/GBAcpu.h Normal file
View File

@ -0,0 +1,302 @@
// -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef VBA_GBAcpu_H
#define VBA_GBAcpu_H
extern int armExecute();
extern int thumbExecute();
#ifdef __GNUC__
# define INSN_REGPARM __attribute__((regparm(1)))
# define LIKELY(x) __builtin_expect(!!(x),1)
# define UNLIKELY(x) __builtin_expect(!!(x),0)
#else
# define INSN_REGPARM /*nothing*/
# define LIKELY(x) (x)
# define UNLIKELY(x) (x)
#endif
#define UPDATE_REG(address, value)\
{\
WRITE16LE(((u16 *)&ioMem[address]),value);\
}\
#define ARM_PREFETCH \
{\
cpuPrefetch[0] = CPUReadMemoryQuick(armNextPC);\
cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC+4);\
}
#define THUMB_PREFETCH \
{\
cpuPrefetch[0] = CPUReadHalfWordQuick(armNextPC);\
cpuPrefetch[1] = CPUReadHalfWordQuick(armNextPC+2);\
}
#define ARM_PREFETCH_NEXT \
cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC+4);
#define THUMB_PREFETCH_NEXT\
cpuPrefetch[1] = CPUReadHalfWordQuick(armNextPC+2);
extern int SWITicks;
extern u32 mastercode;
extern bool busPrefetch;
extern bool busPrefetchEnable;
extern u32 busPrefetchCount;
extern int cpuNextEvent;
extern bool holdState;
extern u32 cpuPrefetch[2];
extern int cpuTotalTicks;
extern u8 memoryWait[16];
extern u8 memoryWait32[16];
extern u8 memoryWaitSeq[16];
extern u8 memoryWaitSeq32[16];
extern u8 cpuBitsSet[256];
extern u8 cpuLowestBitSet[256];
extern void CPUSwitchMode(int mode, bool saveState, bool breakLoop);
extern void CPUSwitchMode(int mode, bool saveState);
extern void CPUUpdateCPSR();
extern void CPUUpdateFlags(bool breakLoop);
extern void CPUUpdateFlags();
extern void CPUUndefinedException();
extern void CPUSoftwareInterrupt();
extern void CPUSoftwareInterrupt(int comment);
// Waitstates when accessing data
inline int dataTicksAccess16(u32 address) // DATA 8/16bits NON SEQ
{
int addr = (address>>24)&15;
int value = memoryWait[addr];
if ((addr>=0x08) || (addr < 0x02))
{
busPrefetchCount=0;
busPrefetch=false;
}
else if (busPrefetch)
{
int waitState = value;
if (!waitState)
waitState = 1;
busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
}
return value;
}
inline int dataTicksAccess32(u32 address) // DATA 32bits NON SEQ
{
int addr = (address>>24)&15;
int value = memoryWait32[addr];
if ((addr>=0x08) || (addr < 0x02))
{
busPrefetchCount=0;
busPrefetch=false;
}
else if (busPrefetch)
{
int waitState = value;
if (!waitState)
waitState = 1;
busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
}
return value;
}
inline int dataTicksAccessSeq16(u32 address)// DATA 8/16bits SEQ
{
int addr = (address>>24)&15;
int value = memoryWaitSeq[addr];
if ((addr>=0x08) || (addr < 0x02))
{
busPrefetchCount=0;
busPrefetch=false;
}
else if (busPrefetch)
{
int waitState = value;
if (!waitState)
waitState = 1;
busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
}
return value;
}
inline int dataTicksAccessSeq32(u32 address)// DATA 32bits SEQ
{
int addr = (address>>24)&15;
int value = memoryWaitSeq32[addr];
if ((addr>=0x08) || (addr < 0x02))
{
busPrefetchCount=0;
busPrefetch=false;
}
else if (busPrefetch)
{
int waitState = value;
if (!waitState)
waitState = 1;
busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
}
return value;
}
// Waitstates when executing opcode
inline int codeTicksAccess16(u32 address) // THUMB NON SEQ
{
int addr = (address>>24)&15;
if ((addr>=0x08) && (addr<=0x0D))
{
if (busPrefetchCount&0x1)
{
if (busPrefetchCount&0x2)
{
busPrefetchCount = ((busPrefetchCount&0xFF)>>2) | (busPrefetchCount&0xFFFFFF00);
return 0;
}
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
return memoryWaitSeq[addr]-1;
}
else
{
busPrefetchCount=0;
return memoryWait[addr];
}
}
else
{
busPrefetchCount = 0;
return memoryWait[addr];
}
}
inline int codeTicksAccess32(u32 address) // ARM NON SEQ
{
int addr = (address>>24)&15;
if ((addr>=0x08) && (addr<=0x0D))
{
if (busPrefetchCount&0x1)
{
if (busPrefetchCount&0x2)
{
busPrefetchCount = ((busPrefetchCount&0xFF)>>2) | (busPrefetchCount&0xFFFFFF00);
return 0;
}
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
return memoryWaitSeq[addr] - 1;
}
else
{
busPrefetchCount = 0;
return memoryWait32[addr];
}
}
else
{
busPrefetchCount = 0;
return memoryWait32[addr];
}
}
inline int codeTicksAccessSeq16(u32 address) // THUMB SEQ
{
int addr = (address>>24)&15;
if ((addr>=0x08) && (addr<=0x0D))
{
if (busPrefetchCount&0x1)
{
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
return 0;
}
else
if (busPrefetchCount>0xFF)
{
busPrefetchCount=0;
return memoryWait[addr];
}
else
return memoryWaitSeq[addr];
}
else
{
busPrefetchCount = 0;
return memoryWaitSeq[addr];
}
}
inline int codeTicksAccessSeq32(u32 address) // ARM SEQ
{
int addr = (address>>24)&15;
if ((addr>=0x08) && (addr<=0x0D))
{
if (busPrefetchCount&0x1)
{
if (busPrefetchCount&0x2)
{
busPrefetchCount = ((busPrefetchCount&0xFF)>>2) | (busPrefetchCount&0xFFFFFF00);
return 0;
}
busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
return memoryWaitSeq[addr];
}
else
if (busPrefetchCount>0xFF)
{
busPrefetchCount=0;
return memoryWait32[addr];
}
else
return memoryWaitSeq32[addr];
}
else
{
return memoryWaitSeq32[addr];
}
}
// Emulates the Cheat System (m) code
inline void cpuMasterCodeCheck()
{
if((mastercode) && (mastercode == armNextPC))
{
u32 joy = 0;
if(systemReadJoypads())
joy = systemReadJoypad(-1);
u32 ext = (joy >> 10);
cpuTotalTicks += cheatsCheckKeys(P1^0x3FF, ext);
}
}
#endif //VBA_GBAcpu_H

738
source/vba/agb/GBAinline.h Normal file
View File

@ -0,0 +1,738 @@
// -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef VBA_GBAinline_H
#define VBA_GBAinline_H
#include "../System.h"
#include "../Port.h"
#include "../RTC.h"
#include "../Sound.h"
#include "agbprint.h"
extern const u32 objTilesAddress[3];
extern bool stopState;
extern bool holdState;
extern int holdType;
extern int cpuNextEvent;
extern bool cpuSramEnabled;
extern bool cpuFlashEnabled;
extern bool cpuEEPROMEnabled;
extern bool cpuEEPROMSensorEnabled;
extern bool cpuDmaHack;
extern u32 cpuDmaLast;
extern bool timer0On;
extern int timer0Ticks;
extern int timer0ClockReload;
extern bool timer1On;
extern int timer1Ticks;
extern int timer1ClockReload;
extern bool timer2On;
extern int timer2Ticks;
extern int timer2ClockReload;
extern bool timer3On;
extern int timer3Ticks;
extern int timer3ClockReload;
extern int cpuTotalTicks;
#define CPUReadByteQuick(addr) \
map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]
#define CPUReadHalfWordQuick(addr) \
READ16LE(((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
#define CPUReadMemoryQuick(addr) \
READ32LE(((u32*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
static inline u32 CPUReadMemory(u32 address)
{
#ifdef GBA_LOGGING
if(address & 3) {
if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
log("Unaligned word read: %08x at %08x\n", address, armMode ?
armNextPC - 4 : armNextPC - 2);
}
}
#endif
u32 value;
switch(address >> 24) {
case 0:
if(reg[15].I >> 24) {
if(address < 0x4000) {
#ifdef GBA_LOGGING
if(systemVerbose & VERBOSE_ILLEGAL_READ) {
log("Illegal word read: %08x at %08x\n", address, armMode ?
armNextPC - 4 : armNextPC - 2);
}
#endif
value = READ32LE(((u32 *)&biosProtected));
}
else goto unreadable;
} else
value = READ32LE(((u32 *)&bios[address & 0x3FFC]));
break;
case 2:
value = READ32LE(((u32 *)&workRAM[address & 0x3FFFC]));
break;
case 3:
value = READ32LE(((u32 *)&internalRAM[address & 0x7ffC]));
break;
case 4:
if((address < 0x4000400) && ioReadable[address & 0x3fc]) {
if(ioReadable[(address & 0x3fc) + 2])
value = READ32LE(((u32 *)&ioMem[address & 0x3fC]));
else
value = READ16LE(((u16 *)&ioMem[address & 0x3fc]));
} else goto unreadable;
break;
case 5:
value = READ32LE(((u32 *)&paletteRAM[address & 0x3fC]));
break;
case 6:
address = (address & 0x1fffc);
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
{
value = 0;
break;
}
if ((address & 0x18000) == 0x18000)
address &= 0x17fff;
value = READ32LE(((u32 *)&vram[address]));
break;
case 7:
value = READ32LE(((u32 *)&oam[address & 0x3FC]));
break;
case 8:
case 9:
case 10:
case 11:
case 12:
value = READ32LE(((u32 *)&rom[address&0x1FFFFFC]));
break;
case 13:
if(cpuEEPROMEnabled)
// no need to swap this
return eepromRead(address);
goto unreadable;
case 14:
if(cpuFlashEnabled | cpuSramEnabled)
// no need to swap this
return flashRead(address);
// default
default:
unreadable:
#ifdef GBA_LOGGING
if(systemVerbose & VERBOSE_ILLEGAL_READ) {
log("Illegal word read: %08x at %08x\n", address, armMode ?
armNextPC - 4 : armNextPC - 2);
}
#endif
if(cpuDmaHack) {
value = cpuDmaLast;
} else {
if(armState) {
value = CPUReadMemoryQuick(reg[15].I);
} else {
value = CPUReadHalfWordQuick(reg[15].I) |
CPUReadHalfWordQuick(reg[15].I) << 16;
}
}
}
if(address & 3) {
#ifdef C_CORE
int shift = (address & 3) << 3;
value = (value >> shift) | (value << (32 - shift));
#else
#ifdef __GNUC__
asm("and $3, %%ecx;"
"shl $3 ,%%ecx;"
"ror %%cl, %0"
: "=r" (value)
: "r" (value), "c" (address));
#else
__asm {
mov ecx, address;
and ecx, 3;
shl ecx, 3;
ror [dword ptr value], cl;
}
#endif
#endif
}
return value;
}
extern u32 myROM[];
static inline u32 CPUReadHalfWord(u32 address)
{
#ifdef GBA_LOGGING
if(address & 1) {
if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
log("Unaligned halfword read: %08x at %08x\n", address, armMode ?
armNextPC - 4 : armNextPC - 2);
}
}
#endif
u32 value;
switch(address >> 24) {
case 0:
if (reg[15].I >> 24) {
if(address < 0x4000) {
#ifdef GBA_LOGGING
if(systemVerbose & VERBOSE_ILLEGAL_READ) {
log("Illegal halfword read: %08x at %08x\n", address, armMode ?
armNextPC - 4 : armNextPC - 2);
}
#endif
value = READ16LE(((u16 *)&biosProtected[address&2]));
} else goto unreadable;
} else
value = READ16LE(((u16 *)&bios[address & 0x3FFE]));
break;
case 2:
value = READ16LE(((u16 *)&workRAM[address & 0x3FFFE]));
break;
case 3:
value = READ16LE(((u16 *)&internalRAM[address & 0x7ffe]));
break;
case 4:
if((address < 0x4000400) && ioReadable[address & 0x3fe])
{
value = READ16LE(((u16 *)&ioMem[address & 0x3fe]));
if (((address & 0x3fe)>0xFF) && ((address & 0x3fe)<0x10E))
{
if (((address & 0x3fe) == 0x100) && timer0On)
value = 0xFFFF - ((timer0Ticks-cpuTotalTicks) >> timer0ClockReload);
else
if (((address & 0x3fe) == 0x104) && timer1On && !(TM1CNT & 4))
value = 0xFFFF - ((timer1Ticks-cpuTotalTicks) >> timer1ClockReload);
else
if (((address & 0x3fe) == 0x108) && timer2On && !(TM2CNT & 4))
value = 0xFFFF - ((timer2Ticks-cpuTotalTicks) >> timer2ClockReload);
else
if (((address & 0x3fe) == 0x10C) && timer3On && !(TM3CNT & 4))
value = 0xFFFF - ((timer3Ticks-cpuTotalTicks) >> timer3ClockReload);
}
}
else goto unreadable;
break;
case 5:
value = READ16LE(((u16 *)&paletteRAM[address & 0x3fe]));
break;
case 6:
address = (address & 0x1fffe);
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
{
value = 0;
break;
}
if ((address & 0x18000) == 0x18000)
address &= 0x17fff;
value = READ16LE(((u16 *)&vram[address]));
break;
case 7:
value = READ16LE(((u16 *)&oam[address & 0x3fe]));
break;
case 8:
case 9:
case 10:
case 11:
case 12:
if(address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8)
value = rtcRead(address);
else
value = READ16LE(((u16 *)&rom[address & 0x1FFFFFE]));
break;
case 13:
if(cpuEEPROMEnabled)
// no need to swap this
return eepromRead(address);
goto unreadable;
case 14:
if(cpuFlashEnabled | cpuSramEnabled)
// no need to swap this
return flashRead(address);
// default
default:
unreadable:
#ifdef GBA_LOGGING
if(systemVerbose & VERBOSE_ILLEGAL_READ) {
log("Illegal halfword read: %08x at %08x\n", address, armMode ?
armNextPC - 4 : armNextPC - 2);
}
#endif
if(cpuDmaHack) {
value = cpuDmaLast & 0xFFFF;
} else {
if(armState) {
value = CPUReadHalfWordQuick(reg[15].I + (address & 2));
} else {
value = CPUReadHalfWordQuick(reg[15].I);
}
}
break;
}
if(address & 1) {
value = (value >> 8) | (value << 24);
}
return value;
}
static inline u16 CPUReadHalfWordSigned(u32 address)
{
u16 value = CPUReadHalfWord(address);
if((address & 1))
value = (s8)value;
return value;
}
static inline u8 CPUReadByte(u32 address)
{
switch(address >> 24) {
case 0:
if (reg[15].I >> 24) {
if(address < 0x4000) {
#ifdef GBA_LOGGING
if(systemVerbose & VERBOSE_ILLEGAL_READ) {
log("Illegal byte read: %08x at %08x\n", address, armMode ?
armNextPC - 4 : armNextPC - 2);
}
#endif
return biosProtected[address & 3];
} else goto unreadable;
}
return bios[address & 0x3FFF];
case 2:
return workRAM[address & 0x3FFFF];
case 3:
return internalRAM[address & 0x7fff];
case 4:
if((address < 0x4000400) && ioReadable[address & 0x3ff])
return ioMem[address & 0x3ff];
else goto unreadable;
case 5:
return paletteRAM[address & 0x3ff];
case 6:
address = (address & 0x1ffff);
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
return 0;
if ((address & 0x18000) == 0x18000)
address &= 0x17fff;
return vram[address];
case 7:
return oam[address & 0x3ff];
case 8:
case 9:
case 10:
case 11:
case 12:
return rom[address & 0x1FFFFFF];
case 13:
if(cpuEEPROMEnabled)
return eepromRead(address);
goto unreadable;
case 14:
if(cpuSramEnabled | cpuFlashEnabled)
return flashRead(address);
if(cpuEEPROMSensorEnabled) {
switch(address & 0x00008f00) {
case 0x8200:
return systemGetSensorX() & 255;
case 0x8300:
return (systemGetSensorX() >> 8)|0x80;
case 0x8400:
return systemGetSensorY() & 255;
case 0x8500:
return systemGetSensorY() >> 8;
}
}
// default
default:
unreadable:
#ifdef GBA_LOGGING
if(systemVerbose & VERBOSE_ILLEGAL_READ) {
log("Illegal byte read: %08x at %08x\n", address, armMode ?
armNextPC - 4 : armNextPC - 2);
}
#endif
if(cpuDmaHack) {
return cpuDmaLast & 0xFF;
} else {
if(armState) {
return CPUReadByteQuick(reg[15].I+(address & 3));
} else {
return CPUReadByteQuick(reg[15].I+(address & 1));
}
}
break;
}
}
static inline void CPUWriteMemory(u32 address, u32 value)
{
#ifdef GBA_LOGGING
if(address & 3) {
if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
log("Unaligned word write: %08x to %08x from %08x\n",
value,
address,
armMode ? armNextPC - 4 : armNextPC - 2);
}
}
#endif
switch(address >> 24) {
case 0x02:
#ifdef BKPT_SUPPORT
if(*((u32 *)&freezeWorkRAM[address & 0x3FFFC]))
cheatsWriteMemory(address & 0x203FFFC,
value);
else
#endif
WRITE32LE(((u32 *)&workRAM[address & 0x3FFFC]), value);
break;
case 0x03:
#ifdef BKPT_SUPPORT
if(*((u32 *)&freezeInternalRAM[address & 0x7ffc]))
cheatsWriteMemory(address & 0x3007FFC,
value);
else
#endif
WRITE32LE(((u32 *)&internalRAM[address & 0x7ffC]), value);
break;
case 0x04:
if(address < 0x4000400) {
CPUUpdateRegister((address & 0x3FC), value & 0xFFFF);
CPUUpdateRegister((address & 0x3FC) + 2, (value >> 16));
} else goto unwritable;
break;
case 0x05:
#ifdef BKPT_SUPPORT
if(*((u32 *)&freezePRAM[address & 0x3fc]))
cheatsWriteMemory(address & 0x70003FC,
value);
else
#endif
WRITE32LE(((u32 *)&paletteRAM[address & 0x3FC]), value);
break;
case 0x06:
address = (address & 0x1fffc);
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
return;
if ((address & 0x18000) == 0x18000)
address &= 0x17fff;
#ifdef BKPT_SUPPORT
if(*((u32 *)&freezeVRAM[address]))
cheatsWriteMemory(address + 0x06000000, value);
else
#endif
WRITE32LE(((u32 *)&vram[address]), value);
break;
case 0x07:
#ifdef BKPT_SUPPORT
if(*((u32 *)&freezeOAM[address & 0x3fc]))
cheatsWriteMemory(address & 0x70003FC,
value);
else
#endif
WRITE32LE(((u32 *)&oam[address & 0x3fc]), value);
break;
case 0x0D:
if(cpuEEPROMEnabled) {
eepromWrite(address, value);
break;
}
goto unwritable;
case 0x0E:
if(!eepromInUse | cpuSramEnabled | cpuFlashEnabled) {
(*cpuSaveGameFunc)(address, (u8)value);
break;
}
// default
default:
unwritable:
#ifdef GBA_LOGGING
if(systemVerbose & VERBOSE_ILLEGAL_WRITE) {
log("Illegal word write: %08x to %08x from %08x\n",
value,
address,
armMode ? armNextPC - 4 : armNextPC - 2);
}
#endif
break;
}
}
static inline void CPUWriteHalfWord(u32 address, u16 value)
{
#ifdef GBA_LOGGING
if(address & 1) {
if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
log("Unaligned halfword write: %04x to %08x from %08x\n",
value,
address,
armMode ? armNextPC - 4 : armNextPC - 2);
}
}
#endif
switch(address >> 24) {
case 2:
#ifdef BKPT_SUPPORT
if(*((u16 *)&freezeWorkRAM[address & 0x3FFFE]))
cheatsWriteHalfWord(address & 0x203FFFE,
value);
else
#endif
WRITE16LE(((u16 *)&workRAM[address & 0x3FFFE]),value);
break;
case 3:
#ifdef BKPT_SUPPORT
if(*((u16 *)&freezeInternalRAM[address & 0x7ffe]))
cheatsWriteHalfWord(address & 0x3007ffe,
value);
else
#endif
WRITE16LE(((u16 *)&internalRAM[address & 0x7ffe]), value);
break;
case 4:
if(address < 0x4000400)
CPUUpdateRegister(address & 0x3fe, value);
else goto unwritable;
break;
case 5:
#ifdef BKPT_SUPPORT
if(*((u16 *)&freezePRAM[address & 0x03fe]))
cheatsWriteHalfWord(address & 0x70003fe,
value);
else
#endif
WRITE16LE(((u16 *)&paletteRAM[address & 0x3fe]), value);
break;
case 6:
address = (address & 0x1fffe);
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
return;
if ((address & 0x18000) == 0x18000)
address &= 0x17fff;
#ifdef BKPT_SUPPORT
if(*((u16 *)&freezeVRAM[address]))
cheatsWriteHalfWord(address + 0x06000000,
value);
else
#endif
WRITE16LE(((u16 *)&vram[address]), value);
break;
case 7:
#ifdef BKPT_SUPPORT
if(*((u16 *)&freezeOAM[address & 0x03fe]))
cheatsWriteHalfWord(address & 0x70003fe,
value);
else
#endif
WRITE16LE(((u16 *)&oam[address & 0x3fe]), value);
break;
case 8:
case 9:
if(address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8) {
if(!rtcWrite(address, value))
goto unwritable;
} else if(!agbPrintWrite(address, value)) goto unwritable;
break;
case 13:
if(cpuEEPROMEnabled) {
eepromWrite(address, (u8)value);
break;
}
goto unwritable;
case 14:
if(!eepromInUse | cpuSramEnabled | cpuFlashEnabled) {
(*cpuSaveGameFunc)(address, (u8)value);
break;
}
goto unwritable;
default:
unwritable:
#ifdef GBA_LOGGING
if(systemVerbose & VERBOSE_ILLEGAL_WRITE) {
log("Illegal halfword write: %04x to %08x from %08x\n",
value,
address,
armMode ? armNextPC - 4 : armNextPC - 2);
}
#endif
break;
}
}
static inline void CPUWriteByte(u32 address, u8 b)
{
switch(address >> 24) {
case 2:
#ifdef BKPT_SUPPORT
if(freezeWorkRAM[address & 0x3FFFF])
cheatsWriteByte(address & 0x203FFFF, b);
else
#endif
workRAM[address & 0x3FFFF] = b;
break;
case 3:
#ifdef BKPT_SUPPORT
if(freezeInternalRAM[address & 0x7fff])
cheatsWriteByte(address & 0x3007fff, b);
else
#endif
internalRAM[address & 0x7fff] = b;
break;
case 4:
if(address < 0x4000400) {
switch(address & 0x3FF) {
case 0x301:
if(b == 0x80)
stopState = true;
holdState = 1;
holdType = -1;
cpuNextEvent = cpuTotalTicks;
break;
case 0x60:
case 0x61:
case 0x62:
case 0x63:
case 0x64:
case 0x65:
case 0x68:
case 0x69:
case 0x6c:
case 0x6d:
case 0x70:
case 0x71:
case 0x72:
case 0x73:
case 0x74:
case 0x75:
case 0x78:
case 0x79:
case 0x7c:
case 0x7d:
case 0x80:
case 0x81:
case 0x84:
case 0x85:
case 0x90:
case 0x91:
case 0x92:
case 0x93:
case 0x94:
case 0x95:
case 0x96:
case 0x97:
case 0x98:
case 0x99:
case 0x9a:
case 0x9b:
case 0x9c:
case 0x9d:
case 0x9e:
case 0x9f:
soundEvent(address&0xFF, b);
break;
default:
if(address & 1)
CPUUpdateRegister(address & 0x3fe,
((READ16LE(((u16 *)&ioMem[address & 0x3fe])))
& 0x00FF) |
b<<8);
else
CPUUpdateRegister(address & 0x3fe,
((READ16LE(((u16 *)&ioMem[address & 0x3fe])) & 0xFF00) | b));
}
break;
} else goto unwritable;
break;
case 5:
// no need to switch
*((u16 *)&paletteRAM[address & 0x3FE]) = (b << 8) | b;
break;
case 6:
address = (address & 0x1fffe);
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
return;
if ((address & 0x18000) == 0x18000)
address &= 0x17fff;
// no need to switch
// byte writes to OBJ VRAM are ignored
if ((address) < objTilesAddress[((DISPCNT&7)+1)>>2])
{
#ifdef BKPT_SUPPORT
if(freezeVRAM[address])
cheatsWriteByte(address + 0x06000000, b);
else
#endif
*((u16 *)&vram[address]) = (b << 8) | b;
}
break;
case 7:
// no need to switch
// byte writes to OAM are ignored
// *((u16 *)&oam[address & 0x3FE]) = (b << 8) | b;
break;
case 13:
if(cpuEEPROMEnabled) {
eepromWrite(address, b);
break;
}
goto unwritable;
case 14:
if (!(saveType == 5) && (!eepromInUse | cpuSramEnabled | cpuFlashEnabled)) {
//if(!cpuEEPROMEnabled && (cpuSramEnabled | cpuFlashEnabled)) {
(*cpuSaveGameFunc)(address, b);
break;
}
// default
default:
unwritable:
#ifdef GBA_LOGGING
if(systemVerbose & VERBOSE_ILLEGAL_WRITE) {
log("Illegal byte write: %02x to %08x from %08x\n",
b,
address,
armMode ? armNextPC - 4 : armNextPC -2 );
}
#endif
break;
}
}
#endif //VBA_GBAinline_H

View File

@ -1,106 +1,98 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "GBA.h" #include "GBA.h"
#include "Globals.h" #include "Globals.h"
#include "Port.h" #include "Port.h"
#include "System.h"
#define debuggerWriteHalfWord(addr, value) \
WRITE16LE((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask], (value)) #define debuggerWriteHalfWord(addr, value) \
WRITE16LE((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask], (value))
#define debuggerReadHalfWord(addr) \
READ16LE(((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])) #define debuggerReadHalfWord(addr) \
READ16LE(((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
static bool agbPrintEnabled = false;
static bool agbPrintProtect = false; static bool agbPrintEnabled = false;
static bool agbPrintProtect = false;
bool agbPrintWrite(u32 address, u16 value)
{ bool agbPrintWrite(u32 address, u16 value)
if(agbPrintEnabled) {
{ if(agbPrintEnabled) {
if(address == 0x9fe2ffe) if(address == 0x9fe2ffe) { // protect
{ // protect agbPrintProtect = (value != 0);
agbPrintProtect = (value != 0); debuggerWriteHalfWord(address, value);
debuggerWriteHalfWord(address, value); return true;
return true; } else {
} if(agbPrintProtect &&
else ((address >= 0x9fe20f8 && address <= 0x9fe20ff) // control structure
{ || (address >= 0x8fd0000 && address <= 0x8fdffff)
if(agbPrintProtect && || (address >= 0x9fd0000 && address <= 0x9fdffff))) {
((address >= 0x9fe20f8 && address <= 0x9fe20ff) // control structure debuggerWriteHalfWord(address, value);
|| (address >= 0x8fd0000 && address <= 0x8fdffff) return true;
|| (address >= 0x9fd0000 && address <= 0x9fdffff))) }
{ }
debuggerWriteHalfWord(address, value); }
return true; return false;
} }
}
} void agbPrintReset()
return false; {
} agbPrintProtect = false;
}
void agbPrintReset()
{ void agbPrintEnable(bool enable)
agbPrintProtect = false; {
} agbPrintEnabled = enable;
}
void agbPrintEnable(bool enable)
{ bool agbPrintIsEnabled()
agbPrintEnabled = enable; {
} return agbPrintEnabled;
}
bool agbPrintIsEnabled()
{ void agbPrintFlush()
return agbPrintEnabled; {
} u16 get = debuggerReadHalfWord(0x9fe20fc);
u16 put = debuggerReadHalfWord(0x9fe20fe);
extern void (*dbgOutput)(char *, u32);
u32 address = (debuggerReadHalfWord(0x9fe20fa) << 16);
void agbPrintFlush() if(address != 0xfd0000 && address != 0x1fd0000) {
{ dbgOutput("Did you forget to call AGBPrintInit?\n", 0);
u16 get = debuggerReadHalfWord(0x9fe20fc); // get rid of the text otherwise we will continue to be called
u16 put = debuggerReadHalfWord(0x9fe20fe); debuggerWriteHalfWord(0x9fe20fc, put);
return;
u32 address = (debuggerReadHalfWord(0x9fe20fa) << 16); }
if(address != 0xfd0000 && address != 0x1fd0000)
{ u8 *data = &rom[address];
dbgOutput("Did you forget to call AGBPrintInit?\n", 0);
// get rid of the text otherwise we will continue to be called while(get != put) {
debuggerWriteHalfWord(0x9fe20fc, put); char c = data[get++];
return; char s[2];
} s[0] = c;
s[1] = 0;
u8 *data = &rom[address];
if(systemVerbose & VERBOSE_AGBPRINT)
while(get != put) dbgOutput(s, 0);
{ if(c == '\n')
char c = data[get++]; break;
char s[2]; }
s[0] = c; debuggerWriteHalfWord(0x9fe20fc, get);
s[1] = 0; }
if(systemVerbose & VERBOSE_AGBPRINT)
dbgOutput(s, 0);
if(c == '\n')
break;
}
debuggerWriteHalfWord(0x9fe20fc, get);
}

View File

@ -1,27 +1,27 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef VBA_AGBPRINT_H #ifndef VBA_AGBPRINT_H
#define VBA_AGBPRINT_H #define VBA_AGBPRINT_H
extern void agbPrintEnable(bool); extern void agbPrintEnable(bool);
extern bool agbPrintIsEnabled(); extern bool agbPrintIsEnabled();
extern void agbPrintReset(); extern void agbPrintReset();
extern bool agbPrintWrite(u32, u16); extern bool agbPrintWrite(u32, u16);
extern void agbPrintFlush(); extern void agbPrintFlush();
#endif #endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,33 +1,33 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/************************************************************************/ /************************************************************************/
/* Arm/Thumb command set disassembler */ /* Arm/Thumb command set disassembler */
/************************************************************************/ /************************************************************************/
#ifndef __ARMDIS_H__ #ifndef __ARMDIS_H__
#define __ARMDIS_H__ #define __ARMDIS_H__
#define DIS_VIEW_ADDRESS 1 #define DIS_VIEW_ADDRESS 1
#define DIS_VIEW_CODE 2 #define DIS_VIEW_CODE 2
int disThumb(u32 offset, char *dest, int flags); int disThumb(u32 offset, char *dest, int flags);
int disArm(u32 offset, char *dest, int flags); int disArm(u32 offset, char *dest, int flags);
#endif // __ARMDIS_H__ #endif // __ARMDIS_H__

View File

@ -1,432 +0,0 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** Code adapted from Exult source code by Forgotten
** Scale.cc - Trying to scale with bilinear interpolation.
**
** Written: 6/14/00 - JSF
**/
#include "System.h"
static u8 row_cur[3*322];
static u8 row_next[3*322];
static u8 *rgb_row_cur = row_cur;
static u8 *rgb_row_next = row_next;
#define RGB(r,g,b) ((r)>>3) << systemRedShift |\
((g) >> 3) << systemGreenShift |\
((b) >> 3) << systemBlueShift\
static void fill_rgb_row_16(u16 *from, int src_width, u8 *row, int width)
{
u8 *copy_start = row + src_width*3;
u8 *all_stop = row + width*3;
while (row < copy_start)
{
u16 color = *from++;
*row++ = ((color >> systemRedShift) & 0x1f) << 3;
*row++ = ((color >> systemGreenShift) & 0x1f) << 3;
*row++ = ((color >> systemBlueShift) & 0x1f) << 3;
}
// any remaining elements to be written to 'row' are a replica of the
// preceding pixel
u8 *p = row-3;
while (row < all_stop)
{
// we're guaranteed three elements per pixel; could unroll the loop
// further, especially with a Duff's Device, but the gains would be
// probably limited (judging by profiler output)
*row++ = *p++;
*row++ = *p++;
*row++ = *p++;
}
}
static void fill_rgb_row_32(u32 *from, int src_width, u8 *row, int width)
{
u8 *copy_start = row + src_width*3;
u8 *all_stop = row + width*3;
while (row < copy_start)
{
u32 color = *from++;
*row++ = ((color >> systemRedShift) & 0x1f) << 3;
*row++ = ((color >> systemGreenShift) & 0x1f) << 3;
*row++ = ((color >> systemBlueShift) & 0x1f) << 3;
}
// any remaining elements to be written to 'row' are a replica of the
// preceding pixel
u8 *p = row-3;
while (row < all_stop)
{
// we're guaranteed three elements per pixel; could unroll the loop
// further, especially with a Duff's Device, but the gains would be
// probably limited (judging by profiler output)
*row++ = *p++;
*row++ = *p++;
*row++ = *p++;
}
}
void Bilinear(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
u8 *dstPtr, u32 dstPitch, int width, int height)
{
u16 *to = (u16 *)dstPtr;
u16 *to_odd = (u16 *)(dstPtr + dstPitch);
int from_width = width;
u16 *from = (u16 *)srcPtr;
fill_rgb_row_16(from, from_width, rgb_row_cur, width+1);
for(int y = 0; y < height; y++)
{
u16 *from_orig = from;
u16 *to_orig = to;
if (y+1 < height)
fill_rgb_row_16(from+width+2, from_width, rgb_row_next,
width+1);
else
fill_rgb_row_16(from, from_width, rgb_row_next, width+1);
// every pixel in the src region, is extended to 4 pixels in the
// destination, arranged in a square 'quad'; if the current src
// pixel is 'a', then in what follows 'b' is the src pixel to the
// right, 'c' is the src pixel below, and 'd' is the src pixel to
// the right and down
u8 *cur_row = rgb_row_cur;
u8 *next_row = rgb_row_next;
u8 *ar = cur_row++;
u8 *ag = cur_row++;
u8 *ab = cur_row++;
u8 *cr = next_row++;
u8 *cg = next_row++;
u8 *cb = next_row++;
for(int x=0; x < width; x++)
{
u8 *br = cur_row++;
u8 *bg = cur_row++;
u8 *bb = cur_row++;
u8 *dr = next_row++;
u8 *dg = next_row++;
u8 *db = next_row++;
// upper left pixel in quad: just copy it in
*to++ = RGB(*ar, *ag, *ab);
// upper right
*to++ = RGB((*ar+*br)>>1, (*ag+*bg)>>1, (*ab+*bb)>>1);
// lower left
*to_odd++ = RGB((*ar+*cr)>>1, (*ag+*cg)>>1, (*ab+*cb)>>1);
// lower right
*to_odd++ = RGB((*ar+*br+*cr+*dr)>>2,
(*ag+*bg+*cg+*dg)>>2,
(*ab+*bb+*cb+*db)>>2);
// 'b' becomes 'a', 'd' becomes 'c'
ar = br;
ag = bg;
ab = bb;
cr = dr;
cg = dg;
cb = db;
}
// the "next" rgb row becomes the current; the old current rgb row is
// recycled and serves as the new "next" row
u8 *temp;
temp = rgb_row_cur;
rgb_row_cur = rgb_row_next;
rgb_row_next = temp;
// update the pointers for start of next pair of lines
from = (u16 *)((u8 *)from_orig + srcPitch);
to = (u16 *)((u8 *)to_orig + (dstPitch << 1));
to_odd = (u16 *)((u8 *)to + dstPitch);
}
}
void BilinearPlus(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
u8 *dstPtr, u32 dstPitch, int width, int height)
{
u16 *to = (u16 *)dstPtr;
u16 *to_odd = (u16 *)(dstPtr + dstPitch);
int from_width = width;
u16 *from = (u16 *)srcPtr;
fill_rgb_row_16(from, from_width, rgb_row_cur, width+1);
for(int y = 0; y < height; y++)
{
u16 *from_orig = from;
u16 *to_orig = to;
if (y+1 < height)
fill_rgb_row_16(from+width+2, from_width, rgb_row_next,
width+1);
else
fill_rgb_row_16(from, from_width, rgb_row_next, width+1);
// every pixel in the src region, is extended to 4 pixels in the
// destination, arranged in a square 'quad'; if the current src
// pixel is 'a', then in what follows 'b' is the src pixel to the
// right, 'c' is the src pixel below, and 'd' is the src pixel to
// the right and down
u8 *cur_row = rgb_row_cur;
u8 *next_row = rgb_row_next;
u8 *ar = cur_row++;
u8 *ag = cur_row++;
u8 *ab = cur_row++;
u8 *cr = next_row++;
u8 *cg = next_row++;
u8 *cb = next_row++;
for(int x=0; x < width; x++)
{
u8 *br = cur_row++;
u8 *bg = cur_row++;
u8 *bb = cur_row++;
u8 *dr = next_row++;
u8 *dg = next_row++;
u8 *db = next_row++;
// upper left pixel in quad: just copy it in
//*to++ = manip.rgb(*ar, *ag, *ab);
#ifdef USE_ORIGINAL_BILINEAR_PLUS
*to++ = RGB(
(((*ar)<<2) +((*ar)) + (*cr+*br+*br) )>> 3,
(((*ag)<<2) +((*ag)) + (*cg+*bg+*bg) )>> 3,
(((*ab)<<2) +((*ab)) + (*cb+*bb+*bb) )>> 3);
#else
*to++ = RGB(
(((*ar)<<3) +((*ar)<<1) + (*cr+*br+*br+*cr) )>> 4,
(((*ag)<<3) +((*ag)<<1) + (*cg+*bg+*bg+*cg) )>> 4,
(((*ab)<<3) +((*ab)<<1) + (*cb+*bb+*bb+*cb) )>> 4);
#endif
// upper right
*to++ = RGB((*ar+*br)>>1, (*ag+*bg)>>1, (*ab+*bb)>>1);
// lower left
*to_odd++ = RGB((*ar+*cr)>>1, (*ag+*cg)>>1, (*ab+*cb)>>1);
// lower right
*to_odd++ = RGB((*ar+*br+*cr+*dr)>>2,
(*ag+*bg+*cg+*dg)>>2,
(*ab+*bb+*cb+*db)>>2);
// 'b' becomes 'a', 'd' becomes 'c'
ar = br;
ag = bg;
ab = bb;
cr = dr;
cg = dg;
cb = db;
}
// the "next" rgb row becomes the current; the old current rgb row is
// recycled and serves as the new "next" row
u8 *temp;
temp = rgb_row_cur;
rgb_row_cur = rgb_row_next;
rgb_row_next = temp;
// update the pointers for start of next pair of lines
from = (u16 *)((u8 *)from_orig + srcPitch);
to = (u16 *)((u8 *)to_orig + (dstPitch << 1));
to_odd = (u16 *)((u8 *)to + dstPitch);
}
}
void Bilinear32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
u8 *dstPtr, u32 dstPitch, int width, int height)
{
u32 *to = (u32 *)dstPtr;
u32 *to_odd = (u32 *)(dstPtr + dstPitch);
int from_width = width;
if(width+1 < from_width)
from_width = width+1;
u32 *from = (u32 *)srcPtr;
fill_rgb_row_32(from, from_width, rgb_row_cur, width+1);
for(int y = 0; y < height; y++)
{
u32 *from_orig = from;
u32 *to_orig = to;
if (y+1 < height)
fill_rgb_row_32(from+width+1, from_width, rgb_row_next,
width+1);
else
fill_rgb_row_32(from, from_width, rgb_row_next, width+1);
// every pixel in the src region, is extended to 4 pixels in the
// destination, arranged in a square 'quad'; if the current src
// pixel is 'a', then in what follows 'b' is the src pixel to the
// right, 'c' is the src pixel below, and 'd' is the src pixel to
// the right and down
u8 *cur_row = rgb_row_cur;
u8 *next_row = rgb_row_next;
u8 *ar = cur_row++;
u8 *ag = cur_row++;
u8 *ab = cur_row++;
u8 *cr = next_row++;
u8 *cg = next_row++;
u8 *cb = next_row++;
for(int x=0; x < width; x++)
{
u8 *br = cur_row++;
u8 *bg = cur_row++;
u8 *bb = cur_row++;
u8 *dr = next_row++;
u8 *dg = next_row++;
u8 *db = next_row++;
// upper left pixel in quad: just copy it in
*to++ = RGB(*ar, *ag, *ab);
// upper right
*to++ = RGB((*ar+*br)>>1, (*ag+*bg)>>1, (*ab+*bb)>>1);
// lower left
*to_odd++ = RGB((*ar+*cr)>>1, (*ag+*cg)>>1, (*ab+*cb)>>1);
// lower right
*to_odd++ = RGB((*ar+*br+*cr+*dr)>>2,
(*ag+*bg+*cg+*dg)>>2,
(*ab+*bb+*cb+*db)>>2);
// 'b' becomes 'a', 'd' becomes 'c'
ar = br;
ag = bg;
ab = bb;
cr = dr;
cg = dg;
cb = db;
}
// the "next" rgb row becomes the current; the old current rgb row is
// recycled and serves as the new "next" row
u8 *temp;
temp = rgb_row_cur;
rgb_row_cur = rgb_row_next;
rgb_row_next = temp;
// update the pointers for start of next pair of lines
from = (u32 *)((u8 *)from_orig + srcPitch);
to = (u32 *)((u8 *)to_orig + (dstPitch << 1));
to_odd = (u32 *)((u8 *)to + dstPitch);
}
}
void BilinearPlus32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
u8 *dstPtr, u32 dstPitch, int width, int height)
{
u32 *to = (u32 *)dstPtr;
u32 *to_odd = (u32 *)(dstPtr + dstPitch);
int from_width = width;
if(width+1 < from_width)
from_width = width+1;
u32 *from = (u32 *)srcPtr;
fill_rgb_row_32(from, from_width, rgb_row_cur, width+1);
for(int y = 0; y < height; y++)
{
u32 *from_orig = from;
u32 *to_orig = to;
if (y+1 < height)
fill_rgb_row_32(from+width+1, from_width, rgb_row_next,
width+1);
else
fill_rgb_row_32(from, from_width, rgb_row_next, width+1);
// every pixel in the src region, is extended to 4 pixels in the
// destination, arranged in a square 'quad'; if the current src
// pixel is 'a', then in what follows 'b' is the src pixel to the
// right, 'c' is the src pixel below, and 'd' is the src pixel to
// the right and down
u8 *cur_row = rgb_row_cur;
u8 *next_row = rgb_row_next;
u8 *ar = cur_row++;
u8 *ag = cur_row++;
u8 *ab = cur_row++;
u8 *cr = next_row++;
u8 *cg = next_row++;
u8 *cb = next_row++;
for(int x=0; x < width; x++)
{
u8 *br = cur_row++;
u8 *bg = cur_row++;
u8 *bb = cur_row++;
u8 *dr = next_row++;
u8 *dg = next_row++;
u8 *db = next_row++;
// upper left pixel in quad: just copy it in
//*to++ = manip.rgb(*ar, *ag, *ab);
#ifdef USE_ORIGINAL_BILINEAR_PLUS
*to++ = RGB(
(((*ar)<<2) +((*ar)) + (*cr+*br+*br) )>> 3,
(((*ag)<<2) +((*ag)) + (*cg+*bg+*bg) )>> 3,
(((*ab)<<2) +((*ab)) + (*cb+*bb+*bb) )>> 3);
#else
*to++ = RGB(
(((*ar)<<3) +((*ar)<<1) + (*cr+*br+*br+*cr) )>> 4,
(((*ag)<<3) +((*ag)<<1) + (*cg+*bg+*bg+*cg) )>> 4,
(((*ab)<<3) +((*ab)<<1) + (*cb+*bb+*bb+*cb) )>> 4);
#endif
// upper right
*to++ = RGB((*ar+*br)>>1, (*ag+*bg)>>1, (*ab+*bb)>>1);
// lower left
*to_odd++ = RGB((*ar+*cr)>>1, (*ag+*cg)>>1, (*ab+*cb)>>1);
// lower right
*to_odd++ = RGB((*ar+*br+*cr+*dr)>>2,
(*ag+*bg+*cg+*dg)>>2,
(*ab+*bb+*cb+*db)>>2);
// 'b' becomes 'a', 'd' becomes 'c'
ar = br;
ag = bg;
ab = bb;
cr = dr;
cg = dg;
cb = db;
}
// the "next" rgb row becomes the current; the old current rgb row is
// recycled and serves as the new "next" row
u8 *temp;
temp = rgb_row_cur;
rgb_row_cur = rgb_row_next;
rgb_row_next = temp;
// update the pointers for start of next pair of lines
from = (u32 *)((u8 *)from_orig + srcPitch);
to = (u32 *)((u8 *)to_orig + (dstPitch << 1));
to_odd = (u32 *)((u8 *)to + dstPitch);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,46 +1,47 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004-2006 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef VBA_BIOS_H #ifndef VBA_BIOS_H
#define VBA_BIOS_H #define VBA_BIOS_H
extern void BIOS_ArcTan(); extern void BIOS_ArcTan();
extern void BIOS_ArcTan2(); extern void BIOS_ArcTan2();
extern void BIOS_BitUnPack(); extern void BIOS_BitUnPack();
extern void BIOS_BgAffineSet(); extern void BIOS_GetBiosChecksum();
extern void BIOS_CpuSet(); extern void BIOS_BgAffineSet();
extern void BIOS_CpuFastSet(); extern void BIOS_CpuSet();
extern void BIOS_Diff8bitUnFilterWram(); extern void BIOS_CpuFastSet();
extern void BIOS_Diff8bitUnFilterVram(); extern void BIOS_Diff8bitUnFilterWram();
extern void BIOS_Diff16bitUnFilter(); extern void BIOS_Diff8bitUnFilterVram();
extern void BIOS_Div(); extern void BIOS_Diff16bitUnFilter();
extern void BIOS_DivARM(); extern void BIOS_Div();
extern void BIOS_HuffUnComp(); extern void BIOS_DivARM();
extern void BIOS_LZ77UnCompVram(); extern void BIOS_HuffUnComp();
extern void BIOS_LZ77UnCompWram(); extern void BIOS_LZ77UnCompVram();
extern void BIOS_ObjAffineSet(); extern void BIOS_LZ77UnCompWram();
extern void BIOS_RegisterRamReset(); extern void BIOS_ObjAffineSet();
extern void BIOS_RegisterRamReset(u32); extern void BIOS_RegisterRamReset();
extern void BIOS_RLUnCompVram(); extern void BIOS_RegisterRamReset(u32);
extern void BIOS_RLUnCompWram(); extern void BIOS_RLUnCompVram();
extern void BIOS_SoftReset(); extern void BIOS_RLUnCompWram();
extern void BIOS_Sqrt(); extern void BIOS_SoftReset();
extern void BIOS_MidiKey2Freq(); extern void BIOS_Sqrt();
extern void BIOS_SndDriverJmpTableCopy(); extern void BIOS_MidiKey2Freq();
#endif // VBA_BIOS_H extern void BIOS_SndDriverJmpTableCopy();
#endif // VBA_BIOS_H

View File

@ -2548,9 +2548,11 @@ bool gbReadSaveState(const char *name)
bool gbWritePNGFile(const char *fileName) bool gbWritePNGFile(const char *fileName)
{ {
if(gbBorderOn) // if(gbBorderOn)
return utilWritePNGFile(fileName, 256, 224, pix); // return utilWritePNGFile(fileName, 256, 224, pix);
return utilWritePNGFile(fileName, 160, 144, pix); // return utilWritePNGFile(fileName, 160, 144, pix);
return false;
} }
bool gbWriteBMPFile(const char *fileName) bool gbWriteBMPFile(const char *fileName)

View File

@ -18,7 +18,7 @@
#include <string.h> #include <string.h>
#include "../GBA.h" #include "../agb/GBA.h"
#include "gbGlobals.h" #include "gbGlobals.h"
#include "gbSGB.h" #include "gbSGB.h"

View File

@ -16,7 +16,7 @@
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "../GBA.h" #include "../agb/GBA.h"
u8 *gbMemoryMap[16]; u8 *gbMemoryMap[16];

View File

@ -16,7 +16,7 @@
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "../GBA.h" #include "../agb/GBA.h"
#include "../Port.h" #include "../Port.h"
#include "gbGlobals.h" #include "gbGlobals.h"
#include "gbMemory.h" #include "gbMemory.h"

View File

@ -18,7 +18,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "../GBA.h" #include "../agb/GBA.h"
u8 gbPrinterStatus = 0; u8 gbPrinterStatus = 0;
int gbPrinterState = 0; int gbPrinterState = 0;

File diff suppressed because it is too large Load Diff

View File

@ -1,311 +1,283 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef VBA_ELF_H #ifndef VBA_ELF_H
#define VBA_ELF_H #define VBA_ELF_H
#include <fat.h>
#include <stdio.h> enum LocationType {
#include <stdlib.h> LOCATION_register,
#include <unistd.h> LOCATION_memory,
#include <sys/dir.h> LOCATION_value
};
enum LocationType {
LOCATION_register, #define DW_ATE_boolean 0x02
LOCATION_memory, #define DW_ATE_signed 0x05
LOCATION_value #define DW_ATE_unsigned 0x07
}; #define DW_ATE_unsigned_char 0x08
#define DW_ATE_boolean 0x02 struct ELFHeader {
#define DW_ATE_signed 0x05 u32 magic;
#define DW_ATE_unsigned 0x07 u8 clazz;
#define DW_ATE_unsigned_char 0x08 u8 data;
u8 version;
struct ELFHeader u8 pad[9];
{ u16 e_type;
u32 magic; u16 e_machine;
u8 clazz; u32 e_version;
u8 data; u32 e_entry;
u8 version; u32 e_phoff;
u8 pad[9]; u32 e_shoff;
u16 e_type; u32 e_flags;
u16 e_machine; u16 e_ehsize;
u32 e_version; u16 e_phentsize;
u32 e_entry; u16 e_phnum;
u32 e_phoff; u16 e_shentsize;
u32 e_shoff; u16 e_shnum;
u32 e_flags; u16 e_shstrndx;
u16 e_ehsize; };
u16 e_phentsize;
u16 e_phnum; struct ELFProgramHeader {
u16 e_shentsize; u32 type;
u16 e_shnum; u32 offset;
u16 e_shstrndx; u32 vaddr;
}; u32 paddr;
u32 filesz;
struct ELFProgramHeader u32 memsz;
{ u32 flags;
u32 type; u32 align;
u32 offset; };
u32 vaddr;
u32 paddr; struct ELFSectionHeader {
u32 filesz; u32 name;
u32 memsz; u32 type;
u32 flags; u32 flags;
u32 align; u32 addr;
}; u32 offset;
u32 size;
struct ELFSectionHeader u32 link;
{ u32 info;
u32 name; u32 addralign;
u32 type; u32 entsize;
u32 flags; };
u32 addr;
u32 offset; struct ELFSymbol {
u32 size; u32 name;
u32 link; u32 value;
u32 info; u32 size;
u32 addralign; u8 info;
u32 entsize; u8 other;
}; u16 shndx;
};
struct ELFSymbol
{ struct ELFBlock {
u32 name; int length;
u32 value; u8 *data;
u32 size; };
u8 info;
u8 other; struct ELFAttr {
u16 shndx; u32 name;
}; u32 form;
union {
struct ELFBlock u32 value;
{ char *string;
int length; u8 *data;
u8 *data; bool flag;
}; ELFBlock *block;
};
struct ELFAttr };
{
u32 name; struct ELFAbbrev {
u32 form; u32 number;
union { u32 tag;
u32 value; bool hasChildren;
char *string; int numAttrs;
u8 *data; ELFAttr *attrs;
bool flag; ELFAbbrev *next;
ELFBlock *block; };
};
}; enum TypeEnum {
TYPE_base,
struct ELFAbbrev TYPE_pointer,
{ TYPE_function,
u32 number; TYPE_void,
u32 tag; TYPE_array,
bool hasChildren; TYPE_struct,
int numAttrs; TYPE_reference,
ELFAttr *attrs; TYPE_enum,
ELFAbbrev *next; TYPE_union
}; };
enum TypeEnum { struct Type;
TYPE_base, struct Object;
TYPE_pointer,
TYPE_function, struct FunctionType {
TYPE_void, Type *returnType;
TYPE_array, Object *args;
TYPE_struct, };
TYPE_reference,
TYPE_enum, struct Member {
TYPE_union char *name;
}; Type *type;
int bitSize;
struct Type; int bitOffset;
struct Object; int byteSize;
ELFBlock *location;
struct FunctionType };
{
Type *returnType; struct Struct {
Object *args; int memberCount;
}; Member *members;
};
struct Member
{ struct Array {
char *name; Type *type;
Type *type; int maxBounds;
int bitSize; int *bounds;
int bitOffset; };
int byteSize;
ELFBlock *location; struct EnumMember {
}; char *name;
u32 value;
struct Struct };
{
int memberCount; struct Enum {
Member *members; int count;
}; EnumMember *members;
};
struct Array
{ struct Type {
Type *type; u32 offset;
int maxBounds; TypeEnum type;
int *bounds; const char *name;
}; int encoding;
int size;
struct EnumMember int bitSize;
{ union {
char *name; Type *pointer;
u32 value; FunctionType *function;
}; Array *array;
Struct *structure;
struct Enum Enum *enumeration;
{ };
int count; Type *next;
EnumMember *members; };
};
struct Object {
struct Type char *name;
{ int file;
u32 offset; int line;
TypeEnum type; bool external;
char *name; Type *type;
int encoding; ELFBlock *location;
int size; u32 startScope;
int bitSize; u32 endScope;
union { Object *next;
Type *pointer; };
FunctionType *function;
Array *array; struct Function {
Struct *structure; char *name;
Enum *enumeration; u32 lowPC;
}; u32 highPC;
Type *next; int file;
}; int line;
bool external;
struct Object Type *returnType;
{ Object *parameters;
char *name; Object *variables;
int file; ELFBlock *frameBase;
int line; Function *next;
bool external; };
Type *type;
ELFBlock *location; struct LineInfoItem {
u32 startScope; u32 address;
u32 endScope; char *file;
Object *next; int line;
}; };
struct Function struct LineInfo {
{ int fileCount;
char *name; char **files;
u32 lowPC; int number;
u32 highPC; LineInfoItem *lines;
int file; };
int line;
bool external; struct ARange {
Type *returnType; u32 lowPC;
Object *parameters; u32 highPC;
Object *variables; };
ELFBlock *frameBase;
Function *next; struct ARanges {
}; u32 offset;
int count;
struct LineInfoItem ARange *ranges;
{ };
u32 address;
char *file; struct CompileUnit {
int line; u32 length;
}; u8 *top;
u32 offset;
struct LineInfo ELFAbbrev **abbrevs;
{ ARanges *ranges;
int fileCount; char *name;
char **files; char *compdir;
int number; u32 lowPC;
LineInfoItem *lines; u32 highPC;
}; bool hasLineInfo;
u32 lineInfo;
struct ARange LineInfo *lineInfoTable;
{ Function *functions;
u32 lowPC; Function *lastFunction;
u32 highPC; Object *variables;
}; Type *types;
CompileUnit *next;
struct ARanges };
{
u32 offset; struct DebugInfo {
int count; u8 *debugfile;
ARange *ranges; u8 *abbrevdata;
}; u8 *debugdata;
u8 *infodata;
struct CompileUnit int numRanges;
{ ARanges *ranges;
u32 length; };
u8 *top;
u32 offset; struct Symbol {
ELFAbbrev **abbrevs; const char *name;
ARanges *ranges; int type;
char *name; int binding;
char *compdir; u32 address;
u32 lowPC; u32 value;
u32 highPC; u32 size;
bool hasLineInfo; };
u32 lineInfo;
LineInfo *lineInfoTable; extern u32 elfReadLEB128(u8 *, int *);
Function *functions; extern s32 elfReadSignedLEB128(u8 *, int *);
Function *lastFunction; extern bool elfRead(const char *, int &, FILE *f);
Object *variables; extern bool elfGetSymbolAddress(const char *,u32 *, u32 *, int *);
Type *types; extern const char *elfGetAddressSymbol(u32);
CompileUnit *next; extern const char *elfGetSymbol(int, u32 *, u32 *, int *);
}; extern void elfCleanUp();
extern bool elfGetCurrentFunction(u32, Function **, CompileUnit **c);
struct DebugInfo extern bool elfGetObject(const char *, Function *, CompileUnit *, Object **);
{ extern bool elfFindLineInUnit(u32 *, CompileUnit *, int);
u8 *debugfile; extern bool elfFindLineInModule(u32 *, const char *, int);
u8 *abbrevdata; u32 elfDecodeLocation(Function *, ELFBlock *, LocationType *);
u8 *debugdata; u32 elfDecodeLocation(Function *, ELFBlock *, LocationType *, u32);
u8 *infodata; int elfFindLine(CompileUnit *unit, Function *func, u32 addr, const char **);
int numRanges; #endif
ARanges *ranges;
};
struct Symbol
{
char *name;
int type;
int binding;
u32 address;
u32 value;
u32 size;
};
extern u32 elfReadLEB128(u8 *, int *);
extern s32 elfReadSignedLEB128(u8 *, int *);
extern bool elfRead(const char *, int &, FILE* f);
extern bool elfGetSymbolAddress(char *,u32 *, u32 *, int *);
extern char *elfGetAddressSymbol(u32);
extern char *elfGetSymbol(int, u32 *, u32 *, int *);
extern void elfCleanUp();
extern bool elfGetCurrentFunction(u32, Function **, CompileUnit **c);
extern bool elfGetObject(char *, Function *, CompileUnit *, Object **);
extern bool elfFindLineInUnit(u32 *, CompileUnit *, int);
extern bool elfFindLineInModule(u32 *, char *, int);
u32 elfDecodeLocation(Function *, ELFBlock *, LocationType *);
u32 elfDecodeLocation(Function *, ELFBlock *, LocationType *, u32);
int elfFindLine(CompileUnit *unit, Function *func, u32 addr, char **);
#endif

View File

@ -1,69 +0,0 @@
// -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
struct Node
{
Type *type;
u32 location;
u32 objLocation;
LocationType locType;
int value;
int index;
char *name;
Node *expression;
Member *member;
void (*print)(Node *);
bool (*resolve)(Node *, Function *f, CompileUnit *u);
};
extern void exprNodeCleanUp();
extern Node *exprNodeIdentifier();
extern void exprNodeIdentifierPrint(Node *);
extern bool exprNodeIdentifierResolve(Node *, Function *, CompileUnit *);
extern Node *exprNodeNumber();
extern void exprNodeNumberPrint(Node *);
extern bool exprNodeNumberResolve(Node *, Function *, CompileUnit *);
extern Node *exprNodeStar(Node *);
extern void exprNodeStarPrint(Node *);
extern bool exprNodeStarResolve(Node *, Function *, CompileUnit *);
extern Node *exprNodeDot(Node *, Node *);
extern void exprNodeDotPrint(Node *);
extern bool exprNodeDotResolve(Node *, Function *, CompileUnit *);
extern Node *exprNodeArrow(Node *, Node *);
extern void exprNodeArrowPrint(Node *);
extern bool exprNodeArrowResolve(Node *, Function *, CompileUnit *);
extern Node *exprNodeAddr(Node *);
extern void exprNodeAddrPrint(Node *);
extern bool exprNodeAddrResolve(Node *, Function *, CompileUnit *);
extern Node *exprNodeSizeof(Node *);
extern void exprNodeSizeofPrint(Node *);
extern bool exprNodeSizeofResolve(Node *, Function *, CompileUnit *);
extern Node *exprNodeArray(Node *, Node *);
extern void exprNodeArrayPrint(Node *);
extern bool exprNodeArrayResolve(Node *, Function *, CompileUnit *);
#define YYSTYPE struct Node *

File diff suppressed because it is too large Load Diff

View File

@ -1,142 +0,0 @@
/* Declarations for getopt.
Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 2000
Free Software Foundation, Inc.
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@gnu.org.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA. */
#ifndef _GETOPT_H
#define _GETOPT_H 1
#ifdef __cplusplus
extern "C"
{
#endif
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
extern char *optarg;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `getopt'.
On entry to `getopt', zero means this is the first call; initialize.
When `getopt' returns -1, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
extern int optind;
/* Callers store zero here to inhibit the error message `getopt' prints
for unrecognized options. */
extern int opterr;
/* Set to an option character which was unrecognized. */
extern int optopt;
/* Describe the long-named options requested by the application.
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
of `struct option' terminated by an element containing a name which is
zero.
The field `has_arg' is:
no_argument (or 0) if the option does not take an argument,
required_argument (or 1) if the option requires an argument,
optional_argument (or 2) if the option takes an optional argument.
If the field `flag' is not NULL, it points to a variable that is set
to the value given in the field `val' when the option is found, but
left unchanged if the option is not found.
To have a long-named option do something other than set an `int' to
a compiled-in constant, such as set a value from `optarg', set the
option's `flag' field to zero and its `val' field to a nonzero
value (the equivalent single-letter option character, if there is
one). For long options that have a zero `flag' field, `getopt'
returns the contents of the `val' field. */
struct option
{
#if defined (__STDC__) && __STDC__
const char *name;
#else
char *name;
#endif
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
int has_arg;
int *flag;
int val;
};
/* Names for the values of the `has_arg' field of `struct option'. */
#define no_argument 0
#define required_argument 1
#define optional_argument 2
#if defined (__STDC__) && __STDC__
/* HAVE_DECL_* is a three-state macro: undefined, 0 or 1. If it is
undefined, we haven't run the autoconf check so provide the
declaration without arguments. If it is 0, we checked and failed
to find the declaration so provide a fully prototyped one. If it
is 1, we found it so don't provide any declaration at all. */
#if defined (__GNU_LIBRARY__) || (defined (HAVE_DECL_GETOPT) && !HAVE_DECL_GETOPT)
/* Many other libraries have conflicting prototypes for getopt, with
differences in the consts, in stdlib.h. To avoid compilation
errors, only prototype getopt for the GNU C library. */
extern int getopt (int argc, char *const *argv, const char *shortopts);
#else /* not __GNU_LIBRARY__ */
# if !defined (HAVE_DECL_GETOPT)
extern int getopt ();
# endif
#endif /* __GNU_LIBRARY__ */
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
const struct option *longopts, int *longind);
extern int getopt_long_only (int argc, char *const *argv,
const char *shortopts,
const struct option *longopts, int *longind);
/* Internal only. Users should not call this directly. */
extern int _getopt_internal (int argc, char *const *argv,
const char *shortopts,
const struct option *longopts, int *longind,
int long_only);
#else /* not __STDC__ */
extern int getopt ();
extern int getopt_long ();
extern int getopt_long_only ();
extern int _getopt_internal ();
#endif /* __STDC__ */
#ifdef __cplusplus
}
#endif
#endif /* getopt.h */

View File

@ -1,191 +0,0 @@
/* getopt_long and getopt_long_only entry points for GNU getopt.
Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
Free Software Foundation, Inc.
NOTE: This source is derived from an old version taken from the GNU C
Library (glibc).
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "getopt.h"
#if !defined __STDC__ || !__STDC__
/* This is a separate conditional since some stdc systems
reject `defined (const)'. */
#ifndef const
#define const
#endif
#endif
#include <stdio.h>
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
#define GETOPT_INTERFACE_VERSION 2
#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
#include <gnu-versions.h>
#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
#define ELIDE_CODE
#endif
#endif
#ifndef ELIDE_CODE
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#ifdef __GNU_LIBRARY__
#include <stdlib.h>
#endif
#ifndef NULL
#define NULL 0
#endif
int
getopt_long (argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct option *long_options;
int *opt_index;
{
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
}
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
If an option that starts with '-' (not '--') doesn't match a long option,
but does match a short option, it is parsed as a short option
instead. */
int
getopt_long_only (argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct option *long_options;
int *opt_index;
{
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
}
#endif /* Not ELIDE_CODE. */
#ifdef TEST
#include <stdio.h>
int
main (argc, argv)
int argc;
char **argv;
{
int c;
int digit_optind = 0;
while (1)
{
int this_option_optind = optind ? optind : 1;
int option_index = 0;
static struct option long_options[] =
{
{"add", 1, 0, 0
},
{"append", 0, 0, 0},
{"delete", 1, 0, 0},
{"verbose", 0, 0, 0},
{"create", 0, 0, 0},
{"file", 1, 0, 0},
{0, 0, 0, 0}
};
c = getopt_long (argc, argv, "abc:d:0123456789",
long_options, &option_index);
if (c == -1)
break;
switch (c)
{
case 0:
printf ("option %s", long_options[option_index].name);
if (optarg)
printf (" with arg %s", optarg);
printf ("\n");
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
case 'a':
printf ("option a\n");
break;
case 'b':
printf ("option b\n");
break;
case 'c':
printf ("option c with value `%s'\n", optarg);
break;
case 'd':
printf ("option d with value `%s'\n", optarg);
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
exit (0);
}
#endif /* TEST */

File diff suppressed because it is too large Load Diff

View File

@ -1,298 +1,302 @@
/* /*
* This file is part of the Advance project. * This file is part of the Advance project.
* *
* Copyright (C) 2003 Andrea Mazzoleni * Copyright (C) 2003 Andrea Mazzoleni
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *
* In addition, as a special exception, Andrea Mazzoleni * In addition, as a special exception, Andrea Mazzoleni
* gives permission to link the code of this program with * gives permission to link the code of this program with
* the MAME library (or with modified versions of MAME that use the * the MAME library (or with modified versions of MAME that use the
* same license as MAME), and distribute linked combinations including * same license as MAME), and distribute linked combinations including
* the two. You must obey the GNU General Public License in all * the two. You must obey the GNU General Public License in all
* respects for all of the code used other than MAME. If you modify * respects for all of the code used other than MAME. If you modify
* this file, you may extend this exception to your version of the * this file, you may extend this exception to your version of the
* file, but you are not obligated to do so. If you do not wish to * file, but you are not obligated to do so. If you do not wish to
* do so, delete this exception statement from your version. * do so, delete this exception statement from your version.
*/ */
#ifndef __INTERP_H #ifndef __INTERP_H
#define __INTERP_H #define __INTERP_H
/***************************************************************************/ #define __STDC_CONSTANT_MACROS
/* Basic types */
#include <stdint.h>
/***************************************************************************/
/* interpolation */
typedef uint16_t interp_uint16;
static unsigned interp_mask[2]; typedef uint32_t interp_uint32;
static unsigned interp_bits_per_pixel;
/***************************************************************************/
#define INTERP_16_MASK_1(v) (v & interp_mask[0]) /* Basic types */
#define INTERP_16_MASK_2(v) (v & interp_mask[1])
/***************************************************************************/
static inline u16 interp_16_521(u16 p1, u16 p2, u16 p3) /* interpolation */
{
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*5 + INTERP_16_MASK_1(p2)*2 + INTERP_16_MASK_1(p3)*1) / 8) static unsigned interp_mask[2];
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*5 + INTERP_16_MASK_2(p2)*2 + INTERP_16_MASK_2(p3)*1) / 8); static unsigned interp_bits_per_pixel;
}
#define INTERP_16_MASK_1(v) (v & interp_mask[0])
static inline u16 interp_16_332(u16 p1, u16 p2, u16 p3) #define INTERP_16_MASK_2(v) (v & interp_mask[1])
{
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*3 + INTERP_16_MASK_1(p2)*3 + INTERP_16_MASK_1(p3)*2) / 8) static inline u16 interp_16_521(u16 p1, u16 p2, u16 p3)
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*3 + INTERP_16_MASK_2(p2)*3 + INTERP_16_MASK_2(p3)*2) / 8); {
} return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*5 + INTERP_16_MASK_1(p2)*2 + INTERP_16_MASK_1(p3)*1) / 8)
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*5 + INTERP_16_MASK_2(p2)*2 + INTERP_16_MASK_2(p3)*1) / 8);
static inline u16 interp_16_611(u16 p1, u16 p2, u16 p3) }
{
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*6 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 8) static inline u16 interp_16_332(u16 p1, u16 p2, u16 p3)
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*6 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 8); {
} return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*3 + INTERP_16_MASK_1(p2)*3 + INTERP_16_MASK_1(p3)*2) / 8)
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*3 + INTERP_16_MASK_2(p2)*3 + INTERP_16_MASK_2(p3)*2) / 8);
static inline u16 interp_16_71(u16 p1, u16 p2) }
{
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*7 + INTERP_16_MASK_1(p2)) / 8) static inline u16 interp_16_611(u16 p1, u16 p2, u16 p3)
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*7 + INTERP_16_MASK_2(p2)) / 8); {
} return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*6 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 8)
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*6 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 8);
static inline u16 interp_16_211(u16 p1, u16 p2, u16 p3) }
{
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*2 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 4) static inline u16 interp_16_71(u16 p1, u16 p2)
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*2 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 4); {
} return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*7 + INTERP_16_MASK_1(p2)) / 8)
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*7 + INTERP_16_MASK_2(p2)) / 8);
static inline u16 interp_16_772(u16 p1, u16 p2, u16 p3) }
{
return INTERP_16_MASK_1(((INTERP_16_MASK_1(p1) + INTERP_16_MASK_1(p2))*7 + INTERP_16_MASK_1(p3)*2) / 16) static inline u16 interp_16_211(u16 p1, u16 p2, u16 p3)
| INTERP_16_MASK_2(((INTERP_16_MASK_2(p1) + INTERP_16_MASK_2(p2))*7 + INTERP_16_MASK_2(p3)*2) / 16); {
} return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*2 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 4)
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*2 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 4);
static inline u16 interp_16_11(u16 p1, u16 p2) }
{
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1) + INTERP_16_MASK_1(p2)) / 2) static inline u16 interp_16_772(u16 p1, u16 p2, u16 p3)
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1) + INTERP_16_MASK_2(p2)) / 2); {
} return INTERP_16_MASK_1(((INTERP_16_MASK_1(p1) + INTERP_16_MASK_1(p2))*7 + INTERP_16_MASK_1(p3)*2) / 16)
| INTERP_16_MASK_2(((INTERP_16_MASK_2(p1) + INTERP_16_MASK_2(p2))*7 + INTERP_16_MASK_2(p3)*2) / 16);
static inline u16 interp_16_31(u16 p1, u16 p2) }
{
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*3 + INTERP_16_MASK_1(p2)) / 4) static inline u16 interp_16_11(u16 p1, u16 p2)
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*3 + INTERP_16_MASK_2(p2)) / 4); {
} return INTERP_16_MASK_1((INTERP_16_MASK_1(p1) + INTERP_16_MASK_1(p2)) / 2)
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1) + INTERP_16_MASK_2(p2)) / 2);
static inline u16 interp_16_1411(u16 p1, u16 p2, u16 p3) }
{
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*14 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 16) static inline u16 interp_16_31(u16 p1, u16 p2)
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*14 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 16); {
} return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*3 + INTERP_16_MASK_1(p2)) / 4)
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*3 + INTERP_16_MASK_2(p2)) / 4);
static inline u16 interp_16_431(u16 p1, u16 p2, u16 p3) }
{
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*4 + INTERP_16_MASK_1(p2)*3 + INTERP_16_MASK_1(p3)) / 8) static inline u16 interp_16_1411(u16 p1, u16 p2, u16 p3)
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*4 + INTERP_16_MASK_2(p2)*3 + INTERP_16_MASK_2(p3)) / 8); {
} return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*14 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 16)
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*14 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 16);
static inline u16 interp_16_53(u16 p1, u16 p2) }
{
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*5 + INTERP_16_MASK_1(p2)*3) / 8) static inline u16 interp_16_431(u16 p1, u16 p2, u16 p3)
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*5 + INTERP_16_MASK_2(p2)*3) / 8); {
} return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*4 + INTERP_16_MASK_1(p2)*3 + INTERP_16_MASK_1(p3)) / 8)
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*4 + INTERP_16_MASK_2(p2)*3 + INTERP_16_MASK_2(p3)) / 8);
static inline u16 interp_16_151(u16 p1, u16 p2) }
{
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*15 + INTERP_16_MASK_1(p2)) / 16) static inline u16 interp_16_53(u16 p1, u16 p2)
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*15 + INTERP_16_MASK_2(p2)) / 16); {
} return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*5 + INTERP_16_MASK_1(p2)*3) / 8)
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*5 + INTERP_16_MASK_2(p2)*3) / 8);
static inline u16 interp_16_97(u16 p1, u16 p2) }
{
return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*9 + INTERP_16_MASK_1(p2)*7) / 16) static inline u16 interp_16_151(u16 p1, u16 p2)
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*9 + INTERP_16_MASK_2(p2)*7) / 16); {
} return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*15 + INTERP_16_MASK_1(p2)) / 16)
| INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*15 + INTERP_16_MASK_2(p2)) / 16);
#define INTERP_32_MASK_1(v) (v & 0xFF00FF) }
#define INTERP_32_MASK_2(v) (v & 0x00FF00)
static inline u16 interp_16_97(u16 p1, u16 p2)
static inline u32 interp_32_521(u32 p1, u32 p2, u32 p3) {
{ return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*9 + INTERP_16_MASK_1(p2)*7) / 16)
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*5 + INTERP_32_MASK_1(p2)*2 + INTERP_32_MASK_1(p3)*1) / 8) | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*9 + INTERP_16_MASK_2(p2)*7) / 16);
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*5 + INTERP_32_MASK_2(p2)*2 + INTERP_32_MASK_2(p3)*1) / 8); }
}
#define INTERP_32_MASK_1(v) (v & 0xFF00FF)
static inline u32 interp_32_332(u32 p1, u32 p2, u32 p3) #define INTERP_32_MASK_2(v) (v & 0x00FF00)
{
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*3 + INTERP_32_MASK_1(p2)*3 + INTERP_32_MASK_1(p3)*2) / 8) static inline u32 interp_32_521(u32 p1, u32 p2, u32 p3)
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*3 + INTERP_32_MASK_2(p2)*3 + INTERP_32_MASK_2(p3)*2) / 8); {
} return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*5 + INTERP_32_MASK_1(p2)*2 + INTERP_32_MASK_1(p3)*1) / 8)
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*5 + INTERP_32_MASK_2(p2)*2 + INTERP_32_MASK_2(p3)*1) / 8);
static inline u32 interp_32_211(u32 p1, u32 p2, u32 p3) }
{
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*2 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 4) static inline u32 interp_32_332(u32 p1, u32 p2, u32 p3)
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*2 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 4); {
} return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*3 + INTERP_32_MASK_1(p2)*3 + INTERP_32_MASK_1(p3)*2) / 8)
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*3 + INTERP_32_MASK_2(p2)*3 + INTERP_32_MASK_2(p3)*2) / 8);
static inline u32 interp_32_611(u32 p1, u32 p2, u32 p3) }
{
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*6 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 8) static inline u32 interp_32_211(u32 p1, u32 p2, u32 p3)
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*6 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 8); {
} return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*2 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 4)
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*2 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 4);
static inline u32 interp_32_71(u32 p1, u32 p2) }
{
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*7 + INTERP_32_MASK_1(p2)) / 8) static inline u32 interp_32_611(u32 p1, u32 p2, u32 p3)
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*7 + INTERP_32_MASK_2(p2)) / 8); {
} return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*6 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 8)
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*6 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 8);
static inline u32 interp_32_772(u32 p1, u32 p2, u32 p3) }
{
return INTERP_32_MASK_1(((INTERP_32_MASK_1(p1) + INTERP_32_MASK_1(p2))*7 + INTERP_32_MASK_1(p3)*2) / 16) static inline u32 interp_32_71(u32 p1, u32 p2)
| INTERP_32_MASK_2(((INTERP_32_MASK_2(p1) + INTERP_32_MASK_2(p2))*7 + INTERP_32_MASK_2(p3)*2) / 16); {
} return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*7 + INTERP_32_MASK_1(p2)) / 8)
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*7 + INTERP_32_MASK_2(p2)) / 8);
static inline u32 interp_32_11(u32 p1, u32 p2) }
{
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1) + INTERP_32_MASK_1(p2)) / 2) static inline u32 interp_32_772(u32 p1, u32 p2, u32 p3)
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1) + INTERP_32_MASK_2(p2)) / 2); {
} return INTERP_32_MASK_1(((INTERP_32_MASK_1(p1) + INTERP_32_MASK_1(p2))*7 + INTERP_32_MASK_1(p3)*2) / 16)
| INTERP_32_MASK_2(((INTERP_32_MASK_2(p1) + INTERP_32_MASK_2(p2))*7 + INTERP_32_MASK_2(p3)*2) / 16);
static inline u32 interp_32_31(u32 p1, u32 p2) }
{
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*3 + INTERP_32_MASK_1(p2)) / 4) static inline u32 interp_32_11(u32 p1, u32 p2)
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*3 + INTERP_32_MASK_2(p2)) / 4); {
} return INTERP_32_MASK_1((INTERP_32_MASK_1(p1) + INTERP_32_MASK_1(p2)) / 2)
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1) + INTERP_32_MASK_2(p2)) / 2);
static inline u32 interp_32_1411(u32 p1, u32 p2, u32 p3) }
{
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*14 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 16) static inline u32 interp_32_31(u32 p1, u32 p2)
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*14 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 16); {
} return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*3 + INTERP_32_MASK_1(p2)) / 4)
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*3 + INTERP_32_MASK_2(p2)) / 4);
static inline u32 interp_32_431(u32 p1, u32 p2, u32 p3) }
{
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*4 + INTERP_32_MASK_1(p2)*3 + INTERP_32_MASK_1(p3)) / 8) static inline u32 interp_32_1411(u32 p1, u32 p2, u32 p3)
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*4 + INTERP_32_MASK_2(p2)*3 + INTERP_32_MASK_2(p3)) / 8); {
} return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*14 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 16)
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*14 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 16);
static inline u32 interp_32_53(u32 p1, u32 p2) }
{
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*5 + INTERP_32_MASK_1(p2)*3) / 8) static inline u32 interp_32_431(u32 p1, u32 p2, u32 p3)
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*5 + INTERP_32_MASK_2(p2)*3) / 8); {
} return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*4 + INTERP_32_MASK_1(p2)*3 + INTERP_32_MASK_1(p3)) / 8)
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*4 + INTERP_32_MASK_2(p2)*3 + INTERP_32_MASK_2(p3)) / 8);
static inline u32 interp_32_151(u32 p1, u32 p2) }
{
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*15 + INTERP_32_MASK_1(p2)) / 16) static inline u32 interp_32_53(u32 p1, u32 p2)
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*15 + INTERP_32_MASK_2(p2)) / 16); {
} return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*5 + INTERP_32_MASK_1(p2)*3) / 8)
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*5 + INTERP_32_MASK_2(p2)*3) / 8);
static inline u32 interp_32_97(u32 p1, u32 p2) }
{
return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*9 + INTERP_32_MASK_1(p2)*7) / 16) static inline u32 interp_32_151(u32 p1, u32 p2)
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*9 + INTERP_32_MASK_2(p2)*7) / 16); {
} return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*15 + INTERP_32_MASK_1(p2)) / 16)
| INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*15 + INTERP_32_MASK_2(p2)) / 16);
/***************************************************************************/ }
/* diff */
static inline u32 interp_32_97(u32 p1, u32 p2)
#define INTERP_Y_LIMIT (0x30*4) {
#define INTERP_U_LIMIT (0x07*4) return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*9 + INTERP_32_MASK_1(p2)*7) / 16)
#define INTERP_V_LIMIT (0x06*8) | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*9 + INTERP_32_MASK_2(p2)*7) / 16);
}
static int interp_16_diff(u16 p1, u16 p2)
{ /***************************************************************************/
int r, g, b; /* diff */
int y, u, v;
#define INTERP_Y_LIMIT (0x30*4)
if (p1 == p2) #define INTERP_U_LIMIT (0x07*4)
return 0; #define INTERP_V_LIMIT (0x06*8)
if (interp_bits_per_pixel == 16) static int interp_16_diff(u16 p1, u16 p2)
{ {
b = (int)((p1 & 0x1F) - (p2 & 0x1F)) << 3; int r, g, b;
g = (int)((p1 & 0x7E0) - (p2 & 0x7E0)) >> 3; int y, u, v;
r = (int)((p1 & 0xF800) - (p2 & 0xF800)) >> 8;
} if (p1 == p2)
else return 0;
{
b = (int)((p1 & 0x1F) - (p2 & 0x1F)) << 3; if (interp_bits_per_pixel == 16) {
g = (int)((p1 & 0x3E0) - (p2 & 0x3E0)) >> 2; b = (int)((p1 & 0x1F) - (p2 & 0x1F)) << 3;
r = (int)((p1 & 0x7C00) - (p2 & 0x7C00)) >> 7; g = (int)((p1 & 0x7E0) - (p2 & 0x7E0)) >> 3;
} r = (int)((p1 & 0xF800) - (p2 & 0xF800)) >> 8;
} else {
y = r + g + b; b = (int)((p1 & 0x1F) - (p2 & 0x1F)) << 3;
u = r - b; g = (int)((p1 & 0x3E0) - (p2 & 0x3E0)) >> 2;
v = -r + 2*g - b; r = (int)((p1 & 0x7C00) - (p2 & 0x7C00)) >> 7;
}
if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT)
return 1; y = r + g + b;
u = r - b;
if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT) v = -r + 2*g - b;
return 1;
if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT)
if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT) return 1;
return 1;
if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT)
return 0; return 1;
}
if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT)
static int interp_32_diff(u32 p1, u32 p2) return 1;
{
int r, g, b; return 0;
int y, u, v; }
if ((p1 & 0xF8F8F8) == (p2 & 0xF8F8F8)) static int interp_32_diff(u32 p1, u32 p2)
return 0; {
int r, g, b;
b = (int)((p1 & 0xFF) - (p2 & 0xFF)); int y, u, v;
g = (int)((p1 & 0xFF00) - (p2 & 0xFF00)) >> 8;
r = (int)((p1 & 0xFF0000) - (p2 & 0xFF0000)) >> 16; if ((p1 & 0xF8F8F8) == (p2 & 0xF8F8F8))
return 0;
y = r + g + b;
u = r - b; b = (int)((p1 & 0xFF) - (p2 & 0xFF));
v = -r + 2*g - b; g = (int)((p1 & 0xFF00) - (p2 & 0xFF00)) >> 8;
r = (int)((p1 & 0xFF0000) - (p2 & 0xFF0000)) >> 16;
if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT)
return 1; y = r + g + b;
u = r - b;
if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT) v = -r + 2*g - b;
return 1;
if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT)
if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT) return 1;
return 1;
if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT)
return 0; return 1;
}
if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT)
static void interp_set(unsigned bits_per_pixel) return 1;
{
interp_bits_per_pixel = bits_per_pixel; return 0;
}
switch (bits_per_pixel)
{ static void interp_set(unsigned bits_per_pixel)
case 15 : {
interp_mask[0] = 0x7C1F; interp_bits_per_pixel = bits_per_pixel;
interp_mask[1] = 0x03E0;
break; switch (bits_per_pixel) {
case 16 : case 15 :
interp_mask[0] = 0xF81F; interp_mask[0] = 0x7C1F;
interp_mask[1] = 0x07E0; interp_mask[1] = 0x03E0;
break; break;
case 32 : case 16 :
interp_mask[0] = 0xFF00FF; interp_mask[0] = 0xF81F;
interp_mask[1] = 0x00FF00; interp_mask[1] = 0x07E0;
break; break;
} case 32 :
} interp_mask[0] = 0xFF00FF;
interp_mask[1] = 0x00FF00;
#endif break;
}
}
#endif

View File

@ -1,157 +1,150 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "System.h" #include "System.h"
extern int RGB_LOW_BITS_MASK; extern int RGB_LOW_BITS_MASK;
void Pixelate(u8 *srcPtr, u32 srcPitch, u8 *deltaPtr, void Pixelate(u8 *srcPtr, u32 srcPitch, u8 *deltaPtr,
u8 *dstPtr, u32 dstPitch, int width, int height) u8 *dstPtr, u32 dstPitch, int width, int height)
{ {
u8 *nextLine, *finish; u8 *nextLine, *finish;
u32 colorMask = ~(RGB_LOW_BITS_MASK | (RGB_LOW_BITS_MASK << 16)); u32 colorMask = ~(RGB_LOW_BITS_MASK | (RGB_LOW_BITS_MASK << 16));
nextLine = dstPtr + dstPitch; nextLine = dstPtr + dstPitch;
do do {
{ u32 *bP = (u32 *) srcPtr;
u32 *bP = (u32 *) srcPtr; u32 *xP = (u32 *) deltaPtr;
u32 *xP = (u32 *) deltaPtr; u32 *dP = (u32 *) dstPtr;
u32 *dP = (u32 *) dstPtr; u32 *nL = (u32 *) nextLine;
u32 *nL = (u32 *) nextLine; u32 currentPixel;
u32 currentPixel; u32 nextPixel;
u32 nextPixel; u32 currentDelta;
u32 currentDelta; u32 nextDelta;
u32 nextDelta;
finish = (u8 *) bP + ((width+2) << 1);
finish = (u8 *) bP + ((width+2) << 1); nextPixel = *bP++;
nextPixel = *bP++; nextDelta = *xP++;
nextDelta = *xP++;
do {
do currentPixel = nextPixel;
{ currentDelta = nextDelta;
currentPixel = nextPixel; nextPixel = *bP++;
currentDelta = nextDelta; nextDelta = *xP++;
nextPixel = *bP++;
nextDelta = *xP++; if ((nextPixel != nextDelta) || (currentPixel != currentDelta)) {
u32 colorA, colorB, product;
if ((nextPixel != nextDelta) || (currentPixel != currentDelta))
{ *(xP - 2) = currentPixel;
u32 colorA, colorB, product; #ifdef WORDS_BIGENDIAN
colorA = currentPixel >> 16;
*(xP - 2) = currentPixel; colorB = currentPixel & 0xffff;
#ifdef WORDS_BIGENDIAN #else
colorA = currentPixel >> 16; colorA = currentPixel & 0xffff;
colorB = currentPixel & 0xffff; colorB = currentPixel >> 16;
#else #endif
colorA = currentPixel & 0xffff; product = (((colorA & colorMask) >> 1) & colorMask) >> 1;
colorB = currentPixel >> 16;
#endif #ifdef WORDS_BIGENDIAN
product = (((colorA & colorMask) >> 1) & colorMask) >> 1; *(nL) = (product << 16) | (product);
*(dP) = (colorA << 16) | product;
#ifdef WORDS_BIGENDIAN #else
*(nL) = (product << 16) | (product); *(nL) = product | (product << 16);
*(dP) = (colorA << 16) | product; *(dP) = colorA | (product << 16);
#else #endif
*(nL) = product | (product << 16);
*(dP) = colorA | (product << 16); #ifdef WORDS_BIGENDIAN
#endif colorA = nextPixel >> 16;
#else
#ifdef WORDS_BIGENDIAN colorA = nextPixel & 0xffff;
colorA = nextPixel >> 16; #endif
#else product = (((colorB & colorMask) >> 1) & colorMask) >> 1;
colorA = nextPixel & 0xffff; #ifdef WORDS_BIGENDIAN
#endif *(nL + 1) = (product << 16) | (product);
product = (((colorB & colorMask) >> 1) & colorMask) >> 1; *(dP + 1) = (colorB << 16) | (product);
#ifdef WORDS_BIGENDIAN #else
*(nL + 1) = (product << 16) | (product); *(nL + 1) = (product) | (product << 16);
*(dP + 1) = (colorB << 16) | (product); *(dP + 1) = (colorB) | (product << 16);
#else #endif
*(nL + 1) = (product) | (product << 16); }
*(dP + 1) = (colorB) | (product << 16);
#endif dP += 2;
} nL += 2;
} while ((u8 *) bP < finish);
dP += 2;
nL += 2; deltaPtr += srcPitch;
} srcPtr += srcPitch;
while ((u8 *) bP < finish); dstPtr += dstPitch << 1;
nextLine += dstPitch << 1;
deltaPtr += srcPitch; }
srcPtr += srcPitch; while (--height);
dstPtr += dstPitch << 1; }
nextLine += dstPitch << 1;
} void Pixelate32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
while (--height); u8 *dstPtr, u32 dstPitch, int width, int height)
} {
u8 *nextLine, *finish;
void Pixelate32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */, u32 colorMask = ~RGB_LOW_BITS_MASK;
u8 *dstPtr, u32 dstPitch, int width, int height)
{ nextLine = dstPtr + dstPitch;
u8 *nextLine, *finish;
u32 colorMask = ~RGB_LOW_BITS_MASK; do {
u32 *bP = (u32 *) srcPtr;
nextLine = dstPtr + dstPitch; // u32 *xP = (u32 *) deltaPtr;
u32 *dP = (u32 *) dstPtr;
do u32 *nL = (u32 *) nextLine;
{ u32 currentPixel;
u32 *bP = (u32 *) srcPtr; u32 nextPixel;
// u32 *xP = (u32 *) deltaPtr;
u32 *dP = (u32 *) dstPtr; finish = (u8 *) bP + ((width+1) << 2);
u32 *nL = (u32 *) nextLine; nextPixel = *bP++;
u32 currentPixel;
u32 nextPixel; do {
currentPixel = nextPixel;
finish = (u8 *) bP + ((width+1) << 2); nextPixel = *bP++;
nextPixel = *bP++;
u32 colorA, colorB, product;
do
{ colorA = currentPixel;
currentPixel = nextPixel; colorB = nextPixel;
nextPixel = *bP++;
product = (((colorA & colorMask) >> 1) & colorMask) >> 1;
u32 colorA, colorB, product; *(nL) = product;
*(nL+1) = product;
colorA = currentPixel; *(dP) = colorA;
colorB = nextPixel; *(dP+1) = product;
product = (((colorA & colorMask) >> 1) & colorMask) >> 1; nextPixel = *bP++;
*(nL) = product; colorA = nextPixel;
*(nL+1) = product; product = (((colorB & colorMask) >> 1) & colorMask) >> 1;
*(dP) = colorA; *(nL + 2) = product;
*(dP+1) = product; *(nL + 3) = product;
*(dP + 2) = colorB;
nextPixel = *bP++; *(dP + 3) = product;
colorA = nextPixel;
product = (((colorB & colorMask) >> 1) & colorMask) >> 1; dP += 4;
*(nL + 2) = product; nL += 4;
*(nL + 3) = product; } while ((u8 *) bP < finish);
*(dP + 2) = colorB;
*(dP + 3) = product; srcPtr += srcPitch;
dstPtr += dstPitch << 1;
dP += 4; nextLine += dstPitch << 1;
nL += 4; }
} while (--height);
while ((u8 *) bP < finish); }
srcPtr += srcPitch;
dstPtr += dstPitch << 1;
nextLine += dstPitch << 1;
}
while (--height);
}

View File

@ -1,112 +0,0 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "System.h"
void Simple2x(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
u8 *dstPtr, u32 dstPitch, int width, int height)
{
u8 *nextLine, *finish;
nextLine = dstPtr + dstPitch;
do
{
u32 *bP = (u32 *) srcPtr;
u32 *dP = (u32 *) dstPtr;
u32 *nL = (u32 *) nextLine;
u32 currentPixel;
finish = (u8 *) bP + ((width+2) << 1);
currentPixel = *bP++;
do
{
#ifdef WORDS_BIGENDIAN
u32 color = currentPixel >> 16;
#else
u32 color = currentPixel & 0xffff;
#endif
color = color | (color << 16);
*(dP) = color;
*(nL) = color;
#ifdef WORDS_BIGENDIAN
color = currentPixel & 0xffff;
#else
color = currentPixel >> 16;
#endif
color = color| (color << 16);
*(dP + 1) = color;
*(nL + 1) = color;
currentPixel = *bP++;
dP += 2;
nL += 2;
}
while ((u8 *) bP < finish);
srcPtr += srcPitch;
dstPtr += dstPitch << 1;
nextLine += dstPitch << 1;
}
while (--height);
}
void Simple2x32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
u8 *dstPtr, u32 dstPitch, int width, int height)
{
u8 *nextLine, *finish;
nextLine = dstPtr + dstPitch;
do
{
u32 *bP = (u32 *) srcPtr;
u32 *dP = (u32 *) dstPtr;
u32 *nL = (u32 *) nextLine;
u32 currentPixel;
finish = (u8 *) bP + ((width+1) << 2);
currentPixel = *bP++;
do
{
u32 color = currentPixel;
*(dP) = color;
*(dP+1) = color;
*(nL) = color;
*(nL + 1) = color;
currentPixel = *bP++;
dP += 2;
nL += 2;
}
while ((u8 *) bP < finish);
srcPtr += srcPitch;
dstPtr += dstPitch << 1;
nextLine += dstPitch << 1;
}
while (--height);
}

File diff suppressed because it is too large Load Diff