2 poin oleh GN⁺ 2024-06-09 | 1 komentar | Bagikan ke WhatsApp
  • Perkalian floating-point VU pada PS2 memiliki galat operasi 1 bit, sehingga pada nilai tertentu 1 * X bisa berbeda dari X
  • Menurut manual pengembang VU, akurasi X * 1 dijamin, tetapi 1 * X tidak memiliki jaminan yang sama, dan perbedaan ini menjadi sinyal deteksi emulator
  • Contohnya menggunakan 129.5f, salah satu nilai bermasalah yang ditemukan dengan brute force, untuk memeriksa perbedaan perilaku antara PS2 asli dan emulator
  • Implementasinya berupa struktur sederhana: di mode makro VU0, kalikan 129.5f dengan 1, lalu cukup bandingkan apakah input asli berbeda dari hasilnya
  • PCSX2, Play!, DobieStation, dan hps2x64 saat ini tidak mengemulasikan perilaku ini, dan tingkat kesulitan deteksinya dinilai 1/5

Galat 1 bit yang muncul pada perkalian VU PS2

  • Metode ini adalah entri kedua dalam seri deteksi emulator PS2, dan bisa digunakan di mode mikro VU1, mode mikro VU0, serta mode makro VU0
  • Contoh ini memakai mode makro VU0 untuk menyederhanakan implementasi
    • VU0 digunakan seperti koprosesor sehingga bisa dijalankan langsung dari CPU EE
    • Tidak perlu menangani program VU terpisah
  • Manual pengembang VU memberi catatan bahwa instruksi perkalian seperti MUL, MULi memiliki galat operasi 1 bit
    • 1 * X bisa berbeda dari nilai aslinya, X
    • Jika VF[fs] digunakan sebagai operand yang dikalikan, akurasi hasil dalam bentuk X * 1 dijamin
  • Alasan pasti mengapa bit ini hilang belum dapat dipastikan

Nilai deteksi dan cara implementasi

  • Untuk mendeteksi galat ini, dibutuhkan angka yang memicu masalah, dan cara termudah mencarinya adalah dengan brute force
  • Penulis sebelumnya telah membuat daftar 250 angka pertama yang memicu masalah pada interval 0.5, dan mempublikasikan daftar tersebut di gist
  • Kode contoh menggunakan 129.5f sebagai angka target deteksi
    • Set 129.5f ke VF1 dengan QMTC2
    • Buat nilai 1 di VF2 dengan VADDw
    • Hitung VF1 = 1 * 129.5f dengan VMUL
    • Ambil hasilnya kembali ke sisi EE dengan QMFC2 lalu bandingkan dengan input
  • Nilai kembalian adalah in[0] != out[0]; jika nilai asli dan hasil perkalian berbeda, maka dianggap ada galat perkalian VU

Dampak pada masing-masing emulator

  • Saat ini PCSX2, Play!, DobieStation, dan hps2x64 tidak mengemulasikan perilaku perkalian VU PS2 ini
  • Karena hanya perlu mengalikan satu angka dengan 1 lalu memeriksa hasilnya, tingkat kesulitan metode deteksi ini berada di level 1/5

1 komentar

 
GN⁺ 2024-06-09
Komentar Hacker News
  • Trik paling sederhana untuk mendeteksi emulasi ARM lama, yang tampaknya juga pernah dipakai untuk proteksi salinan Game Boy Advance: menyimpan instruksi jebakan di posisi PC+4, yaitu instruksi tepat berikutnya
    ARM sungguhan, karena pipeline, membaca PC+8 saat mengeksekusi dari PC dan mendekode PC+4, jadi instruksi yang baru disimpan seharusnya tidak berpengaruh. Emulator yang tidak mengemulasikan pipeline hardware akan menjalankan instruksi itu
    Artikel yang menjelaskan lebih detail bersama berbagai teknik pengganggu emulasi dari 2004: https://mgba.io//2014/12/28/classic-nes/
    • Prosesor sinyal digital TI320C40 dari Texas Instruments punya masalah pipeline yang lebih aneh: ada delay slot cabang (https://en.wikipedia.org/wiki/Delay_slot), yaitu satu atau lebih instruksi setelah cabang dieksekusi sebelum cabang sebenarnya terjadi, dan juga load delay slot, di mana nilai yang disimpan ke register baru muncul beberapa instruksi kemudian
      Mungkin selama beberapa siklus nilai register tidak terdefinisi. Menulis kode assembly yang dioptimalkan ketat untuk chip seperti ini terasa seperti memainkan klon Zachtronics dengan selera yang luar biasa buruk, jadi cukup mengerikan
    • Di x86, prefetch queue juga menghasilkan perilaku serupa, tetapi setelah Intel memutuskan untuk mendeteksi self-modifying code pada CPU setelah Pentium, memodifikasi instruksi yang akan segera dieksekusi selalu menjadi efektif
      Jauh kemudian, seseorang menemukan kasus batas lain yang tidak terdeteksi: instruksi string berulang yang menimpa dirinya sendiri
      https://silviocesare.wordpress.com/2009/02/02/anti-debugging...
    • Sebagian CPU pipeline mempertahankan kompatibilitas dengan self-modifying code, sehingga jika instruksi yang sudah berada di pipeline ditimpa, CPU mendeteksinya dan mengosongkan pipeline
      x86 punya mekanisme seperti itu, meski saya tidak yakin apakah akhirnya dihapus pada varian 64-bit
    • Apakah ini alasan ROM Dragon Ball Z: The Legacy of Goku II kadang tidak berjalan di VisualBoyAdvance?
  • Inilah alasan mengapa emulasi yang menargetkan akurasi 100% merupakan ranah keahlian artisan di industri ini
    Anda tidak hanya harus mengetahui semua perilaku ganjil dari hardware dan software asli, tetapi juga harus mereproduksinya apa adanya, seaneh apa pun. Itu sendiri sudah sulit, dan masih harus mempertimbangkan dampak performanya
    • Emulator harus realistis soal akurasi. Saat mengemulasikan sistem yang lebih modern, biasanya mustahil menargetkan akurasi hardware 100% sekaligus performa yang layak, sehingga kita menerima kompromi yang secara teknis berbeda dari hardware asli tetapi hampir tidak memiliki perbedaan yang dapat diamati dalam praktik
      Menggunakan JIT recompiler tidak bisa sepenuhnya akurat per siklus seperti hardware asli, tetapi umumnya tidak menjadi masalah kecuali kode game sengaja dibuat untuk merusak emulator
      Dolphin juga harus menangani keseimbangan ini ketika beberapa game Wii komersial memasukkan kode anti-emulator yang mengeksploitasi detail perilaku cache CPU Wii asli. Secara teori, cache CPU asli bisa diemulasikan agar game berjalan mulus, tetapi overhead performanya mungkin sekitar 10 kali lebih lambat sehingga tidak dapat dimainkan, maka dipilih patch untuk mengakalinya
      https://dolphin-emu.org/blog/2017/02/01/dolphin-progress-rep...
  • Bagaimana cara mulai masuk ke emulasi? Ini tampak seperti ceruk yang sangat sulit bahkan di dalam dunia software
    Rasanya kita harus memahami elektronika sekaligus sihir pemrograman tingkat dalam
    • Seperti hal lain, mulailah secara bertahap
      Saat memulai, dan bahkan sebagian besar saat menyelesaikannya, Anda tidak perlu memahami sihir tingkat dalam. Pada umumnya cukup melihat spesifikasi dan mengimplementasikannya sesuai isi spesifikasi. Anda memang perlu mampu menyusun struktur kode agar tidak berantakan, tetapi ada pola-pola umum, dan setelah membuat satu atau dua emulator semuanya menjadi jauh lebih mudah
      Hampir tidak pernah perlu memahami elektronika. Yang diemulasikan hanyalah perilakunya. Jika bug pada perilaku hardware asli ditemukan, biasanya cukup menambahkan penanganan khusus ke emulator. Pengetahuan elektronika bisa membantu memahami mengapa perilaku seperti itu muncul, tetapi itu lebih merupakan minat historis daripada kebutuhan praktis
      Ada kesulitan khasnya sendiri. Saat terjadi masalah, biasanya Anda men-debug tiga hal sekaligus: pemahaman tentang hardware, implementasi emulator, dan game yang sedang diemulasikan. Menyempitkan penyebab pastinya bisa sulit. Meski begitu, saya sarankan untuk sekadar mencoba membuat versi kasar. Memang tidak rapi, tetapi semua emulator penuh dengan penanganan khusus agar game populer entah bagaimana bisa berjalan. Jika beberapa hack kotor membuat game berjalan, lakukan saja. Anda tidak harus mengimplementasikan perilaku hardware asli secara tepat; cukup buat gamenya berjalan
    • Anda bisa mulai dengan membaca dokumentasi hardware, dan tidak perlu memahami mesin pada tingkat rangkaian elektronik. Ini bukan simulasi rangkaian digital, jadi tidak perlu serumit itu
      CPU 8-bit adalah mesin keadaan sederhana yang hanya punya beberapa byte state, yaitu register. Anda membaca program byte demi byte, lalu menirukan apa yang dilakukan CPU setelah membaca byte itu. Operasinya sangat sederhana, seperti menjumlahkan dan mengurangkan angka, atau membaca dan menyimpan byte
      http://www.6502.org/users/obelisk/6502/registers.html
      http://www.6502.org/users/obelisk/6502/instructions.html
      Emulator CPU 6502 membaca beberapa byte berikutnya dari program, menafsirkan byte-byte itu sebagai instruksi, lalu menjalankan instruksi tersebut. Dalam prosesnya, ia memperbarui beberapa register atau counter CPU, melakukan operasi aritmetika atau bitwise, dan jika perlu membaca atau menyimpan 1 byte data dari satu lokasi ke lokasi lain. Proses ini diulang dalam loop tak terbatas

Ini adalah simulasi dari siklus fetch-decode-execute
https://en.wikipedia.org/wiki/Instruction_cycle

  • Tergantung apa yang dimaksud dengan emulasi
    Dulu saya pernah mem-porting interpreter 6502 dari UNIX ke Classic Macintosh untuk memutar file musik SID. Karena yang penting hanya berjalan cukup cepat, akurasi siklus clock tidak terlalu penting
    Cara kerjanya adalah memanggil kode C dari interpreter
  • Saat dulu mencoba mulai mempelajarinya, panduannya adalah mulai dari sesuatu yang sangat sederhana dan terdokumentasi dengan baik, lalu membangun kemampuan dari sana
    Saya masih ingin mencobanya, tetapi tidak punya waktu
  • Sedikit promosi, saya pernah memberikan presentasi tentang topik ini di FOSDEM lalu: https://fosdem.org/2024/schedule/event/fosdem-2024-2146-how-...
    Selain itu, komentar saudara dari @xcv123 benar-benar tepat
  • Ini adalah contoh menarik yang mungkin tidak terlalu layak dipedulikan dalam emulasi perangkat lunak. Mengemulasikan bug itu juga akan membuatnya cukup lambat
    Jika suatu hari nanti memungkinkan untuk mereplikasi PS2 dengan FPGA, mencari tahu bagaimana perilaku ini terjadi akan menjadi proyek yang menarik bagi seseorang
    • Implementasi FPGA pun sering dibuat berdasarkan kode atau dokumentasi dari proyek emulasi perangkat lunak
      Tidak ada jaminan bahwa versi FPGA dari PS2 tidak akan mengimplementasikan bug yang sama atau mirip
    • Tergantung apakah bug itu merusak game atau tidak
    • Memperbaiki bug ini akan menjadi bagian dari pekerjaan memperbaiki berbagai bug floating-point lainnya, lebih spesifiknya masalah pembulatan dan clamping
      Floating-point perangkat lunak memang akan lambat, tetapi solusi umumnya mungkin akan mengikuti emulator PS2 di PS4. Caranya adalah menetapkan whitelist, per game, untuk bagian-bagian kode yang diizinkan memakai jalur floating-point perangkat lunak
    • Mengapa ada orang ingin mengemulasikan CPU MIPS tua yang buruk dengan FPGA yang relatif mahal? Inti dari mengemulasikan konsol lama adalah agar bisa memainkan game lama di komputer atau ponsel, secara independen dari perangkat keras
  • Apakah ada lagi yang melihat judulnya lalu bingung kenapa mouse atau keyboard harus melakukan matematika?
    Butuh waktu terlalu lama bagi saya untuk menyadari bahwa ini membahas PlayStation 2, bukan port Personal System/2 untuk menghubungkan mouse dan keyboard
    • Yang satu PS2, yang lain PS/2
    • Untuk orang-orang yang memberi downvote: sesuatu yang jelas bagi Anda belum tentu jelas bagi semua orang
      Akronim tiga huruf bisa membuat konteks sangat sulit ditemukan. Kalau hanya memasukkan akronim ke Google, cukup sering hasilnya sebagian besar nyaris tidak relevan