static u16 GBAgame_read16(u32 adr) { //INFO("Read16 at 0x%08X value 0x%04X\n", adr, (u16)T1ReadWord(GBArom, (adr - 0x08000000))); if ( (adr >= 0x08000004) && (adr < 0x080000A0) ) return T1ReadWord(MMU.MMU_MEM[0][0xFF], (adr +0x1C) & MMU.MMU_MASK[0][0xFF]); return (u16)T1ReadWord(GBArom, (adr - 0x08000000)); }
u32 IPC_FIFOrecv(u8 proc) { //LOG("IPC%s recv FIFO:\n", proc?"7":"9"); int i; u32 val = 0; u16 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184); u16 cnt_r = T1ReadWord(MMU.MMU_MEM[proc^1][0x40], 0x184); if (ipc_fifo.recvTail[proc] > 0) // not empty { val = ipc_fifo.recvBuf[proc][0]; for (i = 0; i < ipc_fifo.recvTail[proc]; i++) ipc_fifo.recvBuf[proc][i] = ipc_fifo.recvBuf[proc][i+1]; ipc_fifo.recvTail[proc]--; if (ipc_fifo.recvTail[proc] == 0) // empty cnt_l |= 0x0100; // remove from head for (i = 0; i < ipc_fifo.sendTail[proc^1]; i++) ipc_fifo.sendBuf[proc^1][i] = ipc_fifo.sendBuf[proc^1][i+1]; ipc_fifo.sendTail[proc^1]--; if (ipc_fifo.sendTail[proc^1] == 0) // empty cnt_r |= 0x0001; } else cnt_l |= 0x4100; T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l); T1WriteWord(MMU.MMU_MEM[proc^1][0x40], 0x184, cnt_r); if ((cnt_l & (1<<3))) NDS_makeInt(proc, 19); return (val); }
void IPC_FIFOcnt(u8 proc, u16 val) { u16 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184); u16 cnt_r = T1ReadWord(MMU.MMU_MEM[proc^1][0x40], 0x184); if (val & IPCFIFOCNT_FIFOERROR) { //at least SPP uses this, maybe every retail game cnt_l &= ~IPCFIFOCNT_FIFOERROR; } if (val & IPCFIFOCNT_SENDCLEAR) { ipc_fifo[proc].head = 0; ipc_fifo[proc].tail = 0; ipc_fifo[proc].size = 0; cnt_l |= IPCFIFOCNT_SENDEMPTY; cnt_l &= ~IPCFIFOCNT_SENDFULL; cnt_r |= IPCFIFOCNT_RECVEMPTY; cnt_r &= ~IPCFIFOCNT_RECVFULL; } cnt_l &= ~IPCFIFOCNT_WRITEABLE; cnt_l |= val & IPCFIFOCNT_WRITEABLE; T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l); T1WriteWord(MMU.MMU_MEM[proc^1][0x40], 0x184, cnt_r); NDS_Reschedule(); }
void IPC_FIFOsend(u8 proc, u32 val) { //LOG("IPC%s send FIFO 0x%08X\n", proc?"7":"9", val); u16 cnt_l,cnt_r; cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184); if (!(cnt_l & 0x8000)) return; // FIFO disabled cnt_r = T1ReadWord(MMU.MMU_MEM[proc^1][0x40], 0x184); if (ipc_fifo.sendTail[proc] < 16) // last full == error { ipc_fifo.sendBuf[proc][ipc_fifo.sendTail[proc]] = val; ipc_fifo.sendTail[proc]++; if (ipc_fifo.sendTail[proc] == 16) cnt_l |= 0x02; // full cnt_l &= 0xFFFE; if (ipc_fifo.recvTail[proc^1] < 16) // last full == error { ipc_fifo.recvBuf[proc^1][ipc_fifo.recvTail[proc^1]] = val; ipc_fifo.recvTail[proc^1]++; if (ipc_fifo.recvTail[proc^1] == 16) cnt_r |= 0x0200; // full cnt_r &= 0xFEFF; } else cnt_r |= 0x4200; } else cnt_l |= 0x4002; // save in mem T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l); T1WriteWord(MMU.MMU_MEM[proc^1][0x40], 0x184, cnt_r); if ((cnt_r & (1<<10))) NDS_makeInt(proc^1, 18); }
static u16 GBAgame_read16(u32 adr) { //INFO("GBAgame: read16 at 0x%08X value 0x%04X\n", adr, (u16)T1ReadWord(GBArom, (adr - 0x08000000))); if (adr < 0x0A000000) return (u16)T1ReadWord(GBArom, (adr - 0x08000000)); if (adr < 0x0A010000) { //INFO("GBAgame: flash read16 at 0x%08X\n", adr); return (u16)T1ReadWord(saveData, (adr - 0x0A000000)); } return 0xFFFF; }
NDS_header * NDS_getROMHeader(void) { NDS_header * header = new NDS_header; memcpy(header->gameTile, MMU.CART_ROM, 12); memcpy(header->gameCode, MMU.CART_ROM + 12, 4); header->makerCode = T1ReadWord(MMU.CART_ROM, 16); header->unitCode = MMU.CART_ROM[18]; header->deviceCode = MMU.CART_ROM[19]; header->cardSize = MMU.CART_ROM[20]; memcpy(header->cardInfo, MMU.CART_ROM + 21, 8); header->flags = MMU.CART_ROM[29]; header->ARM9src = T1ReadLong(MMU.CART_ROM, 32); header->ARM9exe = T1ReadLong(MMU.CART_ROM, 36); header->ARM9cpy = T1ReadLong(MMU.CART_ROM, 40); header->ARM9binSize = T1ReadLong(MMU.CART_ROM, 44); header->ARM7src = T1ReadLong(MMU.CART_ROM, 48); header->ARM7exe = T1ReadLong(MMU.CART_ROM, 52); header->ARM7cpy = T1ReadLong(MMU.CART_ROM, 56); header->ARM7binSize = T1ReadLong(MMU.CART_ROM, 60); header->FNameTblOff = T1ReadLong(MMU.CART_ROM, 64); header->FNameTblSize = T1ReadLong(MMU.CART_ROM, 68); header->FATOff = T1ReadLong(MMU.CART_ROM, 72); header->FATSize = T1ReadLong(MMU.CART_ROM, 76); header->ARM9OverlayOff = T1ReadLong(MMU.CART_ROM, 80); header->ARM9OverlaySize = T1ReadLong(MMU.CART_ROM, 84); header->ARM7OverlayOff = T1ReadLong(MMU.CART_ROM, 88); header->ARM7OverlaySize = T1ReadLong(MMU.CART_ROM, 92); header->unknown2a = T1ReadLong(MMU.CART_ROM, 96); header->unknown2b = T1ReadLong(MMU.CART_ROM, 100); header->IconOff = T1ReadLong(MMU.CART_ROM, 104); header->CRC16 = T1ReadWord(MMU.CART_ROM, 108); header->ROMtimeout = T1ReadWord(MMU.CART_ROM, 110); header->ARM9unk = T1ReadLong(MMU.CART_ROM, 112); header->ARM7unk = T1ReadLong(MMU.CART_ROM, 116); memcpy(header->unknown3c, MMU.CART_ROM + 120, 8); header->ROMSize = T1ReadLong(MMU.CART_ROM, 128); header->HeaderSize = T1ReadLong(MMU.CART_ROM, 132); memcpy(header->unknown5, MMU.CART_ROM + 136, 56); memcpy(header->logo, MMU.CART_ROM + 192, 156); header->logoCRC16 = T1ReadWord(MMU.CART_ROM, 348); header->headerCRC16 = T1ReadWord(MMU.CART_ROM, 350); memcpy(header->reserved, MMU.CART_ROM + 352, 160); return header; }
static u16 ExpMemory_read16(u32 procnum, u32 adr) { if(adr>=0x080000B0 && adr<0x080000C0) return T1ReadWord(header_0x00B0,adr-0x080000B0); if (adr == 0x0801FFFC) return 0x7FFF; if (adr == 0x08240002) return 0; //this can't be 0xFFFF. dunno why, we just guessed 0 if (adr >= 0x09000000) { u32 offs = (adr - 0x09000000); if (offs >= expMemSize) return (0xFFFF); return T1ReadWord(expMemory, offs); } EXPINFO("ExpMemory: read 16 at 0x%08X\n", adr); return 0xFFFF; }
u16 FASTCALL Vdp1FrameBufferReadWord(u32 addr) { addr &= 0x3FFFF; if (VIDCore->Vdp1ReadFrameBuffer){ u16 val; VIDCore->Vdp1ReadFrameBuffer(1, addr, &val); return val; } return T1ReadWord(Vdp1FrameBuffer, addr); }
u32 IPC_FIFOrecv(u8 proc) { u16 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184); if (!(cnt_l & IPCFIFOCNT_FIFOENABLE)) return (0); // FIFO disabled u8 proc_remote = proc ^ 1; u32 val = 0; if ( ipc_fifo[proc_remote].size == 0 ) // remote FIFO error { cnt_l |= IPCFIFOCNT_FIFOERROR; T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l); return (0); } u16 cnt_r = T1ReadWord(MMU.MMU_MEM[proc_remote][0x40], 0x184); cnt_l &= 0xBCFF; // clear send full bit & empty cnt_r &= 0xBFFC; // set recv full bit & empty val = ipc_fifo[proc_remote].buf[ipc_fifo[proc_remote].head]; ipc_fifo[proc_remote].head++; ipc_fifo[proc_remote].size--; if (ipc_fifo[proc_remote].head > 15) ipc_fifo[proc_remote].head = 0; //LOG("IPC%s recv FIFO 0x%08X size %03i (l 0x%X, tail %02i) (r 0x%X, tail %02i)\n", // proc?"7":"9", val, ipc_fifo[proc].size, cnt_l, ipc_fifo[proc].tail, cnt_r, ipc_fifo[proc^1].tail); if ( ipc_fifo[proc_remote].size == 0 ) // FIFO empty { cnt_l |= IPCFIFOCNT_RECVEMPTY; cnt_r |= IPCFIFOCNT_SENDEMPTY; if(cnt_r&IPCFIFOCNT_SENDIRQEN) NDS_makeIrq(proc_remote, IRQ_BIT_IPCFIFO_SENDEMPTY); } T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l); T1WriteWord(MMU.MMU_MEM[proc_remote][0x40], 0x184, cnt_r); NDS_Reschedule(); return (val); }
u32 IPC_FIFOrecv(u8 proc) { u16 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184); if (!(cnt_l & 0x8000)) return (0); // FIFO disabled u8 proc_remote = proc ^ 1; u32 val = 0; if ( ipc_fifo[proc_remote].size == 0 ) // remote FIFO error { cnt_l |= 0x4000; T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l); return (0); } u16 cnt_r = T1ReadWord(MMU.MMU_MEM[proc_remote][0x40], 0x184); cnt_l &= 0xBCFF; // clear send full bit & empty cnt_r &= 0xBFFC; // set recv full bit & empty val = ipc_fifo[proc_remote].buf[ipc_fifo[proc_remote].head]; ipc_fifo[proc_remote].head++; ipc_fifo[proc_remote].size--; if (ipc_fifo[proc_remote].head > 15) ipc_fifo[proc_remote].head = 0; //LOG("IPC%s recv FIFO 0x%08X size %03i (l 0x%X, tail %02i) (r 0x%X, tail %02i)\n", // proc?"7":"9", val, ipc_fifo[proc].size, cnt_l, ipc_fifo[proc].tail, cnt_r, ipc_fifo[proc^1].tail); if ( ipc_fifo[proc_remote].size == 0 ) // FIFO empty { cnt_l |= 0x0101; cnt_r |= 0x0001; } T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l); T1WriteWord(MMU.MMU_MEM[proc_remote][0x40], 0x184, cnt_r); NDS_Reschedule(); return (val); }
virtual void connect() { protocol.reset(this); protocol.chipId = gameInfo.chipID; protocol.gameCode = T1ReadLong((u8*)gameInfo.header.gameCode,0); save_adr = 0; handle_save = 0; mode = 0; subAdr = T1ReadWord(gameInfo.header.reserved2, 0x6) << 17; }
void IPC_FIFOcnt(u8 proc, u16 val) { u8 proc_remote = proc ^ 1; u16 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184); u16 cnt_r = T1ReadWord(MMU.MMU_MEM[proc^1][0x40], 0x184); if (val & IPCFIFOCNT_FIFOERROR) { //at least SPP uses this, maybe every retail game cnt_l &= ~IPCFIFOCNT_FIFOERROR; } if (val & IPCFIFOCNT_SENDCLEAR) { ipc_fifo[proc].head = 0; ipc_fifo[proc].tail = 0; ipc_fifo[proc].size = 0; cnt_l |= IPCFIFOCNT_SENDEMPTY; cnt_r |= IPCFIFOCNT_RECVEMPTY; cnt_l &= ~IPCFIFOCNT_SENDFULL; cnt_r &= ~IPCFIFOCNT_RECVFULL; } cnt_l &= ~IPCFIFOCNT_WRITEABLE; cnt_l |= val & IPCFIFOCNT_WRITEABLE; //IPCFIFOCNT_SENDIRQEN may have been set (and/or the fifo may have been cleared) so we may need to trigger this irq //(this approach is used by libnds fifo system on occasion in fifoInternalSend, and began happening frequently for value32 with r4326) if(cnt_l&IPCFIFOCNT_SENDIRQEN) if(cnt_l & IPCFIFOCNT_SENDEMPTY) NDS_makeIrq(proc, IRQ_BIT_IPCFIFO_SENDEMPTY); //IPCFIFOCNT_RECVIRQEN may have been set so we may need to trigger this irq if(cnt_l&IPCFIFOCNT_RECVIRQEN) if(!(cnt_l & IPCFIFOCNT_RECVEMPTY)) NDS_makeIrq(proc, IRQ_BIT_IPCFIFO_RECVNONEMPTY); T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l); T1WriteWord(MMU.MMU_MEM[proc^1][0x40], 0x184, cnt_r); NDS_Reschedule(); }
void IPC_FIFOsend(u8 proc, u32 val) { u16 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184); if (!(cnt_l & IPCFIFOCNT_FIFOENABLE)) return; // FIFO disabled u8 proc_remote = proc ^ 1; if (ipc_fifo[proc].size > 15) { cnt_l |= IPCFIFOCNT_FIFOERROR; T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l); return; } u16 cnt_r = T1ReadWord(MMU.MMU_MEM[proc_remote][0x40], 0x184); //LOG("IPC%s send FIFO 0x%08X size %03i (l 0x%X, tail %02i) (r 0x%X, tail %02i)\n", // proc?"7":"9", val, ipc_fifo[proc].size, cnt_l, ipc_fifo[proc].tail, cnt_r, ipc_fifo[proc^1].tail); cnt_l &= 0xBFFC; // clear send empty bit & full cnt_r &= 0xBCFF; // set recv empty bit & full ipc_fifo[proc].buf[ipc_fifo[proc].tail] = val; ipc_fifo[proc].tail++; ipc_fifo[proc].size++; if (ipc_fifo[proc].tail > 15) ipc_fifo[proc].tail = 0; if (ipc_fifo[proc].size > 15) { cnt_l |= IPCFIFOCNT_SENDFULL; // set send full bit cnt_r |= IPCFIFOCNT_RECVFULL; // set recv full bit } T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l); T1WriteWord(MMU.MMU_MEM[proc_remote][0x40], 0x184, cnt_r); if(cnt_r&IPCFIFOCNT_RECVIRQEN) NDS_makeIrq(proc_remote, IRQ_BIT_IPCFIFO_RECVNONEMPTY); NDS_Reschedule(); }
void IPC_FIFOsend(u8 proc, u32 val) { u16 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184); if (!(cnt_l & 0x8000)) return; // FIFO disabled u8 proc_remote = proc ^ 1; if (ipc_fifo[proc].size > 15) { cnt_l |= 0x4000; T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l); return; } u16 cnt_r = T1ReadWord(MMU.MMU_MEM[proc_remote][0x40], 0x184); //LOG("IPC%s send FIFO 0x%08X size %03i (l 0x%X, tail %02i) (r 0x%X, tail %02i)\n", // proc?"7":"9", val, ipc_fifo[proc].size, cnt_l, ipc_fifo[proc].tail, cnt_r, ipc_fifo[proc^1].tail); cnt_l &= 0xBFFC; // clear send empty bit & full cnt_r &= 0xBCFF; // set recv empty bit & full ipc_fifo[proc].buf[ipc_fifo[proc].tail] = val; ipc_fifo[proc].tail++; ipc_fifo[proc].size++; if (ipc_fifo[proc].tail > 15) ipc_fifo[proc].tail = 0; if (ipc_fifo[proc].size > 15) { cnt_l |= 0x0002; // set send full bit cnt_r |= 0x0200; // set recv full bit } T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l); T1WriteWord(MMU.MMU_MEM[proc_remote][0x40], 0x184, cnt_r); NDS_Reschedule(); }
static u16 ExpMemory_read16(u32 adr) { if (adr == 0x080000B6) return(0x2424); if (adr == 0x080000BC) return(0x7FFF); if (adr == 0x080000BE) return(0x0096); if (adr == 0x0801FFFC) return(0x7FFF); if (adr >= 0x09000000) { u32 offs = (adr - 0x09000000); if (offs >= expMemSize) return (0); return (T1ReadWord(expMemory, offs)); } EXPINFO("ExpMemory: read 16 at 0x%08X\n", adr); return (0); }
void IPC_FIFOcnt(u8 proc, u16 val) { //LOG("IPC%s FIFO context 0x%X\n", proc?"7":"9", val); u16 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184); cnt_l &= ~0x8404; cnt_l |= (val & 0x8404); cnt_l &= (~(val & 0x4000)); if (val & 0x0008) { IPC_FIFOclear(); cnt_l |= 0x0101; } T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l); if ((cnt_l & 0x0004)) NDS_makeInt(proc, 18); }
u16 FASTCALL Vdp1RamReadWord(u32 addr) { addr &= 0x7FFFF; return T1ReadWord(Vdp1Ram, addr); }
//ensure that registers are set correctly void Vdp1FakeDrawCommands(u8 * ram, Vdp1 * regs) { u16 command = T1ReadWord(ram, regs->addr); u32 commandCounter = 0; u32 returnAddr = 0xffffffff; while (!(command & 0x8000) && commandCounter < 2000) { // fix me // First, process the command if (!(command & 0x4000)) { // if (!skip) switch (command & 0x000F) { case 0: // normal sprite draw case 1: // scaled sprite draw case 2: // distorted sprite draw case 3: /* this one should be invalid, but some games (Hardcore 4x4 for instance) use it instead of 2 */ case 4: // polygon draw case 5: // polyline draw case 6: // line draw case 7: // undocumented polyline draw mirror break; case 8: // user clipping coordinates case 11: // undocumented mirror VIDCore->Vdp1UserClipping(ram, regs); break; case 9: // system clipping coordinates VIDCore->Vdp1SystemClipping(ram, regs); break; case 10: // local coordinate VIDCore->Vdp1LocalCoordinate(ram, regs); break; default: // Abort VDP1LOG("vdp1\t: Bad command: %x\n", command); regs->EDSR |= 2; VIDCore->Vdp1DrawEnd(); regs->LOPR = regs->addr >> 3; regs->COPR = regs->addr >> 3; return; } } // Next, determine where to go next switch ((command & 0x3000) >> 12) { case 0: // NEXT, jump to following table regs->addr += 0x20; break; case 1: // ASSIGN, jump to CMDLINK regs->addr = T1ReadWord(ram, regs->addr + 2) * 8; break; case 2: // CALL, call a subroutine if (returnAddr == 0xFFFFFFFF) returnAddr = regs->addr + 0x20; regs->addr = T1ReadWord(ram, regs->addr + 2) * 8; break; case 3: // RETURN, return from subroutine if (returnAddr != 0xFFFFFFFF) { regs->addr = returnAddr; returnAddr = 0xFFFFFFFF; } else regs->addr += 0x20; break; } command = T1ReadWord(ram, regs->addr); commandCounter++; } }
static bool mmu_loadstate(EMUFILE* is, int size) { //read version u32 version; if(read32le(&version,is) != 1) return false; if(version == 0 || version == 1) { u32 bupmem_size; u32 addr_size; if(version == 0) { //version 0 was buggy and didnt save the type. //it would silently fail if there was a size mismatch SAV_silent_fail_flag = true; if(read32le(&bupmem_size,is) != 1) return false; //if(bupmem_size != MMU.bupmem.size) return false; //mismatch between current initialized and saved size addr_size = BackupDevice::addr_size_for_old_save_size(bupmem_size); } else if(version == 1) { //version 1 reinitializes the save system with the type that was saved u32 bupmem_type; if(read32le(&bupmem_type,is) != 1) return false; if(read32le(&bupmem_size,is) != 1) return false; addr_size = BackupDevice::addr_size_for_old_save_type(bupmem_type); if(addr_size == 0xFFFFFFFF) addr_size = BackupDevice::addr_size_for_old_save_size(bupmem_size); } if(addr_size == 0xFFFFFFFF) return false; u8* temp = new u8[bupmem_size]; is->fread((char*)temp,bupmem_size); MMU_new.backupDevice.load_old_state(addr_size,temp,bupmem_size); delete[] temp; if(is->fail()) return false; } if(version < 2) return true; bool ok = MMU_new.backupDevice.load_state(is); if(version < 3) return ok; ok &= MMU_new.gxstat.loadstate(is); for(int i=0;i<2;i++) for(int j=0;j<4;j++) ok &= MMU_new.dma[i][j].loadstate(is); ok &= MMU_timing.arm9codeFetch.loadstate(is, version); ok &= MMU_timing.arm9dataFetch.loadstate(is, version); ok &= MMU_timing.arm7codeFetch.loadstate(is, version); ok &= MMU_timing.arm7dataFetch.loadstate(is, version); ok &= MMU_timing.arm9codeCache.loadstate(is, version); ok &= MMU_timing.arm9dataCache.loadstate(is, version); if(version < 4) return ok; ok &= MMU_new.sqrt.loadstate(is,version); ok &= MMU_new.div.loadstate(is,version); //to prevent old savestates from confusing IF bits, mask out ones which had been stored but should have been generated MMU.reg_IF_bits[0] &= ~0x00200000; MMU.reg_IF_bits[1] &= ~0x00000000; MMU_new.gxstat.fifo_low = gxFIFO.size <= 127; MMU_new.gxstat.fifo_empty = gxFIFO.size == 0; if(version < 5) MMU.reg_DISP3DCNT_bits = T1ReadWord(MMU.ARM9_REG,0x60); if(version < 6) return ok; MMU_new.dsi_tsc.load_state(is); //version 6 if(version < 7) { //recover WRAMCNT from the stashed WRAMSTAT memory location MMU.WRAMCNT = MMU.MMU_MEM[ARMCPU_ARM7][0x40][0x241]; } if(version<8) return ok; //version 8: delete[] MMU.fw.data; MMU.fw.size = is->read32le(); MMU.fw.data = new u8[size]; is->fread(MMU.fw.data,MMU.fw.size); return ok; }
static bool skipSlot2Data() { u16 exmemcnt = T1ReadWord(MMU.MMU_MEM[PROCNUM][0x40], 0x204); return (PROCNUM == ARMCPU_ARM9)? (exmemcnt & EXMEMCNT_MASK_SLOT2_ARM7): !(exmemcnt & EXMEMCNT_MASK_SLOT2_ARM7); }
LRESULT GInfo_IconBoxPaint(HWND hCtl, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; RECT rc; int w, h; SIZE fontsize; HDC mem_hdc; HBITMAP mem_bmp; BITMAPV4HEADER bmph; u32 icontitleOffset; u16 icon[32 * 32]; int x, y; GetClientRect(hCtl, &rc); w = (rc.right - rc.left); h = (rc.bottom - rc.top); hdc = BeginPaint(hCtl, &ps); mem_hdc = CreateCompatibleDC(hdc); mem_bmp = CreateCompatibleBitmap(hdc, w, h); SelectObject(mem_hdc, mem_bmp); FillRect(mem_hdc, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); ZeroMemory(&bmph, sizeof(bmph)); bmph.bV4Size = sizeof(bmph); bmph.bV4Planes = 1; bmph.bV4BitCount = 16; bmph.bV4V4Compression = BI_BITFIELDS; bmph.bV4RedMask = 0x001F; bmph.bV4GreenMask = 0x03E0; bmph.bV4BlueMask = 0x7C00; bmph.bV4Width = 32; bmph.bV4Height = -32; icontitleOffset = T1ReadLong(MMU.CART_ROM, 0x68); if(icontitleOffset >= 0x8000) { for(y = 0; y < 32; y++) { for(x = 0; x < 32; x++) { int tilenum = (((y / 8) * 4) + (x / 8)); int tilex = (x % 8); int tiley = (y % 8); int mapoffset = ((tilenum * 64) + (tiley * 8) + tilex); u8 val = T1ReadByte(MMU.CART_ROM, (icontitleOffset + 0x20 + (mapoffset>>1))); if(mapoffset & 1) val = ((val >> 4) & 0xF); else val = (val & 0xF); icon[(y * 32) + x] = T1ReadWord(MMU.CART_ROM, (icontitleOffset + 0x220 + (val<<1))); } } SetDIBitsToDevice(mem_hdc, ((w/2) - 16), ((h/2) - 16), 32, 32, 0, 0, 0, 32, icon, (BITMAPINFO*)&bmph, DIB_RGB_COLORS); }