- PS2 के VU floating-point multiplication में 1-बिट की arithmetic error होती है, इसलिए कुछ खास मानों पर
1 * X,Xसे अलग हो सकता है - VU developer manual के अनुसार
X * 1की सटीकता की गारंटी है, लेकिन1 * Xके लिए वही गारंटी नहीं है, और यही फर्क emulator detection का संकेत बनता है - उदाहरण में brute force से खोजे गए समस्या पैदा करने वाले मानों में से 129.5f का उपयोग करके असली PS2 और emulator के व्यवहार का अंतर दिखाया गया है
- implementation में VU0 macro mode में
129.5fऔर1को multiply करने के बाद सिर्फ यह तुलना की जाती है कि result मूल input से अलग है या नहीं - PCSX2, Play!, DobieStation, hps2x64 फिलहाल इस व्यवहार को emulate नहीं करते, और detection की कठिनाई 1/5 आंकी गई है
PS2 VU multiplication में होने वाली 1-बिट error
- यह तरीका PS2 emulator detection series की दूसरी प्रविष्टि है, और इसे VU1, VU0 micro mode, VU0 macro mode में इस्तेमाल किया जा सकता है
- उदाहरण implementation को सरल रखने के लिए VU0 macro mode का उपयोग करता है
- इसमें VU0 को coprocessor की तरह इस्तेमाल किया जाता है, इसलिए इसे EE CPU से सीधे चलाया जा सकता है
- अलग VU program संभालने की जरूरत नहीं पड़ती
- VU developer manual में
MUL,MULiजैसे multiplication instructions पर 1-बिट arithmetic error की टिप्पणी है1 * Xमूल मानXसे अलग हो सकता है- अगर
VF[fs]को multiplicand के रूप में इस्तेमाल किया जाए, तोX * 1रूप के result की सटीकता की गारंटी होती है
- बिट क्यों खोता है, यह ठीक-ठीक स्पष्ट नहीं है
detection value और implementation तरीका
- इस error को detect करने के लिए ऐसा नंबर चाहिए जो समस्या पैदा करे, और उसे खोजने का सबसे आसान तरीका brute force है
- लेखक ने पहले 0.5 के अंतराल पर समस्या पैदा करने वाले पहले 250 नंबरों की सूची बनाई थी, और उसे gist में प्रकाशित किया है
- example code detection target number के रूप में 129.5f का उपयोग करता है
QMTC2सेVF1में129.5fसेट किया जाता हैVADDwसेVF2में1बनाया जाता हैVMULसेVF1 = 1 * 129.5fकी गणना की जाती हैQMFC2से result को EE side पर लाकर input से तुलना की जाती है
- return value
in[0] != out[0]है, और अगर मूल मान और multiplication result अलग हों, तो माना जाता है कि VU multiplication error मौजूद है
emulator के अनुसार प्रभाव
- फिलहाल PCSX2, Play!, DobieStation, hps2x64 इस PS2 VU multiplication behavior को emulate नहीं करते
- क्योंकि सिर्फ एक नंबर को
1से multiply करके result देखना होता है, इस detection तरीके की कठिनाई 1/5 स्तर की मानी गई है
1 टिप्पणियां
Hacker News की राय
असली ARM में pipeline की वजह से, जब PC पर execute हो रहा होता है और PC+4 decode हो रहा होता है, तब PC+8 पढ़ा जाता है, इसलिए नई स्टोर की गई instruction का असर नहीं होना चाहिए। अगर emulator hardware pipeline को emulate नहीं करता, तो वह उस instruction को execute कर देगा
2004 की कई emulation-रोधी तकनीकों के साथ इस पर ज़्यादा विस्तार से समझाने वाला लेख: https://mgba.io//2014/12/28/classic-nes/
शायद कुछ cycles तक register value undefined रहती थी। ऐसे chip के लिए बहुत कसकर optimized assembly code लिखना किसी खास तौर पर खराब स्वाद वाले Zachtronics clone खेलने जैसा लगता था, इसलिए काफ़ी भयानक अनुभव था
काफ़ी बाद में किसी ने एक और ऐसा edge case ढूँढा जो detect नहीं होता था: एक self-overwriting repeated string instruction
https://silviocesare.wordpress.com/2009/02/02/anti-debugging...
x86 में ऐसा mechanism है, लेकिन 64-bit variant में इसे आख़िरकार हटा दिया गया या नहीं, यह पक्का नहीं है
आपको original hardware और software के हर अजीब व्यवहार को जानना ही नहीं, बल्कि उसे कितना भी विचित्र क्यों न हो, वैसा ही reproduce भी करना पड़ता है। अपने-आप में यह मुश्किल है, और ऊपर से performance impact का भी ध्यान रखना पड़ता है
JIT recompiler का इस्तेमाल करने का मतलब है कि आप original hardware के साथ पूरी तरह cycle-by-cycle accurate नहीं हो सकते, लेकिन जब तक game code जानबूझकर emulator को तोड़ने के लिए न बनाया गया हो, यह आम तौर पर समस्या नहीं बनता
Dolphin को भी यह संतुलन संभालना पड़ा था, जब कुछ commercial Wii games ने असली Wii CPU के cache behavior की बारीकियों का फायदा उठाने वाला anti-emulator code डाल दिया था। सिद्धांततः वे असली CPU cache को emulate करके games को smoothly चला सकते थे, लेकिन performance overhead शायद 10 गुना slowdown जैसा होता, जिससे खेलना संभव नहीं रहता, इसलिए उन्होंने workaround patch चुना
https://dolphin-emu.org/blog/2017/02/01/dolphin-progress-rep...
ऐसा लगता है जैसे आपको electronics और गहरे programming magic, दोनों की समझ चाहिए
शुरुआत में, और ज़्यादातर मामलों में अंत तक भी, आपको गहरे magic को समझने की ज़रूरत नहीं होती। आम तौर पर आप spec पढ़ते हैं और उसी के मुताबिक implement करते हैं। code structure को बिखरने से बचाने की क्षमता चाहिए, लेकिन इसके common patterns होते हैं, और एक-दो emulator बना लेने के बाद यह काफ़ी आसान हो जाता है
electronics समझने की ज़रूरत भी लगभग कभी नहीं पड़ती। आप सिर्फ behavior को emulate कर रहे होते हैं। अगर original hardware behavior में कोई bug मिलता है, तो आम तौर पर emulator में special handling डालना काफ़ी होता है। ऐसा behavior क्यों आता है, यह समझने में electronics ज्ञान मदद कर सकता है, लेकिन वह व्यावहारिक से ज़्यादा ऐतिहासिक रुचि की चीज़ है
इसमें कुछ अनोखी कठिनाइयाँ ज़रूर हैं। जब समस्या आती है, तो आप आम तौर पर hardware की समझ, emulator implementation, और जिस game को emulate किया जा रहा है, इन तीनों को एक साथ debug कर रहे होते हैं। सही कारण को सीमित करना मुश्किल हो सकता है। फिर भी, पहले बस कुछ बनाकर देखने की सलाह दूँगा। यह साफ-सुथरा नहीं होगा, लेकिन हर emulator लोकप्रिय games को किसी तरह चलाने के लिए special cases से भरा होता है। अगर कुछ गंदे hacks से game चल जाता है, तो वही कर लेना चाहिए। original hardware behavior को बिल्कुल सही implement करना ज़रूरी नहीं, game को चलाना ज़रूरी है
8-bit CPU कुछ bytes की state, यानी सिर्फ registers वाला एक simple state machine होता है। यह program को एक-एक byte पढ़ता है, और CPU उस byte को पढ़ने के बाद जो करेगा, आपको बस उसका अनुकरण करना होता है। ये बहुत सरल operations होते हैं, जैसे संख्याएँ जोड़ना-घटाना, या bytes पढ़ना और स्टोर करना
http://www.6502.org/users/obelisk/6502/registers.html
http://www.6502.org/users/obelisk/6502/instructions.html
6502 CPU emulator program के अगले कुछ bytes पढ़ता है, उन bytes को instructions की तरह interpret करता है, और instructions को execute करता है। इस प्रक्रिया में वह CPU के कुछ registers या counters को update करता है, arithmetic या bit operations करता है, और ज़रूरत पड़ने पर एक जगह से दूसरी जगह 1 byte data पढ़ता या स्टोर करता है। फिर इस प्रक्रिया को एक infinite loop में दोहराता है
यह fetch-decode-execute cycle का simulation है
https://en.wikipedia.org/wiki/Instruction_cycle
बहुत पहले SID music files चलाने के लिए मैंने 6502 interpreter को UNIX से Classic Macintosh पर port किया था। जब तक वह पर्याप्त तेज़ चलता था, clock cycle accuracy महत्वपूर्ण नहीं थी
यह interpreter से C code को call करने के तरीके से काम करता था
अभी भी इसे करना चाहता हूँ, लेकिन समय नहीं है
इसके अलावा, @xcv123 की sibling comment बिल्कुल सही बात कहती है
अगर कभी FPGA से PS2 को recreate करना संभव हो गया, तो यह पता लगाना कि यह व्यवहार कैसे हुआ, किसी के लिए एक मज़ेदार project हो सकता है
सिर्फ़ इसलिए कि यह PS2 का FPGA version है, इसकी कोई गारंटी नहीं कि वही या मिलते-जुलते bugs implement नहीं होंगे
software floating-point धीमा होगा, लेकिन सामान्य समाधान शायद PS4 के PS2 emulator का अनुसरण करेगा। यानी, हर game के लिए code के उन हिस्सों को whitelist करना जहाँ software floating-point path की अनुमति दी जाए
यह समझने में मुझे बहुत ज़्यादा समय लग गया कि यह mouse और keyboard को जोड़ने वाले Personal System/2 port की नहीं, बल्कि PlayStation 2 की बात है
तीन-अक्षर वाले acronyms context ढूँढना वाकई मुश्किल बना सकते हैं। क्योंकि अगर सिर्फ़ acronym को Google में डालो, तो काफ़ी बार ज़्यादातर नतीजे लगभग असंबंधित निकलते हैं