ما تعلمته عن آلة Arc Jack الممرات في عملية إنشاء محاكيها
لقد كتبت مؤخرًا محاكيًا صغيرًا لآلة Bomb Jack ، بشكل أساسي لمعرفة كيف اختلفت أول آلات آركيد 8 بت في التصميم عن أجهزة الكمبيوتر المنزلية 8 بت.
كما علمت بعد ذلك بكثير ، كان لقاء في معرض صيفي في مسقط رأسي مع آلات آركيد مثل قنبلة بوم جاك واحدة من تلك اللحظات التي غيرت قدري. في يوم صيفي عادي ، بعد أن أمضيت إمدادي الكامل من العملات المعدنية على آلات الأروقة ، عدت إلى المنزل ، وكان رأسي مليئًا بالزهور والمؤثرات الصوتية. حاولت أن أفهم كيف عملت هذه الألعاب. ثم حتى نهاية العام قضيت كل وقتي بعد المدرسة في إنشاء نسخ باهتة إلى حد ما من ألعاب arcade هذه على جهاز الكمبيوتر في المنزل. كنت مثل مروحة من عبادة البضائع من جزر المحيط الهادئ ، الذين أرادوا إنشاء محطة إذاعة عسكرية أمريكية من العصي.
في البداية فكرت في فكرة إنشاء محاكي
Pengo ، لأن عقلي المراهق كان أكثر إعجابًا بهذه اللعبة من Bomb Jack (بالمناسبة ، هذه هي
نسخة الشحن الخاصة بي
من Pengo ). لكن معدات Pengo arcade تتطلب إنشاء محاكيات شرائح جديدة للصوت والفيديو ، وبالنسبة لـ Bomb Jack كانت هناك أجزاء كافية لدي بالفعل (Z80 كمعالج CPU و AY-3-8910 للصوت) ، لذلك كنت أول من استخدم قنبلة Jack.
بالإضافة إلى ذلك ، كان Bomb Jack فرصة رائعة لإضافة دعم NMI (المقاطعة غير القابلة للإخفاء) أخيرًا إلى محاكي Z80. لم تستخدم أي من الآلات المستندة إلى Z80 التي قمت بمضاهاة NMI سابقًا ، وبالتالي لم يكن هناك الكثير من الفائدة في إعادة إنشاء هذه الوظيفة - ما زلت لا أستطيع التحقق من عملها.
إذا كنت لا تعرف ما هو Bomb Jack ، فستبدو هذه اللعبة على هذا النحو (لست متأكدًا ما إذا اخترت نسبة العرض إلى الارتفاع المناسبة):
يمكن العثور على إصدار المحاكي على WebAssembly هنا:
https://floooh.imtqy.com/tiny8bit/bombjack.htmlبعد اكتمال إجراء التحميل وظهور جدول الدرجات العالية ، اضغط
1 لإسقاط عملة معدنية ، ثم
أدخل (أو أي مفتاح آخر باستثناء الأسهم وشريط المسافة) لبدء اللعبة.
داخل اللعبة ، استخدم
مفاتيح الأسهم لتغيير الاتجاه
ومفتاح المسافة للقفز. أثناء وجودك في الهواء ، اضغط على
مفتاح المسافة لإبطاء السقوط.
كود المصدر هنا:
https://github.com/floooh/chips-test/blob/master/examples/sokol/bombjack.cيستخدم
رؤوس شرائح لتوفير محاكاة لـ Z80 و AY-3-8910 ، بالإضافة إلى
رؤوس sokol كغلاف متعدد المنصات (لإدخال التطبيق والعرض والإدخال والصوت).
الخطوة 1: البحث
كلمة "البحث" كبيرة جدًا: لقد ضربت للتو "مواصفات أجهزة Bombjack arcade للأجهزة" من Google.
مقارنة بأجهزة الكمبيوتر المنزلية الشهيرة في الثمانينيات (أو حتى أجهزة الكمبيوتر الغامضة في أوروبا الشرقية ، والتي لا تزال بها مجتمعات نشطة في الغالب) ، هناك القليل جدًا من المعلومات حول Bomb Jack على الإنترنت.
لقد وجدت معلمتين مهمتين للغاية:
مخطط الدائرة الكهربائية للجهاز ، وبالطبع ،
الكود المصدر لمحاكي MAME .
هناك أيضًا مشروع يقوم بتطبيق
Bomb Jack على FGPA ، من مصادر VHDL التي تمكنت من معرفة التفاصيل التي ليست في مخطط الدائرة.
قد يكون فهم شفرة مصدر MAME أمرًا صعبًا ، لأن محاكيات آلة arcade عادةً ما تكون مجرد مجموعة من وحدات الماكرو التي تصف كيفية تفاعل قطع مختلفة من المعدات ، ولكن لا يوجد الكثير من
التعليمات البرمجية المصدر .
ومع ذلك ، فإن الأوصاف الكلية للمعدات ، وخاصة التعليقات ، لا تزال مفيدة جدًا لفهم تشغيل الأجهزة ، وحيث أصبحت غامضة للغاية (على سبيل المثال ،
الجزء الخاص بفك تشفير الفيديو ) ، كان التجربة والخطأ كافيين ، وكذلك دراسة تفصيلية للمفهوم.
نظرة عامة على الأجهزة
الشيء الأكثر إثارة للاهتمام حول جهاز Bomb Jack هو أنه في الواقع
جهازان متصلان ببعضهما بواسطة شريط كهربائي: هناك
لوحة رئيسية مع Z80 CPU وفك تشفير الفيديو
وبطاقة صوت منفصلة مع Z80 CPU وثلاثة (نعم ، ثلاثة!) رقائق الصوت AY-3-8910.
لا يتم تنفيذ معدات فك تشفير الفيديو كدائرة متكاملة - إنها عبارة عن الكثير من الرقائق للأغراض العامة الصغيرة (تأخذ دائرتها 6 من أصل 10 صفحات من الرسم البياني لدائرة الجهاز). عند إنشاء محاكي ، قررت أن أقطع مسافة قصيرة: بدلاً من محاكاة الأجزاء الفردية من معدات فك تشفير الفيديو ، قمت بمحاكاة سلوكها فقط ، وإنشاء المخرجات المقابلة من بيانات الإدخال ولا تقلق حقًا حول كيفية عمل المعدات في الوسط.
مثل هذا الحل المبسط مناسب تمامًا لآلة arcade منفصلة ، والتي تم تصميمها لتشغيل برنامج واحد فقط. إذا بدأت اللعبة وعملت بشكل صحيح ، فيمكن اعتبار المحاكاة "جيدة بما يكفي".
بالإضافة إلى ذلك ، يعد هذا النهج المبسط اختلافًا مهمًا عن محاكاة معظم أجهزة الكمبيوتر المنزلية: تتطلب بعض الألعاب مضاهاة أكثر دقة من غيرها ، على سبيل المثال ، تحتاج آلات مثل C64 أو Amstrad CPC إلى محاكاة دقيقة جدًا حتى دورات الساعة ، بحيث أنظمة الفيديو لبعض الألعاب والرسوم البيانية عملت العروض التوضيحية بشكل صحيح.
وهذا يعني أيضًا أن محاكيات وحدة المعالجة المركزية وشرائح الصوت الجاهزة الخاصة بي هي في الواقع عمل غير ضروري لـ Bomb Jack ، على سبيل المثال ، العمل مع وحدات المعالجة المركزية Z80 مع تطبيق كسور دورة الآلة هو مبالغة ، والتجزئة الأبسط والأسرع على مستوى التعليمات كافية.
اللوحة الرئيسية
عادة ما يكون أول شيء أحاول اكتشافه عند كتابة محاكي جديد هو نظام تخصيص الذاكرة (حيث توجد مناطق ROM وذاكرة الوصول العشوائي ، وذاكرة الفيديو والعناوين الخاصة أو منافذ الإدخال / الإخراج).
لا يوجد سوى شريحة واحدة "مثيرة للاهتمام" على اللوحة الرئيسية Bomb Jack - Z80 CPU تعمل بسرعة 4 ميجاهرتز. كل المساحة المتبقية على اللوحة الرئيسية مشغولة بمعدات فك تشفير الفيديو (باستثناء زوج من رقائق ذاكرة الوصول العشوائي ورقاقات ROM).
مساحة العنوان 16 بت هي كما يلي:
- 0000..7FFF : ROM 32 كيلوبايت
- 8000..8FFF : 4 كيلو بايت من ذاكرة الوصول العشوائي للأغراض العامة
- 9000..93FF : 1 كيلو بايت من ذاكرة الفيديو
- 9400..97FF : 1 كيلوبايت من ذاكرة الوصول العشوائي
- 9820..987F : 96 بايت من ذاكرة الوصول العشوائي
- 9C00..9CFF : 256 بايت من لوحة ألوان ذاكرة الوصول العشوائي
- 9E00 ، B000..B005 ، B800 : منافذ الإدخال والإخراج
- C000..DFFF : 8KB ROM
منطقة منفذ الإدخال / الإخراج كما يلي. بعض المنافذ هي للكتابة فقط ، وبعضها للقراءة فقط ، وبعضها له وظائف مختلفة عند القراءة والكتابة إليها:
- 9E00 : اكتب: رقم صورة الخلفية الحالي ، اقرأ: -
- B000 : قراءة: حالة جويستيك المشغل 1 ، كتابة: تمكين / تعطيل قناع NMI
- B001 : قراءة: حالة جويستيك اللاعب 2 ، كتابة: -
- B002 : قراءة: العملات المعدنية وأزرار البدء ، والكتابة: -
- B003 : قراءة: مراقبة وحدة المعالجة المركزية ، الكتابة: ؟؟؟
- B004 : قراءة: مفاتيح التبديل dip 1 ، الكتابة: شاشة التبديل
- B005 : قراءة: مفاتيح dip 2 ، كتابة: -
- B800 : الكتابة: بطاقة صوت الأمر ، قراءة: -
تجدر الإشارة هنا إلى ما يلي:
- يحتوي الجهاز على عدد كبير من ROM (40 كيلوبايت) ، وقليل جدًا من ذاكرة الوصول العشوائي (حوالي 7 كيلوبايت ، و 4 كيلوبايت فقط منها هي "ذاكرة الوصول العشوائي للأغراض العامة")
- يتم تخصيص 2 كيلوبايت فقط لذاكرة الوصول العشوائي الخاصة بالشاشة ، مقسمة إلى جزأين من 1 كيلوبايت ، والتي تبدو صغيرة جدًا لعرض 256 × 256 بالألوان الكاملة ، حيث يبدو أنه يتم تعيين الألوان بكسل تلو بكسل
- هذا هو نظام I / O في مخطط تخصيص الذاكرة!
يعد الإدخال / الإخراج في نظام تخصيص الذاكرة أمرًا غير معتاد بالنسبة لجهاز Z80 ، لأن إحدى السمات المميزة لـ Z80 هي مساحة العنوان المنفصلة ذات 16 بت لـ I / O. يتم ذلك لتوفير مساحة عنوان الذاكرة القيمة. عادةً ما يتم العثور على الإدخال / الإخراج في نظام تخصيص الذاكرة في أجهزة الكمبيوتر التي تحتوي على معالج 6502.
تؤكد نظرة على مخطط الدائرة ما يلي: لم يتم الكشف عن دبوس IORQ على وحدة المعالجة المركزية للوحة الرئيسية ، فقط موصل MREQ متصل (والذي يستخدم لتهيئة القراءة أو الكتابة إلى الذاكرة):
هذا يعني أنه لا داعي للقلق بشأن طلبات الإدخال / الإخراج لوظيفة مؤقت وحدة المعالجة المركزية للوحة الرئيسية في المحاكي ، ولكننا نتعامل فقط مع طلبات الذاكرة.
بعد دراسة مخطط الدائرة ، وجدت تفاصيل أخرى مثيرة للاهتمام حول وحدة المعالجة المركزية للوحة الرئيسية:
يتم توصيل دبوس NMI فقط ، بينما يحتفظ دبوس INT دائمًا بمستوى عالٍ من إشارة الساعة / يظل غير نشط (وهذا يعني أن المقاطعات المقنعة "المعتادة" لا يتم تنفيذها ، ولا تحدث سوى المقاطعات غير المقنعة):
هذا أمر غير معتاد أيضًا بالنسبة لسيارة مع Z80. في جميع أجهزة الكمبيوتر المنزلية القائمة على Z80 التي كنت أتعامل معها ، كان العكس صحيحًا - فقد استخدموا المقاطعات القابلة للإخفاء فقط ولم يستخدموا الأجهزة غير القابلة للإخفاء مطلقًا. المقاطعة المقنعة Z80 هي تحسن مرن وخطير للغاية مقارنة بنظام المقاطعة البدائي لـ "والده غير الشرعي" - Intel 8080 ، أو منافسه - MOS 6502. ولكن هذه المرونة المتزايدة أكثر صعوبة في التنفيذ في المعدات (إلا كمصدر للمقاطعات يتم استخدام رقائق أخرى من عائلة Z80 ، حيث يوجد بالفعل بروتوكول مقاطعة معقد مدمج عند توصيله بالحافلة).
حسنًا ، ما يكفي من التفاصيل حول المعدات ، دعنا ننتقل إلى المحاكي!
إجراء التمهيد
الخطوة التالية بعد تحديد تكوين الذاكرة هي توصيل وحدة المعالجة المركزية التي تمت مضاهاتها بنظام تخصيص الذاكرة التي تمت مضاهاتها ، وتسجيل نوع من التصور لمحتويات ذاكرة الفيديو ، وبدء دورات وحدة المعالجة المركزية.
والمثير للدهشة أن مثل هذا النهج التقريبي غالبًا ما يكون كافيًا لمتابعة إجراءات التحميل وعرض
شيء على الشاشة. عند تصميم محاكي Bomb Jack ، أخذت فقط محتويات ذاكرة الفيديو 1KB في النطاق من 0x9000 إلى 0x93FF كمصفوفة 32 × 32 بايت. عندما كان البايت صفرًا ، عرضت كتلة من وحدات البكسل السوداء 8 × 8 ، وخلاف ذلك - كتلة من وحدات البكسل البيضاء.
ثم قمت بتشغيل وحدة المعالجة المركزية التي تمت محاكاتها وأتمنى الأفضل. ها! ظهر نوع من الصورة الواضحة:
تبدو الصورة العلوية مثل شاشة اختبار الأجهزة عند التمهيد ، ويبدو الجزء السفلي وكأنه شاشة تسجيل درجات تظهر بعد اكتمال إجراء التمهيد:
... لكن استدار 90 درجة (وهو أمر منطقي ، لأن شاشة آلات الألعاب كانت غالبًا في اتجاه "عمودي" عمودي).
عظيم ، البداية واعدة!
الخطوة التالية هي معرفة كيفية تحويل هذه الكتل البيضاء إلى وحدات بكسل ملونة ... (وهذه خطوة ضخمة ، يتم وصف التفاصيل أدناه في القسم الخاص بفك تشفير الفيديو).
في البداية ، سار كل شيء بسرعة كبيرة ، على شاشة الاختبار ، تم عرض وحدات البكسل والألوان أثناء التحميل (لاحقًا لاحظت أن فك تشفير الألوان كان خاطئًا تمامًا ، ومع ذلك ...):
ولكن عندما ظهرت شاشة التسجيل ، حصلت على شاشة سوداء. عند اختراق لون الخلفية بحيث تكون "ليست سوداء" ، اكتشفت أن وحدات البكسل يتم تقديمها ، ولكن لوحة الألوان بأكملها سوداء. همم ...
بعد النظر إلى هذه الشاشة لبضع دقائق ، تذكرت أن بعض الألوان على الشاشة ذات النقاط العالية هي رسوم متحركة ، وعندما يكون هناك رسوم متحركة ، يجب أن يكون هناك نوع من المؤقت. المصدر المنطقي للوقت في تكوين هذا الجهاز هو إشارة عرض VSYNC ، ويتم توصيل VSYNC بدبوس NMI لوحدة المعالجة المركزية (أو بالأحرى ليس VSYNC ، ولكن VBLANK ، وهي اللحظة الوجيزة بين إشارة VSYNC وشعاع شعاع الكاثود يتحرك إلى الزاوية اليسرى العليا).
ولم أقم بعد بتنفيذ كل هذا ...
في الليلة التالية ، عندما أضفت الإصدار الأول من معالجة NMI إلى مضاهاة Z80 وقمت بتوصيلها بالعداد الأول vsync / v blank في وظيفة مؤقت وحدة المعالجة المركزية للوحة الرئيسية ، بدأت الكثير من الأشياء فجأة تحدث!
أولاً ، ظهرت الألوان على شاشة التسجيلات ، وكان بعضها متحركًا:
بعد بضع ثوان ، بدأ شيء أكثر إثارة! اختفى أعلى الدرجات وعرض تصور غريب للخريطة الأولى. كان من الواضح أن هذا هو وضع تجريبي لآلة آركيد لجذب الانتباه - رأيت العديد من القنابل مع الرسوم المتحركة الملونة التي اختفت عندما قفزت قنبلة جاك وهمية على خريطة تجمع هذه القنابل:
كانت الألوان لا تزال خاطئة تمامًا ، ومع ذلك فهي تقدم!
إنه الوقت المناسب للقيام ببقية فك تشفير الفيديو:
حديد فيديو
للوهلة الأولى ، بدت معدات معالجة الفيديو في Bomb Jack قوية جدًا لجهاز 8 بت من عام 1984: على الرغم من دقة 256 × 256 بكسل فقط ، يمكنها عرض 128 لونًا (من 4096) في نفس الوقت ، وتقديم ما يصل إلى 24 نقشًا (16x16 في الحجم) أو 32 × 32) مع لون بكسل بكسل.
كانت أجهزة الكمبيوتر المنزلية ذات 8 بت في ذلك الوقت تقريبًا بنفس دقة العرض ، ولكن كانت لديها العديد من قيود الألوان. هذه القيود واضحة للغاية عند مقارنة إصدارات Bomb Jack لـ ZX Spectrum و Amstrad CPC مع إصدار آلة arcade:
كان
إصدار ZX Spectrum بدقة بكسل جيدة (256x192) ، ولكن ألوان قليلة جدًا ، وعانى من تأثير "تعارض الألوان" النموذجي لـ Spectrum (على الرغم من أن المطورين بذلوا قصارى جهدهم لجعل هذا غير ملحوظ):
إصدار Amstrad CPC هو أكثر ألوانًا كاملة ، ولكن من أجل الحصول على المزيد من الألوان ، كان على المطورين التبديل إلى وضع العرض منخفض الدقة (160x200). ونتيجة لذلك ، تحول جاك والوحوش إلى مجموعة غير مقروءة من البكسل:
قارن ذلك بإصدار جهاز arcade ، الذي كان له نفس دقة البكسل مثل ZX Spectrum ، ولكن مع المزيد من الألوان وزيادة دقة الألوان لكل بكسل:
المثير للاهتمام هنا هو أن إصدار الممرات يحتوي على رسومات أفضل ، ليس لأنه يعمل على أجهزة أكثر قوة (لديه المزيد من ROMs لتخزين المزيد من البيانات الرسومية ، ولكن "قوة الحوسبة" هي نفسها تقريبًا) ، ولكن لأن مطوري الجهاز يمكنهم التركيز حول تصنيع آلة متخصصة لنوع معين من الألعاب ولم يكونوا بحاجة إلى إنشاء كمبيوتر منزلي عالمي للاستخدام العام.
إليك كيفية عمل أجهزة العرض (على الأقل في التفسير عالي المستوى):
ثلاث طبقات للعرض
يتم دمج إشارة فيديو Bomb Jack النهائية من ثلاث طبقات: طبقة خلفية وطبقة أمامية وطبقة نقش متحرك.
لنظام الطبقات هذا ميزتان رئيسيتان:
- إنها تنفذ ضغطًا صعبًا جدًا للأجهزة لتوليد صورة كاملة الألوان ذات "دقة عالية" من كمية صغيرة جدًا من البيانات.
- إنه يقلل بشكل كبير من كمية عمل وحدة المعالجة المركزية اللازمة لتحديث عناصر الشاشة الديناميكية (حتى عند تردد 4 ميجاهرتز ، لا تحتوي وحدة المعالجة المركزية 8 بت على طاقة كافية لتحريك العديد من الكائنات على شاشة 256 × 256 بتردد 60 هرتز)
يختلف مكواة الفيديو تمامًا عما رأيته في أجهزة الكمبيوتر المنزلية ذات 8 بت ، ولكن في الفصول المساعدة المعممة لـ MAME لهذا النوع من المعدات يتم تنفيذها ، لذلك يمكنني أن أفترض أنها شائعة جدًا في آلات الألعاب.
طبقة الخلفية
يمكن لطبقة الخلفية تقديم صورة واحدة من أصل 5 صور خلفية مدمجة في ROM. يتم تحديد صورة الخلفية عن طريق كتابة قيمة من 1 إلى 5 على العنوان 0x9E00 (يبدو أن القيمة 0 خاصة وتعرض خلفية سوداء بالكامل).
في الواقع ، يبدو أن الجهاز قادر على عرض 7 صور مختلفة ، ولكن يتم استخدام 5 فقط في اللعبة. سراً ، كنت آمل في العثور على بيانات صورة لم يتم اكتشافها سابقًا في ROM. لكن للأسف ، ليسوا هناك (نعم ، ربما لست أول من يبحث عنها هناك).
إليك ما ستبدو عليه طبقة الخلفية للخريطة الأولى بدون الطبقتين الأخريين:
يتم تجميع طبقة الخلفية من بلاطات
16x16 بكسل.
ميزة بناء صور الخلفية من المربعات هي أنه يمكن استخدام نفس المربعات عدة مرات ، لذلك يمكن تخزين بيانات أقل في ROM. لاحظ أن السماء الزرقاء وأجزاء من الهرم والرمل تحت الهرم تستخدم نفس البلاط:
لتوفير الذاكرة ، تطبق معدات طبقة الخلفية حيلة أخرى - يمكن تدوير البلاط أفقيًا. لقد فاتني هذا تقريبًا في عملية التنفيذ لأنني افترضت أن البرنامج لا يستخدم وظيفة الأجهزة هذه ، لكنني لاحظت وجود خطأ صغير في خلفية البطاقة الثالثة:
لقد استخدمت الخدعة نفسها على الخريطة الخامسة ، ولكن هنا من الصعب قليلاً ملاحظة ما إذا كنت لا تعرف ما الذي تبحث عنه:
الطبقة الأمامية:
فوق طبقة الخلفية توجد "الطبقة الأمامية" ، التي تعرض جميع الأجزاء الثابتة من الشاشة ، والتي يجب مع ذلك تحديثها بواسطة وحدة المعالجة المركزية (في الغالب النص والمنصات والقنابل). تتم قراءة التخطيط من ذاكرة الوصول العشوائي (RAM) (من أجزاء من ذاكرة الوصول العشوائي سعة 1 كيلوبايت وذاكرة وصول عشوائي سعة 1 كيلوبايت).
إليك ما تبدو عليه الطبقة الأمامية المعزولة للخريطة الأولى:
تتكون الطبقة الأمامية أيضًا من البلاط (بالإضافة إلى الخلفية) ، ولكنها تستخدم مربعات أصغر 8 × 8:
الميزة الرئيسية لتقسيم الخلفية والأمام إلى طبقات منفصلة هي أن وحدة المعالجة المركزية لا داعي للقلق بشأن تخزين واستعادة وحدات بكسل الخلفية عند إنشاء أو حذف العناصر الأمامية.
طبقة العفريت
أخيرًا ، يتم تقديم نقوش الأجهزة فوق الطبقة الأمامية. يتم تنفيذ كل شيء يتحرك حول الشاشة في العفاريت. يمكن أن تقدم معدات Bomb Jack ما يصل إلى 24 نقشًا ، ويمكن أن يكون لكل نقش متحرك حجم 16x16 أو 32x32 بكسل. في هذه الحالة ، يمكن وضع العفاريت بدقة بكسل تلو بكسل:
8x8 فك البلاط
يوجد في قلب جهاز فك تشفير الفيديو لوحة ألوان تحتوي على 128 عنصرًا وجهاز فك ترميز البلاط 8 × 8 بكسل. تتمثل مهمة وحدة فك ترميز البلاط في إنشاء فهرس لوح ألوان 7 بت لكل من وحدات البكسل 64 للبلاط.
هذه المربعات 8x8 هي اللبنات الأساسية لكل شيء على الشاشة - مربعات خلفية 16x16 ، ومربعات 8x8 للطبقة الأمامية و 16x16 أو 32x32 للأجهزة.فيما يلي رسم تخطيطي لمفكك ترميز البلاط 8 × 8 لتقديم الطبقة الأمامية (كما فهمتها):شرح مخطط الكتلة من أعلى لأسفل:- تبدأ عملية فك التشفير في الأعلى من خلال قراءة بايت "كود التجانب" من ذاكرة الفيديو (منظم كمصفوفة لرموز تجانب 32 × 32) و بايت منفصل عن ذاكرة الوصول العشوائي الملونة (أيضًا مصفوفة 32 × 32). يحدث الحصول على رموز المربعات والألوان من ذاكرة الفيديو للطبقة الأمامية فقط ، لكني أضفتها لجعل الصورة ككل أكثر قابلية للفهم. تتطلب وحدة فك ترميز البلاط 8 × 8 نفسها رمزًا للبلاط ولون عند الإدخال.
- . ( ). , , ( ).
- 8 , 8 ( ). , , 8x8 24 (3 ).
- 64 7- . 3 , 4 — . , , 16 «», 8 . 8 .
- 7- , , 12- RGB- (4 ). ( , , ; , ).
هذا هو مخطط عام لفك ترميز البلاط يتم استخدامه من قبل كل من طبقات العرض الثلاث ، ولكن يختلف فك تشفير كل طبقة قليلاً:- يمكن للطبقة الأمامية تقديم 512 بلاط 8x8 مختلف. يتطلب ذلك رموز تجانب 9 بت ، ولكن ذاكرة الفيديو توفر 8 بت فقط لكل تجانب. يتم "استعارة" البت التاسع من البت الخامس من قيمة اللون (حيث يتم استخدام 4 بتات فقط من قيمة اللون لإنشاء فهرس لوحة الألوان ، وتبقى 4 بتات أخرى لأغراض أخرى). إذا كانت كل البتات الثلاث من طبقات بتات البلاط 8 × 8 مساوية للصفر ، فإن البكسل الأمامي يعتبر شفافًا ، وتتألق بيكسل الخلفية من خلاله.
- 16x16, 16x16=256 256 (512 ). , 16x16 8x8, . , ; «» : 7 , .
- 16x16 32x32 , 4 16 8x8 . , 16x16 96 , 32x32 — 384 . , 3 , .
لفهم كيفية ظهور طبقات بت التجانب بشكل أفضل ، كتبت برنامج C صغير يحول تجانبات ROM إلى ملفات PNG (3 بت لكل بكسل تم تحويلها إلى 8 مستويات درجات رمادية).يوضح ما يلي بلاط ROM للطبقة الأمامية. نرى بيانات الأرقام وخط النص ، ومربعات المنصات ، والقنابل (مقسمة إلى نصفين) ، وأجزاء من الشعار من شاشة التوقف Bomb Jack ، وعدد نقاط المضاعف التي تظهر في أعلى الشاشة (بالمناسبة ، يتم تدوير كل شيء 90 درجة ، لأن الشاشة بأكملها يتم تدويرها أيضًا ):بعد ذلك ، ضع في اعتبارك مربعات ROM للخلفية. لا يبدو الأمر واضحًا جدًا ، لأن ما نلاحظه هو في الواقع فك تشفير 16x16 للبلاط إلى 8x8 للبلاط. يتم إنشاء كل بلاطة 16x16 من أربعة بلاطات 8x8 متجاورة. ولكن يمكنك التعرف على أجزاء من المعبد اليوناني من الخريطة 2 والقلعة من الخريطة 3 وناطحات السحاب من الخريطة 4.وأخيرًا ، ROM sprite البلاط. تحتل العفاريت 16x16 النصف العلوي ، وتحتل العفاريت 16x32 النصف السفلي.من الاختراق المثير للاهتمام في شاشة توقف Bomb Jack هو أن الشعار يتم تجميعه من البلاط الأمامي والعفاريت. أعتقد أن المطورين كانوا ينفدون من ذاكرة القراءة فقط للبلاط ، ولكن لم يكن هناك سوى مساحة صغيرة متبقية في ذاكرة الوصول العشوائي:معدات سبرايت
تعد معدات Bomb Jack sprite قوية جدًا مقارنة بما تم استخدامه في أجهزة الكمبيوتر المنزلية في ذلك الوقت:- يمكن أن يعرض ما يصل إلى 24 نقوشًا للأجهزة. يبدو أنه لم تكن هناك قيود على عدد العفاريت لكل خط مسح.
- يمكن أن يكون حجم Sprites 16 × 16 بكسل أو 32 × 32 بكسل
- يمكن لكل نقش متحرك اختيار واحد من 16 فتحة من 8 ألوان في لوحة الألوان الشائعة
- كان Sprites بدقة ألوان بكسل لكل بكسل.
- يمكن قلب كل نقش متحرك رأسيًا أو أفقيًا
- يمكن لكل نقش متحرك اختيار واحد من 128 صورة متحولة تومض في ROM.
عند فك تشفير وحدات البكسل والعفاريت الخاصة بنظام العفريت ، يتم استخدام نفس البلاط الأساسي 8x8 كما هو الحال في الخلفية والطبقات الأمامية.يتم وضع سمات العفريت في نطاق العنوان من 0x9820 إلى 0x987F - 96 بايت ، 4 بايت لكل نقش متحرك. بقدر ما رأيت ، هذه المنطقة للتسجيل فقط ؛ على الأقل لا تقوم وحدة المعالجة المركزية بالوصول للقراءة إلى نطاق الذاكرة هذا.يتم وصف كل نقش متحرك بـ 4 بايت:- بايت 0 :
- بت 7 : إذا تم تعيينه ، فإن هذا هو sprite 32x32 ، وإلا 16x16
- Bits 6..0 : 7 بتات لتعيين رمز تجانب الرموز المتحركة المستخدمة للبحث عن طبقات بت من صورة النقش المتحرك في مربعات ROM.
- البايت 1 :
- بت 7 : إذا تم ضبطه ، يتم قلب العفريت أفقياً
- بت 6 : إذا تم ضبطه ، يتم قلب العفريت عموديًا
- Bits 3..0 : 4 بتات لتحديد قيمة اللون لفك شفرة التجانب
- البايت 2 : موضع sprite على المحور X على الشاشة
- البايتة 3 : موضع العفريت على الشاشة على طول المحور ص
ليس من الواضح ما تفعله البتتان 4 و 5 من البايت 1 ، يقول التعليق في MAME هذا:
e ? (, )
f ? (, (B)?)
منافذ الإدخال / الإخراج للذاكرة
بعض الملاحظات حول منافذ الإدخال / الإخراج للوحة الرئيسية. كما هو مذكور أعلاه ، تبدو منافذ الإدخال / الإخراج كما يلي:
- 9E00 : اكتب: رقم صورة الخلفية الحالي ، اقرأ: -
- B000 : قراءة: حالة جويستيك المشغل 1 ، كتابة: تمكين / تعطيل قناع NMI
- B001 : قراءة: حالة جويستيك اللاعب 2 ، كتابة: -
- B002 : قراءة: العملات المعدنية وأزرار البدء ، والكتابة: -
- B003 : قراءة: مراقبة وحدة المعالجة المركزية ، الكتابة: ؟؟؟
- B004 : قراءة: مفاتيح التبديل dip 1 ، الكتابة: شاشة التبديل
- B005 : قراءة: مفاتيح dip 2 ، كتابة: -
- B800 : الكتابة: بطاقة صوت الأمر ، قراءة: -
العنوان 0x9E00 (اختيار صورة الخلفية) الذي ذكرناه سابقًا ، والعنوان 0xB800 (بطاقة صوت الأمر) الذي سننظر فيه في القسم التالي. يبقى العناوين من 0xB000 إلى 0xB005:
تؤدي القراءة من العنوانين 0xB000 و 0xB001 إلى إرجاع الحالة الحالية لعصي التحكم. تشير وحدات البايت المعينة إلى مفاتيح عصا التحكم المغلقة:
- بت 0 : الاتجاه الصحيح
- بت 1 : الاتجاه الأيسر
- بت 2 : الاتجاه الصاعد
- بت 3 : الاتجاه لأسفل
- بت 4 : الضغط على زر القفز
يتم تجاهل 3 بت المتبقية.
تؤدي القراءة من 0xB002 إلى إرجاع حالة متقبل العملة وأزرار البدء:
- بت 0 : ألقيت عملة اللاعب 1
- بت 1 : رمى عملة اللاعب 2
- بت 2 : زر تشغيل اللاعب 1
- بت 3 : زر تشغيل اللاعب 2
القراءة من العنوانين 0xB004 و 0xB005 تُرجع حالة مفاتيح dip المستخدمة لتكوين سلوك جهاز arcade:
- B004 :
- البتات 0،1 : عدد "الألعاب" المعطاة لعملة واحدة (1 أو 2 أو 3 أو 5)
- بت 2،3 : نفس اللاعب 2
- bits 4،5 : عدد الأرواح في اللعبة (3 أو 4 أو 5 أو 2)
- bit 6 : موقع آلة الأروقة: "طاولة كوكتيل" أو "عمودي".
- بت 7 : سواء لتشغيل الصوت في وضع الاستعداد
- B005 :
- بت 3.4 : صعوبة 1 (سرعة الطيور)
- البتات 5،6 : صعوبة 2 (عدد الأعداء وسرعتهم)
- bit 7 : تكرار حدوث عملة معينة
أخيرًا ، القراءة من العنوان
B003 تنفذ مراقبة البرامج. يجب أن تقرأ وحدة المعالجة المركزية في كثير من الأحيان من هذا العنوان ، وإلا سيقوم جهاز arcade بإعادة ضبط الأجهزة. إذا تعطلت اللعبة لسبب ما ، فسيتم إعادة تشغيل الجهاز تلقائيًا.
يمكنك الكتابة إلى بعض عناوين منافذ الإدخال / الإخراج:
- B000 : ما إذا كان سيتم إنشاء NMI أثناء الفراغ ؛ يبدو أنه تم تعطيله فقط أثناء إجراء التمهيد
- B004 : قلب الشاشة بالكامل ؛ لم أقابل مطلقًا استخدام هذه الوظيفة ، لكن لدي نظرية حولها (انظر أدناه)
إن وظيفة تقليب الشاشة مربكة بعض الشيء ، لأنه عندما ألعب لعبة ، لم أر استخدامها. ومع ذلك ، لدي حدس حول ما يفعله ، ولكن من أجل تأكيد ذلك ، تحتاج إلى كتابة التعليمات البرمجية. عندما تكون آلة الممرات في تكوين "طاولة الكوكتيل" ، يجلس لاعبان مقابل بعضهما البعض. لذلك ، اقترحت أنه عندما تنتقل اللعبة من اللاعب 1 إلى اللاعب 2 ، فإن هذه الوظيفة تقلب الشاشة. ومع ذلك ، لم أقم بعد بتطبيق وضع اللاعبين في المحاكي.
لوحة الصوت
بطاقة الصوت نفسها هي كمبيوتر كامل الميزات مع وحدة معالجة مركزية Z80 (تعمل بتردد 3 ميجاهرتز) ، وثلاث شرائح صوت (AY-38910 تعمل بتردد 1.5 ميجاهرتز) ، بالإضافة إلى ذاكرة الوصول العشوائي وذاكرة القراءة فقط. يبدو مخطط تخصيص ذاكرة بطاقة الصوت بسيطًا جدًا:
- 0000..2000 : 8 كيلوبايت من ROM
- 4000..4400 : 1 كيلو بايت من ذاكرة الوصول العشوائي
- 6000 : أمر صوتي من اللوحة الرئيسية
نظرًا لعدم وجود أي شيء مثير للاهتمام في نظام تخصيص الذاكرة فوق عنوان 0x8000 ، فإن اتصال العنوان الأعلى لوحدة المعالجة المركزية غير متصل حتى:
العنوان الخاص 0x6000 هو منفذ الإدخال / الإخراج (مزلاج 8 بت) الموجود في الذاكرة ، والذي لا يتوافق مع ذاكرة الوصول العشوائي الحقيقية. هذا هو نفس المنفذ الموجود على اللوحة الرئيسية في 0xB800. إنها قناة اتصال بين بطاقات الصوت الرئيسية.
يتم التحكم في شرائح الصوت الثلاثة من خلال تعليمات الإخراج Z80 هذه ، وليس من خلال منافذ الذاكرة. يحتوي AY-3-8910 على منفذي I / O فقط مفتوحين ، يستخدم الأول لتخزين رقم التسجيل ، والثاني يستخدم لكتابة أو قراءة محتويات السجل المحددة بواسطة المنفذ الأول.
دائرة الإدخال / الإخراج هي كما يلي:
- 0x00 : شريحة الصوت الأولى: اختيار التسجيل
- 0x01 : شريحة الصوت الأولى: الوصول إلى التسجيل المحدد
- 0x10 : شريحة الصوت الثانية: اختيار التسجيل
- 0x11 : شريحة الصوت الثانية: الوصول إلى التسجيل المحدد
- 0x80 : رقاقة الصوت الثالثة: اختيار التسجيل
- 0x81 : شريحة الصوت الثالثة: الوصول إلى التسجيل المحدد
بضع كلمات حول شريحة الصوت AY-3-8910:
هذا جهاز قياسي إلى حد ما ، وهو شائع جدًا في أجهزة الكمبيوتر المنزلية في ذلك الوقت (على سبيل المثال ، في Amstrad CPC و ZX Spectrum 128 وفي أجهزة الكمبيوتر MSX وغيرها). أنتجت AY-3-8910 العديد من الاختلافات والاستنساخ (على سبيل المثال ، Yamaha YM2149 ، الذي أصبح في حد ذاته أساسًا لمجموعة كاملة من شرائح الصوت الأكثر قوة).
تحتوي AY-3-8910 على 3 قنوات للإشارات المستطيلة ، ومولد ضوضاء واحد يمكن مزجه مع ثلاث قنوات ، ومولد غلاف واحد. نظرًا لوجود مولد مغلف واحد فقط للقنوات الثلاث ، لم يكن مفيدًا بشكل خاص ، واستخدمت معظم الألعاب وحدة معالجة مركزية لتعديل النغمة والحجم.
هذا يعني أن شريحة AY-3-8910 تتطلب المزيد من تدخل وحدة المعالجة المركزية لإنشاء صوت عالي الجودة (على عكس المزيد من شرائح SID المستقلة ، على سبيل المثال ، في كمبيوتر C64).
من المدهش أن نرى ما يمكن القيام به على ثلاث شرائح صوت بسيطة إلى حد ما ووحدة المعالجة المركزية التي تتحكم بها. الموسيقى والتأثيرات الصوتية لـ Bomb Jack أكثر ثراءً مما سمعته في معظم ألعاب الكمبيوتر المنزلية.
الشيء الوحيد المثير للاهتمام حقًا في بطاقة الصوت هذه هو الطريقة التي تتلقى بها أوامرها من اللوحة الرئيسية.
مزلاج الأوامر الصوتية
"مزلاج الصوت" هو وحدة تخزين أحادية البايت (مزلاج 8 بت) شائعة للبطاقات الرئيسية وبطاقات الصوت. يرتبط المزلاج بالعنوان 0xB800 على اللوحة الرئيسية والعنوان 0x6000 على بطاقة الصوت.
عند تشغيل مقاطعة NMI باستخدام VSYNC ، تقوم بطاقة الصوت بإجراء روتين خدمة مقاطعة بسيط للغاية ، والذي يقرأ مزلاج الأجهزة ، ويكتبه على عنوان الذاكرة العادية ويضبط "بت الإشارة" ، الذي يخبر "الحلقة الرئيسية" التي تم استلام أمر صوت جديد فيها:
ex af,af' ;0066 exx ;0067 ld hl,04390h ;0068 set 0,(hl) ;006b ld a,(06000h) ;006d ld (04391h),a ;0070 exx ;0073 ex af,af' ;0074 retn ;0075
تختلف طريقة تنشيط الاتصال NMI قليلاً عن طريقة اللوحة الرئيسية:
على اللوحة الرئيسية ، يصبح دبوس NMI نشطًا طوال فترة تشغيل VBLANK.
ومع ذلك ، على بطاقة الصوت ، يتم تنشيط NMI عند تشغيل VSYNC ، ويظل نشطًا ليس أثناء VBLANK ، ولكن حتى يقرأ إجراء خدمة المقاطعة البيانات من المزلاج عند 0x6000.
عندما يتعرف الجهاز على القراءة من العنوان 0x6000 ، فإنه ينفذ عمليتين مشفرتين:
- إعادة تعيين محتويات مقطع الصوت إلى 0
- يصبح اتصال NMI غير نشط
في الواقع ، هذا هو التخلص البسيط من ارتداد الاتصال ، والذي لا يسمح بتنفيذ أمر صوتي واحد مرتين.
يبقى السؤال الوحيد: كم مرة يكتب المجلس الرئيسي أمرًا جديدًا (لأن طريقة تنفيذ مضاهاة لوحين تعتمد على ذلك).
بعد تصحيح الأخطاء باستخدام printf ، وجدت أن اللوحة الرئيسية تسجل أمر صوت واحد على الأكثر لكل إطار 60 هرتز. هذا يبسط إلى حد كبير هيكل "الدورة الرئيسية" للمحاكي.
مشكلة العمل المشترك بين جهازي كمبيوتر تمت محاكتهما بشكل منفصل ويجب عليهما تبادل البيانات مع بعضهما البعض هو أن محاكاة جهاز كمبيوتر واحد لا تكون فعالة إلا إذا كان بإمكانه أداء العديد من الدورات في وقت واحد دون تدخل.
على سبيل المثال ، ستكون أسوأ حالة:
- نقوم بتنفيذ تعليمات واحدة في الكمبيوتر 1
- نقوم بتنفيذ تعليمات واحدة في الكمبيوتر 2
- كرر ...
لم يتم تحسين محاكي Z80 للخروج وإدخال المضاهاة لكل تعليمة ، لأنه في هذه الحالة يجب أن يتدفق في الذاكرة ويحمل حالة وحدة المعالجة المركزية في بداية ونهاية كل تعليمة. إذا كان بإمكان وحدة المعالجة المركزية معالجة العديد من الإرشادات دون تدخل ، فيمكنك تخزين (معظم) حالة وحدة المعالجة المركزية في التسجيلات وإعادة تعيين الحالة إلى الذاكرة في آخر تعليمات.
أي أن الوضع المثالي هو ما يلي: نقوم بإجراء نظام مضاهاة دون تداخل طوال الإطار الكامل للنظام المضيف (بالنسبة لوحدة المعالجة المركزية بتردد 4 ميجاهرتز وعند 60 هرتز هذا يعني حوالي 67 ألف دورة لكل إطار ، أو في مكان ما من 3 آلاف إلى 16 ألف التعليمات Z80).
عند العمل مع Bomb Jack ، كنت بحاجة للتأكد من أن اللوحة الرئيسية لا تسجل أمرًا جديدًا قبل أن تتمكن بطاقة الصوت من قراءة الأمر الأخير. قبل أن اكتشفت أن اللوحة الرئيسية لا تسجل أكثر من أمر واحد لكل إطار ، فكرت في الحاجة إلى إنشاء قائمة انتظار معقدة للأوامر التي من شأنها اعتراض التسجيلات في المزلاج الصوتي للوحة الرئيسية وتخزين رقم الدورة و بايت الأوامر في قائمة الانتظار.
بعد ذلك ، في الوقت الذي كانت فيه بطاقة الصوت تنفذ إطارها ، ستأخذ أمرًا جديدًا من قائمة انتظار الأوامر عند الوصول إلى رقم دورة الأمر.
سيعمل مثل هذا النظام وسيكون "صحيحًا" ، ولكنه سيزيد من تعقيد المدونة بشكل كبير.
في النهاية ، قررت استخدام حل أبسط بدون أي طوابير. نظرًا لأن اللوحة الرئيسية تسجل أمرًا واحدًا فقط لكل إطار ، قمت بتبديل التنفيذ على جهازي كمبيوتر بحيث يؤدي كل منهما شريحتين زمنيتين لكل إطار:
- تنفيذ النصف الأول من الإطار على اللوحة الرئيسية
- تنفيذ النصف الأول من الإطار على بطاقة الصوت
- تنفيذ النصف الثاني من الإطار على اللوحة الرئيسية
- أداء النصف الثاني من الإطار على بطاقة الصوت
هذا يضمن أن بطاقة الصوت ترى بشكل صحيح كل أمر مسجل بواسطة اللوحة الرئيسية ، وفي نفس الوقت يمكن تنفيذ كل محاكاة لآلاف الدورات.
بالطبع ، حقيقة أن النظام المضيف يعمل بمعدل إطارات 60 هرتز هو افتراض جريء للغاية :)
والأخير ...
آخر حقيقة مثيرة للاهتمام حول إصدار المحاكي على WebAssembly:
حجم مضغوط لكافة الملفات التي تم تنزيلها عند تشغيل المحاكي على WebAssembly
يساوي تقريبًا 113 كيلوبايت:
- حوالي 2.5 كيلوبايت لـ HTML و CSS و JS "المكتوبة بخط اليد"
- 26.8 كيلوبايت لكل ملف JS لوقت تشغيل emscripten
- 83.7 كيلوبايت لكل ملف wasm
يحتوي ملف WASM على ROM المدمجة في جهاز arcade.
تشغل هذه الأقراص المضغوطة 112 كيلوبايت غير مضغوطة.
أي أن المحاكي المضغوط
بالكامل مع ROM المدمجة يحتل تقريبًا نفس الحجم مثل ROM غير المضغوط :)
يتم ضغط الأقراص المضغوطة 112 كيلوبايت إلى حوالي 57 كيلوبايت ، أي أن الحجم الحقيقي للتعليمة البرمجية المضغوطة في WASM بدون بيانات ROM أقل من 30 كيلوبايت (84-57).
يبدو لي جيدًا جدًا لمحاكي كامل لنظام 8 بت ؛)