Bagaimana saya memulihkan data dalam format yang tidak diketahui dari pita magnetik

Latar Belakang



Sebagai pecinta besi retro, saya pernah membeli ZX Spectrum + dari penjual Inggris. Lengkap dengan komputer itu sendiri, saya mendapatkan beberapa kaset audio dengan permainan (dalam kemasan aslinya dengan instruksi), serta program yang direkam pada kaset tanpa sebutan khusus. Anehnya, data dari kaset berusia 40 tahun dapat dibaca dan saya dapat mengunduh hampir semua game dan program dari mereka.







Namun, pada beberapa kaset saya menemukan rekaman yang jelas tidak dibuat oleh komputer ZX Spectrum. Mereka terdengar sangat berbeda dan, tidak seperti rekaman dari komputer yang disebutkan sebelumnya, tidak dimulai dengan bootloader BASIC pendek, yang biasanya ada dalam rekaman semua program dan permainan.



Untuk beberapa waktu saya dihantui oleh hal ini - saya benar-benar ingin tahu apa yang tersembunyi di dalamnya. Jika Anda bisa membaca sinyal audio sebagai urutan byte, Anda bisa mencari di dalamnya untuk karakter atau sesuatu yang menunjukkan asal sinyal. Semacam arkeologi retro.



Sekarang saya telah datang jauh-jauh dan melihat label kaset itu sendiri, saya tersenyum karena

jawabannya tepat di depan mataku selama ini
— TRS-80, : «Manufactured by Radio Shack in USA»


(Jika Anda ingin menjaga intrik sampai akhir, jangan masuk di bawah spoiler)



Perbandingan sinyal audio



Langkah pertama adalah mendigitalkan rekaman audio. Anda dapat mendengarkan bunyinya:





Dan seperti biasa rekaman dari komputer ZX Spectrum berbunyi:





Dalam kedua kasus, pada awal rekaman, ada yang disebut nada pilot - suara satu frekuensi (pada rekaman pertama itu sangat singkat <1 detik, tetapi dapat dibedakan). Nada pilot memberi sinyal pada komputer untuk bersiap menerima data. Sebagai aturan, setiap komputer hanya mengenali nada pilot "nya" oleh bentuk gelombang dan frekuensinya.



Saya harus katakan tentang bentuk sinyal itu sendiri. Misalnya, pada ZX Spectrum, bentuknya persegi panjang:







Ketika nada pilot terdeteksi, ZX Spectrum menampilkan garis-garis merah dan biru bergantian di perbatasan layar, yang menunjukkan bahwa sinyal dikenali. Nada pilot diakhiri dengan pulsa sinkronisasi, yang memberi sinyal komputer untuk mulai menerima data. Ini ditandai dengan durasi yang lebih pendek (dibandingkan dengan nada pilot dan data berikutnya) (lihat gambar)



Setelah pulsa sinkronisasi diterima, komputer mencatat setiap naik / turunnya sinyal, mengukur durasinya. Jika durasinya kurang dari batas tertentu, bit 1 ditulis ke memori, jika tidak, 0. Bit dikumpulkan ke dalam byte dan proses diulang sampai N byte diterima. Angka N biasanya diambil dari header file yang diunduh. Urutan boot adalah sebagai berikut:



  1. nada pilot
  2. header (panjang tetap), berisi ukuran data yang dimuat (N), nama dan tipe file
  3. nada pilot
  4. data itu sendiri


Untuk memastikan bahwa data dimuat dengan benar, ZX Spectrum membaca byte terakhir dari yang disebut byte parity (parity byte), yang dihitung ketika Anda menyimpan operasi file XOR pada semua byte dari data yang direkam. Saat membaca file, komputer menghitung byte paritas dari data yang diterima dan, jika hasilnya berbeda dari yang disimpan, menampilkan pesan kesalahan "R Tape loading error". Sebenarnya, komputer dapat mengeluarkan pesan ini lebih awal jika, saat membaca, ia tidak dapat mengenali impuls (terlewatkan atau durasinya tidak sesuai dengan batas-batas tertentu)



Jadi, sekarang mari kita lihat seperti apa sinyal yang tidak dikenal:







Ini adalah nada pilot. Bentuk gelombang sangat berbeda, tetapi Anda dapat melihat bahwa sinyal terdiri dari pulsa pendek berulang dari frekuensi tertentu. Pada tingkat sampling 44100 Hz, jarak antara "puncak" adalah sekitar 48 sampel (yang sesuai dengan frekuensi ~ 918 Hz). Mari kita ingat angka ini.



Sekarang mari kita lihat fragmen dengan data:







Jika kita mengukur jarak antara pulsa individu, ternyata jarak antara pulsa "panjang" masih ~ 48 sampel, dan antara yang pendek - ~ 24. Berjalan sedikit di depan, saya akan mengatakan bahwa pada akhirnya ternyata "referensi" pulsa dengan frekuensi 918 Hz ikuti terus menerus, dari awal hingga akhir file. Dapat diasumsikan bahwa selama transmisi data, jika pulsa tambahan terjadi di antara pulsa referensi, kami menganggapnya sebagai bit 1, jika tidak 0.



Ada apa dengan denyut nadi sinkronisasi? Mari kita lihat awal data:







Nada pilot berakhir dan data segera dimulai. Beberapa saat kemudian, setelah menganalisis beberapa rekaman audio yang berbeda, kami menemukan bahwa byte data pertama selalu sama (10100101b, A5h). Komputer dapat mulai membaca data setelah menerimanya.



Anda juga dapat memperhatikan pergeseran pulsa referensi pertama segera setelah 1 terakhir di synchrobyte. Itu ditemukan jauh kemudian dalam proses pengembangan program untuk pengenalan data, ketika data pada awal file tidak dapat dibaca secara stabil.



Sekarang mari kita coba menggambarkan suatu algoritma yang akan memproses file audio dan memuat data.



Memuat data



Pertama, mari kita lihat beberapa asumsi agar tidak menyulitkan algoritma:



  1. Kami hanya akan mempertimbangkan file dalam format WAV;
  2. File audio harus dimulai dengan nada pilot dan tidak boleh berisi diam di awal
  3. File sumber harus memiliki laju sampling 44100 Hz. Dalam hal ini, jarak antara pulsa referensi dari 48 sampel telah ditentukan dan kami tidak perlu menghitungnya secara terprogram;
  4. Format sampel dapat berupa apa saja (8/16 bit / floating point) - karena saat membaca, kita dapat mengubahnya menjadi yang diinginkan;
  5. Kami berasumsi bahwa file asli dinormalisasi dalam amplitudo, yang seharusnya menstabilkan hasilnya;


Algoritma pembacaan akan sebagai berikut:



  1. Kami membaca file menjadi memori, pada saat yang sama kami mengubah format sampel menjadi 8 bit;
  2. Tentukan posisi pulsa pertama dalam data audio. Untuk melakukan ini, Anda perlu menghitung jumlah sampel dengan amplitudo maksimum. Untuk kesederhanaan, mari kita hitung secara manual sekali. Mari kita simpan ke variabel prev_pos;
  3. Tambahkan 48 ke posisi impuls terakhir (pos: = prev_pos + 48)
  4. 48 , ( , ), pos. (pos-8;pos+8) . , , pos. 8 = 48/6 — , , . , 48, , ;
  5. , . , , . , , . , . 2 : , . ;
  6. ( 0 1), (prev_pos;pos) middle_pos middle_pos := (prev_pos+pos)/2 middle_pos (middle_pos-8;middle_pos+8) . 10, 1 0. 10 — ;
  7. prev_pos (prev_pos := pos)
  8. 3, ;
  9. . - , 8, . - 8 . . A5h,


Ruby,
Ruby, .. . , .



#  gem 'wavefile'
require 'wavefile'

reader = WaveFile::Reader.new('input.wav')
samples = []
format = WaveFile::Format.new(:mono, :pcm_8, 44100)

#  WAV ,    Mono, 8 bit 
#  samples       0-255
reader.each_buffer(10000) do |buffer|
  samples += buffer.convert(format).samples
end

#    ( 0)
prev_pos = 0
#   
distance = 48
#       
delta = (distance / 6).floor
#        "0"  "1"
bits = ""

loop do
  #    
  pos = prev_pos + distance
  
  #       
  break if pos + delta >= samples.size

  #   pos     [pos - delta;pos + delta]
  (pos - delta..pos + delta).each { |p| pos = p if samples[p] > samples[pos] }

  #    [prev_pos;pos]
  middle_pos = ((prev_pos + pos) / 2).floor

  #     
  sample = samples[middle_pos - delta..middle_pos + delta]

  #    "1"           10
  bit = sample.max - sample.min > 10
  bits += bit ? "1" : "0"
end

#  -       256   (  ) 
bits.gsub! /^[01]*?10100101/, ("0" * 256) + "10100101"

#   ,    
File.write "output.cas", [bits].pack("B*")






Setelah mencoba beberapa varian dari algoritma dan konstanta, saya beruntung mendapatkan sesuatu yang sangat menarik:







Jadi, dilihat dari string karakter, kami memiliki program untuk merencanakan grafik. Namun, tidak ada kata kunci dalam teks program. Semua kata kunci dikodekan sebagai byte (masing-masing nilai> 80jam). Sekarang kita perlu mencari tahu komputer mana dari tahun 80-an yang dapat menyimpan program dalam format ini.



Ini sebenarnya sangat mirip dengan program BASIC. Dalam format yang kira-kira sama, komputer ZX Spectrum menyimpan dalam memori dan menyimpan program untuk direkam. Untuk jaga-jaga, saya memeriksa kata kunci pada tabel . Namun, hasilnya jelas negatif.



Saya juga memeriksa kata kunci BASIC dari komputer Atari yang saat itu populer, Commodore 64 dan beberapa lainnya, yang saya berhasil menemukan dokumentasi, tetapi tidak berhasil - pengetahuan saya tentang jenis komputer retro tidak begitu luas.



Kemudian saya memutuskan untuk membaca daftar itu , dan kemudian mata saya tertuju pada nama produsen Radio Shack dan komputer TRS-80. Nama-nama ini tertulis di label kaset yang ada di meja saya! Lagi pula, saya tidak tahu nama-nama ini sebelumnya dan tidak terbiasa dengan komputer TRS-80, sehingga bagi saya Radio Shack adalah produsen kaset audio, seperti BASF, Sony atau TDK, dan TRS-80 adalah durasi pemutaran. Kenapa tidak?



Komputer Tandy / Radio Shack TRS-80



Sangat mungkin bahwa rekaman audio yang dimaksud, yang saya berikan sebagai contoh di awal artikel, dibuat pada komputer seperti itu:







Ternyata komputer ini dan variannya (Model I / Model III / Model IV, dll.) Sangat populer di kalangan mereka. waktu (tentu saja, bukan di Rusia). Perlu dicatat bahwa prosesor yang digunakan di dalamnya juga Z80. Banyak informasi dapat ditemukan di komputer ini di Internet . Pada 1980-an, informasi tentang komputer diedarkan di majalah . Saat ini, ada beberapa emulator komputer untuk platform yang berbeda.



Saya mengunduh emulator trs80gpdan untuk pertama kalinya saya dapat melihat bagaimana komputer ini bekerja. Tentu saja, komputer tidak mendukung keluaran warna, resolusi layar hanya 128x48 piksel, tetapi ada banyak ekstensi dan modifikasi yang dapat meningkatkan resolusi layar. Ada juga banyak opsi untuk sistem operasi untuk komputer ini dan opsi untuk mengimplementasikan bahasa BASIC (yang, tidak seperti ZX Spectrum, dalam beberapa model bahkan tidak "di-flash" ke ROM dan opsi apa pun bisa boot dari floppy disk, serta OS itu sendiri)



. Saya menemukan utilitas untuk mengubah rekaman audio ke dalam format CAS, yang didukung oleh emulator, tetapi untuk beberapa alasan saya tidak bisa membaca rekaman dari kaset saya dengan menggunakannya.



Setelah mengetahui format file CAS (yang ternyata hanya salinan data bitwise dari rekaman, yang sudah saya miliki di tangan saya, dengan pengecualian header dengan kehadiran byte sinkronisasi), saya membuat beberapa perubahan pada program saya dan bisa mendapatkan file CAS yang berfungsi pada output, yang ini bekerja di emulator (TRS-80 Model III):







Versi terakhir dari utilitas untuk mengkonversi dengan deteksi otomatis dari pulsa pertama dan jarak antara pulsa referensi yang saya rancang sebagai paket GEM, kode sumber tersedia di Github .



Kesimpulan



Jalan yang dilalui ternyata menjadi perjalanan yang menakjubkan ke masa lalu, dan saya senang bahwa pada akhirnya saya menemukan solusi. Antara lain, saya:



  • Saya menemukan format untuk menyimpan data dalam ZX Spectrum dan mempelajari rutin ROM bawaan untuk menyimpan / membaca data dari kaset audio
  • Saya berkenalan dengan komputer TRS-80 dan varietasnya, mempelajari sistem operasi, melihat contoh program dan bahkan memiliki kesempatan untuk men-debug kode mesin (setelah semua, semua mnemonik Z80 sudah tidak asing bagi saya)
  • Saya menulis utilitas lengkap untuk mengonversi rekaman audio ke format CAS, yang dapat membaca data yang tidak dikenali oleh utilitas "resmi"



All Articles