Only in .: #sr_load.inl# Only in .: #tmp#0 Only in .: BuildCounter.exe diff -C 2 --exclude=*.dsp --exclude=*.vts ../Daedalus-Lkb-0.07b-lkb3/D3DRender.h ./D3DRender.h *** ../Daedalus-Lkb-0.07b-lkb3/D3DRender.h Fri Aug 24 18:50:11 2001 --- ./D3DRender.h Sat Aug 25 19:33:00 2001 *************** *** 196,200 **** __asm fstp dword ptr [vecout + 8] /* (xm01+ym11+zm21+m31) */ \ __asm fstp dword ptr [vecout + 4] /* done */ \ ! } \ #else --- 196,200 ---- __asm fstp dword ptr [vecout + 8] /* (xm01+ym11+zm21+m31) */ \ __asm fstp dword ptr [vecout + 4] /* done */ \ ! } #else Only in .: D3DRender.h~ Only in .: Daedalus.ncb Only in .: Daedalus.opt Only in .: Daedalus.plg Only in .: Debug diff -C 2 --exclude=*.dsp --exclude=*.vts ../Daedalus-Lkb-0.07b-lkb3/Memory.cpp ./Memory.cpp *** ../Daedalus-Lkb-0.07b-lkb3/Memory.cpp Fri Aug 24 18:50:03 2001 --- ./Memory.cpp Sat Aug 25 19:42:30 2001 *************** *** 62,66 **** // dwCartAddr = (dwAddress - 0x7f000000) + GOLDENEYE_HACKED_OFFSET; ! #define GOLDENEYE_HACKED_OFFSET 0x10034b30; static void Memory_PI_CopyToRDRAM(); --- 62,66 ---- // dwCartAddr = (dwAddress - 0x7f000000) + GOLDENEYE_HACKED_OFFSET; ! #define GOLDENEYE_HACKED_OFFSET 0x10034b30 static void Memory_PI_CopyToRDRAM(); *************** *** 139,142 **** --- 139,144 ---- MemFastFunction WriteFastFunction; MemWriteValueFunction WriteValueFunction; + unsigned int ReadRegion; + unsigned int WriteRegion; }; *************** *** 181,248 **** MemMapEntry MemMapEntries[] = { ! { 0x0000, 0x7FFF, ReadMapped, WriteMapped, WriteValueMapped }, // Mapped Memory ! { 0x8000, 0x807F, Read_Noise, Write_Noise, WriteValueNoise }, // RDRAM - filled in with correct function later ! { 0x8080, 0x83EF, Read_Noise, Write_Noise, WriteValueNoise }, // Unused - electrical noise ! { 0x83F0, 0x83F0, Read_83F0_83F0, Write_83F0_83F0,WriteValue_83F0_83F0 }, // RDRAM reg ! { 0x83F4, 0x83FF, ReadInvalid, WriteInvalid, WriteValueInvalid }, // Unused ! { 0x8400, 0x8400, Read_8400_8400, WriteInvalid, WriteValue_8400_8400 }, // DMEM/IMEM ! { 0x8404, 0x8404, Read_8404_8404, Write_8400_8400, WriteValue_8404_8404 }, // SP Reg ! { 0x8408, 0x8408, Read_8408_8408, WriteInvalid, WriteValue_8408_8408 }, // SP PC/IBIST ! { 0x840C, 0x840F, ReadInvalid, WriteInvalid, WriteValueInvalid }, // Unused ! { 0x8410, 0x841F, Read_8410_841F, WriteInvalid, WriteValue_8410_841F }, // DPC Reg ! { 0x8420, 0x842F, Read_8420_842F, WriteInvalid, WriteValue_8420_842F }, // DPS Reg ! { 0x8430, 0x843F, Read_8430_843F, WriteInvalid, WriteValue_8430_843F}, // MI Reg ! { 0x8440, 0x844F, Read_8440_844F, WriteInvalid, WriteValue_8440_844F }, // VI Reg ! { 0x8450, 0x845F, Read_8450_845F, WriteInvalid, WriteValue_8450_845F }, // AI Reg ! { 0x8460, 0x846F, Read_8460_846F, WriteInvalid, WriteValue_8460_846F }, // PI Reg ! { 0x8470, 0x847F, Read_8470_847F, WriteInvalid, WriteValue_8470_847F }, // RI Reg ! { 0x8480, 0x848F, Read_8480_848F, WriteInvalid, WriteValue_8480_848F }, // SI Reg ! { 0x8490, 0x84FF, ReadInvalid, WriteInvalid, WriteValueInvalid }, // Unused ! { 0x8500, 0x85FF, ReadInvalid/*ReadROM*/, WriteInvalid, WriteValue_Cartridge }, // Cartridge Domain 2 Address 1 ! { 0x8600, 0x87FF, ReadROM, WriteInvalid, WriteValue_Cartridge }, // Cartridge Domain 1 Address 1 ! { 0x8800, 0x8FFF, ReadROM, WriteInvalid, WriteValue_Cartridge }, // Cartridge Domain 2 Address 2 ! { 0x9000, 0x9FBF, ReadROM, WriteInvalid, WriteValue_Cartridge }, // Cartridge Domain 1 Address 2 ! { 0x9FC0, 0x9FCF, Read_9FC0_9FCF, WriteInvalid, WriteValue_9FC0_9FCF }, // pif RAM/ROM ! { 0x9FD0, 0x9FFF, ReadROM, WriteInvalid, WriteValue_Cartridge }, // Cartridge Domain 1 Address 3 { 0xA000, 0xA07F, Read_Noise, Write_Noise, WriteValueNoise }, // Physical RAM - Copy of above { 0xA080, 0xA3EF, Read_Noise, Write_Noise, WriteValueNoise }, // Unused ! { 0xA3F0, 0xA3FF, Read_83F0_83F0, Write_83F0_83F0,WriteValue_83F0_83F0 }, // RDRAM Reg //{ 0xA3F4, 0xA3FF, ReadInvalid, WriteInvalid }, // Unused ! { 0xA400, 0xA400, Read_8400_8400, Write_8400_8400, WriteValue_8400_8400 }, // DMEM/IMEM ! { 0xA404, 0xA404, Read_8404_8404, WriteInvalid, WriteValue_8404_8404 }, // SP Reg ! { 0xA408, 0xA408, Read_8408_8408, WriteInvalid, WriteValue_8408_8408 }, // SP PC/OBOST ! { 0xA40C, 0xA40F, ReadInvalid, WriteInvalid, WriteValueInvalid }, // Unused ! { 0xA410, 0xA41F, Read_8410_841F, WriteInvalid, WriteValue_8410_841F }, // DPC Reg ! { 0xA420, 0xA42F, Read_8420_842F, WriteInvalid, WriteValue_8420_842F }, // DPS Reg ! ! { 0xA430, 0xA43F, Read_8430_843F, WriteInvalid, WriteValue_8430_843F }, // MI Reg ! { 0xA440, 0xA44F, Read_8440_844F, WriteInvalid, WriteValue_8440_844F }, // VI Reg ! { 0xA450, 0xA45F, Read_8450_845F, WriteInvalid, WriteValue_8450_845F }, // AI Reg ! { 0xA460, 0xA46F, Read_8460_846F, WriteInvalid, WriteValue_8460_846F }, // PI Reg ! { 0xA470, 0xA47F, Read_8470_847F, WriteInvalid, WriteValue_8470_847F }, // RI Reg ! { 0xA480, 0xA48F, Read_8480_848F, WriteInvalid, WriteValue_8480_848F }, // SI Reg ! { 0xA490, 0xA4FF, ReadInvalid, WriteInvalid, WriteValueInvalid }, // Unused ! { 0xA500, 0xA5FF, ReadROM, WriteInvalid, WriteValue_Cartridge }, // Cartridge Domain 2 Address 1 ! { 0xA600, 0xA7FF, ReadROM, WriteInvalid, WriteValue_Cartridge }, // Cartridge Domain 1 Address 1 ! { 0xA800, 0xAFFF, ReadROM, WriteInvalid, WriteValue_Cartridge }, // Cartridge Domain 2 Address 2 ! { 0xB000, 0xBFBF, ReadROM, WriteInvalid, WriteValue_Cartridge }, // Cartridge Domain 1 Address 2 ! { 0xBFC0, 0xBFCF, Read_9FC0_9FCF, WriteInvalid, WriteValue_9FC0_9FCF }, // pif RAM/ROM ! { 0xBFD0, 0xBFFF, ReadROM, WriteInvalid, WriteValue_Cartridge }, // Cartridge Domain 1 Address 3 ! { 0xC000, 0xDFFF, ReadMapped, WriteMapped, WriteValueMapped }, // Mapped Memory ! { 0xE000, 0xFFFF, ReadMapped, WriteMapped, WriteValueMapped }, // Mapped Memory { ~0, ~0, NULL, NULL } }; ! MemFastFunction *g_ReadAddressLookupTable = NULL; ! MemFastFunction *g_WriteAddressLookupTable = NULL; ! MemWriteValueFunction * g_WriteAddressValueLookupTable = NULL; ! InternalMemFastFunction * InternalReadFastTable = NULL; ! InternalMemFastFunction * InternalWriteFastTable = NULL; void * g_pMemoryBuffers[NUM_MEM_BUFFERS] = --- 183,256 ---- MemMapEntry MemMapEntries[] = { ! { 0x0000, 0x7FFF, ReadMapped, WriteMapped, WriteValueMapped, 0, 0 }, // Mapped Memory ! { 0x8000, 0x807F, Read_Noise, Write_Noise, WriteValueNoise, 0, 0 }, // RDRAM - filled in with correct function later ! { 0x8080, 0x83EF, Read_Noise, Write_Noise, WriteValueNoise, 0, 0 }, // Unused - electrical noise ! { 0x83F0, 0x83F0, Read_83F0_83F0, Write_83F0_83F0,WriteValue_83F0_83F0, MEM_RD_REG, MEM_RD_REG }, // RDRAM reg ! { 0x83F4, 0x83FF, ReadInvalid, WriteInvalid, WriteValueInvalid, 0, 0}, // Unused ! { 0x8400, 0x8400, Read_8400_8400, WriteInvalid, WriteValue_8400_8400, MEM_SP_MEM, MEM_SP_MEM }, // DMEM/IMEM ! { 0x8404, 0x8404, Read_8404_8404, Write_8400_8400,WriteValue_8404_8404, MEM_SP_REG, 0 }, // SP Reg ! { 0x8408, 0x8408, Read_8408_8408, WriteInvalid, WriteValue_8408_8408, 0, 0 }, // SP PC/IBIST ! { 0x840C, 0x840F, ReadInvalid, WriteInvalid, WriteValueInvalid, 0, 0 }, // Unused ! { 0x8410, 0x841F, Read_8410_841F, WriteInvalid, WriteValue_8410_841F, MEM_DP_COMMAND_REG, 0 }, // DPC Reg ! { 0x8420, 0x842F, Read_8420_842F, WriteInvalid, WriteValue_8420_842F, 0, 0 }, // DPS Reg ! { 0x8430, 0x843F, Read_8430_843F, WriteInvalid, WriteValue_8430_843F, MEM_MI_REG, 0}, // MI Reg ! { 0x8440, 0x844F, Read_8440_844F, WriteInvalid, WriteValue_8440_844F, 0, 0 }, // VI Reg ! { 0x8450, 0x845F, Read_8450_845F, WriteInvalid, WriteValue_8450_845F, 0, 0 }, // AI Reg ! { 0x8460, 0x846F, Read_8460_846F, WriteInvalid, WriteValue_8460_846F, MEM_PI_REG, 0 }, // PI Reg ! { 0x8470, 0x847F, Read_8470_847F, WriteInvalid, WriteValue_8470_847F, MEM_RI_REG, MEM_RI_REG }, // RI Reg ! { 0x8480, 0x848F, Read_8480_848F, WriteInvalid, WriteValue_8480_848F, 0, 0 }, // SI Reg ! { 0x8490, 0x84FF, ReadInvalid, WriteInvalid, WriteValueInvalid, 0, 0}, // Unused ! { 0x8500, 0x85FF, ReadInvalid/*ReadROM*/, WriteInvalid, WriteValue_Cartridge, 0, 0 }, // Cartridge Domain 2 Address 1 ! { 0x8600, 0x87FF, ReadROM, WriteInvalid, WriteValue_Cartridge, 0, 0 }, // Cartridge Domain 1 Address 1 ! { 0x8800, 0x8FFF, ReadROM, WriteInvalid, WriteValue_Cartridge, 0, 0 }, // Cartridge Domain 2 Address 2 ! { 0x9000, 0x9FBF, ReadROM, WriteInvalid, WriteValue_Cartridge, 0, 0 }, // Cartridge Domain 1 Address 2 ! { 0x9FC0, 0x9FCF, Read_9FC0_9FCF, WriteInvalid, WriteValue_9FC0_9FCF, 0, 0 }, // pif RAM/ROM ! { 0x9FD0, 0x9FFF, ReadROM, WriteInvalid, WriteValue_Cartridge, 0, 0 }, // Cartridge Domain 1 Address 3 { 0xA000, 0xA07F, Read_Noise, Write_Noise, WriteValueNoise }, // Physical RAM - Copy of above { 0xA080, 0xA3EF, Read_Noise, Write_Noise, WriteValueNoise }, // Unused ! { 0xA3F0, 0xA3FF, Read_83F0_83F0, Write_83F0_83F0,WriteValue_83F0_83F0, MEM_RD_REG, MEM_RD_REG }, // RDRAM Reg //{ 0xA3F4, 0xA3FF, ReadInvalid, WriteInvalid }, // Unused ! { 0xA400, 0xA400, Read_8400_8400, Write_8400_8400, WriteValue_8400_8400, MEM_SP_MEM, MEM_SP_MEM }, // DMEM/IMEM ! { 0xA404, 0xA404, Read_8404_8404, WriteInvalid, WriteValue_8404_8404, MEM_SP_REG, 0 }, // SP Reg ! { 0xA408, 0xA408, Read_8408_8408, WriteInvalid, WriteValue_8408_8408, 0, 0 }, // SP PC/OBOST ! { 0xA40C, 0xA40F, ReadInvalid, WriteInvalid, WriteValueInvalid, 0, 0 }, // Unused ! { 0xA410, 0xA41F, Read_8410_841F, WriteInvalid, WriteValue_8410_841F, MEM_DP_COMMAND_REG, 0 }, // DPC Reg ! { 0xA420, 0xA42F, Read_8420_842F, WriteInvalid, WriteValue_8420_842F, 0, 0 }, // DPS Reg ! ! { 0xA430, 0xA43F, Read_8430_843F, WriteInvalid, WriteValue_8430_843F, MEM_MI_REG, 0 }, // MI Reg ! { 0xA440, 0xA44F, Read_8440_844F, WriteInvalid, WriteValue_8440_844F, 0, 0 }, // VI Reg ! { 0xA450, 0xA45F, Read_8450_845F, WriteInvalid, WriteValue_8450_845F, 0, 0 }, // AI Reg ! { 0xA460, 0xA46F, Read_8460_846F, WriteInvalid, WriteValue_8460_846F, MEM_PI_REG, 0 }, // PI Reg ! { 0xA470, 0xA47F, Read_8470_847F, WriteInvalid, WriteValue_8470_847F, MEM_RI_REG, MEM_RI_REG }, // RI Reg ! { 0xA480, 0xA48F, Read_8480_848F, WriteInvalid, WriteValue_8480_848F, 0, 0 }, // SI Reg ! { 0xA490, 0xA4FF, ReadInvalid, WriteInvalid, WriteValueInvalid, 0, 0 }, // Unused ! { 0xA500, 0xA5FF, ReadROM, WriteInvalid, WriteValue_Cartridge, 0, 0 }, // Cartridge Domain 2 Address 1 ! { 0xA600, 0xA7FF, ReadROM, WriteInvalid, WriteValue_Cartridge, 0, 0 }, // Cartridge Domain 1 Address 1 ! { 0xA800, 0xAFFF, ReadROM, WriteInvalid, WriteValue_Cartridge, 0, 0 }, // Cartridge Domain 2 Address 2 ! { 0xB000, 0xBFBF, ReadROM, WriteInvalid, WriteValue_Cartridge, 0, 0 }, // Cartridge Domain 1 Address 2 ! { 0xBFC0, 0xBFCF, Read_9FC0_9FCF, WriteInvalid, WriteValue_9FC0_9FCF, 0, 0 }, // pif RAM/ROM ! { 0xBFD0, 0xBFFF, ReadROM, WriteInvalid, WriteValue_Cartridge, 0, 0 }, // Cartridge Domain 1 Address 3 ! { 0xC000, 0xDFFF, ReadMapped, WriteMapped, WriteValueMapped, 0, 0 }, // Mapped Memory ! { 0xE000, 0xFFFF, ReadMapped, WriteMapped, WriteValueMapped, 0, 0 }, // Mapped Memory { ~0, ~0, NULL, NULL } }; + #ifdef _DEBUG + MemFastFunction g_ReadAddressLookupTable[0x4000]; + MemFastFunction g_WriteAddressLookupTable[0x4000]; + MemWriteValueFunction g_WriteAddressValueLookupTable[0x4000]; + InternalMemFastFunction InternalReadFastTable[0x4000]; + InternalMemFastFunction InternalWriteFastTable[0x4000]; + void* g_ReadAddressPointerLookupTable[0x4000]; + void* g_WriteAddressPointerLookupTable[0x4000]; ! #else /* not _DEBUG */ ! ALIGNED_GLOBAL(memory_tables_struct_t, memory_tables_struct, PAGE_ALIGN); + #endif /* _DEBUG */ void * g_pMemoryBuffers[NUM_MEM_BUFFERS] = *************** *** 255,259 **** --- 263,285 ---- }; + static size_t Memory_AdjustRegionSize(size_t regionSize) + { + #ifdef DO_MEMORY_BOUNDS_CHECKING + return regionSize; + #else + return ( (regionSize - 1) & ~((1 << 18) - 1) ) + (1 << 18); + #endif + } + + void* Memory_AllocRegion(size_t regionSize) // must be already adjusted + { + // VirtualAlloc ensures page-alignment and is more efficient for large blocks + return VirtualAlloc(NULL, Memory_AdjustRegionSize(regionSize), MEM_COMMIT, PAGE_READWRITE); + } + void Memory_FreeRegion(void* region) // must be already adjusted + { + VirtualFree(region, 0, MEM_RELEASE); + } BOOL Memory_Init() *************** *** 266,286 **** if (MemoryRegionSizes[m] > 0) { ! g_pMemoryBuffers[m] = new BYTE[MemoryRegionSizes[m]]; if (g_pMemoryBuffers[m] == NULL) return FALSE; ! ZeroMemory(g_pMemoryBuffers[m], MemoryRegionSizes[m]); } } - - g_ReadAddressLookupTable = new MemFastFunction[0x4000]; - g_WriteAddressLookupTable = new MemFastFunction[0x4000]; - g_WriteAddressValueLookupTable = new MemWriteValueFunction[0x4000]; - - InternalReadFastTable = new InternalMemFastFunction[0x4000]; - InternalWriteFastTable = new InternalMemFastFunction[0x4000]; - - g_pu8RamBase_8000 = ((u8*)g_pMemoryBuffers[MEM_RD_RAM]) - 0x80000000; g_pu8RamBase_A000 = ((u8*)g_pMemoryBuffers[MEM_RD_RAM]) - 0xa0000000; --- 292,306 ---- if (MemoryRegionSizes[m] > 0) { ! //g_pMemoryBuffers[m] = new BYTE[MemoryRegionSizes[m]]; ! g_pMemoryBuffers[m] = Memory_AllocRegion(MemoryRegionSizes[m]); ! if (g_pMemoryBuffers[m] == NULL) return FALSE; ! // Not required - virtual alloc gives zeroed memory ! //ZeroMemory(g_pMemoryBuffers[m], regionSize); } } g_pu8RamBase_8000 = ((u8*)g_pMemoryBuffers[MEM_RD_RAM]) - 0x80000000; g_pu8RamBase_A000 = ((u8*)g_pMemoryBuffers[MEM_RD_RAM]) - 0xa0000000; *************** *** 297,309 **** DPF(DEBUG_INFO, "Freeing Memory"); - delete [] g_ReadAddressLookupTable; - delete [] g_WriteAddressLookupTable; - delete [] g_WriteAddressValueLookupTable; - for (DWORD m = 0; m < NUM_MEM_BUFFERS; m++) { if (g_pMemoryBuffers[m] != NULL) { ! delete [] (BYTE*)(g_pMemoryBuffers[m]); g_pMemoryBuffers[m] = NULL; } --- 317,326 ---- DPF(DEBUG_INFO, "Freeing Memory"); for (DWORD m = 0; m < NUM_MEM_BUFFERS; m++) { if (g_pMemoryBuffers[m] != NULL) { ! //delete [] (BYTE*)(g_pMemoryBuffers[m]); ! Memory_FreeRegion(g_pMemoryBuffers[m]); g_pMemoryBuffers[m] = NULL; } *************** *** 340,343 **** --- 357,361 ---- Memory_InitTables(); + // Required - virtual alloc gives zeroed memory but this is also used when resetting // Clear memory for (i = 0; i < NUM_MEM_BUFFERS; i++) *************** *** 426,429 **** --- 444,478 ---- } + static void Memory_InitTables_ROM_PointerTable(DWORD startPhys, DWORD endPhys) + { + if(MemoryRegionSizes[MEM_CARTROM] == 0) + return; + + DWORD dwStart = startPhys >> 16; + DWORD dwEnd = (min (endPhys, startPhys + MemoryRegionSizes[MEM_CARTROM]) >> 16) - 1; + DWORD i; + void* pointerLookupTableEntry; + + dwStart += 0x8000; + dwEnd += 0x8000; + + pointerLookupTableEntry = (void*)((UINT_PTR)g_pMemoryBuffers[MEM_CARTROM] - (dwStart << 16)); + + for (i = (dwStart>>2); i <= (dwEnd>>2); i++) + { + g_ReadAddressPointerLookupTable[i] = pointerLookupTableEntry; + } + + dwStart += 0x2000; + dwEnd += 0x2000; + + pointerLookupTableEntry = (void*)((UINT_PTR)g_pMemoryBuffers[MEM_CARTROM] - (dwStart << 16)); + + for (i = (dwStart>>2); i <= (dwEnd>>2); i++) + { + g_ReadAddressPointerLookupTable[i] = pointerLookupTableEntry; + } + } + void Memory_InitTables() { *************** *** 441,445 **** --- 490,502 ---- ZeroMemory(InternalReadFastTable, sizeof(InternalMemFastFunction) * 0x4000); ZeroMemory(InternalWriteFastTable, sizeof(InternalMemFastFunction) * 0x4000); + ZeroMemory(g_ReadAddressPointerLookupTable, sizeof(void*) * 0x4000); + ZeroMemory(g_WriteAddressPointerLookupTable, sizeof(void*) * 0x4000); + // these values cause the result of the addition to be negative (>= 0x80000000) + for(i = 0; i < 0x4000; i++) + { + g_WriteAddressPointerLookupTable[i] = g_ReadAddressPointerLookupTable[i] = Memory_GetInvalidPointerTableEntry(i); + } + while (MemMapEntries[dwEntry].dwStart != ~0) { *************** *** 447,450 **** --- 504,512 ---- dwEnd = MemMapEntries[dwEntry].dwEnd; + #ifndef MEMORY_DO_BOUNDS_CHECKING // this kills bounds checking + void* readPointerLookupTableEntry = MemMapEntries[dwEntry].ReadRegion ? (void*)((UINT_PTR)g_pMemoryBuffers[MemMapEntries[dwEntry].ReadRegion] - (dwStart << 16)) : 0; + void* writePointerLookupTableEntry = MemMapEntries[dwEntry].WriteRegion ? (void*)((UINT_PTR)g_pMemoryBuffers[MemMapEntries[dwEntry].WriteRegion] - (dwStart << 16)) : 0; + #endif + for (i = (dwStart>>2); i <= (dwEnd>>2); i++) { *************** *** 452,455 **** --- 514,525 ---- g_WriteAddressLookupTable[i] = MemMapEntries[dwEntry].WriteFastFunction; g_WriteAddressValueLookupTable[i] = MemMapEntries[dwEntry].WriteValueFunction; + + #ifndef MEMORY_DO_BOUNDS_CHECKING // this kills bounds checking + if(MemMapEntries[dwEntry].ReadRegion) + g_ReadAddressPointerLookupTable[i] = readPointerLookupTableEntry; + + if(MemMapEntries[dwEntry].WriteRegion) + g_WriteAddressPointerLookupTable[i] = writePointerLookupTableEntry; + #endif } *************** *** 495,498 **** --- 565,570 ---- InternalMemFastFunction pInternalReadRam; InternalMemFastFunction pInternalWriteRam; + + void* pointerLookupTableEntry; if (dwRAMSize == MEMORY_4_MEG) *************** *** 521,524 **** --- 593,598 ---- dwEnd = 0x8000 + ((dwRAMSize>>16)-1); + pointerLookupTableEntry = (void*)((UINT_PTR)g_pMemoryBuffers[MEM_RD_RAM] - (dwStart << 16)); + for (i = (dwStart>>2); i <= (dwEnd>>2); i++) { *************** *** 529,532 **** --- 603,609 ---- InternalReadFastTable[i] = pInternalReadRam; InternalWriteFastTable[i] = pInternalWriteRam; + + g_ReadAddressPointerLookupTable[i] = pointerLookupTableEntry; + g_WriteAddressPointerLookupTable[i] = pointerLookupTableEntry; } *************** *** 556,559 **** --- 633,638 ---- dwEnd = 0xA000 + ((dwRAMSize>>16)-1); + pointerLookupTableEntry = (void*)((UINT_PTR)g_pMemoryBuffers[MEM_RD_RAM] - (dwStart << 16)); + for (i = (dwStart>>2); i <= (dwEnd>>2); i++) { *************** *** 564,569 **** InternalReadFastTable[i] = pInternalReadRam; InternalWriteFastTable[i] = pInternalWriteRam; - } // The range 0x7f000000 -> 0x7fffffff is initialised to ReadMapped by default // We map the Goldeneye range over this region --- 643,655 ---- InternalReadFastTable[i] = pInternalReadRam; InternalWriteFastTable[i] = pInternalWriteRam; + g_ReadAddressPointerLookupTable[i] = pointerLookupTableEntry; + g_WriteAddressPointerLookupTable[i] = pointerLookupTableEntry; + } + + Memory_InitTables_ROM_PointerTable(PI_DOM1_ADDR1, PI_DOM2_ADDR2); + Memory_InitTables_ROM_PointerTable(PI_DOM1_ADDR2, 0x1FC00000); + Memory_InitTables_ROM_PointerTable(PI_DOM1_ADDR3, 0x20000000); + // The range 0x7f000000 -> 0x7fffffff is initialised to ReadMapped by default // We map the Goldeneye range over this region *************** *** 586,589 **** --- 672,677 ---- DBGConsole_Msg(0, "[MMapping Virtual Memory (HACK)"); + pointerLookupTableEntry = (void*)((UINT_PTR)g_pMemoryBuffers[MEM_CARTROM] + (GOLDENEYE_HACKED_OFFSET & 0x00FFFFFF) - 0x7f000000); + for (i = (0x7f00>>2); i <= (0x7FFF>>2); i++) { *************** *** 594,597 **** --- 682,688 ---- InternalReadFastTable[i] = InternalReadMappedGolden; InternalWriteFastTable[i] = InternalWriteInvalid; + + g_ReadAddressPointerLookupTable[i] = pointerLookupTableEntry; + g_WriteAddressPointerLookupTable[i] = pointerLookupTableEntry; } } *************** *** 603,607 **** if (g_pMemoryBuffers[MEM_CARTROM] != NULL) { ! delete [] (BYTE*)(g_pMemoryBuffers[MEM_CARTROM]); g_pMemoryBuffers[MEM_CARTROM] = NULL; MemoryRegionSizes[MEM_CARTROM] = 0; --- 694,699 ---- if (g_pMemoryBuffers[MEM_CARTROM] != NULL) { ! //delete [] (BYTE*)(g_pMemoryBuffers[MEM_CARTROM]); ! Memory_FreeRegion(g_pMemoryBuffers[MEM_CARTROM]); g_pMemoryBuffers[MEM_CARTROM] = NULL; MemoryRegionSizes[MEM_CARTROM] = 0; Only in .: Memory.cpp~ diff -C 2 --exclude=*.dsp --exclude=*.vts ../Daedalus-Lkb-0.07b-lkb3/Memory.h ./Memory.h *** ../Daedalus-Lkb-0.07b-lkb3/Memory.h Fri Aug 24 18:50:14 2001 --- ./Memory.h Sat Aug 25 19:33:40 2001 *************** *** 27,31 **** #include "ultra_types.h" ! enum MEMBANKTYPE --- 27,36 ---- #include "ultra_types.h" ! #ifdef DAEDALUS_RELEASE_BUILD ! #define MEMORY_BOUNDS_CHECKING(x) 1 ! #else ! #define DO_MEMORY_BOUNDS_CHECKING ! #define MEMORY_BOUNDS_CHECKING(x) x ! #endif enum MEMBANKTYPE *************** *** 76,79 **** --- 81,86 ---- void Memory_SetCart(u8 * pBytes, DWORD dwLen); + void* Memory_AllocRegion(size_t regionSize); + void Memory_FreeRegion(void* region); void Memory_SiDisable(); *************** *** 84,98 **** typedef DWORD (*InternalMemFastFunction)(DWORD dwAddress, void ** pTranslated); ! extern MemFastFunction * g_ReadAddressLookupTable; ! extern MemFastFunction *g_WriteAddressLookupTable; ! extern MemWriteValueFunction *g_WriteAddressValueLookupTable; ! extern InternalMemFastFunction *InternalReadFastTable; ! extern InternalMemFastFunction *InternalWriteFastTable; ! #define ReadAddress(dwAddr) (void *)(g_ReadAddressLookupTable)[(dwAddr)>>18](dwAddr) ! #define WriteAddress(dwAddr) (void *)(g_WriteAddressLookupTable)[(dwAddr)>>18](dwAddr) ! #define WriteValueAddress(dwAddr, dwValue) (g_WriteAddressValueLookupTable)[(dwAddr)>>18](dwAddr, dwValue) #define InternalReadAddress(dwAddr, pTrans) (InternalReadFastTable)[(dwAddr)>>18](dwAddr, pTrans) --- 91,289 ---- typedef DWORD (*InternalMemFastFunction)(DWORD dwAddress, void ** pTranslated); + /* Modified by Lkb (24/8/2001) + These tables were declared as pointers and dynamically allocated. + However, by declaring them as pointers to access the tables the interpreter must use code like this: + + MOV EAX, DWORD PTR [address_of_the_variable_g_ReadAddressLookupTable] + MOV EAX, DWORD PTR [EAX + desired_offset] + + Instead, by declaring them as integers the address of table is "known" at compile time + (at load-time it may be relocated but the code referencing it will be patched) + and the interpreter can use code like this: + + MOV EAX, DWORD PTR [address_of_the_array_g_ReadAddressLookupTable + desired_offset] + + Note that dynarec-generated code is not affected by this + + The exotic construction is required to ensure page-alignment + + Memory.cpp also changed appropriately + */ + + // For debugging, it's more important to be able to use the debugger + #ifndef DAEDALUS_RELEASE_BUILD + extern MemFastFunction g_ReadAddressLookupTable[0x4000]; + extern MemFastFunction g_WriteAddressLookupTable[0x4000]; + extern MemWriteValueFunction g_WriteAddressValueLookupTable[0x4000]; + extern InternalMemFastFunction InternalReadFastTable[0x4000]; + extern InternalMemFastFunction InternalWriteFastTable[0x4000]; + extern void* g_ReadAddressPointerLookupTable[0x4000]; + extern void* g_WriteAddressPointerLookupTable[0x4000]; + + #else /* DAEDALUS_RELEASE_BUILD */ + + #pragma pack(push, 1) + + ALIGNED_TYPE(struct memory_tables_struct_t, PAGE_ALIGN) + { + MemFastFunction _g_ReadAddressLookupTable[0x4000]; + MemFastFunction _g_WriteAddressLookupTable[0x4000]; + MemWriteValueFunction _g_WriteAddressValueLookupTable[0x4000]; + + InternalMemFastFunction _InternalReadFastTable[0x4000]; + InternalMemFastFunction _InternalWriteFastTable[0x4000]; + + void* _g_ReadAddressPointerLookupTable[0x4000]; + void* _g_WriteAddressPointerLookupTable[0x4000]; + }; + + ALIGNED_EXTERN(memory_tables_struct_t, memory_tables_struct, PAGE_ALIGN); + #pragma pack(pop) ! #define g_ReadAddressLookupTable (memory_tables_struct._g_ReadAddressLookupTable) ! #define g_WriteAddressLookupTable (memory_tables_struct._g_WriteAddressLookupTable) ! #define g_WriteAddressValueLookupTable (memory_tables_struct._g_WriteAddressValueLookupTable) ! #define InternalReadFastTable (memory_tables_struct._InternalReadFastTable) ! #define InternalWriteFastTable (memory_tables_struct._InternalWriteFastTable) ! #define g_ReadAddressPointerLookupTable (memory_tables_struct._g_ReadAddressPointerLookupTable) ! #define g_WriteAddressPointerLookupTable (memory_tables_struct._g_WriteAddressPointerLookupTable) ! ! #endif /* _DEBUG */ ! ! /* Added by Lkb (24/8/2001) ! These tables are used to implement a faster memory system similar to the one used in gnuboy (http://gnuboy.unix-fu.org/ - read docs/HACKING). ! However instead of testing for zero the entry like gnuboy, Daedalus checks the sign of the addition results. ! When the pointer table entry is valid, this should be faster since instead of MOV/TEST/ADD (1+1+1 uops) it uses just ADD mem (2 uops) ! But when the pointer table entry is invalid, it may be slower because it computes the address twice ! ! # Old system: ! .intel_syntax ! MOV EAX, address ! MOV ECX, EAX ! SHR EAX, 18 ! CALL DWORD PTR [g_ReadAddressLookupTable + EAX*4] ! # --> (for RAM) ! ADD ECX, [rambase_variable] ! MOV EAX, ECX ! RET ! ! # gnuboy system: ! .intel_syntax ! MOV EAX, address ! MOV EDX, EAX ! SHR EDX, 18 ! MOV ECX, [g_ReadAddressPointerLookupTable + EDX*4] ! TEST ECX, ECX ! JS pointer_null # usually not taken - thus forward branch ! ADD EAX, ECX ! pointer_null_return_x: ! # [...] ! # RET ! ! pointer_null_x: ! MOV ECX, EAX ! CALL DWORD PTR [g_ReadAddressLookupTable + EDX*4] ! # --> (for RAM) ! # ADD ECX, [rambase_variable] ! # MOV EAX, ECX ! # RET ! # <-- ! JMP pointer_null_return ! ! # New system: ! .intel_syntax ! MOV EAX, address ! MOV EDX, EAX ! SHR EDX, 18 ! ADD EAX, [g_ReadAddressPointerLookupTable + EDX*4] ! JS pointer_null # usually not taken - thus forward branch ! pointer_null_return_x: ! # [...] ! # RET ! ! pointer_null_x: ! MOV ECX, address ! CALL DWORD PTR [g_ReadAddressLookupTable + EDX*4] ! # --> (for RAM) ! # ADD ECX, [rambase_variable] ! # MOV EAX, ECX ! # RET ! # <-- ! JMP pointer_null_return ! ! Note however that the compiler may generate worse code. + The old system is still usable (and it is required even if the new one is used since it will fallback to the old for access to memory-mapped hw registers and similar areas) ! TODO: instead of looking up TLB entries each time TLB-mapped memory is used, it is probably much faster to change the pointer table every time the TLB is modified ! */ ! ! inline void* Memory_GetInvalidPointerTableEntry(int entry) ! { ! return (void*)(0xf0000000 - (entry << 18)); ! } ! ! #define FuncTableReadAddress(dwAddr) (void *)(g_ReadAddressLookupTable)[(dwAddr)>>18](dwAddr) ! #define FuncTableWriteAddress(dwAddr) (void *)(g_WriteAddressLookupTable)[(dwAddr)>>18](dwAddr) ! #define FuncTableWriteValueAddress(dwAddr, dwValue) (g_WriteAddressValueLookupTable)[(dwAddr)>>18](dwAddr, dwValue) ! ! #if 0 ! #define ReadAddress FuncTableReadAddress ! #define WriteAddress FuncTableReadAddress ! #define OldWriteValueAddress FuncTableReadAddress ! #else ! ! inline void* ReadAddress (u32 addr) ! { ! UINT_PTR tableEntry = (UINT_PTR)g_ReadAddressPointerLookupTable[addr >> 18] + addr; ! #ifdef __GNUC__ ! if(__builtin_expect ((INT_PTR)tableEntry >= 0, 1)) ! #else ! if((INT_PTR)tableEntry >= 0) // any way to tell MSC that tableEntry will typically be >= 0 ? ! #endif ! { ! return (void*)(tableEntry); ! } ! else ! { ! return FuncTableReadAddress (addr); ! } ! } ! ! inline void* WriteAddress (u32 addr) ! { ! UINT_PTR tableEntry = (UINT_PTR)g_WriteAddressPointerLookupTable[addr >> 18] + addr; ! #ifdef __GNUC__ ! if(__builtin_expect ((INT_PTR)tableEntry >= 0, 1)) ! #else ! if((INT_PTR)tableEntry >= 0) // any way to tell MSC that tableEntry will typically be >= 0 ? ! #endif ! { ! return (void*)(tableEntry); ! } ! else ! { ! return FuncTableWriteAddress (addr); ! } ! } ! ! inline void WriteValueAddress (u32 addr, u32 value) ! { ! UINT_PTR tableEntry = (UINT_PTR)g_WriteAddressPointerLookupTable[addr >> 18] + addr; ! ! #ifdef __GNUC__ ! if(__builtin_expect ((INT_PTR)tableEntry >= 0, 1)) ! #else ! if((INT_PTR)tableEntry >= 0) // any way to tell MSC that tableEntry will typically be >= 0 ? ! #endif ! { ! *(u32*)(tableEntry) = value; ! } ! else ! { ! FuncTableWriteValueAddress (addr, value); ! } ! } ! #endif /* 0 */ #define InternalReadAddress(dwAddr, pTrans) (InternalReadFastTable)[(dwAddr)>>18](dwAddr, pTrans) *************** *** 131,135 **** #define g_pu16SpMemBase ((u16*)g_pMemoryBuffers[MEM_SP_MEM]) #define g_pu32SpMemBase ((u32*)g_pMemoryBuffers[MEM_SP_MEM]) - inline void Write64Bits(DWORD dwAddress, u64 qwData) --- 322,325 ---- Only in .: Memory.h~ diff -C 2 --exclude=*.dsp --exclude=*.vts ../Daedalus-Lkb-0.07b-lkb3/Memory_Read.inl ./Memory_Read.inl *** ../Daedalus-Lkb-0.07b-lkb3/Memory_Read.inl Fri Aug 24 18:50:22 2001 --- ./Memory_Read.inl Sat Aug 25 19:33:40 2001 *************** *** 18,22 **** */ - static void * ReadInvalid(DWORD dwAddress) { --- 18,21 ---- *************** *** 240,244 **** // 0x83F0 0000 to 0x83FF FFFF RDRAM registers ! if ((dwAddress&0x1FFFFFFF) < 0x04000000) { DPF(DEBUG_MEMORY_RDRAM_REG, "Reading from MEM_RD_REG: 0x%08x", dwAddress); --- 239,243 ---- // 0x83F0 0000 to 0x83FF FFFF RDRAM registers ! if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) < 0x04000000)) { DPF(DEBUG_MEMORY_RDRAM_REG, "Reading from MEM_RD_REG: 0x%08x", dwAddress); *************** *** 254,258 **** { // 0x0400 0000 to 0x0400 FFFF SP registers ! if ((dwAddress&0x1FFFFFFF) < 0x4002000) { DPF(DEBUG_MEMORY_SP_IMEM, "Reading from SP_MEM: 0x%08x", dwAddress); --- 253,257 ---- { // 0x0400 0000 to 0x0400 FFFF SP registers ! if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) < 0x4002000)) { DPF(DEBUG_MEMORY_SP_IMEM, "Reading from SP_MEM: 0x%08x", dwAddress); *************** *** 268,272 **** static void *Read_8404_8404(DWORD dwAddress) { ! if ((dwAddress&0x1FFFFFFF) < 0x04040020) { DPF(DEBUG_MEMORY_SP_REG, "Reading from SP_REG: 0x%08x", dwAddress); return (BYTE *)g_pMemoryBuffers[MEM_SP_REG] + (dwAddress & 0xFF); --- 267,271 ---- static void *Read_8404_8404(DWORD dwAddress) { ! if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) < 0x04040020)) { DPF(DEBUG_MEMORY_SP_REG, "Reading from SP_REG: 0x%08x", dwAddress); return (BYTE *)g_pMemoryBuffers[MEM_SP_REG] + (dwAddress & 0xFF); *************** *** 289,293 **** } // 0x04080004 to 0x04080007 SP_IBIST_REG ! else if ((dwAddress&0x1FFFFFFF) < 0x04080008) { DPF(DEBUG_MEMORY_SP_REG, "Reading from SP_IBIST_REG: 0x%08x", dwAddress); --- 288,292 ---- } // 0x04080004 to 0x04080007 SP_IBIST_REG ! else if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) < 0x04080008)) { DPF(DEBUG_MEMORY_SP_REG, "Reading from SP_IBIST_REG: 0x%08x", dwAddress); *************** *** 304,308 **** { // 0x0410 0000 to 0x041F FFFF DP Command Registers ! if ((dwAddress&0x1FFFFFFF) < 0x04100020) { DPF(DEBUG_MEMORY_DP, "Reading from DP_COMMAND_REG: 0x%08x", dwAddress); --- 303,307 ---- { // 0x0410 0000 to 0x041F FFFF DP Command Registers ! if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) < 0x04100020)) { DPF(DEBUG_MEMORY_DP, "Reading from DP_COMMAND_REG: 0x%08x", dwAddress); *************** *** 330,334 **** static void *Read_8430_843F(DWORD dwAddress) { ! if ((dwAddress&0x1FFFFFFF) <= MI_LAST_REG) { DPF(DEBUG_MEMORY_MI, "Reading from MI Registers: 0x%08x", dwAddress); --- 329,333 ---- static void *Read_8430_843F(DWORD dwAddress) { ! if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) <= MI_LAST_REG)) { DPF(DEBUG_MEMORY_MI, "Reading from MI Registers: 0x%08x", dwAddress); *************** *** 348,352 **** { ! if ((dwAddress&0x1FFFFFFF) <= VI_LAST_REG) { DPF(DEBUG_MEMORY_VI, "Reading from MEM_VI_REG: 0x%08x", dwAddress); --- 347,351 ---- { ! if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) <= VI_LAST_REG)) { DPF(DEBUG_MEMORY_VI, "Reading from MEM_VI_REG: 0x%08x", dwAddress); *************** *** 380,384 **** DWORD dwOffset; ! if ((dwAddress&0x1FFFFFFF) <= AI_LAST_REG) { dwOffset = dwAddress & 0xFF; --- 379,383 ---- DWORD dwOffset; ! if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) <= AI_LAST_REG)) { dwOffset = dwAddress & 0xFF; *************** *** 443,447 **** static void *Read_8470_847F(DWORD dwAddress) { ! if ((dwAddress&0x1FFFFFFF) <= RI_LAST_REG) { DPF(DEBUG_MEMORY_RI, "Reading from MEM_RI_REG: 0x%08x", dwAddress); --- 442,446 ---- static void *Read_8470_847F(DWORD dwAddress) { ! if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) <= RI_LAST_REG)) { DPF(DEBUG_MEMORY_RI, "Reading from MEM_RI_REG: 0x%08x", dwAddress); *************** *** 459,463 **** DWORD dwOffset; ! if ((dwAddress&0x1FFFFFFF) <= SI_LAST_REG) { dwOffset = dwAddress & 0xFF; --- 458,462 ---- DWORD dwOffset; ! if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) <= SI_LAST_REG)) { dwOffset = dwAddress & 0xFF; *************** *** 603,607 **** } ! else if ((dwAddress&0x1FFFFFFF) <= PIF_RAM_END) { DPF(DEBUG_MEMORY_PIF, "Reading from MEM_PI_RAM: 0x%08x", dwAddress); --- 602,606 ---- } ! else if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) <= PIF_RAM_END)) { DPF(DEBUG_MEMORY_PIF, "Reading from MEM_PI_RAM: 0x%08x", dwAddress); diff -C 2 --exclude=*.dsp --exclude=*.vts ../Daedalus-Lkb-0.07b-lkb3/Memory_Write.inl ./Memory_Write.inl *** ../Daedalus-Lkb-0.07b-lkb3/Memory_Write.inl Fri Aug 24 18:50:23 2001 --- ./Memory_Write.inl Sat Aug 25 19:33:40 2001 *************** *** 169,173 **** { ! if ((dwAddress&0x1FFFFFFF) < 0x04000000) { DPF(DEBUG_MEMORY_RDRAM_REG, "Writing to MEM_RD_REG: 0x%08x", dwAddress); --- 169,173 ---- { ! if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) < 0x04000000)) { DPF(DEBUG_MEMORY_RDRAM_REG, "Writing to MEM_RD_REG: 0x%08x", dwAddress); *************** *** 186,190 **** { ! if ((dwAddress&0x1FFFFFFF) <= SP_IMEM_END) { DPF(DEBUG_MEMORY_SP_IMEM, "Writing to SP_MEM: 0x%08x", dwAddress); --- 186,190 ---- { ! if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) <= SP_IMEM_END)) { DPF(DEBUG_MEMORY_SP_IMEM, "Writing to SP_MEM: 0x%08x", dwAddress); diff -C 2 --exclude=*.dsp --exclude=*.vts ../Daedalus-Lkb-0.07b-lkb3/Memory_WriteValue.inl ./Memory_WriteValue.inl *** ../Daedalus-Lkb-0.07b-lkb3/Memory_WriteValue.inl Fri Aug 24 18:50:23 2001 --- ./Memory_WriteValue.inl Sat Aug 25 19:33:40 2001 *************** *** 215,219 **** { ! if ((dwAddress&0x1FFFFFFF) < 0x04000000) { DPF(DEBUG_MEMORY_RDRAM_REG, "Writing to MEM_RD_REG: 0x%08x", dwAddress); --- 215,219 ---- { ! if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) < 0x04000000)) { DPF(DEBUG_MEMORY_RDRAM_REG, "Writing to MEM_RD_REG: 0x%08x", dwAddress); *************** *** 233,237 **** { ! if ((dwAddress&0x1FFFFFFF) <= SP_IMEM_END) { DPF(DEBUG_MEMORY_SP_IMEM, "Writing to SP_MEM: 0x%08x", dwAddress); --- 233,237 ---- { ! if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) <= SP_IMEM_END)) { DPF(DEBUG_MEMORY_SP_IMEM, "Writing to SP_MEM: 0x%08x", dwAddress); *************** *** 251,255 **** DWORD dwOffset; ! if ((dwAddress&0x1FFFFFFF) <= SP_LAST_REG) { DPF(DEBUG_MEMORY_SP_REG, "Writing to SP_REG: 0x%08x/0x%08x", dwAddress, dwValue); --- 251,255 ---- DWORD dwOffset; ! if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) <= SP_LAST_REG)) { DPF(DEBUG_MEMORY_SP_REG, "Writing to SP_REG: 0x%08x/0x%08x", dwAddress, dwValue); *************** *** 310,314 **** } ! else if ((dwAddress&0x1FFFFFFF) <= SP_IBIST_REG) { DPF(DEBUG_MEMORY_SP_REG, "Writing to SP_IBIST_REG: 0x%08x", dwValue); --- 310,314 ---- } ! else if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) <= SP_IBIST_REG)) { DPF(DEBUG_MEMORY_SP_REG, "Writing to SP_IBIST_REG: 0x%08x", dwValue); *************** *** 328,332 **** DWORD dwOffset; ! if ((dwAddress&0x1FFFFFFF) <= DPC_LAST_REG) { DPF(DEBUG_MEMORY_DP, "Writing to DP_COMMAND_REG: 0x%08x", dwAddress); --- 328,332 ---- DWORD dwOffset; ! if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) <= DPC_LAST_REG)) { DPF(DEBUG_MEMORY_DP, "Writing to DP_COMMAND_REG: 0x%08x", dwAddress); *************** *** 384,388 **** DWORD dwOffset; ! if ((dwAddress&0x1FFFFFFF) <= MI_LAST_REG) { DPF(DEBUG_MEMORY_MI, "Writing to MI Registers: 0x%08x", dwAddress); --- 384,388 ---- DWORD dwOffset; ! if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) <= MI_LAST_REG)) { DPF(DEBUG_MEMORY_MI, "Writing to MI Registers: 0x%08x", dwAddress); *************** *** 421,425 **** static void WriteValue_8440_844F(DWORD dwAddress, DWORD dwValue) { ! if ((dwAddress&0x1FFFFFFF) <= VI_LAST_REG) { MemoryUpdateVI(dwAddress, dwValue); --- 421,425 ---- static void WriteValue_8440_844F(DWORD dwAddress, DWORD dwValue) { ! if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) <= VI_LAST_REG)) { MemoryUpdateVI(dwAddress, dwValue); *************** *** 437,441 **** DWORD dwOffset; ! if ((dwAddress&0x1FFFFFFF) <= AI_LAST_REG) { DPF(DEBUG_MEMORY_AI, "Writing to AI Registers: 0x%08x", dwAddress); --- 437,441 ---- DWORD dwOffset; ! if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) <= AI_LAST_REG)) { DPF(DEBUG_MEMORY_AI, "Writing to AI Registers: 0x%08x", dwAddress); *************** *** 495,499 **** DWORD dwOffset; ! if ((dwAddress&0x1FFFFFFF) <= PI_LAST_REG) { dwOffset = dwAddress & 0xFF; --- 495,499 ---- DWORD dwOffset; ! if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) <= PI_LAST_REG)) { dwOffset = dwAddress & 0xFF; *************** *** 549,553 **** DWORD dwOffset; ! if ((dwAddress&0x1FFFFFFF) <= RI_LAST_REG) { DPF(DEBUG_MEMORY_RI, "Writing to MEM_RI_REG: 0x%08x", dwAddress); --- 549,553 ---- DWORD dwOffset; ! if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) <= RI_LAST_REG)) { DPF(DEBUG_MEMORY_RI, "Writing to MEM_RI_REG: 0x%08x", dwAddress); *************** *** 570,574 **** DWORD dwOffset; ! if ((dwAddress&0x1FFFFFFF) <= SI_LAST_REG) { DPF(DEBUG_MEMORY_SI, "Writing to MEM_SI_REG: 0x%08x", dwAddress); --- 570,574 ---- DWORD dwOffset; ! if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) <= SI_LAST_REG)) { DPF(DEBUG_MEMORY_SI, "Writing to MEM_SI_REG: 0x%08x", dwAddress); *************** *** 630,634 **** } ! else if ((dwAddress&0x1FFFFFFF) <= PIF_RAM_END) { DBGConsole_Msg(0, "[WWriting directly to PI ram]: 0x%08x:0x%08x!", dwAddress, dwValue); --- 630,634 ---- } ! else if (MEMORY_BOUNDS_CHECKING((dwAddress&0x1FFFFFFF) <= PIF_RAM_END)) { DBGConsole_Msg(0, "[WWriting directly to PI ram]: 0x%08x:0x%08x!", dwAddress, dwValue); diff -C 2 --exclude=*.dsp --exclude=*.vts ../Daedalus-Lkb-0.07b-lkb3/R4300_Regs.cpp ./R4300_Regs.cpp *** ../Daedalus-Lkb-0.07b-lkb3/R4300_Regs.cpp Fri Aug 24 18:50:04 2001 --- ./R4300_Regs.cpp Sat Aug 25 19:33:41 2001 *************** *** 24,29 **** #include "CPU.h" // 32 64-bit General Purpose Registers ! DWORD g_dwPC = 0x80000000; u64 g_qwMultHI = 0; u64 g_qwMultLO = 0; --- 24,30 ---- #include "CPU.h" + #ifndef DAEDALUS_RELEASE_BUILD // 32 64-bit General Purpose Registers ! DWORD g_dwPC = 0; // = 0x80000000; u64 g_qwMultHI = 0; u64 g_qwMultLO = 0; *************** *** 40,41 **** --- 41,45 ---- BYTE *g_pPCMemBase = NULL; + #else + ALIGNED_GLOBAL(registers_struct_t, registers_struct, PAGE_ALIGN); + #endif \ No newline at end of file diff -C 2 --exclude=*.dsp --exclude=*.vts ../Daedalus-Lkb-0.07b-lkb3/R4300_Regs.h ./R4300_Regs.h *** ../Daedalus-Lkb-0.07b-lkb3/R4300_Regs.h Fri Aug 24 18:50:15 2001 --- ./R4300_Regs.h Sat Aug 25 19:33:41 2001 *************** *** 25,28 **** --- 25,29 ---- #include "ultra_types.h" + #pragma pack(push, 1) struct TLBEntry { *************** *** 37,43 **** --- 38,48 ---- DWORD addrcheck; // vpn2 & vpnmask DWORD lastaccessed; // for least recently used algorithm + + DWORD padding1, padding2; // ensures 64-byte size and thus alignment }; + typedef u64 register_set[32]; + #ifndef DAEDALUS_RELEASE_BUILD extern DWORD g_dwPC; extern u64 g_qwMultHI; *************** *** 55,61 **** --- 60,111 ---- extern BYTE *g_pPCMemBase; + #define g_qwCPR0 (g_qwCPR[0]) + #define g_qwCPR1 (g_qwCPR[1]) + #define g_qwCCR1 (g_qwCCR[1]) + + #else /* DAEDALUS_RELEASE_BUILD */ + + // types are layed out in decreasing order of size + ALIGNED_TYPE(struct registers_struct_t, PAGE_ALIGN) + { + TLBEntry _g_TLBs[32]; + register_set _g_qwGPR; + register_set _g_qwCPR0; + register_set _g_qwCPR1; + register_set _g_qwCCR1; + u64 _g_qwMultLO; + u64 _g_qwMultHI; + DWORD _g_dwPC; + DWORD _g_dwNewPC; + int _g_nDelay; + BYTE* _g_pPCMemBase; + DWORD _g_bLLbit; + }; + + ALIGNED_EXTERN(registers_struct_t, registers_struct, PAGE_ALIGN); + + #define g_TLBs (registers_struct._g_TLBs) + #define g_dwPC (registers_struct._g_dwPC) + #define g_dwNewPC (registers_struct._g_dwNewPC) + #define g_nDelay (registers_struct._g_nDelay) + #define g_qwGPR (registers_struct._g_qwGPR) + #define g_qwCPR0 (registers_struct._g_qwCPR0) + #define g_qwCPR1 (registers_struct._g_qwCPR1) + #define g_qwCCR1 (registers_struct._g_qwCCR1) + #define g_qwMultLO (registers_struct._g_qwMultLO) + #define g_qwMultHI (registers_struct._g_qwMultHI) + #define g_nDelay (registers_struct._g_nDelay) + #define g_pPCMemBase (registers_struct._g_pPCMemBase) + #define g_bLLbit (registers_struct._g_bLLbit) + + #define g_qwCPR ((register_set*)registers_struct._g_qwCPR0) + #define g_qwCCR ((register_set*)registers_struct._g_qwCPR1) // CPR1 is immediately before CCR1 + #define g_qwFCR0 (g_qwCCR1[0]) + #define g_qwFCR1 (g_qwCCR1[1]) + #endif + #pragma pack(pop, 1) #endif diff -C 2 --exclude=*.dsp --exclude=*.vts ../Daedalus-Lkb-0.07b-lkb3/ROM.cpp ./ROM.cpp *** ../Daedalus-Lkb-0.07b-lkb3/ROM.cpp Fri Aug 24 18:50:05 2001 --- ./ROM.cpp Sat Aug 25 19:38:41 2001 *************** *** 48,52 **** static void ROM_CheckIniFile(LPROMINFO pRomInfo); static BOOL ROM_LoadCartToMemory(LPCTSTR szFileName); ! static HRESULT ROM_LoadDataFromFile(LPCTSTR szFileName, BYTE ** ppBuffer, DWORD * pdwLenToRead); static void DumpROMInfo(); BOOL ROM_ByteSwap(u8 * pBytes, DWORD dwLen); --- 48,52 ---- static void ROM_CheckIniFile(LPROMINFO pRomInfo); static BOOL ROM_LoadCartToMemory(LPCTSTR szFileName); ! static HRESULT ROM_LoadDataFromFile(LPCTSTR szFileName, BYTE ** ppBuffer, DWORD * pdwLenToRead, bool useAllocRegion = false); static void DumpROMInfo(); BOOL ROM_ByteSwap(u8 * pBytes, DWORD dwLen); *************** *** 609,613 **** hr = ROM_LoadDataFromFile(szFileName, (LPBYTE*)&pBytes, ! &dwROMSize); if (FAILED(hr)) { --- 609,613 ---- hr = ROM_LoadDataFromFile(szFileName, (LPBYTE*)&pBytes, ! &dwROMSize, true); if (FAILED(hr)) { *************** *** 639,643 **** // Pass in length to read in pdwLenToRead. (0 for entire rom) // Actual length read returned in pdwLenToRead ! HRESULT ROM_LoadDataFromFile(LPCTSTR szFileName, BYTE ** ppBuffer, DWORD * pdwLenToRead) { HANDLE hFile; --- 639,643 ---- // Pass in length to read in pdwLenToRead. (0 for entire rom) // Actual length read returned in pdwLenToRead ! HRESULT ROM_LoadDataFromFile(LPCTSTR szFileName, BYTE ** ppBuffer, DWORD * pdwLenToRead, bool useAllocRegion) { HANDLE hFile; *************** *** 678,682 **** // Now, allocate memory for rom. ! pBytes = new BYTE[dwLenToRead]; if (pBytes == NULL) { --- 678,690 ---- // Now, allocate memory for rom. ! if(useAllocRegion) ! { ! pBytes = (BYTE*)Memory_AllocRegion(dwLenToRead); ! } ! else ! { ! pBytes = new BYTE[dwLenToRead]; ! } ! if (pBytes == NULL) { *************** *** 690,694 **** { CloseHandle(hFile); ! delete [] pBytes; return E_FAIL; } --- 698,709 ---- { CloseHandle(hFile); ! if(useAllocRegion) ! { ! Memory_FreeRegion(pBytes); ! } ! else ! { ! delete [] pBytes; ! } return E_FAIL; } Only in .: Release Only in .: ReleaseWithLogging diff -C 2 --exclude=*.dsp --exclude=*.vts ../Daedalus-Lkb-0.07b-lkb3/SR.cpp ./SR.cpp *** ../Daedalus-Lkb-0.07b-lkb3/SR.cpp Fri Aug 24 18:50:06 2001 --- ./SR.cpp Sat Aug 25 19:34:21 2001 *************** *** 44,47 **** --- 44,79 ---- static DWORD g_dwGlobalBufferSize = 0; + /* Added by Lkb (24/8/2001) + The second buffer is used to hold conditionally executed code pieces that will usually not be executed + + Example: + + globalbuffer: + ... + TEST a, a + JZ globalsecondbuffer_1234 # usually a is nonzero + MOV EAX, a + return_from_globalsecondbuffer_1234: + + globalsecondbuffer: + ... + globalsecondbuffer_1234 + CALL xxx + JMP return_from_globalsecondbuffer_1234 + + The code that uses this is responsible to mantain the pointer 16-byte-aligned. + The second buffer must come AFTER the first in the memory layout, otherwise branch prediction will be screwed up. + + This is the same algorithm used in the Linux schedule() function (/usr/src/linux/kernel/sched.c) + + The only problem of this system is that it uses 32-bit relative addresses (and thus 6-byte long instructions) are used. + However managing 8-bit +127/-128 relative displacements would be challenging since they would interfere with the normal code + Otherwise a 16-bit override prefix could be used (but is it advantageous?) + */ + + static BYTE * g_pGlobalSecondBuffer = NULL; + static DWORD g_dwGlobalSecondBufferPtr = 0; + static DWORD g_dwGlobalSecondBufferSize = 0; + DWORD g_dwNumSRCompiled = 0; DWORD g_dwNumSROptimised = 0; *************** *** 642,645 **** --- 674,679 ---- static DWORD SR_CheckStuff(DWORD dwNumCycles); + // this is really, really, really ugly - however until the dynarec support routines get better, this cannot be easily split + void SR_Emit_ReadWriteAddress(CDynarecCode* pCode, DWORD base, DWORD offset, DWORD xor, bool write = false, DWORD rt = ~0, bool baseimm = false, bool base_already_loaded = false, DWORD destreg = EAX_CODE); ///////////////////////////////////////////////////////////////////// *************** *** 669,672 **** --- 703,710 ---- g_dwGlobalBufferSize = 0; + g_pGlobalSecondBuffer = g_pGlobalBuffer + 192 * 1024 * 1024; + g_dwGlobalSecondBufferPtr = 0; + g_dwGlobalSecondBufferSize = 0; + return S_OK; } *************** *** 715,718 **** --- 753,757 ---- VirtualFree(g_pGlobalBuffer, 0, MEM_RELEASE); g_pGlobalBuffer = NULL; + g_pGlobalSecondBuffer = NULL; } *************** *** 877,887 **** MOVI(EAX_CODE, dwPC); \ MOV_MEM_REG(&g_dwPC, EAX_CODE); \ MOV(ECX_CODE, EAX_CODE); \ SHRI(EAX_CODE, 18); \ ! /* call dword ptr [g_ReadAddressLookupTable + eax*4] */ \ pCode->EmitBYTE(0xFF); \ pCode->EmitBYTE(0x14); \ pCode->EmitBYTE(0x85); \ pCode->EmitDWORD((DWORD)g_ReadAddressLookupTable); \ MOV_MEM_REG(&g_pPCMemBase, EAX_CODE); \ RET(); --- 916,929 ---- MOVI(EAX_CODE, dwPC); \ MOV_MEM_REG(&g_dwPC, EAX_CODE); \ + /* \ MOV(ECX_CODE, EAX_CODE); \ SHRI(EAX_CODE, 18); \ ! /* call dword ptr [g_ReadAddressLookupTable + eax*4] * / \ pCode->EmitBYTE(0xFF); \ pCode->EmitBYTE(0x14); \ pCode->EmitBYTE(0x85); \ pCode->EmitDWORD((DWORD)g_ReadAddressLookupTable); \ + */ \ + SR_Emit_ReadWriteAddress(pCode, dwPC, 0, 0, false, ~0, true, true); \ MOV_MEM_REG(&g_pPCMemBase, EAX_CODE); \ RET(); *************** *** 903,910 **** g_dwGlobalBufferSize += 1024 * 1024; pNewAddress = VirtualAlloc(g_pGlobalBuffer, g_dwGlobalBufferSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); ! if (pNewAddress != g_pGlobalBuffer) { ! DBGConsole_Msg(0, "SR Buffer base address has changed 0x%08x 0x%08x", ! g_pGlobalBuffer, pNewAddress); } else --- 945,958 ---- g_dwGlobalBufferSize += 1024 * 1024; pNewAddress = VirtualAlloc(g_pGlobalBuffer, g_dwGlobalBufferSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); ! //if (pNewAddress != g_pGlobalBuffer) ! if (pNewAddress == 0) { ! // By Lkb: What does this mean? When the address is explicitly specified it should be always returned ! // by VirtualAlloc unless the allocation fails (return is 0). Am I missing something? ! ! //DBGConsole_Msg(0, "SR Buffer base address has changed 0x%08x 0x%08x", ! // g_pGlobalBuffer, pNewAddress); ! ! DBGConsole_Msg(0, "SR Buffer allocation failed"); // maybe this should be an abort? } else *************** *** 916,919 **** --- 964,985 ---- } + if (g_dwGlobalSecondBufferPtr + 32768 > g_dwGlobalSecondBufferSize) + { + // Increase by 1MB + LPVOID pNewAddress; + + g_dwGlobalSecondBufferSize += 1024 * 1024; + pNewAddress = VirtualAlloc(g_pGlobalSecondBuffer, g_dwGlobalSecondBufferSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + if (pNewAddress == 0) + { + DBGConsole_Msg(0, "SR Second Buffer allocation failed"); // maybe this should be an abort? + } + else + { + DBGConsole_Msg(0, "Allocated %dMB of storage for dynarec second buffer", + g_dwGlobalSecondBufferSize / (1024*1024)); + } + } + pCode->pCodeBuffer = &g_pGlobalBuffer[g_dwGlobalBufferPtr]; pCode->dwBuffSize = 0; *************** *** 1147,1150 **** --- 1213,1217 ---- pCode->bSpCachedInESI = TRUE; + /* // Calculate SP address and store in esi: // Will use cached value if present *************** *** 1161,1166 **** pCode->EmitBYTE(0x85); // 0x8d for ecx pCode->EmitDWORD((DWORD)g_ReadAddressLookupTable); // Won't work if g_ReadAddressLookupTable recreated ! MOV(ESI_CODE, EAX_CODE); } --- 1228,1236 ---- pCode->EmitBYTE(0x85); // 0x8d for ecx pCode->EmitDWORD((DWORD)g_ReadAddressLookupTable); // Won't work if g_ReadAddressLookupTable recreated + */ + + SR_Emit_ReadWriteAddress(pCode, REG_sp, 0, 0, false, ~0, false, false, ESI_CODE); ! //MOV(ESI_CODE, EAX_CODE); } *************** *** 1785,1788 **** --- 1855,2044 ---- { return SR_EmitCop1Instruction[cop0fmt(dwOp)](pCode, dwOp, pdwFlags); + } + + // this is really, really, really ugly - however until the dynarec support routines get better, this cannot be easily split + void SR_Emit_ReadWriteAddress(CDynarecCode* pCode, DWORD base, DWORD offset, DWORD xor, bool write, DWORD rt, bool baseimm, bool base_already_loaded, DWORD destreg) + { + if(!base_already_loaded) + { + if(baseimm) + { + MOVI(destreg, base); + } + else if(base > 31) // memory location + { + MOV_REG_MEM(destreg, base); + } + else + { + LoadMIPSLo(pCode, destreg, base); + } + } + + // Add offset + if (offset != 0) + { + ADDI(destreg, offset); + } + + MOV (EDX_CODE, destreg) + + // it's here to improve parallelism + // but maybe it would be better to put it after the JS + if(xor) + { + XORI(destreg, xor); + } + + SHRI (EDX_CODE, 18); + + // ADD EAX, [g_ReadAddressPointerLookupTable + EDX*4] + pCode->EmitBYTE (0x03); + pCode->EmitBYTE ((destreg << 3) | 4); + pCode->EmitBYTE (0x95); + pCode->EmitDWORD (write ? (DWORD)g_WriteAddressPointerLookupTable : (DWORD)g_ReadAddressPointerLookupTable); + + // JS special + pCode->EmitBYTE (0x0f); + pCode->EmitBYTE (0x88); + + g_dwGlobalSecondBufferPtr = ((g_dwGlobalSecondBufferPtr - 1) & 0xfffffff0) + 0x10; // align to 16-byte boundary + + pCode->EmitDWORD ((UINT_PTR)g_pGlobalSecondBuffer + g_dwGlobalSecondBufferPtr - (UINT_PTR)pCode->pCodeBuffer - pCode->dwCurrentPos - 4); + + BOOL was_rt_valid = g_MIPSRegInfo[rt].bValid; + + if(rt != ~0) + { + LoadMIPSLo(pCode, EDX_CODE, rt); + + // MOV [EAX], EDX + pCode->EmitBYTE (0x89); + pCode->EmitBYTE (0x10 | destreg); + } + + // FIXME: this is truly horrible + + // MOV ECX, address + if(baseimm) + { + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = 0xb8 | ECX_CODE; + *(DWORD*)(g_pGlobalSecondBuffer + g_dwGlobalSecondBufferPtr) = (DWORD)base; + g_dwGlobalSecondBufferPtr += 4; + } + else if(base > 31) // memory location + { + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = 0x8b; + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = (ECX_CODE << 3) | 0x5; + *(DWORD*)(g_pGlobalSecondBuffer + g_dwGlobalSecondBufferPtr) = (DWORD)base; + g_dwGlobalSecondBufferPtr += 4; + } + else + { + // similar to LoadMIPSLo + DWORD iCachedReg = g_MIPSRegInfo[base].dwCachedIReg; + + if (iCachedReg != ~0) + { + if (ECX_CODE != (WORD)iCachedReg) + { + // MOV ECX, cachedreg + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = 0x8b; + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = 0xc0 | (ECX_CODE<<3) | (WORD)iCachedReg; + } + } + else if (base == REG_r0) + { + // XOR ECX, ECX + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = 0x31; + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = 0xc9; + } + else + { + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = 0x8b; + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = (ECX_CODE << 3) | 0x5; + *(DWORD*)(g_pGlobalSecondBuffer + g_dwGlobalSecondBufferPtr) = (DWORD)((BYTE*)&g_qwGPR[0] + (base * 8)); + g_dwGlobalSecondBufferPtr += 4; + } + } + + if(rt != ~0) + { + // MOV EAX, EDX + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = 0x89; + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = 0xd0; + + // MOV EDX, rt + // similar to LoadMIPSLo + DWORD iCachedReg = g_MIPSRegInfo[rt].dwCachedIReg; + + if (iCachedReg != ~0) + { + if (!was_rt_valid) + { + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = 0x8b; + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = ((WORD)iCachedReg << 3) | 0x5; + *(DWORD*)(g_pGlobalSecondBuffer + g_dwGlobalSecondBufferPtr) = (DWORD)((BYTE*)&g_qwGPR[0] + (rt * 8)); + g_dwGlobalSecondBufferPtr += 4; + + g_MIPSRegInfo[rt].bValid = TRUE; + } + + if (EDX_CODE != (WORD)iCachedReg) + { + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = 0x8b; + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = 0xc0 | (EDX_CODE<<3) | (WORD)iCachedReg; + } + } + else if (rt == REG_r0) + { + // XOR EDX, EDX + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = 0x31; + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = 0xd2; + } + else + { + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = 0x8b; + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = (EDX_CODE << 3) | 0x5; + *(DWORD*)(g_pGlobalSecondBuffer + g_dwGlobalSecondBufferPtr) = (DWORD)((BYTE*)&g_qwGPR[0] + (rt * 8)); + g_dwGlobalSecondBufferPtr += 4; + } + } + + if(offset) + { + // ADD ECX, offset + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = 0x81; + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = 0xc0 | ECX_CODE; + *(DWORD*)(g_pGlobalSecondBuffer + g_dwGlobalSecondBufferPtr) = offset; + g_dwGlobalSecondBufferPtr += 4; + } + + if(xor) + { + // XOR ECX, xor + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = 0x83; + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = 0xf0 | ECX_CODE; + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = xor; + } + + // CALL DWORD PTR [g_ReadAddressLookupTable + EAX/EDX*4] + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = 0xff; + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = 0x14; + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = (rt != ~0) ? 0x85 : 0x95; + + *(DWORD*)(g_pGlobalSecondBuffer + g_dwGlobalSecondBufferPtr) = write ? ((rt != ~0) ? (DWORD)g_WriteAddressValueLookupTable : (DWORD)g_WriteAddressLookupTable) : (DWORD)g_ReadAddressLookupTable; + g_dwGlobalSecondBufferPtr += 4; + + if(destreg != EAX_CODE) + { + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = 0x8b; + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = 0xc0 | (destreg << 3) | (WORD)EAX_CODE; + } + + // JMP after_pointer_null + g_pGlobalSecondBuffer[g_dwGlobalSecondBufferPtr++] = 0xe9; + *(DWORD*)(g_pGlobalSecondBuffer + g_dwGlobalSecondBufferPtr) = (UINT_PTR)pCode->pCodeBuffer + pCode->dwCurrentPos - (UINT_PTR)(g_pGlobalSecondBuffer + g_dwGlobalSecondBufferPtr + 4); + g_dwGlobalSecondBufferPtr += 4; } Only in .: VTUNE Only in .: a.out Binary files ../Daedalus-Lkb-0.07b-lkb3/build.count and ./build.count differ diff -C 2 --exclude=*.dsp --exclude=*.vts ../Daedalus-Lkb-0.07b-lkb3/build.h ./build.h *** ../Daedalus-Lkb-0.07b-lkb3/build.h Fri Aug 24 18:50:18 2001 --- ./build.h Sat Aug 25 19:33:00 2001 *************** *** 1 **** ! #define DAEDALUS_BUILD_NO (2376) --- 1 ---- ! #define DAEDALUS_BUILD_NO 2 diff -C 2 --exclude=*.dsp --exclude=*.vts ../Daedalus-Lkb-0.07b-lkb3/main.cpp ./main.cpp *** ../Daedalus-Lkb-0.07b-lkb3/main.cpp Fri Aug 24 18:50:08 2001 --- ./main.cpp Sat Aug 25 19:33:39 2001 *************** *** 90,93 **** --- 90,94 ---- int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR lpszArgs, int nWinMode) + { int nResult; diff -C 2 --exclude=*.dsp --exclude=*.vts ../Daedalus-Lkb-0.07b-lkb3/sr_load.inl ./sr_load.inl *** ../Daedalus-Lkb-0.07b-lkb3/sr_load.inl Fri Aug 24 18:50:28 2001 --- ./sr_load.inl Sat Aug 25 19:34:21 2001 *************** *** 2,6 **** //#define SR_LOAD_OPTIMISE_FLAG 1 - BOOL SR_Emit_LB(CDynarecCode *pCode, DWORD dwOp, DWORD * pdwFlags) { --- 2,5 ---- *************** *** 24,52 **** // Use the alternative code ! //DWORD dwAddress = (u32)((s32)g_qwGPR[dwBase] + (s32)wOffset); ! //g_qwGPR[dwRT] = (s64)(s16)Read16Bits(dwAddress); ! ! // Get base - we could cache this? ! LoadMIPSLo(pCode, EAX_CODE, dwBase); ! ! // Add offset ! if (nOffset != 0) ! { ! ADDI(EAX_CODE, nOffset); ! } ! ! // Fiddle bits! ! XORI(EAX_CODE, 0x3); ! ! MOV(ECX_CODE, EAX_CODE); // For fastcall ! ! // Get top bits (offset into table) in EAX ! SHRI(EAX_CODE, 18); ! ! // call dword ptr [g_ReadAddressLookupTable + eax*4] ! pCode->EmitBYTE(0xFF); ! pCode->EmitBYTE(0x14); ! pCode->EmitBYTE(0x85); ! pCode->EmitDWORD((DWORD)g_ReadAddressLookupTable); // Won't work if g_ReadAddressLookupTable recreated // mov al, byte ptr [eax] --- 23,27 ---- // Use the alternative code ! SR_Emit_ReadWriteAddress(pCode, dwBase, nOffset, 3, false); // mov al, byte ptr [eax] *************** *** 98,127 **** // Use the alternative code ! //DWORD dwAddress = (u32)((s32)g_qwGPR[dwBase] + (s32)wOffset); ! //g_qwGPR[dwRT] = (u64)(u16)(u8)Read8Bits(dwAddress); - // Get base - we could cache this? - LoadMIPSLo(pCode, EAX_CODE, dwBase); - - // Add offset - if (nOffset != 0) - { - ADDI(EAX_CODE, nOffset); - } - - // Fiddle bits! - XORI(EAX_CODE, 0x3); - - MOV(ECX_CODE, EAX_CODE); // For fastcall - - // Get top bits (offset into table) in ECX - SHRI(EAX_CODE, 18); - - // call dword ptr [g_ReadAddressLookupTable + eax*4] - pCode->EmitBYTE(0xFF); - pCode->EmitBYTE(0x14); - pCode->EmitBYTE(0x85); - pCode->EmitDWORD((DWORD)g_ReadAddressLookupTable); // Won't work if g_ReadAddressLookupTable recreated - // mov al, byte ptr [eax] pCode->EmitBYTE(0x8A); --- 73,78 ---- // Use the alternative code ! SR_Emit_ReadWriteAddress(pCode, dwBase, nOffset, 3, false); // mov al, byte ptr [eax] pCode->EmitBYTE(0x8A); *************** *** 170,195 **** //g_qwGPR[dwRT] = (s64)(s16)Read16Bits(dwAddress); ! // Get base - we could cache this? ! LoadMIPSLo(pCode, EAX_CODE, dwBase); ! ! // Add offset ! if (nOffset != 0) ! { ! ADDI(EAX_CODE, nOffset); ! } ! ! // Fiddle bits! ! XORI(EAX_CODE, 0x2); ! ! MOV(ECX_CODE, EAX_CODE); // For fastcall ! ! // Get top bits (offset into table) in ECX ! SHRI(EAX_CODE, 18); ! ! // call dword ptr [g_ReadAddressLookupTable + eax*4] ! pCode->EmitBYTE(0xFF); ! pCode->EmitBYTE(0x14); ! pCode->EmitBYTE(0x85); ! pCode->EmitDWORD((DWORD)g_ReadAddressLookupTable); // Won't work if g_ReadAddressLookupTable recreated // mov ax, word ptr [eax] --- 121,125 ---- //g_qwGPR[dwRT] = (s64)(s16)Read16Bits(dwAddress); ! SR_Emit_ReadWriteAddress(pCode, dwBase, nOffset, 2, false); // mov ax, word ptr [eax] *************** *** 244,269 **** //g_qwGPR[dwRT] = (u64)(u16)Read16Bits(dwAddress); ! // Get base - we could cache this? ! LoadMIPSLo(pCode, EAX_CODE, dwBase); ! ! // Add offset ! if (nOffset != 0) ! { ! ADDI(EAX_CODE, nOffset); ! } ! ! // Fiddle bits! ! XORI(EAX_CODE, 0x2); ! ! MOV(ECX_CODE, EAX_CODE); // For fastcall ! ! // Get top bits (offset into table) in ECX ! SHRI(EAX_CODE, 18); ! ! // call dword ptr [g_ReadAddressLookupTable + eax*4] ! pCode->EmitBYTE(0xFF); ! pCode->EmitBYTE(0x14); ! pCode->EmitBYTE(0x85); ! pCode->EmitDWORD((DWORD)g_ReadAddressLookupTable); // Won't work if g_ReadAddressLookupTable recreated // mov ax, word ptr [eax] --- 174,178 ---- //g_qwGPR[dwRT] = (u64)(u16)Read16Bits(dwAddress); ! SR_Emit_ReadWriteAddress(pCode, dwBase, nOffset, 2, false); // mov ax, word ptr [eax] *************** *** 288,292 **** } - BOOL SR_Emit_LW(CDynarecCode *pCode, DWORD dwOp, DWORD * pdwFlags) { --- 197,200 ---- *************** *** 350,372 **** // Get base - we could cache this? ! LoadMIPSLo(pCode, EAX_CODE, dwBase); ! ! // Add offset ! if (nOffset != 0) ! { ! ADDI(EAX_CODE, nOffset); ! } ! ! MOV(ECX_CODE, EAX_CODE); // For fastcall ! ! // Get top bits (offset into table) in ECX ! SHRI(EAX_CODE, 18); ! ! // call dword ptr [g_ReadAddressLookupTable + eax*4] ! pCode->EmitBYTE(0xFF); ! pCode->EmitBYTE(0x14); ! pCode->EmitBYTE(0x85); ! pCode->EmitDWORD((DWORD)g_ReadAddressLookupTable); // Won't work if g_ReadAddressLookupTable recreated ! // mov eax, dword ptr [eax] pCode->EmitBYTE(0x8B); --- 258,263 ---- // Get base - we could cache this? ! SR_Emit_ReadWriteAddress(pCode, dwBase, nOffset, 0, false); ! // mov eax, dword ptr [eax] pCode->EmitBYTE(0x8B); *************** *** 448,470 **** else { ! // Get base (this could be cached!) ! LoadMIPSLo(pCode, EAX_CODE, dwBase); ! ! // Add offset ! if (nOffset != 0) ! { ! ADDI(EAX_CODE, nOffset); ! } ! ! MOV(ECX_CODE, EAX_CODE); ! ! // Get top bits (offset into table) in ECX ! SHRI(EAX_CODE, 18); ! ! // call dword ptr [g_ReadAddressLookupTable + eax*4] ! pCode->EmitBYTE(0xFF); ! pCode->EmitBYTE(0x14); ! pCode->EmitBYTE(0x85); ! pCode->EmitDWORD((DWORD)g_ReadAddressLookupTable); // Won't work if g_ReadAddressLookupTable recreated // mov eax, dword ptr [eax] --- 339,343 ---- else { ! SR_Emit_ReadWriteAddress(pCode, dwBase, nOffset, 0, false); // mov eax, dword ptr [eax] Only in .: sr_load.inl~ diff -C 2 --exclude=*.dsp --exclude=*.vts ../Daedalus-Lkb-0.07b-lkb3/sr_store.inl ./sr_store.inl *** ../Daedalus-Lkb-0.07b-lkb3/sr_store.inl Fri Aug 24 18:50:28 2001 --- ./sr_store.inl Sat Aug 25 19:34:22 2001 *************** *** 55,102 **** // the call to update system registers, copy memory etc ! // push data - if data is cached, push that reg!! ! if (dwRT == 0) ! { ! // push 0 ! DPF(DEBUG_DYNREC, " ++ Pushing constant 0"); ! XOR(EDX_CODE, EDX_CODE); // fastcall ! } ! else if (g_MIPSRegInfo[dwRT].dwCachedIReg != ~0) ! { ! // If dwRT is cached, push that value instead ! DPF(DEBUG_DYNREC, " ++ Pushing cached value"); ! ! EnsureCachedValidLo(pCode, dwRT); ! ! MOV(EDX_CODE, (WORD)g_MIPSRegInfo[dwRT].dwCachedIReg); // Fastcall ! } ! else ! { ! LoadMIPSLo(pCode, EDX_CODE, dwRT); ! } ! ! // Get base - we could cache this? ! LoadMIPSLo(pCode, ECX_CODE, dwBase); // For fastcall, arg in ecx ! ! ! // Add offset ! if (nOffset != 0) ! { ! ADDI(ECX_CODE, nOffset); ! } ! ! // dwAddress in ECX ! // dwData in EDX ! ! MOV(EAX_CODE, ECX_CODE); // For fastcall ! ! // Get top bits (offset into table) in ECX ! SHRI(EAX_CODE, 18); ! ! // call dword ptr [g_WriteAddressValueLookupTable + eax*4] ! pCode->EmitBYTE(0xFF); ! pCode->EmitBYTE(0x14); ! pCode->EmitBYTE(0x85); ! pCode->EmitDWORD((DWORD)g_WriteAddressValueLookupTable); // Won't work if g_ReadAddressLookupTable recreated } --- 55,59 ---- // the call to update system registers, copy memory etc ! SR_Emit_ReadWriteAddress(pCode, dwBase, nOffset, 0, true, dwRT); } *************** *** 131,157 **** // Writes to system registers! ! // Get base (this could be cached!) ! LoadMIPSLo(pCode, EAX_CODE, dwBase); ! ! // Add offset ! if (nOffset != 0) ! { ! ADDI(EAX_CODE, nOffset); ! } ! ! // Fiddle Bits! ! XORI(EAX_CODE, 0x2); ! ! MOV(ECX_CODE, EAX_CODE); // For fastcall ! ! ! // Get top bits (offset into table) in ECX ! SHRI(EAX_CODE, 18); ! ! // call dword ptr [g_WriteAddressLookupTable + eax*4] ! pCode->EmitBYTE(0xFF); ! pCode->EmitBYTE(0x14); ! pCode->EmitBYTE(0x85); ! pCode->EmitDWORD((DWORD)g_WriteAddressLookupTable); // Won't work if g_WriteAddressLookupTable recreated // EAX hold memory address to write to --- 88,92 ---- // Writes to system registers! ! SR_Emit_ReadWriteAddress(pCode, dwBase, nOffset, 2, true); // EAX hold memory address to write to *************** *** 199,224 **** // Writes to system registers! ! // Get base (this could be cached!) ! LoadMIPSLo(pCode, EAX_CODE, dwBase); ! ! // Add offset ! if (nOffset != 0) ! { ! ADDI(EAX_CODE, nOffset); ! } ! ! // Fiddle Bits! ! XORI(EAX_CODE, 0x3); ! ! MOV(ECX_CODE, EAX_CODE); ! ! // Get top bits (offset into table) in ECX ! SHRI(EAX_CODE, 18); ! ! // call dword ptr [g_WriteAddressLookupTable + eax*4] ! pCode->EmitBYTE(0xFF); ! pCode->EmitBYTE(0x14); ! pCode->EmitBYTE(0x85); ! pCode->EmitDWORD((DWORD)g_WriteAddressLookupTable); // Won't work if g_WriteAddressLookupTable recreated // EAX hold memory address to write to --- 134,138 ---- // Writes to system registers! ! SR_Emit_ReadWriteAddress(pCode, dwBase, nOffset, 3, true); // EAX hold memory address to write to *************** *** 304,325 **** // Get base (this could be cached!) ! LoadMIPSLo(pCode, EAX_CODE, dwBase); ! ! // Add offset ! if (nOffset != 0) ! { ! ADDI(EAX_CODE, nOffset); ! } ! ! MOV(ECX_CODE, EAX_CODE); // For fastcall ! ! // Get top bits (offset into table) in ECX ! SHRI(EAX_CODE, 18); ! ! // call dword ptr [g_WriteAddressLookupTable + eax*4] ! pCode->EmitBYTE(0xFF); ! pCode->EmitBYTE(0x14); ! pCode->EmitBYTE(0x85); ! pCode->EmitDWORD((DWORD)g_WriteAddressLookupTable); // Won't work if g_WriteAddressLookupTable recreated // EAX hold memory address to write to --- 218,223 ---- // Get base (this could be cached!) ! ! SR_Emit_ReadWriteAddress(pCode, dwBase, nOffset, 0, true); // EAX hold memory address to write to diff -C 2 --exclude=*.dsp --exclude=*.vts ../Daedalus-Lkb-0.07b-lkb3/stdafx.h ./stdafx.h *** ../Daedalus-Lkb-0.07b-lkb3/stdafx.h Fri Aug 24 18:50:20 2001 --- ./stdafx.h Sat Aug 25 19:34:22 2001 *************** *** 61,68 **** #define DAEDALUS_SITE "http://daedalus.boob.co.uk/" ! // Uncomment this to disable some of the developer functions like // DL_PF etc for performance improvements #define DAEDALUS_RELEASE_BUILD ! #undef DAEDALUS_RELEASE_BUILD extern HINSTANCE g_hInstance; --- 61,72 ---- #define DAEDALUS_SITE "http://daedalus.boob.co.uk/" ! // Uncomment the #undef to disable some of the developer functions like // DL_PF etc for performance improvements #define DAEDALUS_RELEASE_BUILD ! //#undef DAEDALUS_RELEASE_BUILD ! ! #ifdef _DEBUG ! #undef DAEDALUS_RELEASE_BUILD ! #endif extern HINSTANCE g_hInstance; *************** *** 113,117 **** --- 117,150 ---- #include "ResourceString.h" // Useful everywhere + #define ALIGNED_TYPE(type, alignval) type + #define ALIGNED_EXTERN(type, var, alignval) extern type var + #define ALIGNED_GLOBAL(type, var, alignval) type var + #define ALIGNED_MEMBER(type, var, alignval) type var + + #ifdef _MSC_VER + #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 12008804) + #undef ALIGNED_TYPE + #undef ALIGNED_GLOBAL + #undef ALIGNED_MEMBER + #define ALIGNED_TYPE(type, alignval) __declspec(align(alignval)) type + #define ALIGNED_GLOBAL(type, var, alignval) __declspec(align(alignval)) type var + #define ALIGNED_MEMBER(type, var, alignval) __declspec(align(alignval)) type var + #else + #pragma message("You should install Microsoft Visual C++ 6.0 Service Pack 5 and Processor Pack (both free of charge)" + #endif + #endif + + #ifdef __GNUC__ + // GCC has __attribute__((aligned)) but it complains that the maximum alignment is 16 + #undef ALIGNED_GLOBAL + #undef ALIGNED_MEMBER + #define ALIGNED_GLOBAL(type, var, alignval) __asm__(".balign " #alignval ) type var; + #define ALIGNED_MEMBER(type, var, alignval) __attribute__((aligned(alignval))) type var; + #endif + // Pentium 4 has 64-byte cachelines + #define DATA_ALIGN 16 + #define CACHE_ALIGN 64 + #define PAGE_ALIGN 4096 //{{AFX_INSERT_LOCATION}}