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

Seperti yang kami temukan di bagian sebelumnya , kode mesin permainan tidak dapat diunduh langsung dari disket ke alamat tujuan. Kami akan mengunggahnya ke lokasi lain, dan setelah mengunduh kami akan memindahkannya jika perlu. Selain itu, kami ingin membuat bootloader satu blok ketika bootloader dan data yang dimuat berada dalam file dasar yang sama. Pemuat seperti itu hanya dapat ditulis dalam kode mesin. Pada saat yang sama, karena kita memiliki file monoblock, loader dalam kode mesin perlu ditempatkan di komentar ke loader di BASIC.


Floppy 5.25 "


Total, ternyata mnogohodovka berikut:


  1. Dari BASIC kami mentransfer kontrol ke program dalam kode mesin.
  2. Program dalam kode mesin mentransfer bootloader dari area BASIC ke area lain yang tidak akan terpengaruh oleh kode mesin game, dan mentransfer kontrol ke sana.
  3. Unduh dan buka paket imej boot.
  4. Kami memuat kode mesin game ke area yang tidak tumpang tindih dengan area variabel sistem.
  5. Kami mentransfer kode mesin ke alamat tujuan.
  6. Kami mentransfer kontrol ke program.

Pengembangan harus dimulai di tengah (paragraf 3). Faktanya adalah bahwa untuk menulis sebuah program untuk dipindahkan, Anda perlu mengetahui ukuran program yang akan dipindahkan, dan untuk menanamkan kode mesin dalam dasar, Anda perlu mengetahui ukuran program untuk bergerak.


Monoblock bootloader (bagian dalam kode mesin)


Dalam TR-DOS, memuat data dari file monoblock lebih seperti memuat file tanpa header dari tape, ketika data dengan ukuran yang telah ditentukan hanya dibaca dari posisi saat ini dan dimuat ke area memori tertentu. Untuk ini, di TR-DOS, rutin di #3D13 . Pertama, unduh dan hapus zip gambar:


 LD DE, ($5CF4) ;        LD BC, $0805 ;  B  -  (9)*, ;   —   #05 ( ) LD HL, $8000 ;    32768** CALL $3D13 ;   TR-DOS CALL $8000 ;    

& ast; - lihat kompresi gambar boot di bagian sebelumnya;
& ast; & ast; - Pembongkaran dapat dipindahkan, sehingga Anda dapat mengunduh di mana saja.


Demikian pula, unduh kode mesin game:


 LD DE, ($5CF4) ;        LD BC, $2505 ;  B  - , ;   —   #05 ( ) LD HL, $6000 ;    24576 CALL $3D13 ;   TR-DOS 

Pada tahap ini, kita tidak lagi membutuhkan TR-DOS, kita dapat mentransfer kode mesin ke alamat tujuan menggunakan LDIR prosesor LDIR :


 LD HL, $6000 ;  (,      ) LD DE, $5B00 ;  LD BC, $2500 ;     (  data.bin) LDIR 

Pada akhirnya, kami mentransfer kontrol ke program dengan cara yang sama seperti pada bootloader asli - dengan menggerakkan penunjuk tumpukan:


 LD SP, $5D7C RET 

Sekarang setelah kode loader siap, Anda perlu mengkompilasinya untuk mengetahui ukurannya, yang akan kami butuhkan lebih lanjut.


 $ pasmo tmp.asm tmp.bin $ wc -c tmp.bin 44 tmp.bin 

Prosedur Transfer Bootloader


Bootloader membutuhkan 44 byte. Sekarang Anda perlu menulis prosedur untuk memindahkan bootloader dari komentar di BASIC (poin 2 dari daftar di awal artikel). Halangannya adalah bahwa alamat tempat area BASIC berada dapat bervariasi tergantung pada periferal yang terhubung ke komputer, oleh karena itu, untuk menentukan di mana Anda ingin mentransfer data, Anda perlu fokus pada variabel sistem PROG (seperti pada bootloader asli) atau ke penghitung perangkat lunak (register prosesor PC ).


Tidak mudah mengakses penghitung perangkat lunak - tidak ada instruksi prosesor seperti LD HL, PC ada. Saya memata-matai solusi di Laser Compress dan sepertinya ini (tidak benar-benar menargetkan penggunaan prosedur UNSTACK_Z ):


 LD DE, $00 ;     ,     , ;    .     ;    1 INC E ;  1  E,    ,    ;      .     1  CALL $1FC6 ;    ( ,  LD HL, PC) ADD HL, DE ;       LD DE, $F800 ;    LD BC, $002C ;  ,   (44 ) LDIR JP $F800 ;    ;      ;        

Pada saat memanggil prosedur ROM #1FC6 , alamat instruksi berikutnya ( ADD HL, DE ) akan berada di tumpukan. Dialah yang akan direkam sebagai hasil dari memanggil prosedur di HL . Oleh karena itu, untuk menentukan angka yang perlu dituliskan di baris pertama, Anda perlu mengkompilasi bagian dari ADD HL, DE sampai akhir lagi dan melihat berapa banyak yang dibutuhkan:


 $ pasmo tmp.asm tmp.bin $ wc -c tmp.bin 12 tmp.bin 

Ternyata 12 byte. Dengan demikian, pada baris pertama kita menulis 11 ( #0B ).


Selanjutnya, kami membuat prosedur pemindahan dengan loader (lihat file yang sudah selesai ), yang akan dipindahkan dan dikompilasi lagi. Seharusnya menghasilkan 56 byte.


Perlu dicatat di sini bahwa setelah saya menulis bagian ini, saya menemukan bahwa alih-alih menghitung panjang program yang akan dipindahkan, Anda dapat menggunakan label dan membiarkan assembler mengetahuinya. Tapi untuk keadilan historis, biarkan saja apa adanya.


Monoblock bootloader (bagian dasar)


Sekarang kita tahu ukuran bootloader dalam kode mesin, kita dapat menulis bootloader dalam BASIC dan mengumpulkan semuanya dalam file monoblock.


Kode mesin tertanam dalam file dasar baik dalam komentar atau di akhir file. Yang kedua biasanya menyulitkan studi file dan lebih cocok untuk perlindungan, jadi kami akan menggunakan opsi pertama. Opsi komentar adalah sebagai berikut:


  1 REM @#$%... 10 RANDOMIZE USR (PEEK 23635+256*PEEK 23636+5) 

23635 ( #5C53 ) adalah alamat variabel sistem PROG yang kami sebutkan sebelumnya. 5 adalah offset karakter pertama dari komentar relatif terhadap PROG (2 byte adalah nomor baris, 2 byte adalah panjang baris dan 1 byte adalah operator REM ). Jika Anda ingin menambahkan komentar lain sebelum kode mesin, misalnya nama, nomor telepon, atau alamat surat Anda, nilai 5 perlu disesuaikan.


Jika kami tidak menggunakan utilitas tambahan apa pun untuk membuat bootloader, kami perlu memasukkan karakter sewenang-wenang setelah REM dalam jumlah yang tidak kurang dari panjang program dalam kode mesin yang ingin kami tempatkan di tempat komentar (dalam kasus kami 56 byte). Setelah itu, seseorang dapat memuat program melalui LOAD "" CODE PEEK 23635+256*PEEK 23636+5 dan menyimpan file.


Namun, bas2tap dapat membuat proses lebih mudah. itu dapat mengkompilasi file dasar dan menanamkan data biner ke dalamnya jika setiap byte direpresentasikan sebagai angka heksadesimal dalam kurung keriting. Untuk melakukan ini, jalankan bootloader yang dikompilasi melalui hexdump :


  $ hexdump -ve '1/1 "{%02x}"' loader.bin {11}{0b}{00}{1c}{cd}{c6}{1f}{19}{11}... 

hexdump output ke tempat komentar di baris pertama setelah REM dan kompilasi bootloader di -sboot ( -sboot adalah nama file pada rekaman itu, -a10 adalah nomor baris dari -a10 ):


 $ bas2tap -sboot -a10 boot.bas boot.tap 

Ubah bootloader dari format tap ke hobeta melalui format antara 0 :


 $ tapto0 -f boot.tap $ 0tohob boot.000 

Membuat file satu bagian


Pada titik ini, kita sudah memiliki semua file yang diperlukan untuk membuat gambar floppy disk. Anda dapat membuat gambar dan menyalin semua file yang diperlukan ke dalamnya:


 createtrd Pac-Man.trd hobeta2trd boot.\$$B Pac-Man.trd hobeta2trd screen.\$$C Pac-Man.trd hobeta2trd data.\$$C Pac-Man.trd 

Gambar floppy disk yang dihasilkan seharusnya sudah berfungsi. Anda dapat menjalankannya di emulator dan memeriksa, tetapi itu belum semuanya. Karena kita, bootloader tidak mengunduh file-file berikutnya bukan berdasarkan nama, tetapi berdasarkan posisi kepala drive, memuat hanya akan berfungsi jika file-file tersebut berada di disk satu per satu. Ini perlu diperbaiki.


Prinsipnya adalah sebagai berikut: TR-DOS menyimpan informasi ukuran file yang berlebihan:


  1. Ukuran dalam sektor - digunakan untuk menempatkan file pada floppy disk dan menyalin.
  2. Ukuran dalam byte - digunakan untuk memuat konten.

Biasanya ukuran ini saling berhubungan (256 byte per sektor), tetapi ini tidak perlu. Kami akan mengambil keuntungan dari ini. Jika Anda mengubah ukuran file boot di sektor ke nilai yang sama dengan ukuran total semua file yang ingin Anda unduh, tetapi jangan mengubah ukuran dalam byte, TR-DOS akan menyalin semua data sebagai satu file besar, tetapi hanya dasar yang akan dimuat saat boot bagian.


Pada Spectrum nyata atau dalam emulator, jalur nol dapat diedit dengan program seperti Disk Doctor, misalnya, Hex Disk Editor :


Editor hex disk


Tapi itu bisa dibuat lebih sederhana: trd-image tidak lebih dari salinan byte dari semua data pada disket, sehingga dapat diedit di hex editor apa pun:


 $ hexdump -C Pac-Man.trd | head -4 00000000 62 6f 6f 74 20 20 20 20 42 d0 00 d0 00 01 00 01 |boot B.......| 00000010 73 63 72 65 65 6e 20 20 43 40 9c 14 07 08 01 01 |screen C@......| 00000020 64 61 74 61 20 20 20 20 43 00 5b 00 25 25 09 01 |data C.[.%%..| 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 

Seperti yang Anda lihat, di awal disket (di jalur nol) ada tabel alokasi file di mana informasi tentang setiap file membutuhkan 16 byte. Ukuran dalam sektor disimpan dalam byte dengan offset #0D (kolom ketiga di sebelah kanan). Ukuran file kami adalah #01 , #08 dan #25 sektor, yang totalnya adalah #2E . Kami menulis nilai ini dalam byte yang sesuai, dan menghapus header yang tersisa, karena mereka tidak lagi dibutuhkan:


 $ hexdump -C Pac-Man.trd | head -4 00000000 62 6f 6f 74 20 20 20 20 42 d0 00 d0 00 2E 00 01 |boot B.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 

Sekarang kita memiliki gambar disket full-blown. Itu harus memuat dengan benar dan sepenuhnya disalin dari disk ke disk. Tetap hanya untuk mengurangi ukuran gambar. Karena gambar trd adalah salinan byte, selalu dibutuhkan 640KB. Dalam praktiknya, dalam banyak kasus, lebih nyaman menggunakan format scl, yang lebih seperti toko hobeta yang secara langsung mengajukan data:


 $ trd2scl Pac-Man.trd Pac-Man.scl 

Sekarang sudah pasti. Proses adaptasi dari awal hingga selesai dapat ditemukan di repositori proyek di github.


Alat:


  1. Pasmo adalah perakit silang untuk Z80.
  2. bas2tap adalah kompiler silang dari dialek Spectrum BASIC.
  3. trd2scl - trd2scl -image converter ke scl.

Tautan terkait:


  1. "Adaptasi program ke sistem TR-DOS" oleh Nikolai Rodionov.
  2. "Fungsi TR-DOS" dari Info Guide Magazine No. 1.
  3. "Struktur disket TR-DOS" dari buku "TR-DOS untuk profesional dan amatir . "
  4. Referensi ke variabel sistem dan prosedur Spectrum ROM .

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


All Articles