diff --git a/desmume/src/ARM9.h b/desmume/src/ARM9.h index 1208358ef..0a9b6849d 100644 --- a/desmume/src/ARM9.h +++ b/desmume/src/ARM9.h @@ -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]; }; diff --git a/desmume/src/GPU.cpp b/desmume/src/GPU.cpp index bea3f6d1c..b19b5fdba 100644 --- a/desmume/src/GPU.cpp +++ b/desmume/src/GPU.cpp @@ -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 { diff --git a/desmume/src/GPU.h b/desmume/src/GPU.h index a5004435d..936273531 100644 --- a/desmume/src/GPU.h +++ b/desmume/src/GPU.h @@ -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]; diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index 9061169ae..792160810 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -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>14)&(VRAM_ARM9_PAGES-1); + assert(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 +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_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;iNDS_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 -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); } diff --git a/desmume/src/saves.cpp b/desmume/src/saves.cpp index 2259c2ed8..38ab97f14 100644 --- a/desmume/src/saves.cpp +++ b/desmume/src/saves.cpp @@ -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 } }; diff --git a/desmume/src/texcache.cpp b/desmume/src/texcache.cpp index f99e72d10..1f14115ed 100644 --- a/desmume/src/texcache.cpp +++ b/desmume/src/texcache.cpp @@ -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); diff --git a/desmume/src/windows/palView.cpp b/desmume/src/windows/palView.cpp index c361e6eeb..73db477c0 100644 --- a/desmume/src/windows/palView.cpp +++ b/desmume/src/windows/palView.cpp @@ -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); diff --git a/desmume/src/windows/tileView.cpp b/desmume/src/windows/tileView.cpp index 809e34c77..aea0ec771 100644 --- a/desmume/src/windows/tileView.cpp +++ b/desmume/src/windows/tileView.cpp @@ -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);