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:
parent
45661199e6
commit
30502706ee
|
@ -11,18 +11,16 @@ struct ALIGN(16) ARM9_struct {
|
||||||
u8 ARM9_REG[0x1000000];
|
u8 ARM9_REG[0x1000000];
|
||||||
u8 ARM9_BIOS[0x8000];
|
u8 ARM9_BIOS[0x8000];
|
||||||
u8 ARM9_VMEM[0x800];
|
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_LCD[0xA4000];
|
||||||
u8 ARM9_OAM[0x800];
|
u8 ARM9_OAM[0x800];
|
||||||
|
|
||||||
u8 * ExtPal[2][4];
|
u8* ExtPal[2][4];
|
||||||
u8 * ObjExtPal[2][2];
|
u8* ObjExtPal[2][2];
|
||||||
u8 * texPalSlot[6];
|
|
||||||
|
struct TextureInfo {
|
||||||
u8 *textureSlotAddr[4];
|
u8* texPalSlot[6];
|
||||||
|
u8* textureSlotAddr[4];
|
||||||
|
} texInfo;
|
||||||
|
|
||||||
u8 blank_memory[0x20000];
|
u8 blank_memory[0x20000];
|
||||||
};
|
};
|
||||||
|
|
|
@ -458,8 +458,8 @@ void GPU_setVideoProp(GPU * gpu, u32 p)
|
||||||
// core B : 32k, 64k, 128k, 128k
|
// core B : 32k, 64k, 128k, 128k
|
||||||
gpu->sprBoundary = 5 + cnt->OBJ_Tile_1D_Bound ;
|
gpu->sprBoundary = 5 + cnt->OBJ_Tile_1D_Bound ;
|
||||||
|
|
||||||
//zero 10-apr-09 - this is just wrong.
|
//zero 10-apr-09 - not sure whether this is right...
|
||||||
//if((gpu->core == GPU_SUB) && (cnt->OBJ_Tile_1D_Bound == 3)) gpu->sprBoundary = 7;
|
if((gpu->core == GPU_SUB) && (cnt->OBJ_Tile_1D_Bound == 3)) gpu->sprBoundary = 7;
|
||||||
|
|
||||||
gpu->spriteRenderMode = GPU::SPRITE_1D;
|
gpu->spriteRenderMode = GPU::SPRITE_1D;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -405,6 +405,7 @@ void register_gl_fun(fun_gl_Begin beg,fun_gl_End end);
|
||||||
#define ADDRESS_STEP_64kB 0x10000
|
#define ADDRESS_STEP_64kB 0x10000
|
||||||
#define ADDRESS_STEP_128KB 0x20000
|
#define ADDRESS_STEP_128KB 0x20000
|
||||||
#define ADDRESS_STEP_256KB 0x40000
|
#define ADDRESS_STEP_256KB 0x40000
|
||||||
|
#define ADDRESS_STEP_512KB 0x80000
|
||||||
#define ADDRESS_MASK_256KB (ADDRESS_STEP_256KB-1)
|
#define ADDRESS_MASK_256KB (ADDRESS_STEP_256KB-1)
|
||||||
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
|
@ -593,6 +594,7 @@ typedef struct
|
||||||
#define ARM9MEM_BBG 0x06200000
|
#define ARM9MEM_BBG 0x06200000
|
||||||
#define ARM9MEM_AOBJ 0x06400000
|
#define ARM9MEM_AOBJ 0x06400000
|
||||||
#define ARM9MEM_BOBJ 0x06600000
|
#define ARM9MEM_BOBJ 0x06600000
|
||||||
|
#define ARM9MEM_LCDC 0x06800000
|
||||||
|
|
||||||
extern CACHE_ALIGN u8 gpuBlendTable555[17][17][32][32];
|
extern CACHE_ALIGN u8 gpuBlendTable555[17][17][32][32];
|
||||||
|
|
||||||
|
|
|
@ -187,11 +187,8 @@ u8 * MMU_struct::MMU_MEM[2][256] = {
|
||||||
/* 3X*/ DUP16(MMU.SWIRAM),
|
/* 3X*/ DUP16(MMU.SWIRAM),
|
||||||
/* 4X*/ DUP16(ARM9Mem.ARM9_REG),
|
/* 4X*/ DUP16(ARM9Mem.ARM9_REG),
|
||||||
/* 5X*/ DUP16(ARM9Mem.ARM9_VMEM),
|
/* 5X*/ DUP16(ARM9Mem.ARM9_VMEM),
|
||||||
/* 6X*/ DUP2(ARM9Mem.ARM9_ABG),
|
/* 6X*/ DUP8(0), //this gets handled by special logic
|
||||||
DUP2(ARM9Mem.ARM9_BBG),
|
DUP8(ARM9Mem.ARM9_LCD),
|
||||||
DUP2(ARM9Mem.ARM9_AOBJ),
|
|
||||||
DUP2(ARM9Mem.ARM9_BOBJ),
|
|
||||||
DUP8(ARM9Mem.ARM9_LCD),
|
|
||||||
/* 7X*/ DUP16(ARM9Mem.ARM9_OAM),
|
/* 7X*/ DUP16(ARM9Mem.ARM9_OAM),
|
||||||
/* 8X*/ DUP16(NULL),
|
/* 8X*/ DUP16(NULL),
|
||||||
/* 9X*/ DUP16(NULL),
|
/* 9X*/ DUP16(NULL),
|
||||||
|
@ -212,7 +209,7 @@ u8 * MMU_struct::MMU_MEM[2][256] = {
|
||||||
/* 4X*/ DUP8(MMU.ARM7_REG),
|
/* 4X*/ DUP8(MMU.ARM7_REG),
|
||||||
DUP8(MMU.ARM7_WIRAM),
|
DUP8(MMU.ARM7_WIRAM),
|
||||||
/* 5X*/ DUP16(MMU.UNUSED_RAM),
|
/* 5X*/ DUP16(MMU.UNUSED_RAM),
|
||||||
/* 6X*/ DUP16(ARM9Mem.ARM9_ABG),
|
/* 6X*/ DUP16(MMU.UNUSED_RAM),
|
||||||
/* 7X*/ DUP16(MMU.UNUSED_RAM),
|
/* 7X*/ DUP16(MMU.UNUSED_RAM),
|
||||||
/* 8X*/ DUP16(NULL),
|
/* 8X*/ DUP16(NULL),
|
||||||
/* 9X*/ DUP16(NULL),
|
/* 9X*/ DUP16(NULL),
|
||||||
|
@ -235,10 +232,7 @@ u32 MMU_struct::MMU_MASK[2][256] = {
|
||||||
/* 3X*/ DUP16(0x00007FFF),
|
/* 3X*/ DUP16(0x00007FFF),
|
||||||
/* 4X*/ DUP16(0x00FFFFFF),
|
/* 4X*/ DUP16(0x00FFFFFF),
|
||||||
/* 5X*/ DUP16(0x000007FF),
|
/* 5X*/ DUP16(0x000007FF),
|
||||||
/* 6X*/ DUP2(0x0007FFFF),
|
/* 6X*/ DUP8(0x00000003),
|
||||||
DUP2(0x0001FFFF),
|
|
||||||
DUP2(0x0003FFFF),
|
|
||||||
DUP2(0x0001FFFF),
|
|
||||||
DUP8(0x000FFFFF),
|
DUP8(0x000FFFFF),
|
||||||
/* 7X*/ DUP16(0x000007FF),
|
/* 7X*/ DUP16(0x000007FF),
|
||||||
/* 8X*/ DUP16(ROM_MASK),
|
/* 8X*/ DUP16(ROM_MASK),
|
||||||
|
@ -260,7 +254,7 @@ u32 MMU_struct::MMU_MASK[2][256] = {
|
||||||
/* 4X*/ DUP8(0x00FFFFFF),
|
/* 4X*/ DUP8(0x00FFFFFF),
|
||||||
DUP8(0x0000FFFF),
|
DUP8(0x0000FFFF),
|
||||||
/* 5X*/ DUP16(0x00000003),
|
/* 5X*/ DUP16(0x00000003),
|
||||||
/* 6X*/ DUP16(0x0003FFFF),
|
/* 6X*/ DUP16(0x00000003),
|
||||||
/* 7X*/ DUP16(0x00000003),
|
/* 7X*/ DUP16(0x00000003),
|
||||||
/* 8X*/ DUP16(ROM_MASK),
|
/* 8X*/ DUP16(ROM_MASK),
|
||||||
/* 9X*/ 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
|
{ 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) {
|
void MMU_Init(void) {
|
||||||
int i;
|
int i;
|
||||||
|
@ -309,12 +782,11 @@ void MMU_Init(void) {
|
||||||
|
|
||||||
MMU.CART_ROM = MMU.UNUSED_RAM;
|
MMU.CART_ROM = MMU.UNUSED_RAM;
|
||||||
|
|
||||||
for(i = 0x80; i<0xA0; ++i)
|
for(i = 0x80; i<0xA0; ++i)
|
||||||
{
|
{
|
||||||
MMU_struct::MMU_MEM[0][i] = MMU.CART_ROM;
|
MMU_struct::MMU_MEM[0][i] = MMU.CART_ROM;
|
||||||
MMU_struct::MMU_MEM[1][i] = MMU.CART_ROM;
|
MMU_struct::MMU_MEM[1][i] = MMU.CART_ROM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MMU.DTCMRegion = 0x027C0000;
|
MMU.DTCMRegion = 0x027C0000;
|
||||||
MMU.ITCMRegion = 0x00000000;
|
MMU.ITCMRegion = 0x00000000;
|
||||||
|
@ -366,11 +838,6 @@ u32 DMADst[2][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}};
|
||||||
|
|
||||||
void MMU_clearMem()
|
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_DTCM, 0, sizeof(ARM9Mem.ARM9_DTCM));
|
||||||
memset(ARM9Mem.ARM9_ITCM, 0, sizeof(ARM9Mem.ARM9_ITCM));
|
memset(ARM9Mem.ARM9_ITCM, 0, sizeof(ARM9Mem.ARM9_ITCM));
|
||||||
memset(ARM9Mem.ARM9_LCD, 0, sizeof(ARM9Mem.ARM9_LCD));
|
memset(ARM9Mem.ARM9_LCD, 0, sizeof(ARM9Mem.ARM9_LCD));
|
||||||
|
@ -416,49 +883,8 @@ void MMU_clearMem()
|
||||||
SubScreen.offset = 192;
|
SubScreen.offset = 192;
|
||||||
osdA->setOffset(MainScreen.offset);
|
osdA->setOffset(MainScreen.offset);
|
||||||
osdB->setOffset(SubScreen.offset);
|
osdB->setOffset(SubScreen.offset);
|
||||||
|
|
||||||
for(int i=0;i<4;i++)
|
MMU_VRAM_unmap_all();
|
||||||
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.powerMan_CntReg = 0x00;
|
MMU.powerMan_CntReg = 0x00;
|
||||||
MMU.powerMan_CntRegWritten = FALSE;
|
MMU.powerMan_CntRegWritten = FALSE;
|
||||||
|
@ -473,288 +899,6 @@ void MMU_clearMem()
|
||||||
Mic_Reset();
|
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)
|
void MMU_setRom(u8 * rom, u32 mask)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
@ -1699,7 +1843,9 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val)
|
||||||
return;
|
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]
|
// 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;
|
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;
|
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]
|
// 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);
|
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;
|
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]
|
// 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);
|
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_log_debug_ARM9(adr, "(read08) %0x%X",
|
||||||
MMU.MMU_MEM[ARMCPU_ARM9][(adr>>20)&0xFF][adr&MMU.MMU_MASK[ARMCPU_ARM9][(adr>>20)&0xFF]]);
|
MMU.MMU_MEM[ARMCPU_ARM9][(adr>>20)&0xFF][adr&MMU.MMU_MASK[ARMCPU_ARM9][(adr>>20)&0xFF]]);
|
||||||
#endif
|
#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]];
|
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]);
|
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]);
|
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)]);
|
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]
|
// 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)]);
|
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) {
|
void mmu_select_savetype(int type, int *bmemtype, u32 *bmemsize) {
|
||||||
if (type<0 || type > 6) return;
|
if (type<0 || type > 6) return;
|
||||||
*bmemtype=save_types[type][0];
|
*bmemtype=save_types[type][0];
|
||||||
*bmemsize=save_types[type][1];
|
*bmemsize=save_types[type][1];
|
||||||
mc_realloc(&MMU.bupmem, *bmemtype, *bmemsize);
|
mc_realloc(&MMU.bupmem, *bmemtype, *bmemsize);
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,10 +143,6 @@ SFORMAT SF_MEM[]={
|
||||||
|
|
||||||
{ "VMEM", 1, 0x800, ARM9Mem.ARM9_VMEM},
|
{ "VMEM", 1, 0x800, ARM9Mem.ARM9_VMEM},
|
||||||
{ "OAMS", 1, 0x800, ARM9Mem.ARM9_OAM},
|
{ "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},
|
{ "LCDM", 1, 0xA4000, ARM9Mem.ARM9_LCD},
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
|
@ -90,7 +90,7 @@ static MemSpan MemSpan_TexMem(u32 ofs, u32 len)
|
||||||
len -= curr.len;
|
len -= curr.len;
|
||||||
ofs += curr.len;
|
ofs += curr.len;
|
||||||
currofs += curr.len;
|
currofs += curr.len;
|
||||||
u8* ptr = ARM9Mem.textureSlotAddr[slot];
|
u8* ptr = ARM9Mem.texInfo.textureSlotAddr[slot];
|
||||||
|
|
||||||
if(ptr == ARM9Mem.blank_memory) {
|
if(ptr == ARM9Mem.blank_memory) {
|
||||||
PROGINFO("Tried to reference unmapped texture memory: slot %d\n",slot);
|
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)
|
//if(len != 0)
|
||||||
//here is an actual test case of bank spanning
|
//here is an actual test case of bank spanning
|
||||||
currofs += curr.len;
|
currofs += curr.len;
|
||||||
u8* ptr = ARM9Mem.texPalSlot[slot];
|
u8* ptr = ARM9Mem.texInfo.texPalSlot[slot];
|
||||||
|
|
||||||
if(ptr == ARM9Mem.blank_memory) {
|
if(ptr == ARM9Mem.blank_memory) {
|
||||||
PROGINFO("Tried to reference unmapped texture palette memory: 16k slot #%d\n",slot);
|
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:
|
//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");
|
//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;
|
u16* slot1;
|
||||||
u32* map = (u32*)ms.items[0].ptr;
|
u32* map = (u32*)ms.items[0].ptr;
|
||||||
|
@ -410,9 +410,9 @@ REJECT:
|
||||||
u32 d = 0;
|
u32 d = 0;
|
||||||
if ( (texcache[tx].frm & 0xc000) == 0x8000)
|
if ( (texcache[tx].frm & 0xc000) == 0x8000)
|
||||||
// texel are in slot 2
|
// 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
|
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 yTmpSize = (texcache[tx].sizeY>>2);
|
||||||
u16 xTmpSize = (texcache[tx].sizeX>>2);
|
u16 xTmpSize = (texcache[tx].sizeX>>2);
|
||||||
|
|
|
@ -275,7 +275,7 @@ BOOL CALLBACK ViewPalProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam
|
||||||
case 17 :
|
case 17 :
|
||||||
case 18 :
|
case 18 :
|
||||||
case 19 :
|
case 19 :
|
||||||
PalView->adr = ((u16 *)(ARM9Mem.texPalSlot[sel-16]));
|
PalView->adr = ((u16 *)(ARM9Mem.texInfo.texPalSlot[sel-16]));
|
||||||
PalView->palnum = 0;
|
PalView->palnum = 0;
|
||||||
ShowWindow(GetDlgItem(hwnd, IDC_SCROLLER), SW_SHOW);
|
ShowWindow(GetDlgItem(hwnd, IDC_SCROLLER), SW_SHOW);
|
||||||
EnableWindow(GetDlgItem(hwnd, IDC_SCROLLER), TRUE);
|
EnableWindow(GetDlgItem(hwnd, IDC_SCROLLER), TRUE);
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "../MMU.h"
|
#include "../MMU.h"
|
||||||
|
#include "../gpu.h"
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -31,7 +32,7 @@ typedef struct
|
||||||
bool autoup;
|
bool autoup;
|
||||||
|
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
u8 * mem;
|
u32 target;
|
||||||
u16 * pal;
|
u16 * pal;
|
||||||
s16 palnum;
|
s16 palnum;
|
||||||
u16 tilenum;
|
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));
|
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);
|
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;
|
u32 i, num2, num, y, x;
|
||||||
|
|
||||||
//for(i = 0; i<256*256; ++i)
|
u8* mem = MMU_RenderMapToLCD(win->target);
|
||||||
// bitmap[i] = pal[win->mem[i]];
|
if(mem)
|
||||||
for(num2 = 0; num2<32; ++num2)
|
{
|
||||||
for(num = 0; num<32; ++num)
|
for(num2 = 0; num2<32; ++num2)
|
||||||
for(y = 0; y<8; ++y)
|
for(num = 0; num<32; ++num)
|
||||||
for(x = 0; x<8; ++x)
|
for(y = 0; y<8; ++y)
|
||||||
bitmap[x + (y*256) + (num*8) +(num2*256*8)] = pal[win->mem[x + (y*8) + (num*64) +(num2*2048)]];
|
for(x = 0; x<8; ++x)
|
||||||
SetDIBitsToDevice(mem_dc, 0, 0, 256, 256, 0, 0, 0, 256, bitmap, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
|
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);
|
sprintf(text, "Pal : %d", win->palnum);
|
||||||
SetWindowText(GetDlgItem(hwnd, IDC_PALNUM), text);
|
SetWindowText(GetDlgItem(hwnd, IDC_PALNUM), text);
|
||||||
}
|
}
|
||||||
|
@ -198,16 +203,20 @@ LRESULT TileViewBox_Pal16(HWND hwnd, tileview_struct * win, WPARAM wParam, LPARA
|
||||||
|
|
||||||
if(win->pal)
|
if(win->pal)
|
||||||
{
|
{
|
||||||
u32 num2, num, y, x;
|
u8* mem = MMU_RenderMapToLCD(win->target);
|
||||||
for(num2 = 0; num2<32; ++num2)
|
if(mem)
|
||||||
for(num = 0; num<64; ++num)
|
{
|
||||||
for(y = 0; y<8; ++y)
|
u32 num2, num, y, x;
|
||||||
for(x = 0; x<4; ++x)
|
for(num2 = 0; num2<32; ++num2)
|
||||||
{
|
for(num = 0; num<64; ++num)
|
||||||
bitmap[(x<<1) + (y*512) + (num*8) +(num2*512*8)] = pal[win->mem[x + (y*4) + (num*32) +(num2*2048)]&0xF];
|
for(y = 0; y<8; ++y)
|
||||||
bitmap[(x<<1)+1 + (y*512) + (num*8) +(num2*512*8)] = pal[win->mem[x + (y*4) + (num*32) +(num2*2048)]>>4];
|
for(x = 0; x<4; ++x)
|
||||||
}
|
{
|
||||||
SetDIBitsToDevice(mem_dc, 0, 0, 512, 256, 0, 0, 0, 256, bitmap, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
|
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);
|
sprintf(text, "Pal : %d", win->palnum);
|
||||||
SetWindowText(GetDlgItem(hwnd, IDC_PALNUM), text);
|
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;
|
TileView = new tileview_struct;
|
||||||
memset(TileView, 0, sizeof(tileview_struct));
|
memset(TileView, 0, sizeof(tileview_struct));
|
||||||
TileView->hwnd = hwnd;
|
TileView->hwnd = hwnd;
|
||||||
TileView->mem = ARM9Mem.ARM9_ABG;
|
TileView->target = ARM9MEM_ABG;
|
||||||
TileView->pal = ((u16 *)ARM9Mem.ARM9_VMEM);
|
TileView->pal = ((u16 *)ARM9Mem.ARM9_VMEM);
|
||||||
TileView->autoup_secs = 1;
|
TileView->autoup_secs = 1;
|
||||||
SendMessage(GetDlgItem(hwnd, IDC_AUTO_UPDATE_SPIN),
|
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 5 :
|
||||||
case 6 :
|
case 6 :
|
||||||
case 7 :
|
case 7 :
|
||||||
TileView->mem = ARM9Mem.ARM9_ABG + 0x10000*sel;
|
TileView->target = ARM9MEM_ABG + 0x10000*sel;
|
||||||
break;
|
break;
|
||||||
case 8 :
|
case 8 :
|
||||||
case 9 :
|
case 9 :
|
||||||
TileView->mem = ARM9Mem.ARM9_BBG + 0x10000*(sel-8);
|
TileView->target = ARM9MEM_BBG + 0x10000*(sel-8);
|
||||||
break;
|
break;
|
||||||
case 10 :
|
case 10 :
|
||||||
case 11 :
|
case 11 :
|
||||||
case 12 :
|
case 12 :
|
||||||
case 13 :
|
case 13 :
|
||||||
TileView->mem = ARM9Mem.ARM9_AOBJ + 0x10000*(sel-10);
|
TileView->target = ARM9MEM_AOBJ + 0x10000*(sel-10);
|
||||||
break;
|
break;
|
||||||
case 14 :
|
case 14 :
|
||||||
case 15 :
|
case 15 :
|
||||||
TileView->mem = ARM9Mem.ARM9_BOBJ + 0x10000*(sel-14);
|
TileView->target = ARM9MEM_BOBJ + 0x10000*(sel-14);
|
||||||
break;
|
break;
|
||||||
case 16 :
|
case 16 :
|
||||||
case 17 :
|
case 17 :
|
||||||
|
@ -518,7 +527,7 @@ BOOL CALLBACK ViewTilesProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lPar
|
||||||
case 23 :
|
case 23 :
|
||||||
case 24 :
|
case 24 :
|
||||||
case 25 :
|
case 25 :
|
||||||
TileView->mem = ARM9Mem.ARM9_LCD + 0x10000*(sel-16);
|
TileView->target = ARM9MEM_LCDC + 0x10000*(sel-16);
|
||||||
break;
|
break;
|
||||||
default :
|
default :
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -617,7 +626,7 @@ BOOL CALLBACK ViewTilesProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lPar
|
||||||
case 17 :
|
case 17 :
|
||||||
case 18 :
|
case 18 :
|
||||||
case 19 :
|
case 19 :
|
||||||
TileView->pal = ((u16 *)(ARM9Mem.texPalSlot[sel-16]));
|
TileView->pal = ((u16 *)(ARM9Mem.texInfo.texPalSlot[sel-16]));
|
||||||
TileView->palnum = 0;
|
TileView->palnum = 0;
|
||||||
ShowWindow(GetDlgItem(hwnd, IDC_16COUL), SW_SHOW);
|
ShowWindow(GetDlgItem(hwnd, IDC_16COUL), SW_SHOW);
|
||||||
EnableWindow(GetDlgItem(hwnd, IDC_16COUL), TRUE);
|
EnableWindow(GetDlgItem(hwnd, IDC_16COUL), TRUE);
|
||||||
|
|
Loading…
Reference in New Issue