
خط OpenType يفك تجميع تعليمات Z80
ما هو مفككك المفضل؟ مفضلتي هي خط:
https://github.com/user-attachments/assets/bb6ceb18-c2fd-40a9-be4f-202321a214d9
يحول هذا الخط تسلسلات الأحرف السداسية العشرية الصغيرة إلى تعليمات Z80 مفككة، باستخدام مكثف لـ جدول استبدال الحروف الرسومية (GSUB) الخاص بـ OpenType وجدول وضع الحروف الرسومية (GPOS).
إذا كنت ترغب فقط في تجربته، فهناك نسخة متاحة في ./test/z80-sans.ttf.
تم الاختبار على Debian GNU/Linux 12. لاحظ أن إصدار Debian هذا يأتي مع إصدار ruby 3، بينما كُتب fontcustom لإصدار ruby 2، وهو غير متوافق مع الإصدارات الأحدث (مثل أخطاء بناء الجملة). كما يتطلب تثبيت ruby إصدارًا متوافقًا من OpenSSL. لذلك، يمكن استخدام RVM لإدارة كل من ruby وتثبيت محلي لـ OpenSSL.
apt install imagemagick potrace
pip install fonttools
git submodule update --init --recursive
# fontforge
(
cd ./modules/fontforge/
git checkout 4f4907d9541857b135bd0b361099e778325b4e28
git apply ../../resources/fontforge.diff
mkdir -p build
cd build
cmake -GNinja ..
ninja
ninja install
)
# woff2
(
cd ./modules/woff2/
make clean all
)
# fontcustom
rvm use 2.7
rvm pkg install openssl
rvm install 2.4 --with-openssl-dir=$HOME/.rvm/usr
gem update --system 3.3.22
(
export PATH=$PWD/modules/woff2/build:$PATH
cd ./modules/fontcustom/
git apply ../../resources/fontcustom.diff
gem build fontcustom.gemspec
gem install ./fontcustom-2.0.0.gem
)
cp ./resources/droid-sans-mono.ttf /tmp/base.ttf
./gen.py ./resources/instructions.json
يتم نسخ ملف الخط .ttf إلى ~/.local/share/fonts/، والذي يستخدمه مثلاً LibreOffice.
بالمقارنة مع الخطوط الملعونة الأخرى، يواجه Z80 Sans هذه التحديات:
CALL كـ mnemonic)، ولكن هذا يرتبط أيضًا بالنقطة التالية...65536 * 7 = 458752 مجموعة محتملة؛0x80..0xff كرقم سالب بتكملة اثنين؛كل هذا يدعو إلى حل برمجي. بينما يتولى fontcustom وImageMagick عناية بتوليد الحروف الرسومية، يبدو أن طريقة ملائمة لكتابة قواعد البحث هي تنسيق .fea، لكنني لم أجد طريقة لدمجه مع تنسيق .ttx الخاص بـ fonttools (وهو في الأساس xml). اتبعت نهج المقام المشترك الأصغر بتعديل ملف .ttx الخاص بـ Noto Sans Mono مباشرة (على الرغم من أن أشكال الحروف الرسومية تُحسب من Droid Sans Mono، حيث أن هذا ما بدأت به عند تصحيح FontForge).
يتم استخدام محلل الانحدار التكراري لتوليد جميع الحروف الرسومية الممكنة، مما يساعد في تقييم التعبيرات في الترميزات (مثل SET b,(IX+o) يأخذ بتًا وإزاحة، مُرمّزًا كتعبير DD CB o C6+8*b). ثم تم توسيع هذه الترميزات إلى جميع القيم الممكنة التي يمكن أن تأخذها المعاملات، قبل ربط 1 أو أكثر من البايتات السداسية العشرية في النهاية بكل حرف رسومي للتفكيك المطلوب لعرض تعليمة موسعة.
هناك بعض المراجع الجيدة لميزات OpenType، لكنها مكتوبة بمستوى عالٍ، أو بتنسيق .fea(؟):
ليس واضحًا أبدًا كيفية ترجمتها إلى .ttx، لذا في النهاية قمت بتحويل جميع عائلة Noto Sans واستخدمت نهج القوة الغاشمة القديم الجيد "التعلم بالمثال". هذا أكثر متعة مما يبدو، بفضل الكثير من الإخفاقات الصامتة عند التحويل من .ttx إلى .ttf، حيث لا تتطابق عمليات البحث بسبب بعض الافتراضات التي لم يتم التحقق منها بواسطة fonttools (على سبيل المثال، يجب أن تحتوي تعريفات الفئات لاستبدالات السلسلة السياقية على حرف رسومي تغطية واحد على الأقل بقيمة class="1").
تم حل معظم التحديات إلى حد كبير بقواعد السلسلة السياقية. للتعامل مع العناوين، تم ترميز كل nibble في النطاق 0..f بحروف رسومية مميزة، مع استخدام أحرف المسافات لإنشاء استبدالات متعددة، حرف واحد في كل مرة. كما تحتوي الإزاحات على متغيرات موقعة إضافية. يعطينا هذا إجمالي (4 + 2) * 16 حرفًا رسوميًا للأرقام. كان هذا كافيًا بالفعل لإبقاء ملف الخط تحت حد 65536 حرفًا رسوميًا.
الجزء الأسوأ كان بالطبع المعاملات غير المرتبة. ومع ذلك، ونظرًا للعدد المحدود من الاختلافات التي تمتلكها هذه المعاملات في التعليمات، يمكن تغطيتها بنفس استراتيجية التعليمات ذات البادئات المشفرة بشكل غامض، على سبيل المثال
["SET b,(IX+o)", "DD CB o C6+8*b"],
["SET b,(IY+o)", "FD CB o C6+8*b"],
تغطى بنفس قواعد البحث مثل:
["SRA (IX+o)", "DD CB o 2E"],
["SRA (IY+o)", "FD CB o 2E"],
["SRL (IX+o)", "DD CB o 3E"],
["SRL (IY+o)", "FD CB o 3E"],
خاصية مثيرة للاهتمام في ISA لـ Z80 هي أن البتات والمسجلات تحتوي على ما يصل إلى 8 متغيرات، وأن حالات عدم الترتيب هذه تتضمن فقط الإزاحات وأحد هذه المعاملات المحددة. لذلك، يمكننا ترميز البتات أو المسجلات كقيم حرفية. مع وجود قدر كافٍ من النظر للأمام، يمكننا مطابقة آخر بايت سداسي عشري، وإنشاء عمليات بحث مخصصة لكل حالة. يمكن تقليل القيم الحرفية الأخيرة عن طريق توليد ربط يطابق الحرف الرسومي اللاحق. كانت النتيجة النهائية عشرات عمليات البحث المولدة الإضافية لهذه الحالات (والتي يمكن على الأرجح تجميعها لتقليل هذا العدد).
LD (IX+o),r كـ LD (IX+o r),؛SET b,(IX+o) كـ SET b,(IX+o))؛يدعم FontForge التعديل القابل للبرمجة للميزات باستخدام الأوامر GenerateFeatureFile() وMergeFeature() (تم تغطيتها بإيجاز في The Terrible Secret of OpenType Glyph Substitution - Ansuz - mskala's home page). كنت على علم بذلك فقط بعد إنشاء التنفيذ القائم على .ttx، لكنه كان يمكن أن يتجنب العبث بملفات .ttx.
لمجموعات تعليمات أكثر تعقيدًا، هناك نهج بديل يبدو أن له قيودًا أقل وهو استخدام مشكلات الخطوط (font shapers). بعض الأمثلة: