2 puan yazan GN⁺ 2024-06-09 | 1 yorum | WhatsApp'ta paylaş
  • PS2’nin VU kayan nokta çarpımı işleminde 1 bitlik bir hesaplama hatası bulunur; bu yüzden belirli değerlerde 1 * X, X ile aynı olmayabilir
  • VU geliştirici kılavuzuna göre X * 1 için doğruluk garanti edilirken 1 * X için aynı garanti yoktur; bu fark emülatör algılama sinyali haline gelir
  • Örnek, brute force ile bulunan sorunlu değerlerden 129.5f’yi kullanarak gerçek PS2 ile emülatörlerin davranış farkını doğrular
  • Uygulama, VU0 makro modunda 129.5f ile 1i çarpıp ardından yalnızca sonuç ile özgün girdinin farklı olup olmadığını karşılaştıran basit bir yapıdadır
  • PCSX2, Play!, DobieStation ve hps2x64 şu anda bu davranışı emüle etmez; algılama zorluğu 1/5 olarak değerlendirilir

PS2 VU çarpımında oluşan 1 bitlik hata

  • Bu yöntem, PS2 emülatör algılama serisinin ikinci maddesidir ve VU1, VU0 mikro modu ve VU0 makro modunda kullanılabilir
  • Örnek, uygulamayı basit tutmak için VU0 makro modu kullanır
    • VU0, bir yardımcı işlemci gibi kullanıldığı için EE CPU üzerinden doğrudan çalıştırılabilir
    • Ayrı bir VU programını ele almak gerekmez
  • VU geliştirici kılavuzunda MUL, MULi gibi çarpma komutlarında 1 bitlik hesaplama hatası olduğuna dair not bulunur
    • 1 * X, özgün değer X ile farklı olabilir
    • VF[fs] çarpılan değer olarak kullanıldığında X * 1 biçimindeki sonucun doğruluğu garanti edilir
  • Bitin neden kaybolduğu tam olarak doğrulanmış değildir

Algılama değeri ve uygulama yöntemi

  • Bu hatayı algılamak için sorunu tetikleyen bir sayı gerekir; bunu bulmanın en kolay yolu brute force yöntemidir
  • Yazar daha önce 0.5 aralıklarla soruna yol açan ilk 250 sayının bir listesini oluşturdu ve bunu bir gist olarak yayımladı
  • Örnek kod, algılama hedefi olarak 129.5f kullanır
    • QMTC2 ile VF1 içine 129.5f atanır
    • VADDw ile VF2 içinde 1 oluşturulur
    • VMUL ile VF1 = 1 * 129.5f hesaplanır
    • QMFC2 ile sonuç EE tarafına alınır ve girdiyle karşılaştırılır
  • Dönüş değeri in[0] != out[0] şeklindedir; özgün değer ile çarpım sonucu farklıysa VU çarpım hatasının mevcut olduğu kabul edilir

Emülatörlere etkisi

  • Şu anda PCSX2, Play!, DobieStation, hps2x64 bu PS2 VU çarpım davranışını emüle etmiyor
  • Yalnızca bir sayı ile 1 çarpılıp sonuca bakmak yeterli olduğundan, bu algılama yönteminin zorluğu 1/5 düzeyindedir

1 yorum

 
GN⁺ 2024-06-09
Hacker News yorumları
  • Eski ARM emülasyonunu tespit etmenin en basit hilelerinden biri; sanırım Game Boy Advance kopya korumasında da kullanılıyordu: PC+4 konumuna, yani hemen sonraki komuta bir tuzak komutu yazmak
    Gerçek ARM, pipeline nedeniyle PC’de yürütürken PC+4’ü decode ederken PC+8’i okur; bu yüzden yeni yazılan komutun etkisi olmamalı. Donanım pipeline’ını emüle etmeyen bir emülatörse o komutu çalıştırır
    2004’ten çeşitli emülasyon engelleme teknikleriyle birlikte bunu daha ayrıntılı anlatan yazı: https://mgba.io//2014/12/28/classic-nes/
    • Texas Instruments TI320C40 dijital sinyal işlemcisinin pipeline sorunları daha da tuhaftı: Dallanmanın arkasındaki bir veya daha fazla komutun gerçek dallanmadan önce çalıştığı branch delay slot’ları (https://en.wikipedia.org/wiki/Delay_slot) vardı; ayrıca register’a yazılan değerin ancak birkaç komut sonra görünür olduğu load delay slot’ları da vardı
      Muhtemelen birkaç cycle boyunca register değeri tanımsız kalıyordu. Böyle bir çip için sıkı optimize edilmiş assembly kodu yazmak, özellikle zevksiz bir Zachtronics klonunu oynamak gibi hissettirdiğinden epey korkunçtu
    • x86’da da prefetch queue benzer bir davranış üretiyordu; ancak Intel, Pentium sonrası CPU’larda self-modifying code’u algılamaya karar verince, yakında yürütülecek bir komutu değiştirmek her zaman etkili olmaya başladı
      Çok daha sonra biri algılanmayan başka bir uç durum buldu: kendi kendisinin üzerine yazan tekrarlı string komutu
      https://silviocesare.wordpress.com/2009/02/02/anti-debugging...
    • Bazı pipeline CPU’lar self-modifying code ile uyumluluğu korur; pipeline’a alınmış bir komutun üzerine yazarsanız bunu algılar ve pipeline’ı boşaltır
      x86’da böyle bir mekanizma var; 64 bit türevlerinde sonunda kaldırılıp kaldırılmadığından emin değilim
    • VisualBoyAdvance’ta Dragon Ball Z: The Legacy of Goku II ROM’unun bazen çalışmamasının nedeni bu muydu?
  • %100 doğruluğu hedefleyen emülasyonun sektörde neden zanaatkârlık alanı sayıldığını gösteren şey tam da bu
    Yalnızca orijinal donanım ve yazılımın tüm garip davranışlarını bilmek yetmez; ne kadar tuhaf olursa olsun bunları aynen yeniden üretmek gerekir. Bu başlı başına zordur, bir de performans etkisini düşünmek gerekir
    • Emülatörler doğruluk konusunda gerçekçi olmalı. Daha modern sistemleri emüle ederken %100 donanım doğruluğu ile kullanılabilir performansı aynı anda hedeflemek genellikle imkânsızdır; bu yüzden gerçek donanımdan teknik olarak farklı olsa da pratikte gözlemlenebilir farkı çok az olan ödünler kabul edilir
      JIT recompiler kullanmak, orijinal donanımla mükemmel cycle düzeyinde doğru olamaz; ancak oyun kodu kasıtlı olarak emülatörü bozacak şekilde tasarlanmadıysa genelde sorun olmaz
      Dolphin de bazı ticari Wii oyunları, gerçek Wii CPU’sunun cache davranışındaki ayrıntıları kötüye kullanan emülatör karşıtı kod eklediğinde bu dengeyle uğraşmak zorunda kaldı. Teorik olarak gerçek CPU cache’ini emüle edip oyunu sorunsuz çalıştırabilirdi; ancak performans ek yükü muhtemelen 10 kat yavaşlama düzeyinde olup oynanamaz hale getireceğinden, bypass patch’i seçtiler
      https://dolphin-emu.org/blog/2017/02/01/dolphin-progress-rep...
  • Emülasyona nasıl başlanır? Yazılım içinde bile inanılmaz zor bir niş alan gibi görünüyor
    Fiilen elektronik mühendisliğini ve derin programlama büyüsünü anlamak gerekiyormuş gibi
    • Her şeyde olduğu gibi aşama aşama başlamak yeterli
      Başlarken, hatta çoğu zaman bitirirken de derin büyüyü anlamanız gerekmez. Genelde spesifikasyonu okuyup orada yazanı uygulamak yeterlidir. Kodun çorbaya dönmemesi için yapıyı kurabilmek gerekir ama yaygın kalıplar var; bir iki emülatör yaptıktan sonra çok daha kolaylaşır
      Elektroniği anlamanız gereken durumlar da neredeyse yoktur. Emüle ettiğiniz şey yalnızca davranıştır. Orijinal donanım davranışında bir bug bulunursa genellikle emülatöre özel işlem eklersiniz. Elektronik bilgisi, bu davranışın neden ortaya çıktığını anlamaya yardımcı olabilir; ama pratik olmaktan çok tarihsel merak konusu sayılır
      Kendine özgü zorlukları var. Bir sorun çıktığında genelde üç şeyi aynı anda debug edersiniz: donanım hakkındaki anlayışınızı, emülatör uygulamasını ve emüle edilen oyunu. Kesin nedeni daraltmak zor olabilir. Yine de önce kabaca bir şey yapmayı öneririm. Temiz değildir ama tüm emülatörler, popüler oyunları bir şekilde çalıştırmak için özel işlemlerle doludur. Birkaç kirli hack ile oyun çalışıyorsa öyle yapın. Orijinal donanım davranışını birebir doğru uygulamak zorunda değilsiniz; oyunu çalışır hale getirmeniz yeter
    • Donanım belgelerini okumakla başlayabilirsiniz; makineyi elektronik devre düzeyinde anlamanız gerekmez. Bu dijital devre simülasyonu olmadığı için o kadar karmaşık olmak zorunda değil
      8 bit CPU, birkaç byte’lık durumdan, yani register’lardan oluşan basit bir durum makinesidir. Programı byte byte okur, CPU’nun o byte’ı okuduktan sonra ne yapacağını taklit edersiniz. Sayı toplama/çıkarma ya da byte okuma ve yazma gibi çok basit işlemlerdir
      http://www.6502.org/users/obelisk/6502/registers.html
      http://www.6502.org/users/obelisk/6502/instructions.html
      Bir 6502 CPU emülatörü, programın sıradaki birkaç byte’ını okur, bu byte’ları komut olarak yorumlar ve komutu çalıştırır. Bu sırada CPU’nun birkaç register’ını veya counter’ını günceller, aritmetik ya da bit işlemleri yapar ve gerekirse bir konumdan başka bir konuma 1 byte veri okur veya yazar. Bu süreci sonsuz döngü içinde tekrarlar

Bu, getir-çöz-yürüt döngüsünün bir simülasyonu
https://en.wikipedia.org/wiki/Instruction_cycle

  • Emülasyon derken ne kastettiğinize bağlı
    Eskiden SID müzik dosyalarını çalmak için bir 6502 yorumlayıcısını UNIX'ten Classic Macintosh'a port etmiştim. Yeterince hızlı çalışması yettiği için saat çevrimi doğruluğu önemli değildi
    Yorumlayıcıdan C kodu çağırarak çalışıyordu
  • Uzun zaman önce bu işe girmeyi denediğimde verilen tavsiye, çok basit ve iyi belgelenmiş bir şeyle başlayıp oradan beceriyi geliştirmekti
    Hâlâ denemek istiyorum ama zamanım yok
  • Biraz tanıtım yapmak gerekirse, geçen FOSDEM'de bu konuda bir sunum yaptım: https://fosdem.org/2024/schedule/event/fosdem-2024-2146-how-...
    Bunun dışında @xcv123'ün kardeş yorumunda söyledikleri gerçekten doğru
  • Yazılım emülasyonunda muhtemelen pek uğraşmaya değmeyecek türden ilginç bir örnek. O hatayı da emüle etmek epey yavaşlatır
    Bir gün FPGA ile PS2'yi kopyalamak mümkün hâle gelirse, bu davranışın nasıl ortaya çıktığını bulmak birileri için eğlenceli bir proje olur
    • FPGA uygulamaları da çoğu zaman yazılım emülasyonu projelerinin kodu veya belgeleri temel alınarak yapılıyor
      PS2'nin FPGA sürümünün aynı ya da benzer hataları uygulamayacağının garantisi yok
    • Bu hatanın oyunları bozup bozmadığına bağlı
    • Bu hatayı düzeltmek, başka birçok kayan nokta hatasını, daha spesifik olarak yuvarlama ve clamping sorunlarını düzeltme işinin bir parçası olacak
      Yazılım kayan nokta yavaş olurdu, ama genel çözüm muhtemelen PS4'ün PS2 emülatörünü izlerdi. Her oyun için yazılım kayan nokta yoluna izin verilecek kod bölgelerini beyaz listeye alma yöntemi
    • Nispeten pahalı bir FPGA ile eski ve berbat bir MIPS CPU'yu emüle etmek istemenin sebebi ne olabilir? Eski konsolları emüle etmenin özü, donanımdan bağımsız biçimde bilgisayarda veya telefonda eski oyunları oynayabilmeyi sağlamaktır
  • Başlığı görüp fare ya da klavye neden matematik yapmak zorunda diye kafası karışan başka biri oldu mu?
    Bunun fare ve klavye bağlanan Personal System/2 portu değil, PlayStation 2 hakkında olduğunu anlamam çok uzun sürdü
    • Biri PS2, diğeri PS/2
    • Eksi oy verenlere: size açık olması, herkes için açık olduğu anlamına gelmez
      Üç harfli kısaltmalar bağlamı bulmayı gerçekten zorlaştırabilir. Çünkü yalnızca kısaltmayı Google'a yazınca çoğu zaman neredeyse alakasız sonuçlar ağırlıkta çıkar