totally rewrite vram mapping. a few of your savestates might be ugly until you reload a level or somesuch. this fixes drill spirits and kirby. some regressions are to be expected, please let me know when you see them

This commit is contained in:
zeromus 2009-04-11 09:00:56 +00:00
parent 45661199e6
commit 30502706ee
8 changed files with 581 additions and 421 deletions

View File

@ -11,18 +11,16 @@ struct ALIGN(16) ARM9_struct {
u8 ARM9_REG[0x1000000];
u8 ARM9_BIOS[0x8000];
u8 ARM9_VMEM[0x800];
u8 ARM9_ABG[0x80000];
u8 ARM9_BBG[0x20000];
u8 ARM9_AOBJ[0x40000];
u8 ARM9_BOBJ[0x20000];
u8 ARM9_LCD[0xA4000];
u8 ARM9_OAM[0x800];
u8 * ExtPal[2][4];
u8 * ObjExtPal[2][2];
u8 * texPalSlot[6];
u8 *textureSlotAddr[4];
u8* ExtPal[2][4];
u8* ObjExtPal[2][2];
struct TextureInfo {
u8* texPalSlot[6];
u8* textureSlotAddr[4];
} texInfo;
u8 blank_memory[0x20000];
};

View File

@ -458,8 +458,8 @@ void GPU_setVideoProp(GPU * gpu, u32 p)
// core B : 32k, 64k, 128k, 128k
gpu->sprBoundary = 5 + cnt->OBJ_Tile_1D_Bound ;
//zero 10-apr-09 - this is just wrong.
//if((gpu->core == GPU_SUB) && (cnt->OBJ_Tile_1D_Bound == 3)) gpu->sprBoundary = 7;
//zero 10-apr-09 - not sure whether this is right...
if((gpu->core == GPU_SUB) && (cnt->OBJ_Tile_1D_Bound == 3)) gpu->sprBoundary = 7;
gpu->spriteRenderMode = GPU::SPRITE_1D;
} else {

View File

@ -405,6 +405,7 @@ void register_gl_fun(fun_gl_Begin beg,fun_gl_End end);
#define ADDRESS_STEP_64kB 0x10000
#define ADDRESS_STEP_128KB 0x20000
#define ADDRESS_STEP_256KB 0x40000
#define ADDRESS_STEP_512KB 0x80000
#define ADDRESS_MASK_256KB (ADDRESS_STEP_256KB-1)
#ifdef WORDS_BIGENDIAN
@ -593,6 +594,7 @@ typedef struct
#define ARM9MEM_BBG 0x06200000
#define ARM9MEM_AOBJ 0x06400000
#define ARM9MEM_BOBJ 0x06600000
#define ARM9MEM_LCDC 0x06800000
extern CACHE_ALIGN u8 gpuBlendTable555[17][17][32][32];

View File

@ -187,11 +187,8 @@ u8 * MMU_struct::MMU_MEM[2][256] = {
/* 3X*/ DUP16(MMU.SWIRAM),
/* 4X*/ DUP16(ARM9Mem.ARM9_REG),
/* 5X*/ DUP16(ARM9Mem.ARM9_VMEM),
/* 6X*/ DUP2(ARM9Mem.ARM9_ABG),
DUP2(ARM9Mem.ARM9_BBG),
DUP2(ARM9Mem.ARM9_AOBJ),
DUP2(ARM9Mem.ARM9_BOBJ),
DUP8(ARM9Mem.ARM9_LCD),
/* 6X*/ DUP8(0), //this gets handled by special logic
DUP8(ARM9Mem.ARM9_LCD),
/* 7X*/ DUP16(ARM9Mem.ARM9_OAM),
/* 8X*/ DUP16(NULL),
/* 9X*/ DUP16(NULL),
@ -212,7 +209,7 @@ u8 * MMU_struct::MMU_MEM[2][256] = {
/* 4X*/ DUP8(MMU.ARM7_REG),
DUP8(MMU.ARM7_WIRAM),
/* 5X*/ DUP16(MMU.UNUSED_RAM),
/* 6X*/ DUP16(ARM9Mem.ARM9_ABG),
/* 6X*/ DUP16(MMU.UNUSED_RAM),
/* 7X*/ DUP16(MMU.UNUSED_RAM),
/* 8X*/ DUP16(NULL),
/* 9X*/ DUP16(NULL),
@ -235,10 +232,7 @@ u32 MMU_struct::MMU_MASK[2][256] = {
/* 3X*/ DUP16(0x00007FFF),
/* 4X*/ DUP16(0x00FFFFFF),
/* 5X*/ DUP16(0x000007FF),
/* 6X*/ DUP2(0x0007FFFF),
DUP2(0x0001FFFF),
DUP2(0x0003FFFF),
DUP2(0x0001FFFF),
/* 6X*/ DUP8(0x00000003),
DUP8(0x000FFFFF),
/* 7X*/ DUP16(0x000007FF),
/* 8X*/ DUP16(ROM_MASK),
@ -260,7 +254,7 @@ u32 MMU_struct::MMU_MASK[2][256] = {
/* 4X*/ DUP8(0x00FFFFFF),
DUP8(0x0000FFFF),
/* 5X*/ DUP16(0x00000003),
/* 6X*/ DUP16(0x0003FFFF),
/* 6X*/ DUP16(0x00000003),
/* 7X*/ DUP16(0x00000003),
/* 8X*/ DUP16(ROM_MASK),
/* 9X*/ DUP16(ROM_MASK),
@ -284,21 +278,500 @@ TWaitState MMU_struct::MMU_WAIT32[2][16] = {
{ 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 5, 1, 1, 1, 1, 1 }, //arm7
};
//////////////////////////////////////////////////////////////
//-------------
//VRAM MEMORY MAPPING
//-------------
//(Everything is mapped through to ARM9_LCD in blocks of 16KB)
//for all of the below, values = 41 indicate unmapped memory
#define VRAM_PAGE_UNMAPPED 41
#define VRAM_LCDC_PAGES 41
u8 vram_lcdc_map[VRAM_LCDC_PAGES];
//in the range of 0x06000000 - 0x06800000 in 16KB pages (the ARM9 vram mappable area)
//this maps to 16KB pages in the LCDC buffer which is what will actually contain the data
#define VRAM_ARM9_PAGES 512
u8 vram_arm9_map[VRAM_ARM9_PAGES];
//----->
//consider these later, for better recordkeeping, instead of using the u8* in ARM9Mem
////for each 128KB texture slot, this maps to a 16KB starting page in the LCDC buffer
//#define VRAM_TEX_SLOTS 4
//u8 vram_tex_map[VRAM_TEX_SLOTS];
//
////for each 16KB tex palette slot, this maps to a 16KB starting page in the LCDC buffer
//#define VRAM_TEX_PALETTE_SLOTS 6
//u8 vram_tex_palette_map[VRAM_TEX_PALETTE_SLOTS];
//<---------
#define VRAM_BANKS 9
#define VRAM_BANK_A 0
#define VRAM_BANK_B 1
#define VRAM_BANK_C 2
#define VRAM_BANK_D 3
#define VRAM_BANK_E 4
#define VRAM_BANK_F 5
#define VRAM_BANK_G 6
#define VRAM_BANK_H 7
#define VRAM_BANK_I 8
#define VRAM_PAGE_ABG 0
#define VRAM_PAGE_BBG 128
#define VRAM_PAGE_AOBJ 256
#define VRAM_PAGE_BOBJ 384
void MMU_VRAM_unmap_all();
struct TVramBankInfo {
u8 page_addr, num_pages;
};
static const TVramBankInfo vram_bank_info[VRAM_BANKS] = {
{0,8},
{8,8},
{16,8},
{24,8},
{32,4},
{36,1},
{37,1},
{38,2},
{40,1}
};
//maps an ARM9 BG/OBJ or LCDC address into an LCDC address, and informs the caller of whether it isn't mapped
static FORCEINLINE u32 MMU_LCDmap(u32 addr, bool& unmapped)
{
unmapped = false;
//in case the address is entirely outside of the interesting ranges
if(addr < 0x06000000) return addr;
if(addr >= 0x07000000) return addr;
//handle LCD memory mirroring
if(addr>=0x068A4000)
addr = 0x06800000 +
//(addr%0xA4000); //yuck!! is this even how it mirrors? but we have to keep from overrunning the buffer somehow
(addr&0x80000); //just as likely to be right (I have no clue how it should work) but faster.
u32 vram_page;
u32 ofs = addr & 0x3FFF;
//return addresses in LCDC range
if(addr>=0x06800000)
{
//already in LCDC range. just look it up to see whether it is unmapped
vram_page = (addr>>14)&63;
assert(vram_page<VRAM_LCDC_PAGES);
vram_page = vram_lcdc_map[vram_page];
}
else
{
//map addresses in BG/OBJ range to an LCDC range
vram_page = (addr>>14)&(VRAM_ARM9_PAGES-1);
assert(vram_page<VRAM_ARM9_PAGES);
vram_page = vram_arm9_map[vram_page];
if(vram_page>=8&&vram_page<12) {
//return 0x06800000;
}
}
finish:
if(vram_page == VRAM_PAGE_UNMAPPED)
{
unmapped = true;
return 0;
}
else
return + 0x06800000 + (vram_page<<14) + ofs;
}
u8 *MMU_RenderMapToLCD(u32 vram_addr)
{
//THIS FUNCTION IS DANGEROUS!
//the very idea is heinous, since people are
//certainly reading several bytes which probably overrun a page or something
//this needs to go through a system like what is used for textures for mapping into chunks
bool unmapped;
vram_addr = MMU_LCDmap(vram_addr,unmapped);
if(unmapped) return 0;
else return ARM9Mem.ARM9_LCD + (vram_addr - 0x06800000);
}
template<u8 DMA_CHANNEL>
void DMAtoVRAMmapping()
{
//THIS IS ALSO DANGEROUS!!!!!!
//but i dont think it needs to be done
/*u32 dst = DMADst[ARMCPU_ARM9][DMA_CHANNEL];
bool unmapped;
dst = MMU_LCDmap(dst,unmapped);
DMADst[ARMCPU_ARM9][DMA_CHANNEL] = dst;*/
}
#define LOG_VRAM_ERROR() LOG("No data for block %i MST %i\n", block, VRAMBankCnt & 0x07);
//maps the specified bank to LCDC
static inline void MMU_vram_lcdc(const int bank)
{
for(int i=0;i<vram_bank_info[bank].num_pages;i++)
{
int page = vram_bank_info[bank].page_addr+i;
vram_lcdc_map[page] = page;
}
}
//maps the specified bank to ARM9 at the provided page offset
static inline void MMU_vram_arm9(const int bank, const int offset)
{
for(int i=0;i<vram_bank_info[bank].num_pages;i++)
{
int page = vram_bank_info[bank].page_addr+i;
vram_arm9_map[i+offset] = page;
}
}
static inline u8* MMU_vram_physical(const int page)
{
return ARM9Mem.ARM9_LCD + (page*ADDRESS_STEP_16KB);
}
//todo - templateize
//note: it doesnt seem right to me to map LCDC whenever a bank is allocated to BG/OBJ but thats how it is
//(in FF4, when entering a town from worldmap, the subscreen tiles are via LCDC while mapped to sub BG)
static inline void MMU_VRAMmapRefreshBank(const int bank)
{
int block = bank;
if(bank >= VRAM_BANK_H) block++;
u8 VRAMBankCnt = T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x240 + block);
//do nothing if the bank isnt enabled
u8 en = VRAMBankCnt & 0x80;
if(!en) return;
int mst,ofs;
switch(bank) {
case VRAM_BANK_A:
case VRAM_BANK_B:
mst = VRAMBankCnt & 3;
ofs = (VRAMBankCnt>>3) & 3;
switch(mst)
{
case 0: //LCDC
MMU_vram_lcdc(bank);
break;
case 1: //ABG
MMU_vram_lcdc(bank);
MMU_vram_arm9(bank,VRAM_PAGE_ABG+ofs*8);
break;
case 2: //AOBJ
switch(ofs) {
case 0:
case 1:
MMU_vram_lcdc(bank);
MMU_vram_arm9(bank,VRAM_PAGE_AOBJ+ofs*8);
break;
default:
PROGINFO("Unsupported ofs setting %d for engine A OBJ vram bank %c\n", ofs, 'A'+bank);
}
break;
case 3: //texture
ARM9Mem.texInfo.textureSlotAddr[ofs] = MMU_vram_physical(vram_bank_info[bank].page_addr);
break;
}
break;
case VRAM_BANK_C:
case VRAM_BANK_D:
mst = VRAMBankCnt & 7;
ofs = (VRAMBankCnt>>3) & 3;
switch(mst)
{
case 0: //LCDC
MMU_vram_lcdc(bank);
break;
case 1: //ABG
MMU_vram_lcdc(bank);
MMU_vram_arm9(bank,VRAM_PAGE_ABG+ofs*8);
break;
case 2: //arm7
//MMU_vram_lcdc(bank); ?
if(bank == 2) T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240, T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240) | 2);
if(bank == 3) T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240, T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240) | 1);
break;
case 3: //texture
ARM9Mem.texInfo.textureSlotAddr[ofs] = MMU_vram_physical(vram_bank_info[bank].page_addr);
break;
case 4: //BGB or BOBJ
MMU_vram_lcdc(bank);
if(bank == VRAM_BANK_C)
MMU_vram_arm9(bank,VRAM_PAGE_BBG); //BBG
else
MMU_vram_arm9(bank,VRAM_PAGE_BOBJ); //BOBJ
break;
default: goto unsupported_mst;
}
break;
case VRAM_BANK_E:
mst = VRAMBankCnt & 7;
switch(mst) {
case 0: //LCDC
MMU_vram_lcdc(bank);
break;
case 1: //ABG
MMU_vram_lcdc(bank);
MMU_vram_arm9(bank,VRAM_PAGE_ABG);
break;
case 2: //AOBJ
MMU_vram_lcdc(bank);
MMU_vram_arm9(bank,VRAM_PAGE_AOBJ);
break;
case 3: //texture palette
ARM9Mem.texInfo.texPalSlot[0] = MMU_vram_physical(vram_bank_info[bank].page_addr);
ARM9Mem.texInfo.texPalSlot[1] = MMU_vram_physical(vram_bank_info[bank].page_addr+1);
ARM9Mem.texInfo.texPalSlot[2] = MMU_vram_physical(vram_bank_info[bank].page_addr+2);
ARM9Mem.texInfo.texPalSlot[3] = MMU_vram_physical(vram_bank_info[bank].page_addr+3);
break;
case 4: //A BG extended palette
ARM9Mem.ExtPal[0][0] = MMU_vram_physical(vram_bank_info[bank].page_addr);
ARM9Mem.ExtPal[0][1] = ARM9Mem.ExtPal[0][0] + ADDRESS_STEP_8KB;
ARM9Mem.ExtPal[0][2] = ARM9Mem.ExtPal[0][1] + ADDRESS_STEP_8KB;
ARM9Mem.ExtPal[0][3] = ARM9Mem.ExtPal[0][2] + ADDRESS_STEP_8KB;
break;
default: goto unsupported_mst;
}
break;
case VRAM_BANK_F:
case VRAM_BANK_G: {
mst = VRAMBankCnt & 7;
ofs = (VRAMBankCnt>>3) & 3;
const int pageofslut[] = {0,1,4,5};
const int pageofs = pageofslut[ofs];
switch(mst)
{
case 0: //LCDC
MMU_vram_lcdc(bank);
break;
case 1: //ABG
MMU_vram_lcdc(bank);
MMU_vram_arm9(bank,VRAM_PAGE_ABG+pageofs);
MMU_vram_arm9(bank,VRAM_PAGE_ABG+pageofs+2); //unexpected mirroring (required by spyro eternal night)
break;
case 2: //AOBJ
MMU_vram_lcdc(bank);
MMU_vram_arm9(bank,VRAM_PAGE_AOBJ+pageofs);
MMU_vram_arm9(bank,VRAM_PAGE_ABG+pageofs+2); //unexpected mirroring - I have no proof, but it is inferred from the ABG above
break;
case 3: //texture palette
ARM9Mem.texInfo.texPalSlot[pageofs] = MMU_vram_physical(vram_bank_info[bank].page_addr);
break;
case 4: //A BG extended palette
switch(ofs) {
case 0:
case 1:
ARM9Mem.ExtPal[0][ofs*2] = MMU_vram_physical(vram_bank_info[bank].page_addr);
ARM9Mem.ExtPal[0][ofs*2+1] = ARM9Mem.ExtPal[0][ofs*2] + ADDRESS_STEP_8KB;
break;
default:
PROGINFO("Unsupported ofs setting %d for engine A bgextpal vram bank %c\n", ofs, 'A'+bank);
break;
}
break;
case 5: //A OBJ extended palette
ARM9Mem.ObjExtPal[0][0] = MMU_vram_physical(vram_bank_info[bank].page_addr);
ARM9Mem.ObjExtPal[0][1] = ARM9Mem.ObjExtPal[0][1] + ADDRESS_STEP_8KB;
break;
default: goto unsupported_mst;
}
break;
}
case VRAM_BANK_H:
mst = VRAMBankCnt & 3;
switch(mst)
{
case 0: //LCDC
MMU_vram_lcdc(bank);
break;
case 1: //BBG
MMU_vram_lcdc(bank);
MMU_vram_arm9(bank,VRAM_PAGE_BBG);
MMU_vram_arm9(bank,VRAM_PAGE_BBG + 4); //unexpected mirroring
break;
case 2: //B BG extended palette
ARM9Mem.ExtPal[1][0] = MMU_vram_physical(vram_bank_info[bank].page_addr);
ARM9Mem.ExtPal[1][1] = ARM9Mem.ExtPal[1][0] + ADDRESS_STEP_8KB;
ARM9Mem.ExtPal[1][2] = ARM9Mem.ExtPal[1][1] + ADDRESS_STEP_8KB;
ARM9Mem.ExtPal[1][3] = ARM9Mem.ExtPal[1][2] + ADDRESS_STEP_8KB;
break;
default: goto unsupported_mst;
}
break;
case VRAM_BANK_I:
mst = VRAMBankCnt & 3;
switch(mst)
{
case 0: //LCDC
MMU_vram_lcdc(bank);
break;
case 1: //BBG
MMU_vram_lcdc(bank);
MMU_vram_arm9(bank,VRAM_PAGE_BBG+2);
MMU_vram_arm9(bank,VRAM_PAGE_BBG+3); //unexpected mirroring
break;
case 2: //BOBJ
MMU_vram_lcdc(bank);
MMU_vram_arm9(bank,VRAM_PAGE_BOBJ);
break;
case 3: //B OBJ extended palette
ARM9Mem.ObjExtPal[1][0] = MMU_vram_physical(vram_bank_info[bank].page_addr);
ARM9Mem.ObjExtPal[1][1] = ARM9Mem.ObjExtPal[1][1] + ADDRESS_STEP_8KB;
break;
}
break;
} //switch(bank)
return;
unsupported_mst:
PROGINFO("Unsupported mst setting %d for vram bank %c\n", mst, 'A'+bank);
}
void MMU_VRAM_unmap_all()
{
for(int i=0;i<VRAM_LCDC_PAGES;i++)
vram_lcdc_map[i] = VRAM_PAGE_UNMAPPED;
for(int i=0;i<VRAM_ARM9_PAGES;i++)
vram_arm9_map[i] = VRAM_PAGE_UNMAPPED;
for (int i = 0; i < 4; i++)
{
ARM9Mem.ExtPal[0][i] = ARM9Mem.blank_memory;
ARM9Mem.ExtPal[1][i] = ARM9Mem.blank_memory;
}
ARM9Mem.ObjExtPal[0][0] = ARM9Mem.blank_memory;
ARM9Mem.ObjExtPal[0][1] = ARM9Mem.blank_memory;
ARM9Mem.ObjExtPal[1][0] = ARM9Mem.blank_memory;
ARM9Mem.ObjExtPal[1][1] = ARM9Mem.blank_memory;
for(int i=0;i<6;i++)
ARM9Mem.texInfo.texPalSlot[i] = ARM9Mem.blank_memory;
for(int i=0;i<4;i++)
ARM9Mem.texInfo.textureSlotAddr[i] = ARM9Mem.blank_memory;
}
static inline void MMU_VRAMmapControl(u8 block, u8 VRAMBankCnt)
{
//dont handle wram mappings in here
if(block == 7) {
//wram
return;
}
//first, save the texture info so we can check it for changes and trigger purges of the texcache
ARM9_struct::TextureInfo oldTexInfo = ARM9Mem.texInfo;
//unmap everything
MMU_VRAM_unmap_all();
//unmap VRAM_BANK_C and VRAM_BANK_D from arm7. theyll get mapped again in a moment if necessary
T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240, T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240) & 2);
T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240, T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240) & 1);
//write the new value to the reg
T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x240 + block, VRAMBankCnt);
//refresh all bank settings
for(int i=0;i<VRAM_BANKS;i++)
MMU_VRAMmapRefreshBank(i);
//if texInfo changed, trigger notifications
if(memcmp(&oldTexInfo,&ARM9Mem.texInfo,sizeof(ARM9_struct::TextureInfo)))
{
if(!nds.isIn3dVblank())
PROGINFO("Changing texture or texture palette mappings outside of 3d vblank\n");
gpu3D->NDS_3D_VramReconfigureSignal();
}
//-------------------------------
//set up arm9 mirrorings
//these are probably not entirely accurate. more study will be necessary.
//in general, we find that it is not uncommon at all for games to accidentally do this.
//
//being able to easily do these experiments was one of the primary motivations for this remake of the vram mapping system
//see the "unexpected mirroring" comments above for some more mirroring
//so far "unexpected mirrorings" are tested by combining these games:
//despereaux - storybook subtitles
//NSMB - world map sub screen
//drill spirits EU - mission select (just for control purposes, as it doesnt use H or I)
//...
//note that the "unexpected mirroring" items above may at some point rely on being executed in a certain order.
//(sequentially A..I)
const int types[] = {VRAM_PAGE_ABG,VRAM_PAGE_BBG,VRAM_PAGE_AOBJ,VRAM_PAGE_BOBJ};
const int sizes[] = {32,8,16,8};
for(int t=0;t<4;t++)
{
//the idea here is to pad out the mirrored space with copies of the mappable area,
//without respect to what is mapped within that mappable area.
//we hope that this is correct in all cases
//required for driller spirits in mission select (mapping is simple A,B,C,D to each purpose)
const int size = sizes[t];
const int mask = size-1;
const int type = types[t];
for(int i=size;i<128;i++)
{
const int page = type + i;
vram_arm9_map[page] = vram_arm9_map[type+(i&mask)];
}
//attempt #1: screen corruption in drill spirits EU
//it seems like these shouldnt pad out 128K banks (space beyond those should have remained unmapped)
//int mirrorMask = -1;
//int type = types[t];
////if(type==VRAM_PAGE_BOBJ) continue;
//if(type==VRAM_PAGE_AOBJ) continue;
//for(int i=0;i<128;i++)
//{
// int page = type + i;
// if(vram_arm9_map[page] == VRAM_PAGE_UNMAPPED)
// {
// if(i==0) break; //can't mirror anything if theres nothing mapped!
// if(mirrorMask == -1)
// mirrorMask = i-1;
// vram_arm9_map[page] = vram_arm9_map[type+(i&mirrorMask)];
// }
//}
}
//-------------------------------
}
//////////////////////////////////////////////////////////////
//end vram
//////////////////////////////////////////////////////////////
// VRAM mapping
u8 *LCDdst[10] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
u8 *EngineAddr[4] = { NULL, NULL, NULL, NULL };
const static u32 LCDdata[10][2]= {
{0x6800000, 8}, // Bank A
{0x6820000, 8}, // Bank B
{0x6840000, 8}, // Bank C
{0x6860000, 8}, // Bank D
{0x6880000, 4}, // Bank E
{0x6890000, 1}, // Bank F
{0x6894000, 1}, // Bank G
{0, 0},
{0x6898000, 2}, // Bank H
{0x68A0000, 1}}; // Bank I
void MMU_Init(void) {
int i;
@ -309,12 +782,11 @@ void MMU_Init(void) {
MMU.CART_ROM = MMU.UNUSED_RAM;
for(i = 0x80; i<0xA0; ++i)
{
MMU_struct::MMU_MEM[0][i] = MMU.CART_ROM;
MMU_struct::MMU_MEM[1][i] = MMU.CART_ROM;
}
for(i = 0x80; i<0xA0; ++i)
{
MMU_struct::MMU_MEM[0][i] = MMU.CART_ROM;
MMU_struct::MMU_MEM[1][i] = MMU.CART_ROM;
}
MMU.DTCMRegion = 0x027C0000;
MMU.ITCMRegion = 0x00000000;
@ -366,11 +838,6 @@ u32 DMADst[2][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}};
void MMU_clearMem()
{
memset(ARM9Mem.ARM9_ABG, 0, sizeof(ARM9Mem.ARM9_ABG));
memset(ARM9Mem.ARM9_AOBJ, 0, sizeof(ARM9Mem.ARM9_AOBJ));
memset(ARM9Mem.ARM9_BBG, 0, sizeof(ARM9Mem.ARM9_BBG));
memset(ARM9Mem.ARM9_BOBJ, 0, sizeof(ARM9Mem.ARM9_BOBJ));
memset(ARM9Mem.ARM9_DTCM, 0, sizeof(ARM9Mem.ARM9_DTCM));
memset(ARM9Mem.ARM9_ITCM, 0, sizeof(ARM9Mem.ARM9_ITCM));
memset(ARM9Mem.ARM9_LCD, 0, sizeof(ARM9Mem.ARM9_LCD));
@ -416,49 +883,8 @@ void MMU_clearMem()
SubScreen.offset = 192;
osdA->setOffset(MainScreen.offset);
osdB->setOffset(SubScreen.offset);
for(int i=0;i<4;i++)
ARM9Mem.textureSlotAddr[i] = ARM9Mem.blank_memory;
for(int i=0;i<6;i++)
ARM9Mem.texPalSlot[i] = ARM9Mem.blank_memory;
LCDdst[0] = ARM9Mem.ARM9_LCD; // Bank A
LCDdst[1] = ARM9Mem.ARM9_LCD + 0x20000; // Bank B
LCDdst[2] = ARM9Mem.ARM9_LCD + 0x40000; // Bank C
LCDdst[3] = ARM9Mem.ARM9_LCD + 0x60000; // Bank D
LCDdst[4] = ARM9Mem.ARM9_LCD + 0x80000; // Bank E
LCDdst[5] = ARM9Mem.ARM9_LCD + 0x90000; // Bank F
LCDdst[6] = ARM9Mem.ARM9_LCD + 0x94000; // Bank G
LCDdst[7] = NULL;
LCDdst[8] = ARM9Mem.ARM9_LCD + 0x98000; // Bank H
LCDdst[9] = ARM9Mem.ARM9_LCD + 0xA0000; // Bank I
EngineAddr[0] = ARM9Mem.ARM9_ABG; // Engine ABG
EngineAddr[1] = ARM9Mem.ARM9_BBG; // Engine BBG
EngineAddr[2] = ARM9Mem.ARM9_AOBJ; // Engine BOBJ
EngineAddr[3] = ARM9Mem.ARM9_BOBJ; // Engine BOBJ
for (int i = 0; i < 4; i++)
{
ARM9Mem.ExtPal[0][i] = ARM9Mem.ARM9_LCD;
ARM9Mem.ExtPal[1][i] = ARM9Mem.ARM9_LCD;
}
ARM9Mem.ObjExtPal[0][0] = ARM9Mem.ARM9_LCD;
ARM9Mem.ObjExtPal[0][1] = ARM9Mem.ARM9_LCD;
ARM9Mem.ObjExtPal[1][0] = ARM9Mem.ARM9_LCD;
ARM9Mem.ObjExtPal[1][1] = ARM9Mem.ARM9_LCD;
ARM9Mem.texPalSlot[0] = ARM9Mem.ARM9_LCD;
ARM9Mem.texPalSlot[1] = ARM9Mem.ARM9_LCD;
ARM9Mem.texPalSlot[2] = ARM9Mem.ARM9_LCD;
ARM9Mem.texPalSlot[3] = ARM9Mem.ARM9_LCD;
for (int i =0; i < 9; i++)
{
MMU.LCD_VRAM_ADDR[i] = 0;
for (int t = 0; t < 32; t++)
MMU.VRAM_MAP[i][t] = 7;
}
MMU_VRAM_unmap_all();
MMU.powerMan_CntReg = 0x00;
MMU.powerMan_CntRegWritten = FALSE;
@ -473,288 +899,6 @@ void MMU_clearMem()
Mic_Reset();
}
// VRAM mapping control
u8 *MMU_RenderMapToLCD(u32 vram_addr)
{
if ((vram_addr < 0x6000000)) return NULL;
if ((vram_addr > 0x661FFFF)) return NULL; // Engine BOBJ max 128KB
// holes
if ((vram_addr > 0x6080000) && (vram_addr < 0x6200000)) return NULL; // Engine ABG max 512KB
if ((vram_addr > 0x6220000) && (vram_addr < 0x6400000)) return NULL; // Engine BBG max 128KB
if ((vram_addr >= 0x6440000) && (vram_addr < 0x6600000)) {
assert(false); //please verify
vram_addr = (vram_addr & ADDRESS_MASK_256KB) + 0x6440000; // Engine AOBJ max 256KB
}
vram_addr &= 0x0FFFFFF;
u8 engine = (vram_addr >> 21);
vram_addr &= 0x01FFFFF;
u8 engine_offset = (vram_addr >> 14);
u8 block = MMU.VRAM_MAP[engine][engine_offset];
if (block == 7) return (EngineAddr[engine] + vram_addr); // not mapped to LCD
vram_addr -= MMU.LCD_VRAM_ADDR[block];
return (LCDdst[block] + vram_addr);
}
static FORCEINLINE u32 MMU_LCDmap(u32 addr)
{
//handle LCD memory mirroring
if ((addr < 0x07000000) && (addr>=0x068A4000))
return 0x06800000 +
//(addr%0xA4000); //yuck!! is this even how it mirrors? but we have to keep from overrunning the buffer somehow
(addr&0x80000); //just as likely to be right (I have no clue how it should work) but faster.
if ((addr < 0x6000000)) return addr;
if ((addr > 0x661FFFF)) return addr; // Engine BOBJ max 128KB
// holes
if ((addr > 0x6080000) && (addr < 0x6200000)) return addr; // Engine ABG max 512KB
if ((addr > 0x6220000) && (addr < 0x6400000)) return addr; // Engine BBG max 128KB
if ((addr > 0x6420000) && (addr < 0x6600000)) return addr; // Engine AOBJ max 256KB
u32 save_addr = addr;
addr &= 0x0FFFFFF;
u8 engine = (addr >> 21);
addr &= 0x01FFFFF;
u8 engine_offset = (addr >> 14);
u8 block = MMU.VRAM_MAP[engine][engine_offset];
if (block == 7) return (save_addr); // not mapped to LCD
addr -= MMU.LCD_VRAM_ADDR[block];
return (addr + LCDdata[block][0]);
}
template<u8 DMA_CHANNEL>
void DMAtoVRAMmapping()
{
if (DMADst[ARMCPU_ARM9][DMA_CHANNEL] < 0x6000000) return;
if (DMADst[ARMCPU_ARM9][DMA_CHANNEL] > 0x661FFFF) return;
u32 addr = DMADst[ARMCPU_ARM9][DMA_CHANNEL];
addr &= 0x0FFFFFF;
u8 engine = (addr >> 21);
addr &= 0x01FFFFF;
u8 engine_offset = (addr >> 14);
u8 block = MMU.VRAM_MAP[engine][engine_offset];
if (block == 7) return;
addr -= MMU.LCD_VRAM_ADDR[block];
//INFO("ARM9 DMA%i at dst address 0x%08X mapped to 0x%X\n", DMA_CHANNEL, DMADst[ARMCPU_ARM9][DMA_CHANNEL], (addr + LCDdata[block][0]) );
DMADst[ARMCPU_ARM9][DMA_CHANNEL] = (addr + LCDdata[block][0]);
}
#define LOG_VRAM_ERROR() LOG("No data for block %i MST %i\n", block, VRAMBankCnt & 0x07);
static inline void MMU_VRAMmapControl(u8 block, u8 VRAMBankCnt)
{
if (!(VRAMBankCnt & 0x80)) return; // disabled
u32 vram_map_addr = 0xFFFFFFFF;
u8 *LCD_addr = LCDdst[block];
bool changingTexOrTexPalette = false;
for (int i = 0; i < 4; i++)
{
for (int t = 0; t < 32; t++)
if (MMU.VRAM_MAP[i][t] == block)
MMU.VRAM_MAP[i][t] = 7;
}
switch (VRAMBankCnt & 0x07)
{
case 0: // not mapped
MMU.LCDCenable[block] = FALSE;
return;
case 1:
switch(block)
{
case 0: // A
case 1: // B
case 2: // C
case 3: // D Engine A, BG
vram_map_addr = ((VRAMBankCnt >> 3) & 3) * 0x20000;
if(block == 2) T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240, T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240) & 2);
if(block == 3) T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240, T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240) & 1);
break ;
case 4: // E Engine A, BG
vram_map_addr = 0x0000000;
break;
case 5: // F
case 6: // G Engine A, BG
vram_map_addr = (((VRAMBankCnt>>3)&1)*0x4000)+(((VRAMBankCnt>>4)&1)*0x10000);
break;
case 8: // H Engine B, BG
vram_map_addr = 0x0200000;
break ;
case 9: // I Engine B, BG
vram_map_addr = 0x0208000;
break;
default:
LOG_VRAM_ERROR();
break;
}
break ;
case 2:
switch(block)
{
case 0: // A
case 1: // B Engine A, OBJ
vram_map_addr = 0x0400000 + (((VRAMBankCnt>>3)&1)*0x20000);
break;
case 2: // C
T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240, T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240) | 1);
break;
case 3: // D
T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240, T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240) | 2);
break;
case 4: // E Engine A, OBJ
vram_map_addr = 0x0400000;
break;
case 5: // F
case 6: // G Engine A, OBJ
vram_map_addr = 0x0400000 + (((VRAMBankCnt>>3)&1)*0x4000)+(((VRAMBankCnt>>4)&1)*0x10000);
break;
case 8: // H Engine B, BG
ARM9Mem.ExtPal[1][0] = LCD_addr;
ARM9Mem.ExtPal[1][1] = LCD_addr+0x2000;
ARM9Mem.ExtPal[1][2] = LCD_addr+0x4000;
ARM9Mem.ExtPal[1][3] = LCD_addr+0x6000;
break;
case 9: // I Engine B, OBJ
vram_map_addr = 0x0600000;
break;
default:
LOG_VRAM_ERROR();
break;
}
break ;
case 3:
switch (block)
{
case 0: // A
case 1: // B
case 2: // C
case 3: // D
// Textures
{
changingTexOrTexPalette = true;
int slot_index = (VRAMBankCnt >> 3) & 0x3;
ARM9Mem.textureSlotAddr[slot_index] = LCD_addr;
gpu3D->NDS_3D_VramReconfigureSignal();
if(block == 2) T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240, T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240) & 2);
if(block == 3) T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240, T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240) & 1);
}
break;
case 4: // E
changingTexOrTexPalette = true;
ARM9Mem.texPalSlot[0] = LCD_addr;
ARM9Mem.texPalSlot[1] = LCD_addr+0x4000;
ARM9Mem.texPalSlot[2] = LCD_addr+0x8000;
ARM9Mem.texPalSlot[3] = LCD_addr+0xC000;
gpu3D->NDS_3D_VramReconfigureSignal();
break;
case 5: // F
case 6: // G
{
changingTexOrTexPalette = true;
u8 tmp_slot = ((VRAMBankCnt >> 3) & 0x01) + (((VRAMBankCnt >> 4) & 0x01)*4);
ARM9Mem.texPalSlot[tmp_slot] = LCD_addr;
gpu3D->NDS_3D_VramReconfigureSignal();
}
break;
case 9: // I Engine B, OBJ
ARM9Mem.ObjExtPal[1][0] = LCD_addr;
ARM9Mem.ObjExtPal[1][1] = LCD_addr+0x2000;
break;
default:
LOG_VRAM_ERROR();
break;
}
break ;
case 4:
switch(block)
{
case 2: // C Engine B, BG
vram_map_addr = 0x0200000;
T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240, T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240) & 2);
break ;
case 3: // D Engine B, OBJ
vram_map_addr = 0x0600000;
T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240, T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x240) & 1);
break ;
case 4: // E Engine A, BG
ARM9Mem.ExtPal[0][0] = LCD_addr;
ARM9Mem.ExtPal[0][1] = LCD_addr+0x2000;
ARM9Mem.ExtPal[0][2] = LCD_addr+0x4000;
ARM9Mem.ExtPal[0][3] = LCD_addr+0x6000;
break;
case 5: // F
case 6: // G Engine A, BG
{
u8 tmp_slot = (VRAMBankCnt >> 2) & 0x02;
ARM9Mem.ExtPal[0][tmp_slot] = LCD_addr;
ARM9Mem.ExtPal[0][tmp_slot+1] = LCD_addr+0x2000;
}
break;
default:
LOG_VRAM_ERROR();
break;
}
break;
case 5:
if ((block == 5) || (block == 6)) // F, G Engine A, OBJ
{
ARM9Mem.ObjExtPal[0][0] = LCD_addr;
ARM9Mem.ObjExtPal[0][1] = LCD_addr + 0x2000;
}
break;
}
if(changingTexOrTexPalette && !nds.isIn3dVblank())
{
PROGINFO("Changing texture or texture palette mappings outside of 3d vblank\n");
}
if (vram_map_addr != 0xFFFFFFFF)
{
u8 engine = (vram_map_addr >> 21);
vram_map_addr &= 0x001FFFFF;
u8 engine_offset = (vram_map_addr >> 14);
MMU.LCD_VRAM_ADDR[block] = vram_map_addr;
MMU.LCDCenable[block] = TRUE;
for (unsigned int i = 0; i < LCDdata[block][1]; i++)
MMU.VRAM_MAP[engine][engine_offset + i] = (u8)block;
//INFO("VRAM %i mapping: eng=%i (offs=%i, size=%i), addr = 0x%X, MST=%i\n",
// block, engine, engine_offset, LCDdata[block][1]*0x4000, MMU.LCD_VRAM_ADDR[block], VRAMBankCnt & 0x07);
//unmap texmem
for(int i=0;i<4;i++)
if(ARM9Mem.textureSlotAddr[i] == LCD_addr)
ARM9Mem.textureSlotAddr[i] = ARM9Mem.blank_memory;
//unmap texpal mem. This is not a straightforward way to do it,
//but it is the only place we have this information stored.
for(int i=0;i<4;i++)
if( (ARM9Mem.texPalSlot[i] == LCD_addr + 0x4000*i) || (ARM9Mem.texPalSlot[i] == LCD_addr) )
ARM9Mem.texPalSlot[i] = ARM9Mem.blank_memory;
for(int i=4;i<6;i++)
if(ARM9Mem.texPalSlot[i] == LCD_addr)
ARM9Mem.texPalSlot[i] = ARM9Mem.blank_memory;
return;
}
MMU.LCDCenable[block] = FALSE;
}
void MMU_setRom(u8 * rom, u32 mask)
{
unsigned int i;
@ -1699,7 +1843,9 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val)
return;
}
adr = MMU_LCDmap(adr);
bool unmapped;
adr = MMU_LCDmap(adr, unmapped);
if(unmapped) return;
// Removed the &0xFF as they are implicit with the adr&0x0FFFFFFFF [shash]
MMU.MMU_MEM[ARMCPU_ARM9][adr>>20][adr&MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]]=val;
@ -2282,7 +2428,9 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
return;
}
adr = MMU_LCDmap(adr); // VRAM mapping
bool unmapped;
adr = MMU_LCDmap(adr, unmapped);
if(unmapped) return;
// Removed the &0xFF as they are implicit with the adr&0x0FFFFFFFF [shash]
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr&MMU.MMU_MASK[ARMCPU_ARM9][adr>>20], val);
@ -2859,7 +3007,9 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
return;
}
adr = MMU_LCDmap(adr); // VRAM mapping
bool unmapped;
adr = MMU_LCDmap(adr, unmapped);
if(unmapped) return;
// Removed the &0xFF as they are implicit with the adr&0x0FFFFFFFF [shash]
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr&MMU.MMU_MASK[ARMCPU_ARM9][adr>>20], val);
@ -2891,7 +3041,10 @@ u8 FASTCALL _MMU_ARM9_read08(u32 adr)
mmu_log_debug_ARM9(adr, "(read08) %0x%X",
MMU.MMU_MEM[ARMCPU_ARM9][(adr>>20)&0xFF][adr&MMU.MMU_MASK[ARMCPU_ARM9][(adr>>20)&0xFF]]);
#endif
adr = MMU_LCDmap(adr);
bool unmapped;
adr = MMU_LCDmap(adr, unmapped);
if(unmapped) return 0;
return MMU.MMU_MEM[ARMCPU_ARM9][(adr>>20)&0xFF][adr&MMU.MMU_MASK[ARMCPU_ARM9][(adr>>20)&0xFF]];
}
@ -2970,9 +3123,10 @@ u16 FASTCALL _MMU_ARM9_read16(u32 adr)
return T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], adr & MMU.MMU_MASK[ARMCPU_ARM9][(adr >> 20) & 0xFF]);
}
adr = MMU_LCDmap(adr);
bool unmapped;
adr = MMU_LCDmap(adr,unmapped);
if(unmapped) return 0;
/* Returns data from memory */
return T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][(adr >> 20) & 0xFF], adr & MMU.MMU_MASK[ARMCPU_ARM9][(adr >> 20) & 0xFF]);
}
@ -3168,9 +3322,10 @@ u32 FASTCALL _MMU_ARM9_read32(u32 adr)
return T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], adr & MMU.MMU_MASK[ARMCPU_ARM9][(adr >> 20)]);
}
adr = MMU_LCDmap(adr);
bool unmapped;
adr = MMU_LCDmap(adr,unmapped);
if(unmapped) return 0;
//Returns data from memory
// Removed the &0xFF as they are implicit with the adr&0x0FFFFFFFF [zeromus, inspired by shash]
return T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][(adr >> 20)], adr & MMU.MMU_MASK[ARMCPU_ARM9][(adr >> 20)]);
}
@ -4209,8 +4364,8 @@ void FASTCALL MMU_write8(u32 proc, u32 adr, u8 val)
}
void mmu_select_savetype(int type, int *bmemtype, u32 *bmemsize) {
if (type<0 || type > 6) return;
*bmemtype=save_types[type][0];
*bmemsize=save_types[type][1];
mc_realloc(&MMU.bupmem, *bmemtype, *bmemsize);
if (type<0 || type > 6) return;
*bmemtype=save_types[type][0];
*bmemsize=save_types[type][1];
mc_realloc(&MMU.bupmem, *bmemtype, *bmemsize);
}

View File

@ -143,10 +143,6 @@ SFORMAT SF_MEM[]={
{ "VMEM", 1, 0x800, ARM9Mem.ARM9_VMEM},
{ "OAMS", 1, 0x800, ARM9Mem.ARM9_OAM},
{ "ABGM", 1, 0x80000, ARM9Mem.ARM9_ABG},
{ "BBGM", 1, 0x20000, ARM9Mem.ARM9_BBG},
{ "AOBJ", 1, 0x40000, ARM9Mem.ARM9_AOBJ},
{ "BOBJ", 1, 0x20000, ARM9Mem.ARM9_BOBJ},
{ "LCDM", 1, 0xA4000, ARM9Mem.ARM9_LCD},
{ 0 }
};

View File

@ -90,7 +90,7 @@ static MemSpan MemSpan_TexMem(u32 ofs, u32 len)
len -= curr.len;
ofs += curr.len;
currofs += curr.len;
u8* ptr = ARM9Mem.textureSlotAddr[slot];
u8* ptr = ARM9Mem.texInfo.textureSlotAddr[slot];
if(ptr == ARM9Mem.blank_memory) {
PROGINFO("Tried to reference unmapped texture memory: slot %d\n",slot);
@ -121,7 +121,7 @@ static MemSpan MemSpan_TexPalette(u32 ofs, u32 len)
//if(len != 0)
//here is an actual test case of bank spanning
currofs += curr.len;
u8* ptr = ARM9Mem.texPalSlot[slot];
u8* ptr = ARM9Mem.texInfo.texPalSlot[slot];
if(ptr == ARM9Mem.blank_memory) {
PROGINFO("Tried to reference unmapped texture palette memory: 16k slot #%d\n",slot);
@ -402,7 +402,7 @@ REJECT:
//this check isnt necessary since the addressing is tied to the texture data which will also run out:
//if(msIndex.numItems != 1) PROGINFO("Your 4x4 texture index has overrun its slot.\n");
#define PAL4X4(offset) ( *(u16*)( ARM9Mem.texPalSlot[((paletteAddress + (offset)*2)>>14)] + ((paletteAddress + (offset)*2)&0x3FFF) ) )
#define PAL4X4(offset) ( *(u16*)( ARM9Mem.texInfo.texPalSlot[((paletteAddress + (offset)*2)>>14)] + ((paletteAddress + (offset)*2)&0x3FFF) ) )
u16* slot1;
u32* map = (u32*)ms.items[0].ptr;
@ -410,9 +410,9 @@ REJECT:
u32 d = 0;
if ( (texcache[tx].frm & 0xc000) == 0x8000)
// texel are in slot 2
slot1=(u16*)&ARM9Mem.textureSlotAddr[1][((texcache[tx].frm & 0x3FFF)<<2)+0x010000];
slot1=(u16*)&ARM9Mem.texInfo.textureSlotAddr[1][((texcache[tx].frm & 0x3FFF)<<2)+0x010000];
else
slot1=(u16*)&ARM9Mem.textureSlotAddr[1][(texcache[tx].frm & 0x3FFF)<<2];
slot1=(u16*)&ARM9Mem.texInfo.textureSlotAddr[1][(texcache[tx].frm & 0x3FFF)<<2];
u16 yTmpSize = (texcache[tx].sizeY>>2);
u16 xTmpSize = (texcache[tx].sizeX>>2);

View File

@ -275,7 +275,7 @@ BOOL CALLBACK ViewPalProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam
case 17 :
case 18 :
case 19 :
PalView->adr = ((u16 *)(ARM9Mem.texPalSlot[sel-16]));
PalView->adr = ((u16 *)(ARM9Mem.texInfo.texPalSlot[sel-16]));
PalView->palnum = 0;
ShowWindow(GetDlgItem(hwnd, IDC_SCROLLER), SW_SHOW);
EnableWindow(GetDlgItem(hwnd, IDC_SCROLLER), TRUE);

View File

@ -24,6 +24,7 @@
#include "resource.h"
#include "debug.h"
#include "../MMU.h"
#include "../gpu.h"
typedef struct
{
@ -31,7 +32,7 @@ typedef struct
bool autoup;
HWND hwnd;
u8 * mem;
u32 target;
u16 * pal;
s16 palnum;
u16 tilenum;
@ -78,7 +79,9 @@ LRESULT TileViewBox_Direct(HWND hwnd, tileview_struct * win, WPARAM wParam, LPAR
FillRect(mem_dc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
SetDIBitsToDevice(mem_dc, 0, 0, 256, 256, 0, 0, 0, 256, win->mem, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
u8* mem = MMU_RenderMapToLCD(win->target);
if(mem)
SetDIBitsToDevice(mem_dc, 0, 0, 256, 256, 0, 0, 0, 256, mem, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
BitBlt(hdc, 0, 0, lg, ht, mem_dc, 0, 0, SRCCOPY);
@ -133,14 +136,16 @@ LRESULT TileViewBox_Pal256(HWND hwnd, tileview_struct * win, WPARAM wParam, LPAR
{
u32 i, num2, num, y, x;
//for(i = 0; i<256*256; ++i)
// bitmap[i] = pal[win->mem[i]];
for(num2 = 0; num2<32; ++num2)
for(num = 0; num<32; ++num)
for(y = 0; y<8; ++y)
for(x = 0; x<8; ++x)
bitmap[x + (y*256) + (num*8) +(num2*256*8)] = pal[win->mem[x + (y*8) + (num*64) +(num2*2048)]];
SetDIBitsToDevice(mem_dc, 0, 0, 256, 256, 0, 0, 0, 256, bitmap, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
u8* mem = MMU_RenderMapToLCD(win->target);
if(mem)
{
for(num2 = 0; num2<32; ++num2)
for(num = 0; num<32; ++num)
for(y = 0; y<8; ++y)
for(x = 0; x<8; ++x)
bitmap[x + (y*256) + (num*8) +(num2*256*8)] = pal[mem[x + (y*8) + (num*64) +(num2*2048)]];
SetDIBitsToDevice(mem_dc, 0, 0, 256, 256, 0, 0, 0, 256, bitmap, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
}
sprintf(text, "Pal : %d", win->palnum);
SetWindowText(GetDlgItem(hwnd, IDC_PALNUM), text);
}
@ -198,16 +203,20 @@ LRESULT TileViewBox_Pal16(HWND hwnd, tileview_struct * win, WPARAM wParam, LPARA
if(win->pal)
{
u32 num2, num, y, x;
for(num2 = 0; num2<32; ++num2)
for(num = 0; num<64; ++num)
for(y = 0; y<8; ++y)
for(x = 0; x<4; ++x)
{
bitmap[(x<<1) + (y*512) + (num*8) +(num2*512*8)] = pal[win->mem[x + (y*4) + (num*32) +(num2*2048)]&0xF];
bitmap[(x<<1)+1 + (y*512) + (num*8) +(num2*512*8)] = pal[win->mem[x + (y*4) + (num*32) +(num2*2048)]>>4];
}
SetDIBitsToDevice(mem_dc, 0, 0, 512, 256, 0, 0, 0, 256, bitmap, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
u8* mem = MMU_RenderMapToLCD(win->target);
if(mem)
{
u32 num2, num, y, x;
for(num2 = 0; num2<32; ++num2)
for(num = 0; num<64; ++num)
for(y = 0; y<8; ++y)
for(x = 0; x<4; ++x)
{
bitmap[(x<<1) + (y*512) + (num*8) +(num2*512*8)] = pal[mem[x + (y*4) + (num*32) +(num2*2048)]&0xF];
bitmap[(x<<1)+1 + (y*512) + (num*8) +(num2*512*8)] = pal[mem[x + (y*4) + (num*32) +(num2*2048)]>>4];
}
SetDIBitsToDevice(mem_dc, 0, 0, 512, 256, 0, 0, 0, 256, bitmap, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
}
sprintf(text, "Pal : %d", win->palnum);
SetWindowText(GetDlgItem(hwnd, IDC_PALNUM), text);
}
@ -325,7 +334,7 @@ BOOL CALLBACK ViewTilesProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lPar
TileView = new tileview_struct;
memset(TileView, 0, sizeof(tileview_struct));
TileView->hwnd = hwnd;
TileView->mem = ARM9Mem.ARM9_ABG;
TileView->target = ARM9MEM_ABG;
TileView->pal = ((u16 *)ARM9Mem.ARM9_VMEM);
TileView->autoup_secs = 1;
SendMessage(GetDlgItem(hwnd, IDC_AUTO_UPDATE_SPIN),
@ -492,21 +501,21 @@ BOOL CALLBACK ViewTilesProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lPar
case 5 :
case 6 :
case 7 :
TileView->mem = ARM9Mem.ARM9_ABG + 0x10000*sel;
TileView->target = ARM9MEM_ABG + 0x10000*sel;
break;
case 8 :
case 9 :
TileView->mem = ARM9Mem.ARM9_BBG + 0x10000*(sel-8);
TileView->target = ARM9MEM_BBG + 0x10000*(sel-8);
break;
case 10 :
case 11 :
case 12 :
case 13 :
TileView->mem = ARM9Mem.ARM9_AOBJ + 0x10000*(sel-10);
TileView->target = ARM9MEM_AOBJ + 0x10000*(sel-10);
break;
case 14 :
case 15 :
TileView->mem = ARM9Mem.ARM9_BOBJ + 0x10000*(sel-14);
TileView->target = ARM9MEM_BOBJ + 0x10000*(sel-14);
break;
case 16 :
case 17 :
@ -518,7 +527,7 @@ BOOL CALLBACK ViewTilesProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lPar
case 23 :
case 24 :
case 25 :
TileView->mem = ARM9Mem.ARM9_LCD + 0x10000*(sel-16);
TileView->target = ARM9MEM_LCDC + 0x10000*(sel-16);
break;
default :
return 1;
@ -617,7 +626,7 @@ BOOL CALLBACK ViewTilesProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lPar
case 17 :
case 18 :
case 19 :
TileView->pal = ((u16 *)(ARM9Mem.texPalSlot[sel-16]));
TileView->pal = ((u16 *)(ARM9Mem.texInfo.texPalSlot[sel-16]));
TileView->palnum = 0;
ShowWindow(GetDlgItem(hwnd, IDC_16COUL), SW_SHOW);
EnableWindow(GetDlgItem(hwnd, IDC_16COUL), TRUE);