عندما تكون في دول مجلس التعاون الخليجي هناك عناوين 16 بت ، وفجأة الذاكرة هي 256 كيلو

... أو كيف تطلق النار على قدمك على أردوينو




في مدرسة الكمبيوتر الصيفية ، نستخدم جهاز كمبيوتر قديمًا صنعناه بأنفسنا لتدريس تطوير الألعاب.

الآن يحتوي على لوحة Arduino Mega مع معالج ATmega2560 ، حيث يصل حجم ذاكرة الفلاش إلى 256 كيلو بايت. كان من المفترض أن هذا سيستمر لفترة طويلة جدًا ، لأن الألعاب بسيطة (الشاشة 64 × 64 بكسل فقط). في الواقع ، واجهنا بعض المشكلات عندما وصلت البرامج الثابتة إلى ما يقرب من 128 كيلوبايت.

في ذاكرة البرنامج ، على الرغم من اسمه ، بالإضافة إلى الرمز القابل للتنفيذ للألعاب ، يتم تخزين جميع أنواع البيانات غير المتغيرة مثل العفاريت وجداول المستوى. هذه البيانات ليست كثيرة.

ولكن عندما قمنا بتوصيل شريحة الصوت YM2149F بجهاز الكمبيوتر الخاص بنا ، وقمنا بتنزيل بضع عشرات من الألحان في ذاكرة البرنامج نفسها ، بدأت المشاكل.


تعطلت البادئة عند محاولة لعب لحن ، أو رسم بعض القمامة في قائمة اللعبة. لم يكن من الواضح كيفية تصحيح ذلك على الإطلاق ، لأن المعالج لا يتعامل فقط مع منطق اللعبة ، ولكنه يعرض أيضًا الصورة والصوت. ونتيجة لذلك ، اتضح أن مترجم gcc-avr يستخدم متغيرات بحجم 2 بايت لتخزين المؤشرات. ولكن معالجة 256 كيلو بايت ببايتين فقط أمر مستحيل! كيف يخرج؟

مؤشرات الكود


أولاً ، يمكن أن تستخدم تعليمات المكالمات والقفزات الوظيفية عناوين ثلاثية البايت. لذلك ، يكفي أن يقوم الرابط باستبدال العنوان الكامل في مثل هذه التعليمات وسوف يعمل. إذا تم تمرير عنوان الوظيفة من خلال مؤشر ، فلن يمر مثل هذا الرقم - لأن لدينا مؤشر مزدوج البايت.

في هذه الحالة ، يقوم مجلس التعاون الخليجي بإدراج "نقطة انطلاق" في 64 كيلو بايت السفلي - تعليمات jmp ، والتي تتحول إلى الوظيفة المطلوبة. ثم سيكون عنوان لوحة المعلومات هذه بمثابة عنوان الوظيفة التي يجب تخزينها في المتغير - بعد كل شيء ، يتم وضعها في وحدتي بايت. وعند الاتصال ، سيكون هناك انتقال عند الضرورة.

مؤشرات البيانات


لكننا نخزن في ذاكرة البرنامج ليس فقط الكود القابل للتنفيذ. لذا فإن القفزات لن تساعد هنا - نحن نلغي تحديد المؤشرات ، لكننا لن نذهب إليها.

تحتوي مكتبة AVR على وظائف / وحدات ماكرو مثل pgm_read_byte_far (addr) لإعادة الإشارة إلى المؤشر الكامل (يتم تمريرها بقيم رباعية البايت). لكن دول مجلس التعاون الخليجي لا تعرف كيفية الحصول على هذه المؤشرات باستخدام لغة C.

لحسن الحظ ، يوجد ماكرو pgm_get_far_address (var) للحصول على العنوان الكامل للمتغير. يتم ذلك باستخدام المجمع المدمج (الحالة عندما يكون المجمع أكثر ذكاءً من المجمع).

يبقى إعادة كتابة جميع التعليمات البرمجية التي تستخدم البيانات الموجودة في ROM. هذا هو ، مشغل موسيقى ، تقديم العفاريت ، إخراج النص ، ... ليست تجربة ممتعة للغاية. نعم ، وسيصبح الكود أكثر تثبيطًا ، وبالنسبة للرسومات فهو في غاية الأهمية. لذلك ،

نوزع البيانات على ROM


يحاول Linker بجد لوضع بيانات ذاكرة البرنامج في الإصدار 64k السفلي. هذا لا يعمل إذا كان هناك الكثير من البيانات. لكن أكبر البيانات التي لدينا هي ملفات الموسيقى. لذلك إذا قمت بإزالتها فقط ، فسيتم احتواء كل شيء آخر في الذاكرة السفلية ولن تضطر إلى إعادة الجزء الرئيسي من الرمز.

للقيام بذلك ، سوف نستغل ميزات البرنامج النصي للرابط. يسمى أحد الأقسام الأخيرة التي يضعها الرابط في ROM .fini7. احفظ جميع صفائف الموسيقى في هذا القسم:

#define MUSICMEM __attribute__((section(".fini7"))) const uint8_t tetris2[] MUSICMEM = { ... }; 

يخبرنا avr-nm الآن أن كل شيء على ما يرام - فالبيانات ذات العفاريت والمستويات تبين أنها في الجزء السفلي من ROM ، والموسيقى في الأعلى.

 00002f9c t _ZL10level_menu 00002e0f t _ZL10rope_lines 000006de t _ZL10ShipSprite 00023a09 t tetris2 00024714 T the_last_v8 

يبقى إعادة المشغل لاستخدام مؤشرات رباعية البايت وبدلاً من استخدام المؤشر إلى مصفوفة برمز اللحن ، استخدم الوظيفة للحصول على عنوانه. هناك حاجة إلى وظائف لأن لدينا تطبيق لاعب حيث يمكنك الاستماع إلى جميع النغمات التي تختارها. يقوم الآن بتخزين المؤشرات إلى وظائف من هذا النوع:

 00006992 <_Z12tetris2_addrv>: 6992: 61 ef ldi r22, 0xF1 ; 241 6994: 7a e3 ldi r23, 0x3A ; 58 6996: 82 e0 ldi r24, 0x02 ; 2 6998: 99 27 eor r25, r25 699a: 08 95 ret 

تأخرت نهاية العالم حتى ضربت العفاريت القاع 64 كيلو. هذا غير مرجح ، لأنه لا يزال هناك رمز أكثر من العفاريت ، مما يعني أن الذاكرة ستنتهي بشكل عام على الأرجح.

مكافأة


كتبنا هذا الصيف لعبة بأسلوب Sokoban. تبين أن بعض المستويات كانت صعبة للغاية. حاول ، على سبيل المثال ، لتمرير هذا:



المراجع


  1. صفحة مشروع جيثب
  2. اردوينو وشاشة LED
  3. اردوينو وحجر الفيلسوف الموسيقي
  4. ألعاب قليلة العام الماضي

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


All Articles