Adaptasi program untuk ZX Spectrum ke TR-DOS dengan cara modern. Bagian 1

Tidak seperti komputer modern, pada spektrum konsep sistem file tidak seperti itu. Ini berarti bahwa mengunduh dari setiap jenis media memerlukan implementasi yang terpisah, dan dalam kebanyakan kasus program tidak dapat hanya disalin dari tape ke disk. Dalam kasus di mana program loader ditulis dalam BASIC, itu bisa diadaptasi ke TR-DOS dengan revisi yang cukup sederhana. Namun, situasinya diperumit oleh kenyataan bahwa dalam banyak game (baik yang bermerek maupun yang diretas), pemuatnya ditulis dalam kode mesin dan terkadang berisi perlindungan salinan.


5.25 "Floppy


Meskipun terdapat "tombol ajaib" yang hanya membuang memori komputer dan memungkinkan untuk menyimpan program ke disket, namun dianggap oleh para ahli untuk membuat versi permainan dari disk sambil mempertahankan image boot asli dan atribut lainnya.


Pada artikel ini, saya akan memberi tahu Anda cara melakukan adaptasi seperti itu pada contoh game Pac-Man , yaitu gambar Pac-Man.tzx asli .


Alat-alatnya


Terlepas dari kenyataan bahwa di masa lalu semua pekerjaan seperti itu dilakukan secara langsung pada ZX Spectrum (tanpa adanya opsi lain), saya akan mengadaptasi game menggunakan emulator dan utilitas baris perintah. Alasan utamanya adalah bahwa terutama pada awalnya proses adaptasi terdiri dari sejumlah besar trial and error, dan prosesnya akan jauh lebih menyakitkan jika diotomatisasi. Semua hal yang sama dapat dilakukan langsung di Spectrum.


Pada bagian pertama kita akan menggunakan alat-alat berikut:


  1. Emulator sekering untuk debugging dan pengujian.
  2. SkoolKit untuk pembongkaran.

Menonaktifkan startup di bootloader


Karena file gambar dan data diunduh tanpa blok header (17 byte dengan nama dan jenis file), ini berarti bahwa loader ditulis dalam kode mesin. Anda perlu menemukan di mana kode-kode ini berada dan dari alamat apa mereka diluncurkan.


Ada beberapa cara untuk melihat kode bootloader:


  1. Cara termudah adalah mulai mengunduh program, menunggu bootloader untuk memulai, dan menghentikannya dengan menekan tombol Space . Dalam banyak kasus, ini berfungsi, tetapi dalam kasus Pacman, seperti dalam banyak kasus lainnya, ini mengarah ke reset.


  2. Cara selanjutnya adalah memuat program menggunakan MERGE "" bukan LOAD "" . Tidak seperti LOAD , MERGE mengabaikan program autorun. Dalam kasus Pac-Man, booting melalui MERGE menyebabkan komputer membeku dengan karakteristik pergeseran layar kiri. Ini disebabkan oleh fakta bahwa alih-alih mengeksekusi program baris demi baris, MERGE mencoba menguraikannya secara keseluruhan dan menggabungkannya dengan program yang sudah dimuat. Namun, jika program memiliki blok dengan kode mesin yang melanggar sintaks program, ini akan menyebabkan crash.


  3. Jika Anda tidak ingin memutar otak Anda, Anda dapat mengonversi gambar rekaman dari TZX ke TAP dan menggunakan utilitas listbasic yang menyertai Fuse:


     $ tzx2tap Pac-Man.tzx $ listbasic Pac-Man.tap 1 RANDOMIZE USR (PEEK 23635+256*PEEK 23636+91) 

    Alamat 23635 ( $5C53 ) sesuai dengan variabel sistem PROG , yang berisi alamat awal area BASIC. Dengan demikian, titik masuk ke bootloader diimbangi oleh 91 byte relatif terhadap area BASIC.


  4. Cara lain untuk melihat bootloader dijelaskan dalam artikel Desativando a autoexecução de um programa BASIC . Dalam Fuse debugger, Anda perlu mengatur breakpoint br 2053 , memuat program, dan ketika unduhan selesai dan eksekusi kode berhenti, jalankan set 23619 128 . Ini akan mencegah program memulai dan memungkinkan Anda untuk keluar ke BASIC.



Bootloader dibongkar


Mengetahui pergeseran titik masuk relatif ke area BASIC, Anda dapat menghitung alamat absolutnya. Dalam kasus ZX Spectrum 48K tanpa TR-DOS yang dimuat, area BASIC dimulai pada 23755 ( $5CCB ). Akibatnya, bootloader akan mulai pada 23755 + 91 = 23846 ( $5D26 ).


Untuk memulai, cukup letakkan breakpoint di alamat awal dan lihat kode mesin. Dalam Fuse, Anda dapat membuat br 23846 dan mulai mengunduh program. Segera setelah bootloader mulai dijalankan, emulator akan berhenti:


Debugger


Dalam hal ketika loader sangat sederhana, lihat saja kode yang dibongkar di panel tengah dan pahami apa yang sedang dimuat. Biasanya, kode unduhan untuk file tanpa header terlihat seperti ini:


 LD IX, $8000 ;    LD DE, $4000 ;    LD A, $FF ;    CALL $0556 ;  LD-BYTES JP $8000 ;    

Dalam kasus yang lebih kompleks dengan eksekusi kode, Anda perlu memahami langkah-langkah dan membuat catatan. Utilitas SkoolKit sangat cocok untuk ini. Jika Anda menetapkan tujuan, dengan bantuannya game dapat diuraikan ke sekrup terakhir (pesan, sprite, suara). Cara ini dilakukan dijelaskan secara rinci dalam dokumentasi .


Singkatnya, lakukan hal berikut:


  1. Buat snapshot memori komputer Pac-Man.z80 menggunakan fitur tap2sna.py atau emulator.
  2. Buat file kontrol Pac-Man.ctl dengan set instruksi awal untuk pembongkaran:
     i 16384 Ignore for now c $5D26 Loader 
  3. Jalankan pembongkaran: sna2skool.py -H -c Pac-Man.ctl Pac-Man.z80 > Pac-Man.skool .
  4. Saat Anda mempelajari kode, tambahkan instruksi dan komentar baru ke file kontrol.
  5. Ulangi sampai benar-benar tercerahkan.

Akibatnya, setelah pass pertama kami mendapatkan yang berikut (komentar saya, alamat dihilangkan):


 ORG $5D26 ;   23846,   ;   DI IM 1 ;   LD D, IYh ; LD E, IYl ; LD B, $25 ;    EX DE, HL ; LD DE, $0019 ; ADD HL, DE ;    HL  $5C53 (  PROG) LD E, (HL) ;   PROG  DE  IX INC HL ; LD D, (HL) ; LD IXh, D ; LD IXl, E ; LD A, (IX+$7F) ;      (  $7F-  ;  PROG) LD HL, $0035 ;    ($35   PROG) ADD HL, DE ; PUSH HL ;      XOR (HL) ;    LD (HL), A ; INC HL ; DJNZ $5D43 ;   AND (HL) ; RET NZ ;           ;    DEFB $77 

Dekripsi Bootloader


Yang paling penting adalah bootloader yang didekripsi tersebut berada di PROG + $35 . Ini berarti bahwa jika kita meletakkan breakpoint pada br 23808 , maka pada saat ini dekripsi akan selesai kita akan melihat bootloader yang didekripsi:


Loader


Program ini sudah jauh lebih mirip dengan kasus khas yang disebutkan di atas. Nilai $4000 ( 16384 ) dimuat ke dalam register IX dan DE , sesuatu yang lain dilakukan dan kontrol ditransfer ke rutin ROM pada $055A (ini adalah beberapa byte lebih rendah dari titik masuk standar di LD-BYTES ). Tampaknya pendekatan ini mengimplementasikan semacam perlindungan terhadap salinan prosedur standar tidak memuat file ini dan beberapa penyalin tidak memahaminya.


Titik masuk program


Masih mencari tahu bagaimana program dipanggil setelah memuat. Alih-alih CALL LD-BYTES dan JP , LD SP, XXXX dan JP LD-BYTES biasa digunakan di sini. Opsi pertama (biasanya) berfungsi sebagai berikut:


  1. CALL mendorong nilai saat ini dari penghitung perangkat lunak ( PC ) ke tumpukan.
  2. Kontrol dilewatkan ke rutin yang disebut.
  3. Ketika kembali dari subrutin ( RET ), nilai dihapus dari tumpukan dan transisi ke program panggilan terjadi.

Mengapa ini dilakukan secara berbeda di sini? Faktanya adalah bahwa Pac-Man kompatibel dengan ZX Spectrum 16K dan benar-benar menempati semua RAM (lihat ukuran file di atas). Jadi, ketika memuat, program menimpa dirinya sendiri baik loader maupun stack, di mana pun mereka berada. Jika kami ingin beralih dari ROM ke bootloader menggunakan tumpukan dan kemudian memanggil program yang diunduh melalui JP , pada saat unduhan selesai, tidak akan ada alamat memori pada saat di mana JP berada, juga instruksi itu sendiri.


Sebagai gantinya, penunjuk tumpukan bergerak ke area memori tempat, setelah pemuatan, alamat titik masuk ke program muncul, dan prosesor, tanpa memperhatikan spoofing, memindahkannya dari tumpukan dengan penunjuk baru dan pergi ke alamat yang ditentukan.


Hasil pembongkaran lengkap dapat dilihat di repositori proyek di github.


Total


Sebagai hasil dari mempelajari bootloader, kami menemukan yang berikut:


  1. File tanpa header dengan panjang 16384 byte diunduh pada 16384 (di area layar, yang umumnya jelas selama proses pengunduhan).
  2. Pada akhir pengunduhan, penunjuk tumpukan terletak di $5D7C , di mana kontrol ditransfer ke.

Pada bagian berikut saya akan berbicara tentang bagaimana mempersiapkan file untuk menulis ke disk dan menulis loader file monoblock di assembler.


Tautan terkait:


  1. Profil "TRUB Spectrumist . "
  2. Game reverse engineering ZX Spectrum (Z80) .
  3. Adaptação de jogos de fita para Beta 48 .

Source: https://habr.com/ru/post/id451174/


All Articles