ฉันจะกู้คืนข้อมูลในรูปแบบที่ไม่รู้จักจากเทปแม่เหล็กได้อย่างไร

ประวัติศาสตร์

ในฐานะผู้ชื่นชอบฮาร์ดแวร์ย้อนยุค ฉันเคยซื้อ ZX Spectrum+ จากผู้ขายในสหราชอาณาจักร เมื่อรวมเข้ากับคอมพิวเตอร์แล้ว ฉันได้รับเทปเสียงพร้อมเกมหลายแผ่น (ในบรรจุภัณฑ์ดั้งเดิมพร้อมคำแนะนำ) รวมถึงโปรแกรมที่บันทึกบนเทปโดยไม่มีเครื่องหมายพิเศษ น่าแปลกที่ข้อมูลจากเทปอายุ 40 ปีสามารถอ่านได้ดี และฉันสามารถดาวน์โหลดเกมและโปรแกรมเกือบทั้งหมดจากเทปเหล่านั้นได้

ฉันจะกู้คืนข้อมูลในรูปแบบที่ไม่รู้จักจากเทปแม่เหล็กได้อย่างไร

อย่างไรก็ตาม ในเทปบางแผ่น ฉันพบการบันทึกที่ไม่ได้จัดทำโดยคอมพิวเตอร์ ZX Spectrum อย่างชัดเจน พวกเขาฟังดูแตกต่างไปจากเดิมอย่างสิ้นเชิงและแตกต่างจากการบันทึกจากคอมพิวเตอร์ที่กล่าวถึงพวกเขาไม่ได้เริ่มต้นด้วยโปรแกรมโหลดบูต BASIC สั้น ๆ ซึ่งโดยปกติจะมีอยู่ในการบันทึกของโปรแกรมและเกมทั้งหมด

สิ่งนี้หลอกหลอนฉันมาระยะหนึ่งแล้ว - ฉันอยากจะค้นหาสิ่งที่ซ่อนอยู่ในตัวพวกเขาจริงๆ หากคุณสามารถอ่านสัญญาณเสียงเป็นลำดับไบต์ได้ คุณสามารถค้นหาอักขระหรืออะไรก็ได้ที่บ่งบอกถึงที่มาของสัญญาณ โบราณคดีย้อนยุคชนิดหนึ่ง

ตอนนี้ผมดูฉลากของตลับเทปจนหมดแล้ว ผมก็ยิ้มเพราะว่า

คำตอบนั้นอยู่ตรงหน้าฉันมาตลอด
บนฉลากของคาสเซ็ตด้านซ้ายคือชื่อของคอมพิวเตอร์ TRS-80 และใต้ชื่อผู้ผลิต: “Manufactured by Radio Shack in USA”

(ถ้าอยากเก็บอุบายให้จบอย่าไปโดนสปอยล์นะ)

การเปรียบเทียบสัญญาณเสียง

ก่อนอื่น เรามาแปลงการบันทึกเสียงให้เป็นดิจิทัลกันก่อน คุณสามารถฟังสิ่งที่ดูเหมือน:


และตามปกติเสียงที่บันทึกจากคอมพิวเตอร์ ZX Spectrum จะดังขึ้น:


ในทั้งสองกรณีจะมีสิ่งที่เรียกว่าเกิดขึ้นที่จุดเริ่มต้นของการบันทึก โทนเสียงนำร่อง - เสียงที่มีความถี่เท่ากัน (ในการบันทึกครั้งแรกจะสั้นมาก <1 วินาที แต่แยกแยะได้) เสียงสัญญาณนำร่องจะส่งสัญญาณให้คอมพิวเตอร์เตรียมรับข้อมูล ตามกฎแล้ว คอมพิวเตอร์แต่ละเครื่องจะจดจำเฉพาะโทนเสียงนำ "ของตัวเอง" ตามรูปร่างของสัญญาณและความถี่

จำเป็นต้องพูดอะไรบางอย่างเกี่ยวกับรูปร่างของสัญญาณนั้นเอง ตัวอย่างเช่น บน ZX Spectrum รูปร่างของมันจะเป็นสี่เหลี่ยม:

ฉันจะกู้คืนข้อมูลในรูปแบบที่ไม่รู้จักจากเทปแม่เหล็กได้อย่างไร

เมื่อตรวจพบโทนเสียงนำร่อง ZX Spectrum จะแสดงแถบสีแดงและสีน้ำเงินสลับกันที่ขอบของหน้าจอเพื่อระบุว่าสัญญาณได้รับการยอมรับแล้ว โทนเสียงนำสิ้นสุดลง ชีพจรแบบซิงโครนัส, который сигнализирует компьютеру о том, что следует начинать принимать данные. Он характеризуется меньшей (по сравнению с пилотным тоном и последующими данными) длительностью (см. рисунок)

หลังจากได้รับพัลส์ซิงค์แล้ว คอมพิวเตอร์จะบันทึกการขึ้น/ลงของสัญญาณแต่ละครั้ง เพื่อวัดระยะเวลา หากระยะเวลาน้อยกว่าขีดจำกัดที่กำหนด บิต 1 จะถูกเขียนลงในหน่วยความจำ มิฉะนั้นจะเป็น 0 บิตจะถูกรวบรวมเป็นไบต์ และกระบวนการจะถูกทำซ้ำจนกว่าจะได้รับ N ไบต์ โดยทั่วไปหมายเลข N จะนำมาจากส่วนหัวของไฟล์ที่ดาวน์โหลด ลำดับการโหลดมีดังนี้:

  1. โทนเสียงนำร่อง
  2. ส่วนหัว (ความยาวคงที่) ประกอบด้วยขนาดของข้อมูลที่ดาวน์โหลด (N) ชื่อไฟล์และประเภท
  3. โทนเสียงนำร่อง
  4. ข้อมูลนั้นเอง

เพื่อให้แน่ใจว่าข้อมูลถูกโหลดอย่างถูกต้อง ZX Spectrum จะอ่านสิ่งที่เรียกว่า พาริตีไบต์ (พาริตีไบต์) ซึ่งคำนวณเมื่อบันทึกไฟล์โดย XORing ไบต์ทั้งหมดของข้อมูลที่เขียน เมื่ออ่านไฟล์ คอมพิวเตอร์จะคำนวณพาริตีไบต์จากข้อมูลที่ได้รับ และหากผลลัพธ์แตกต่างจากข้อมูลที่บันทึกไว้ จะแสดงข้อความแสดงข้อผิดพลาด “R ข้อผิดพลาดในการโหลดเทป” พูดอย่างเคร่งครัด คอมพิวเตอร์สามารถส่งข้อความนี้เร็วขึ้นหากไม่สามารถจดจำชีพจรได้เมื่ออ่าน (พลาดหรือระยะเวลาไม่สอดคล้องกับขีดจำกัดที่แน่นอน)

ตอนนี้เรามาดูกันว่าสัญญาณที่ไม่รู้จักมีลักษณะอย่างไร:

ฉันจะกู้คืนข้อมูลในรูปแบบที่ไม่รู้จักจากเทปแม่เหล็กได้อย่างไร

นี่คือโทนเสียงนำร่อง รูปร่างของสัญญาณมีความแตกต่างกันอย่างมีนัยสำคัญ แต่เป็นที่ชัดเจนว่าสัญญาณประกอบด้วยพัลส์สั้น ๆ ซ้ำ ๆ ในความถี่ที่แน่นอน ที่ความถี่สุ่มตัวอย่าง 44100 Hz ระยะห่างระหว่าง "จุดสูงสุด" จะอยู่ที่ประมาณ 48 ตัวอย่าง (ซึ่งสอดคล้องกับความถี่ ~ 918 Hz) มาจำตัวเลขนี้กัน

ตอนนี้เรามาดูส่วนของข้อมูลกัน:

ฉันจะกู้คืนข้อมูลในรูปแบบที่ไม่รู้จักจากเทปแม่เหล็กได้อย่างไร

หากเราวัดระยะห่างระหว่างพัลส์แต่ละตัว ปรากฎว่าระยะห่างระหว่างพัลส์ "ยาว" ยังคงอยู่ ~48 ตัวอย่าง และระหว่างพัลส์สั้น – ~24 เมื่อมองไปข้างหน้าเล็กน้อยฉันจะบอกว่าในท้ายที่สุดปรากฎว่าพัลส์ "อ้างอิง" ที่มีความถี่ 918 Hz ติดตามอย่างต่อเนื่องตั้งแต่ต้นจนจบไฟล์ สันนิษฐานได้ว่าเมื่อส่งข้อมูล หากพบพัลส์เพิ่มเติมระหว่างพัลส์อ้างอิง เราจะพิจารณาว่าเป็นบิต 1 มิฉะนั้นจะเป็น 0

แล้วซิงค์พัลส์ล่ะ? ลองดูที่จุดเริ่มต้นของข้อมูล:

ฉันจะกู้คืนข้อมูลในรูปแบบที่ไม่รู้จักจากเทปแม่เหล็กได้อย่างไร

โทนเสียงนำสิ้นสุดและข้อมูลจะเริ่มต้นทันที หลังจากนั้นไม่นาน หลังจากวิเคราะห์การบันทึกเสียงต่างๆ หลายๆ รายการ เราก็สามารถค้นพบว่าไบต์แรกของข้อมูลจะเหมือนกันเสมอ (10100101b, A5h) คอมพิวเตอร์อาจเริ่มอ่านข้อมูลหลังจากได้รับข้อมูลแล้ว

คุณยังสามารถให้ความสนใจกับการเปลี่ยนแปลงของพัลส์อ้างอิงแรกทันทีหลังจากพัลส์ที่ 1 สุดท้ายในซิงค์ไบต์ มันถูกค้นพบในภายหลังในกระบวนการพัฒนาโปรแกรมจดจำข้อมูลเมื่อข้อมูลที่จุดเริ่มต้นของไฟล์ไม่สามารถอ่านได้อย่างเสถียร

ตอนนี้เรามาลองอธิบายอัลกอริทึมที่จะประมวลผลไฟล์เสียงและโหลดข้อมูล

กำลังโหลดข้อมูล

ขั้นแรก มาดูสมมติฐานบางประการเพื่อทำให้อัลกอริทึมเรียบง่าย:

  1. เราจะพิจารณาเฉพาะไฟล์ในรูปแบบ WAV เท่านั้น
  2. ไฟล์เสียงต้องขึ้นต้นด้วยเสียงนำร่องและต้องไม่มีความเงียบที่จุดเริ่มต้น
  3. ไฟล์ต้นฉบับต้องมีอัตราการสุ่มตัวอย่าง 44100 Hz ในกรณีนี้ ระยะห่างระหว่างพัลส์อ้างอิงของตัวอย่าง 48 ตัวอย่างถูกกำหนดไว้แล้ว และเราไม่จำเป็นต้องคำนวณโดยทางโปรแกรม
  4. รูปแบบตัวอย่างอาจเป็นรูปแบบใดก็ได้ (8/16 บิต/จุดลอยตัว) เนื่องจากเมื่ออ่านเราสามารถแปลงเป็นรูปแบบที่ต้องการได้
  5. เราถือว่าไฟล์ต้นฉบับได้รับการทำให้เป็นมาตรฐานตามแอมพลิจูด ซึ่งน่าจะทำให้ผลลัพธ์มีความเสถียร

อัลกอริธึมการอ่านจะเป็นดังนี้:

  1. เราอ่านไฟล์ลงในหน่วยความจำในขณะเดียวกันก็แปลงรูปแบบตัวอย่างเป็น 8 บิต
  2. กำหนดตำแหน่งของพัลส์แรกในข้อมูลเสียง ในการดำเนินการนี้ คุณจะต้องคำนวณจำนวนตัวอย่างด้วยแอมพลิจูดสูงสุด เพื่อความง่าย เราจะคำนวณด้วยตนเองหนึ่งครั้ง มาบันทึกลงในตัวแปร prev_pos;
  3. เพิ่ม 48 ไปที่ตำแหน่งของพัลส์สุดท้าย (pos := prev_pos + 48)
  4. เนื่องจากการเพิ่มตำแหน่ง 48 ไม่ได้รับประกันว่าเราจะไปถึงตำแหน่งของพัลส์อ้างอิงถัดไป (ข้อบกพร่องของเทป การทำงานที่ไม่เสถียรของกลไกเทปไดรฟ์ ฯลฯ) เราจึงต้องปรับตำแหน่งของพัลส์ pos เมื่อต้องการทำเช่นนี้ ให้ใช้ข้อมูลชิ้นเล็กๆ (pos-8;pos+8) และค้นหาค่าแอมพลิจูดสูงสุดจากข้อมูลนั้น ตำแหน่งที่สอดคล้องกับค่าสูงสุดจะถูกจัดเก็บไว้ในตำแหน่ง โดยที่ 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*")

ผล

หลังจากลองใช้อัลกอริธึมและค่าคงที่หลายรูปแบบแล้ว ฉันโชคดีที่ได้รับสิ่งที่น่าสนใจอย่างยิ่ง:

ฉันจะกู้คืนข้อมูลในรูปแบบที่ไม่รู้จักจากเทปแม่เหล็กได้อย่างไร

เมื่อพิจารณาจากสตริงอักขระแล้ว เรามีโปรแกรมสำหรับพล็อตกราฟ อย่างไรก็ตาม ไม่มีคำหลักในข้อความของโปรแกรม คำหลักทั้งหมดถูกเข้ารหัสเป็นไบต์ (แต่ละค่า > 80h) ตอนนี้เราต้องค้นหาว่าคอมพิวเตอร์เครื่องใดในยุค 80 ที่สามารถบันทึกโปรแกรมในรูปแบบนี้ได้

อันที่จริงมันคล้ายกับโปรแกรม BASIC มาก คอมพิวเตอร์ ZX Spectrum จัดเก็บโปรแกรมในรูปแบบเดียวกันโดยประมาณในหน่วยความจำและบันทึกโปรแกรมลงในเทป ในกรณีที่ฉันตรวจสอบคำหลักกับ ตาราง. อย่างไรก็ตาม ผลลัพธ์ที่ได้กลับเป็นลบอย่างเห็นได้ชัด

ฉันยังตรวจสอบคำหลักพื้นฐานของ Atari, Commodore 64 และคอมพิวเตอร์อื่น ๆ ยอดนิยมในเวลานั้นด้วยซึ่งฉันสามารถค้นหาเอกสารได้ แต่ไม่ประสบความสำเร็จ - ความรู้ของฉันเกี่ยวกับคอมพิวเตอร์ย้อนยุคประเภทต่างๆ กลับกลายเป็นว่าไม่กว้างนัก

จากนั้นฉันก็ตัดสินใจไป รายการแล้วฉันก็จ้องมองไปที่ชื่อของผู้ผลิต Radio Shack และคอมพิวเตอร์ TRS-80 นี่คือชื่อที่เขียนไว้บนฉลากเทปที่วางอยู่บนโต๊ะของฉัน! ฉันไม่รู้จักชื่อเหล่านี้มาก่อนและไม่คุ้นเคยกับคอมพิวเตอร์ TRS-80 ดังนั้นสำหรับฉันแล้วดูเหมือนว่า Radio Shack จะเป็นผู้ผลิตเทปเสียงเช่น BASF, Sony หรือ TDK และ TRS-80 เป็นเวลาในการเล่น ทำไมจะไม่ล่ะ?

กระท่อมคอมพิวเตอร์ Tandy/วิทยุ TRS-80

มีโอกาสมากที่การบันทึกเสียงที่เป็นปัญหาซึ่งฉันยกตัวอย่างในตอนต้นของบทความนั้นถูกสร้างขึ้นบนคอมพิวเตอร์ในลักษณะนี้:

ฉันจะกู้คืนข้อมูลในรูปแบบที่ไม่รู้จักจากเทปแม่เหล็กได้อย่างไร

ปรากฎว่าคอมพิวเตอร์เครื่องนี้และรุ่นต่างๆ (รุ่น I/รุ่น III/รุ่น IV ฯลฯ) ได้รับความนิยมอย่างมากในคราวเดียว (แน่นอน ไม่ใช่ในรัสเซีย) เป็นที่น่าสังเกตว่าโปรเซสเซอร์ที่พวกเขาใช้ก็คือ Z80 เช่นกัน สำหรับคอมพิวเตอร์เครื่องนี้ คุณสามารถค้นหาได้บนอินเทอร์เน็ต ข้อมูลมากมาย. ในยุค 80 มีการเผยแพร่ข้อมูลคอมพิวเตอร์ นิตยสาร. ในขณะนี้มีหลายรายการ อีมูเลเตอร์ คอมพิวเตอร์สำหรับแพลตฟอร์มต่างๆ

ฉันดาวน์โหลดโปรแกรมจำลอง trs80gp และเป็นครั้งแรกที่ฉันได้เห็นว่าคอมพิวเตอร์เครื่องนี้ทำงานอย่างไร แน่นอนว่าคอมพิวเตอร์ไม่รองรับเอาต์พุตสี ความละเอียดหน้าจอเพียง 128x48 พิกเซล แต่มีส่วนขยายและการปรับเปลี่ยนมากมายที่สามารถเพิ่มความละเอียดของหน้าจอได้ นอกจากนี้ยังมีตัวเลือกมากมายสำหรับระบบปฏิบัติการสำหรับคอมพิวเตอร์เครื่องนี้และตัวเลือกสำหรับการใช้ภาษา BASIC (ซึ่งต่างจาก ZX Spectrum ในบางรุ่นไม่ได้ "แฟลช" ลงใน ROM ด้วยซ้ำและตัวเลือกใด ๆ ก็สามารถโหลดจากฟล็อปปี้ดิสก์ได้เช่นเดียวกับ ระบบปฏิบัติการนั้นเอง)

ฉันยังพบ ประโยชน์ เพื่อแปลงการบันทึกเสียงเป็นรูปแบบ CAS ซึ่งได้รับการสนับสนุนโดยโปรแกรมจำลอง แต่ด้วยเหตุผลบางอย่างจึงไม่สามารถอ่านการบันทึกจากเทปของฉันโดยใช้สิ่งเหล่านี้ได้

เมื่อทราบรูปแบบไฟล์ CAS (ซึ่งกลายเป็นเพียงสำเนาข้อมูลจากเทปที่ฉันมีอยู่แล้วทีละบิต ยกเว้นส่วนหัวที่มีซิงค์ไบต์) ฉันจึงสร้าง การเปลี่ยนแปลงเล็กน้อยในโปรแกรมของฉันและสามารถส่งออกไฟล์ CAS ที่ใช้งานได้ซึ่งทำงานในโปรแกรมจำลอง (TRS-80 Model III):

ฉันจะกู้คืนข้อมูลในรูปแบบที่ไม่รู้จักจากเทปแม่เหล็กได้อย่างไร

ฉันออกแบบยูทิลิตี้การแปลงเวอร์ชันล่าสุดพร้อมการกำหนดพัลส์แรกโดยอัตโนมัติและระยะห่างระหว่างพัลส์อ้างอิงเป็นแพ็คเกจ GEM ซอร์สโค้ดมีอยู่ที่ Github.

ข้อสรุป

เส้นทางที่เราเดินทางกลับกลายเป็นการเดินทางย้อนอดีตอันน่าหลงใหลและดีใจที่สุดท้ายก็พบคำตอบ เหนือสิ่งอื่นใด ฉัน:

  • ฉันค้นหารูปแบบสำหรับการบันทึกข้อมูลใน ZX Spectrum และศึกษารูทีน ROM ในตัวสำหรับการบันทึก/อ่านข้อมูลจากเทปเสียง
  • ฉันคุ้นเคยกับคอมพิวเตอร์ TRS-80 และรุ่นต่างๆของมันศึกษาระบบปฏิบัติการดูโปรแกรมตัวอย่างและยังมีโอกาสทำการดีบั๊กในรหัสเครื่อง (ท้ายที่สุดแล้วตัวช่วยจำ Z80 ทั้งหมดก็คุ้นเคยกับฉัน)
  • เขียนยูทิลิตี้เต็มรูปแบบสำหรับการแปลงการบันทึกเสียงเป็นรูปแบบ CAS ซึ่งสามารถอ่านข้อมูลที่ยูทิลิตี้ "อย่างเป็นทางการ" ไม่ได้รับการยอมรับ

ที่มา: will.com

เพิ่มความคิดเห็น