Ini adalah artikel pertama dalam seri 161eForth v0.5b, berakhir di sini: habr.com/en/post/452572Penerjemah EFORTH sekarang juga menggunakan kalkulator Electronics MK-161 domestik! Pada 17 Mei, versi v0.5b berhasil lulus tes saya, serta lima tes penulisan TEST-TEST4. Saya telah mencapai apa yang bisa dilakukan sendiri, tetapi saya pikir ini hanya setengah dari pertempuran. Inilah saatnya untuk memperkenalkan alat baru kepada masyarakat dengan membuka kode 161eForth untuk pengujian publik. Saya punya daftar apa yang harus diperbaiki dan di mana "bekerja pada stabilitas." Saran dan komentar Anda akan diperhitungkan saat menyelesaikan pekerjaan dan merilis versi 1.0
Ketika mentransfer versi terbaru eForth ke platform domestik, dua rintangan berhasil diatasi - kecepatan relatif rendah dari mesin 8-bit, yang diprogram dalam bahasa inputnya sendiri, dan jumlah sederhana dari memori biner yang tersedia (lihat 2.4.1), total 4.096 byte.

Saat menulis 161eForth, solusi siap pakai yang disiapkan untuk Callisto, bahasa input generasi berikutnya untuk PMK domestik, digunakan. Ini adalah teknologi untuk mengimplementasikan mesin benteng di atas ALU desimal dan arsitektur "Harvard", driver konsol, dan tata letak keyboard alfanumerik, serta terminal perangkat lunak yang berdasarkan padanya, yang beroperasi melalui port serial RS-232. Selain Electronics MK-161 dan distribusi 161eForth, Anda mungkin memerlukan keyboard tambalan buatan sendiri di mana huruf-huruf dari huruf Rusia dan Inggris ditandatangani pada tombol. Huruf-huruf disusun menurut abjad baris demi baris, dari kiri ke kanan dan dari atas ke bawah.

Dr. Chen-Hanson Ting, penulis versi modern eForth, menekankan dalam bukunya [1] pentingnya memahami dua komponen Benteng. Ini adalah interpreter internal ("alamat") yang memungkinkan peralatan untuk mengeksekusi kode dijahit Fort, dan interpreter eksternal ("teks") yang bertanggung jawab untuk berdialog dengan seseorang.
Dalam dua artikel, saya akan membahas secara terperinci solusi paling radikal yang digunakan dalam implementasi masing-masing dari dua penafsir ini di Electronics. Mempelajari solusi ini dapat berguna dan menginspirasi untuk bermigrasi eForth ke perangkat lain dengan memori dan kinerja yang terbatas. Memahami artikel akan membantu dengan pengantar awal untuk mikrokalkulator (PMC) yang dapat diprogram dan Fort. Saya akan menjelaskan saat-saat sulit yang unik untuk Electronics MK dan penerjemah eForth.
Untuk mulai dengan, kata-kata eForth dibagi menjadi umum dan sistemik.
Ukuran surat itu penting. Nama-nama kata biasa didefinisikan dalam huruf besar, dan sistem - huruf kecil. Saya juga membuat inovasi di eForth dalam huruf kecil. Penulis eForth menyarankan untuk melakukan dialog utama dalam mode CAPS. Saat Anda perlu menggunakan kata sistem, alihkan waktu ke huruf kecil (kombinasi tombol FP).
Dalam artikel tersebut, semua kata ditulis dalam huruf kapital agar menonjol dari teks. Dalam beberapa implementasi eForth awal, header kata sistem dikeluarkan dan tidak di-output oleh perintah WORDS. Ini membantu menyederhanakan penampilan eForth dan menghemat perhatian mereka yang menggunakan Fort untuk pertama kalinya. Dalam 161eForth, judul kata-kata ini disimpan terutama karena adanya dekompiler kata kolon SEE (lihat video No. 3 di akhir artikel), yang tidak akan menampilkan nama-nama kata sistem jika judulnya dihapus.
Untuk merampingkan artikel dan menjadikannya bermanfaat sebagai referensi, saya harus menggunakan beberapa istilah sebelum mendefinisikannya. Profesional Fort dan PMK harus terbiasa dengan istilah-istilah ini. Pemula terkadang harus melihat di bagian tetangga (saya meletakkan tautan di tempat yang tepat) atau membaca kembali artikel beberapa kali.
161eForth sendiri diletakkan di sini, bersama dengan teks sumber, grafik di layar keyboard dan kata-kata bantuan.txt dengan deskripsi dari semua kata yang diimplementasikan:
http://the-hacker.ru/2019/161eforth0.5b.zipSaya juga memposting 5 video kecil di YouTube yang menggambarkan operasi 161eForth bagi mereka yang tidak memiliki MK-161. Anda dapat
menonton seluruh daftar putar di YouTube . Di bawah ini adalah yang pertama, 4 sisanya di akhir artikel.
eForth dan implementasinya
eForth dirancang sebagai pengganti modern untuk penerjemah fig-Fort yang dikenal luas. Untuk mentransfer ke MK-161, saya memilih versi 32-bit 5.2 dari penerjemah 86eForth dengan kode dijahit tidak langsung, ditulis pada tahun 2016 pada MASM assembler untuk sistem operasi Windows. Versi ini dijelaskan secara rinci dalam edisi ketiga eForth dan Zen [1]. Mereka yang tahu bahasa Inggris, saya sarankan Anda untuk mencari dan mempelajari buku ini, sangat berguna untuk memahami keutamaan.
Dalam surat pribadi, penulis mengonfirmasi bahwa 86eForth502.asme dari buku ini adalah versi terbaru eForth. Di Internet, Anda dapat menemukan banyak informasi berbahasa Inggris tentang ini dan versi eForth sebelumnya.
Pengembangan eForth mengikuti jalur ilmiah yang diajarkan oleh Profesor Wirth menggunakan contoh bahasa pemrogramannya Oberon. Setiap versi eForth berikutnya adalah penyederhanaan dari versi sebelumnya. Segala sesuatu yang dapat ditiadakan telah dihapus dari lidah. Masih ada serangkaian konstruksi bahasa ekspresif yang kuat dan dipikirkan dengan cermat, yang kekuatannya telah diuji pada lebih dari 40 implementasi eForth untuk berbagai platform. Sekarang dengan kalkulator!
Menjadi dialek Fort yang minimalis, eForth tidak bertujuan untuk memenangkan perlombaan melawan Fort terkecil. Seperangkat kata yang ia tawarkan cukup praktis dan dapat dengan mudah diperluas oleh programmer ke arah yang diperlukan untuk tugas-tugasnya.
Versi pertama eForth dirilis pada tahun 1990 dalam assembler MASM untuk 8086 prosesor dan bekerja di bawah MS-DOS. Itu berisi 31 kata inti yang bergantung pada mesin dan 191 kata tingkat tinggi. Idenya sederhana - Anda menerjemahkan hanya 31 kata ke assembler Anda, dan segera mendapatkan eForth di komputer Anda.
Pendekatan ini telah dikritik di Internet, karena cara untuk meminimalkan jumlah kata dalam assembler telah menyebabkan kinerja yang sangat rendah untuk sistem embedded. Sudah di versi kedua eForth, jumlah maksimum kata-kata mulai diimplementasikan dalam assembler, yang meluruskan kemiringan ke arah tidak hanya portabel, tetapi juga sistem pemrograman praktis.
Selama beberapa tahun, Bill Munch, penulis asli eForth, dan rekannya Dr. Chen-Hanson Ting merilis rilis eForth secara paralel. Setiap versi memiliki karakteristiknya sendiri. Opsi eForth untuk platform yang berbeda juga telah dimasukkan oleh programmer lain.
Versi 5.2, dirilis pada 2016, berisi 71 kata "kode" dan 110 kata "titik dua". Seperempat abad pencarian ideal telah menyebabkan berkurangnya jumlah kata secara signifikan. Pada saat yang sama, untuk alasan kinerja, persentase kata yang diterapkan pada level rendah meningkat.
Usulan 161eForth menikmati manfaat besar dari kemajuan ini, tetapi tidak berpura-pura mengembangkan garis trunk. Implementasi saya memberi programmer semua alat yang ada dalam versi 5.2. Ketika arsitektur MK-161 membuat implementasi beberapa kata yang sulit tidak mungkin atau tidak berarti, alih-alih membuang kelebihannya, saya memberikan programer pengganti yang lengkap, mengambilnya dari standar ANSI / ISO [4]. Mereka yang mencari minimalis dapat secara mandiri membuang kata-kata "ekstra", karena secara tradisi ,eForth dilengkapi dengan kode sumber.
Saat menerapkan eForth, saya berpegang pada pemahaman penulis. Sebagai contoh, menurut pendapat saya, sebuah loop UNTUK BERIKUTNYA dengan nilai awal n harus mengeksekusi tepat n kali. Kesimpulan yang sama akhirnya datang Chuck Moore, penulis bahasa Forth dan colorForth. Sayangnya, eForth menggunakan konvensi yang sudah ketinggalan zaman dan mengeksekusi siklus seperti itu n + 1 kali, dengan penghitung dari n hingga 0. Saya tidak memperbaiki ini dan beberapa kekurangan lainnya, lebih memilih kompatibilitas 161 eForth dengan implementasi untuk platform lain.
Karena 161eForth adalah sistem pemrograman on-board praktis pertama untuk Elektronik MK-161, dengan pengecualian bahasa pabrik, saya menelusuri sejarah panjang eForth dan mengembalikan beberapa kata ke bahasa yang berguna pada platform lain dan mungkin diminati sekarang.
Misalnya, variabel baru-lama 'BOOT berisi token (lihat 3.1) kata, yang dieksekusi pertama setelah lingkungan diinisialisasi, tetapi sebelum dialog dimulai. Secara default, 'BOOT berisi token TLOAD untuk menafsirkan kode dari "area teks" (lihat 2.4.2). Hal ini memungkinkan pemrogram untuk menyesuaikan eForth untuk dirinya sendiri tanpa mengkompilasi ulang lingkungan, yang masih mustahil diproduksi di papan "Elektronik".
Tugas prioritas implementasi adalah menghemat memori biner (lihat 2.4.1) dan meningkatkan kinerja. Solusi mereka menyebabkan penurunan dramatis dalam jumlah kata tingkat tinggi, karena kode mereka menempati memori yang berharga ini, karena peningkatan jumlah kata inti cepat yang diterapkan dalam memori program yang murah (lihat 2.4.3).
Sebagai hasilnya, 161eForth berisi 129 kata kode, 78 kata tingkat tinggi dan menempati memori biner MK-161 1.816 byte, yaitu kurang dari setengahnya. Ini memberi harapan untuk metakompilasi bagian tingkat tinggi langsung di papan Elektronik.
Kode sumber untuk eForth MK-161 dibagi menjadi dua bagian besar. Inti yang ditulis dalam sistem perintah MK-161 terkandung dalam file eForth0.mkl. Kata-kata tingkat tinggi didefinisikan dalam SP-Forth dan ditempatkan dalam file eForth.f.
Distribusi juga memiliki file bantuan words.txt, yang mendokumentasikan semua kata-kata penting dengan notasi tumpukan dan penjelasan singkat, dalam satu baris.
1.1 Kode sumber kernel eForth0.mkl
Kernel eForth berisi kode yang dapat dieksekusi yang beroperasi dalam memori program MK-161 (lihat 2.4.3), yang dikompilasi pada komputer ke dalam file eForth0.mkp dengan cara standar, misalnya, kompiler MKL2MKP yang dipatenkan.
Kode sumber kernel yang terkandung dalam file eForth0.mkl ditulis dalam
bahasa Latin mnemonics . Sebagai contoh, perintah IPE untuk membaca register E (alias R14) ditulis dalam mnemonik ini sebagai RME. Menjadi tidak biasa bagi pemilik PMK Soviet, mnemonik Latin nyaman untuk mengetik dari keyboard komputer. Memang, lebih mudah untuk mengetik FX ^ 2 yang aneh daripada terbiasa sejak kecil FxΒ².
File eForth0.mkp adalah preset kernel. Selain kode primitif, ini berisi header kernel dan daftar nama tblNames, yang ditransfer eForth.f selama decoding ke register desimal (lihat 2.4.4). Berdasarkan eForth0.mkp-lah inti eForth.mkp akan dibuat (lihat 2.4.3), jadi eForth0.mkl harus dikompilasi terlebih dahulu.
1.2 Kode sumber untuk kata-kata tingkat tinggi eForth.f
File eForth.f diumpankan ke input dari kompiler domestik luar biasa SP-Forth [5]. File berisi definisi semua kata tingkat tinggi. Seiring waktu, mereka dapat diidentifikasi pada eForth itu sendiri dan mungkin dikompilasi langsung di papan Elektronik MK-161.
Selama kompilasi, eForth.f membaca inti eForth0.mkp kosong dan dengan bantuannya membuat tiga file dalam direktori saat ini untuk memuat selanjutnya ke MK-161: eForth.mkp, eForth.mkd dan eForth.mkb. Ini adalah eForth.mkb yang berisi isi kata-kata tingkat tinggi, meskipun tajuknya terletak di file eForth.mkd.
File keempat, eForth.mkt, secara manual ditulis dalam eForth dan dapat diedit di atas kapal MK-161 menggunakan editor teks bawaan. Masing-masing dari empat file ini akan saya analisis secara lebih rinci di bawah ini (lihat 2.4).
2. Elektronik MK-161
Sebuah pabrik dari Novosibirsk menyebut MK-161 sebuah akronim lama. Itu adalah nama kalkulator pertama di USSR. Sistem instruksi MK-161 mewarisi sistem komando kalkulator Soviet "Electronics B3-34" dan "Electronics MK-61." Ini berarti bahwa program yang ditulis untuk kalkulator Soviet akan menggunakan MK-161 tanpa perubahan atau dengan perubahan kecil.
Kebalikannya tidak benar. eForth tidak akan pergi ke PMK Soviet, karena menggunakan banyak sumber daya yang pertama kali muncul di MK-152/161 dan tidak tersedia dalam model seri sebelumnya.
Pertimbangkan fitur-fitur bahasa input dan arsitektur MK-161, yang memengaruhi 161eForth (selanjutnya hanya eForth) dan memberikan implementasi eForth yang dibahas sebagai "aksen Rusia."
Yang pertama dari fitur-fitur ini adalah perjanjian
"senior at junior address", yang secara konsisten dipertahankan dalam MK-161. Misalnya, angka 1000 = 3 Γ 256 + 232 akan ditulis dalam dua byte berturut-turut, seperti 3 dan 232.
2.1 Mengatasi Tidak Langsung
Pemrograman PMK Soviet mendengar tentang pengalamatan tidak langsung. Untuk
pengalamatan langsung, kami secara eksplisit menunjukkan nomor register yang kami maksud. Misalnya, P IP 44 mempertimbangkan konten register 44. Kunci P yang muncul di MK-152 digunakan untuk mengakses register dengan nomor 15 atau lebih - register ini tidak ada di PMK Soviet.
Dalam
pengalamatan tidak langsung, jumlah register yang diperlukan tidak diketahui sebelumnya. Nomor ini ada di register yang berbeda. Misalnya, jika register 8 berisi angka 44, perintah K PI 8 mempertimbangkan konten register 44 (R44).
Tombol K dan P dapat digabungkan. Misalnya, perintah RK BP 20 akan mentransfer kontrol (GOTO dalam bahasa Latin mnemonics) ke alamat yang disimpan dalam R20.
Fitur yang ternyata penting bagi interpreter internal eForth terkait dengan peningkatan / penurunan register awal selama pengalamatan tidak langsung. Fitur ini diwarisi dari PMK Soviet.
Sebagai contoh, perintah pembacaan tidak langsung KI 0, KI 1, KI 2 dan KI 3 mengurangi isi register 0, 1, 2 atau 3 oleh satu ke register yang diinginkan. Perintah KI 4, KI 5 dan KI 6 sebelum membaca, tambah isi register 4, 5, atau 6 per satu.
"Modifikasi" register alamat ini memungkinkan Anda untuk memproses seluruh grup register dalam satu lingkaran. Ini mirip dengan ++ R dan --R di C. Nomor register register penting. Dialah yang menentukan apakah akan meningkat (register 4-6) atau berkurang (register 0-3) dengan pengalamatan tidak langsung.
Arsitektur 161eForth dipengaruhi oleh fakta bahwa peningkatan register 4-6 dengan pengalamatan tidak langsung adalah
awal . Akibatnya, penafsiran penunjuk (IP) yang terletak di R6 selalu
menunjuk ke byte terakhir dari kode yang dijahit. Di 86eForth, IP selalu menunjukkan byte berikutnya yang belum dibaca.
Ini juga berlaku untuk pointer tumpukan kembali (RP) yang disimpan dalam register 2. R2 selalu menunjuk ke atas tumpukan kembali.
Fitur yang berguna dari MK-161 adalah tidak adanya kenaikan / penurunan register jika pengalamatan tidak langsung terjadi dengan kunci R. yang baru. Misalnya, RKIP02 menghitung angka dari atas tumpukan kembali tanpa mengubah pointer. Ini adalah tim Fort R @ yang siap pakai. Dari penjelasan di atas, berikut bahwa nilai baca adalah satu kurang dari alamat token berikutnya, yang akan dieksekusi setelah kembali dari kata "titik dua".
Ketika Anda harus mengembangkan atau mempelajari kata-kata yang berinteraksi erat dengan interpreter internal eForth, pastikan untuk sepenuhnya memahami titik halus ini terkait dengan
berlebihan .
2.2 Tabel, dipesan dan asosiatif
Tabel MK-161 terletak di memori program (lihat 2.4.3). Mereka muncul di "Electronics MK" Novosibirsk dan sama sekali tidak terbiasa dengan para ahli PMK Soviet. Alamat tabel yang digunakan selalu disimpan dalam register 9042, tetapi aksesnya berbeda.
Tabel dipesan adalah array bilangan bulat 16-bit yang tidak ditandatangani. eForth berisi tabel tblTokens dengan alamat primitif (lihat 3.1.1) - Fort kata yang ditulis dalam sistem perintah MK-161. Penerjemah alamat (lihat 3.2) menggunakan tblTokens untuk mengeksekusi kode dijahit dengan cepat, jadi eForth berusaha untuk selalu memuat alamat tabel ini di R9042.
Untuk mengakses tabel yang dipesan, Anda perlu menulis nomor item yang diinginkan di R9210. Angka n dalam register X akan digantikan oleh nilai elemen tabel dengan angka n, hitungan dimulai dari nol.
Tabel asosiatif ("pencarian berdasarkan nilai") secara aktif digunakan oleh eForth, terutama oleh primitif (FIND), mencari kata dengan namanya. Selain itu, tabel asosiatif tblCHPUT digunakan saat mencetak huruf ke layar untuk memproses umpan baris dan kode kontrol lainnya.
Untuk mencari elemen n dalam tabel asosiatif, tulis n ke R9212. Angka n dalam register X (manajemen menyebutnya "indeks") akan diganti dengan nilai 16-bit yang dicatat dalam tabel segera setelah "indeks" n.
Kehadiran fungsi pencarian yang cepat, meskipun sederhana ini diimplementasikan dalam bahasa assembly di "firmware" MK-161 membantu eForth mencapai kinerja yang dapat diterima ketika mengenali nama kata dan menyusun program. Tentu saja, untuk ini saya harus mengembangkan bukan tabel pengenalan nama yang paling sederhana, "dipertajam" untuk fungsi ini. Kami akan membicarakan hal ini secara lebih rinci di artikel kedua.
2.3 Interupsi dan Konsol
"MK Electronics" memungkinkan pemiliknya untuk menulis program dalam bahasa input yang merespons peristiwa tertentu - seperti menekan atau melepaskan tombol, mengakhiri penghitung waktu.
eForth secara aktif menggunakan
sistem interupsi ini untuk input keyboard dan kursor yang berkedip ketika diminta untuk input tersebut, dan untuk input / output melalui port serial universal (RS-232).
Huruf-huruf yang dimasukkan dari keyboard dalam antrian bufKbd saat Anda menekan tombol. Ini sangat mudah dan menghemat waktu pada sistem dengan kecepatan rendah. Alfabet dan penggantian kasus ditangani oleh interupsi KeyPress dan tidak memakan ruang antrian. Tekan lama pada tombol panggil ulang otomatis.
Ketika garis 8 huruf penuh, dan eForth belum siap untuk memproses input (situasinya sangat jarang), MK-161 akan mengeluarkan mencicit yang tidak bahagia. Tentu saja, saya tidak ingin menerapkan semua pekerjaan alami keyboard ini pada penerjemah, tetapi untuk mengeluarkan MK-161 di luar kotak sebagai layanan dari program bawaan (firmware). Tapi apa, seperti kata mereka, kaya.
Setelah mulai bekerja, seluruh output eForth diarahkan ke
layar grafik MK-161. Keluaran huruf di atasnya dilakukan oleh rutinitas CNCut yang relatif sederhana. Satu-satunya kesulitan di sini adalah penerapan kode kontrol BS, "ruang belakang". MK-161 menggunakan font proporsional. Oleh karena itu, dalam tblBS buffer khusus Anda harus mengingat posisi karakter yang ditampilkan, dari mana kode output BS kemudian mengambilnya.
Selama dialog, pengguna dapat menggunakan kata IO> untuk mengalihkan semua input / output ke port serial RS-232, yang memungkinkan untuk memprogram MK-161 dari keyboard komputer yang sudah dikenal atau dari MK-161 lain . Kata CON> mengembalikan kendali ke konsol kalkulator.2.4 Area Memori dan Instalasi eForth pada MK-161
Memori "MK-161 Electronics" terdiri dari memori program yang dapat dialamatkan secara terpisah dan memori register data. Pada gilirannya, memori register heterogen dan dibagi menjadi tiga area besar.Mendaftar dengan angka dari 0 hingga 999 menyimpan "angka desimal". Ini adalah register biasa, seperti pada "Elektronik B3-34" dan kalkulator lainnya. Mereka hanya mampu menyimpan bukan 8, tetapi 12 tempat desimal "mantissa".Register dengan angka dari 1000 hingga 8167 menyimpan integer dari 0 hingga 255. 3 Kbytes terakhir dari area ini dengan alamat dari 5096 hingga 8167 disebut area teks .Register dengan angka dari 9000 hingga 9999 disebut register fungsi. Area layanan ini dari ruang alamat menyerupai port I / O mikroprosesor. Dengan bantuan perintah tulis dan baca, alamat ini digunakan untuk mengakses perangkat I / O, sistem interupsi, dll.Untuk menginstal eForth pada Electronics MK-161, cukup untuk mentransfer empat file ke kalkulator, misalnya, menggunakan program dari produsen MK.EXE:- Tulis eForth.mkp ke memori program mulai dari halaman 0. Versi 0.5b menempati 74 halaman.
- Tulis eForth.mkd ke memori data desimal
- Tulis eForth.mkb ke memori data biner
- Tulis eForth.mkt ke memori teks
Setelah mentransfer ke kalkulator, saya sarankan segera menyimpan keempat file ini di direktori terpisah "disk elektronik" bawaan. Karena mereka memiliki nama yang sama, Anda dapat mengunduh eForth segera sekaligus sebagai "paket".2.4.1 Memori biner ("byte") MK-161: eForth.mkb
Register Electronics MK dengan angka dari 1000 hingga 5095 digunakan untuk menyimpan angka dari 0 hingga 255. Area memori register kalkulator ini disebut biner. Dua register biner berturut-turut dapat diakses dari eForth sebagai βselβ 16-bit tunggal, dan (seperti di semua tempat pada MK-161), 8 bit atas berada dalam register dengan angka yang lebih rendah.eForth menggunakan "memori biner" kecil ini sebagai yang utama. Kata-kata bekerja dengannya! dan @, DI SINI dan ALLOT, hanya dari sini penerjemah alamat mengeksekusi kode dijahit (lihat 3.2). Berikut adalah variabel eForth, buffer input teks (TIB), kamus, dan tumpukan rollback tblBS untuk mengimplementasikan backspace.4096 byte sangat sederhana, dengan standar modern. Oleh karena itu, upaya besar telah dikeluarkan untuk membawa ke bidang memori lain segala sesuatu yang mungkin.2.4.2 Area teks: eForth.mkt
Segera setelah memori biner adalah area teks , register dengan angka dari 5095 ke 8167. Secara teknis, ini adalah register byte yang sama, tetapi kemampuan untuk menuliskannya ke disk dan membaca sebagai file terpisah membuat area ini spesial.Kata TLOAD digunakan untuk bekerja dengan "teks" di eForth. Ini memberi makan seluruh area ini ke input penerjemah teks, sebagai string, 3072 huruf.Ada perbedaan pendapat tentang cara memecah teks menjadi beberapa baris. Seorang editor yang tergabung dalam MK Electronics bersikukuh pada panjang garis 24 karakter. Callisto menggunakan konvensi Fort, di mana string berisi 64 karakter. eForth memberi pengguna pilihan untuk menghitung semua teks sebagai satu garis panjang. Anda dapat menggunakan editor bawaan MK-161. Anda dapat menulis sendiri, kompatibel dengan Callisto.Berikut adalah konten awal eForth.mkt, untuk kenyamanan, dibagi menjadi tiga baris:: hi ." , %user%!" CR ; ' hi 'boot ! hi \
Baris pertama mendefinisikan kata baru hai yang menyapa pengguna. Baris kedua mengambil token kata ini (lihat 3.1) dan menempatkannya dalam variabel 'BOOT (lihat 1). Sekarang area teks akan berhenti mengkompilasi setiap kali eForth dimulai. Sebaliknya, salam yang sudah dikompilasi akan dieksekusi.
Baris terakhir memulai kata hi, menampilkan salam di layar. Kata \ melengkapi interpretasi teks, mengembalikan kontrol ke konsol.
Untuk mengkompilasi file teks sewenang-wenang, Anda harus pergi ke kalkulator dengan perintah BYE, pergi ke menu utama dan memuat file yang diinginkan dalam mode DOS. Anda juga dapat mentransfer file mkt dari komputer. Kunci C / P akan mengembalikan Anda ke eForth, setelah itu dengan perintah TLOAD Anda dapat mengkompilasi file yang dimuat ke dalam area teks.
2.4.3 Memori program: eForth.mkp
Memori program MK-161 adalah ruang alamat yang terisolasi. Itu juga menyimpan byte, tetapi mereka hanya baca. Memori program berisi 10.000 "langkah", yang ternyata berlebihan untuk eForth. Lebih dari seperempat memori program ternyata gratis, yang memberikan cadangan yang baik untuk pengembangan penerjemah.
Hanya dalam memori program "kode kata" dapat diimplementasikan. Juga, tabel pengenalan nama dan semua string teks yang dikenal di-render di sini, yang menghemat memori biner.
Beberapa kata, seperti C @, COUNT, dan TYPE, dapat mengatasi memori program jika alamatnya bukan angka positif. Misalnya, frasa 0 C @ dihitung sebagai "langkah" (byte) dari alamat 0 memori program.
2.4.4 Memori desimal: eForth.mkd
Register dari MK Electronics dengan angka dari 0 hingga 999 disebut desimal dan mengandung angka yang digunakan untuk perhitungan biasa pada kalkulator - 12 angka desimal dari "mantissa" dan 2 angka desimal dari "pesanan". Benteng dirancang untuk bekerja dengan bilangan bulat hingga 4 byte, sumber daya seperti itu jelas berlebihan untuk eForth.
Memori desimal digunakan untuk menghemat memori biner yang berharga. Tumpukan data dan pengembalian dilakukan di sini. Judul kata disimpan di sini - baik yang ditentukan pengguna dan disematkan, satu register per judul. Pendekatan ini memungkinkan Anda untuk mendefinisikan kembali kata-kata genap dengan nama standar.
Tumpukan dalam memori desimal mengarah ke sejumlah fitur karakteristik Benteng pada MK-161. Pertama, rentang nilai elemen stack sangat besar, dapat mengakomodasi bilangan bulat 32-bit. Kebutuhan untuk "bilangan bulat ganda" pada MK-161 menghilang, meskipun demi kompatibilitas saya telah menerapkan kata-kata yang sesuai eForth. "Bilangan bulat ganda" disajikan pada MK-161, sebagai dua elemen tumpukan yang berisi angka dari 0 hingga 65535, menyandikan satu bilangan bulat 32-bit dengan tanda pada kode tambahan. Tinggi 16 bit dari angka ini ditempatkan di atas, yaitu di alamat terendah.
Operasi logis bitwise DAN, ATAU, XOR, dan TIDAK memperlakukan argumen mereka sebagai bilangan bulat 16-bit. Hasil dari 32768 hingga 65535 dikonversi ke angka negatif dari -32768 hingga -1. Di eForth, false dikodekan dengan nol dan kebenaran minus satu. Juga benar adalah nilai selain nol.
Fitur kedua dari tumpukan data 161eForth adalah bahwa ia berisi angka yang ditandatangani. Ketika kata @ membaca angka 65535 dari "sel" 16-bit, kata itu secara otomatis dikonversi ke -1. Sebuah
kata "tidak bertanda" khusus U @ disediakan untuk menghitung secara langsung 65535, dengan tanda tambah.
Saya ingat bahwa demi kecepatan,
dua elemen teratas dari tumpukan data tidak terletak di memori desimal, tetapi langsung
di register X dan Y.Fakta bahwa register desimal dapat mengandung angka fraksional dan angka floating point tidak digunakan oleh eForth. Mesin virtual eForth menggunakan register ini untuk menyimpan bilangan bulat desimal 12-bit yang sudah ditandatangani. Register desimal diakses dengan kata-kata C @ dan C! - yang sama yang bekerja dengan register tunggal.
3. Penerjemah internal
Inti eForth adalah program yang ditulis dalam bahasa input MK-161. Perintah MAIN pertamanya mentransfer kontrol ke kode MAIN, yang pertama-tama mengetahui keadaan reboot. Jika itu disebabkan oleh token yang salah, MK-161 akan mencicit. Pada start-up pertama, dan juga setelah menyalakan MK-161, layar dihapus. Selanjutnya, MAIN memanggil subitut Init untuk menginisialisasi sistem interupsi dan semua yang dibutuhkan driver konsol MK-161.
Setelah menginisialisasi tumpukan dan pengembalian data, bagian level rendah dari permulaan selesai. Hal-hal luar biasa terjadi untuk mesin dengan arsitektur Harvard - eForth melanjutkan untuk mengeksekusi "kode berkabel" dari memori byte. Kehormatan menjadi yang pertama milik kata yang alamat tajuknya dicatat di R43. Ini biasanya kata DINGIN.
Bagaimana
kata-kata tingkat tinggi (IED) diatur? Kata apa pun terdiri dari dua bagian, satu badan dan satu judul.
Header disimpan dalam desimal. Ini membantu interpreter eksternal dan dekompiler menemukan nama dan isi kata. Judul ini juga berisi
bidang "leksikon" - satu set bendera yang membantu penerjemah eksternal memproses kata yang ditemukan dengan benar. Interpreter internal jauh lebih penting bagi badan VCA yang terletak di memori biner dan disimpan dalam kamus. Dia bahkan dapat mengeksekusi kata-kata yang tidak memiliki heading.
Badan VCA dimulai dengan byte dari
bidang kode , yang berisi alamat
prosesor dari kata yang diberikan. Empat penangan VCA ditulis dalam bahasa input MK-161 dan mulai pada halaman pertama memori program. Kami akan menganalisis semuanya (lihat 3.3), tetapi yang utama disebut DOLST dan terletak di alamat 02, segera setelah perintah MAIN BP dipertimbangkan. Pawang ini mengeksekusi kata-kata Fort yang didefinisikan dengan titik dua.
Setelah byte
bidang kode
adalah bidang parameter yang panjangnya sewenang
- wenang. Dalam "kata-kata titik dua", bidang parameter berisi "kode dijahit" - urutan token 16-bit, masing-masing menunjukkan satu tindakan yang ditugaskan untuk itu.
Pertama, kami akan mempertimbangkan token secara lebih rinci. Kemudian kita akan mempelajari interpreter internal INEXT, yang mentransfer dari satu token ke eksekusi berikutnya. EForth menyebut INEXT sebagai penangan primitif. Kami menyimpulkan tur interpreter internal ini dengan menganalisis keempat prosesor IED.
3.1 Token
Token mewakili kata dalam kode dan tumpukan yang dijahit, yang memungkinkannya dieksekusi dengan cepat. Token adalah penunjuk ke badan kata, tetapi arsitektur kasar dari MK-161 membuat penyesuaian sendiri untuk ide sederhana ini. Mari kita menganalisis semua jenis token, dimulai dengan token primitif.
3.1.1 Token Primitif
Semua kata yang termasuk dalam distribusi eForth diberi nomor dari 0 hingga 206. Penomoran ini end-to-end, dengan mempertimbangkan primitif dan VCA. Ini dilakukan agar dengan jumlah kata itu mudah untuk mengembalikan
namanya . Nama-nama ini disimpan dalam memori program. Tautan ke nama yang diinginkan mudah ditemukan melalui tabel header.
Angka primitif adalah tokennya . Seperti token apa pun, primitif mengambil dua byte dalam kode dijahit. Yang pertama adalah nol. Yang kedua berisi nomornya. Tabel tblTokens memungkinkan Anda untuk dengan cepat menemukan alamat kode primitif dengan nomor ini. Alamat tblTokens disimpan secara permanen di R9042 (lihat 2.2), artinya, semuanya selalu ada untuk mengeksekusi primitif.
Kata XT> memungkinkan Anda untuk mengetahui alamat kode primitif dengan nomornya (token). Karena kode primitif selalu terletak di memori program, alamat yang diterima selalu negatif (lihat 2.4.3).
3.1.2 Token VCA
VCA dapat memiliki nomor sendiri dan nama standar yang terkait, atau dapat sepenuhnya baru, dibuat oleh pengguna. Dalam semua kasus,
token VCA adalah alamat bidang kode-nya (lihat 3), yaitu angka dari 1000 hingga 5095.
Dalam kode dijahit, token VCA ditulis dengan cara yang sangat tidak biasa. Jumlah ratusan (angka dari 10 hingga 50) ditulis dalam byte pertama, sisanya dari membagi token dengan 100 (angka dari 0 hingga 99) dalam byte kedua.
Misalnya, token 1234 akan diwakili oleh dua byte 12 dan 34. Kompilasi ini, dan token lainnya, dilakukan dengan menggunakan kata COMPILE yang diambil dari standar ANSI. Untuk menulis dan membaca token VCA dalam kode dijahit, kata-kata XT! dan XT @. Mereka mengakses alamat (lihat 3.1.4), dan kata XT @ juga dapat membaca token primitif.
3.1.3 Literal integer
Seluruh literal adalah semacam token primitif. Mereka cukup tidak biasa untuk dipertimbangkan secara terpisah.
Dalam kode dijahit, token DOLIT dan DOLITM menempati empat byte. Dua byte pertama berisi token primitif yang sudah dipertimbangkan, yaitu 0 dan jumlah primitif. Dua byte berikutnya berisi bilangan bulat yang akan diberikan literal pada tumpukan data selama eksekusi.
DOLITM berbeda karena mengubah tanda nomor sebelum meletakkannya di tumpukan. Ini dirancang untuk menerapkan angka negatif.
3.1.4 Alamat Literal
Seperti seluruh literal, tiga
literal alamat BRANCH ,? BRANCH, dan DONXT masing-masing menempati 4 byte dalam kode dijahit. 2 byte pertama berisi token primitif, dua byte terakhir adalah alamat lompat.
Alamat tersebut direkam dalam format yang sama dengan token VCA (lihat 3.1.2). Byte pertama berisi jumlah ratusan, yang kedua berisi sisa dari membagi alamat dengan 100. Saya ingat bahwa karena berlebihan (lihat 2.1), alamat transisi tidak berisi alamat token yang diinginkan, tetapi angka kurang per satu.
Token DONXT membantu mengimplementasikan "akhir siklus" FOR-NEXT (lihat 1). Lompatan tanpa syarat CABANG diperlukan untuk mengimplementasikan loop BEGIN-AGAIN yang tak terbatas. Cabang bersyarat? CABANG mentransfer kontrol jika nol ada di atas tumpukan data (salah). Ini berfungsi untuk mengimplementasikan pernyataan IF-THEN bersyarat, keluar dari "loop tidak terbatas" BEGIN-UNTIL dan BEGIN-WHILE-REPEAT.
3.1.5 String literal
String literal adalah jenis token VCA. Dalam kode dijahit string literal, setelah token, ada byte dengan panjang string, setelah itu adalah string itu sendiri, dari byte pertama ke yang terakhir.
EForth memiliki tiga string literal: $ "| ,." | | dan batalkan "|. Mereka didefinisikan dalam file eForth0.mkl masing-masing sebagai STRQP, DOTQP, dan ABORQ. Pekerjaan" literal "utama dilakukan untuk mereka dengan kata do $, token DOSTR.
Untuk membuat ukuran artikel masuk akal, saya tidak bisa terlalu memikirkan topik menarik ini, tapi senang mengetahui tentang ketersediaannya di eForth.
3.2 Penerjemah alamat
Sudah waktunya untuk mempertimbangkan
token interpreter , yang alamatnya selalu dituliskan dalam register 9. Kebanyakan primitif menyelesaikan pekerjaan mereka dengan perintah K BP 9, yang mentransfer kendali ke label INEXT.
INEXT: 6 Fxβ 0 NPrime NData: 2 6 + 7 Fβ³ 7 8 Fβ³ 8
Pertama, penerjemah alamat membaca byte pertama dari token berikutnya dengan perintah KIP6. Jika nol, ini primitif dan kode di bawah label NPrime akan menangani token.
Label NData menunjukkan pemrosesan token VCA. Byte pertama dikalikan dengan seratus oleh perintah VP 2, setelah itu KIP6 + menambahkan byte kedua dari token ke hasilnya (lihat 3.1.2). Tanda baca dimasukkan oleh tim P7 ke dalam "register kerja" WP (R7).
Kita tahu bahwa token VCA adalah alamat bidang kode-nya, yang berisi alamat prosesor. Perintah KIP7 P8 membaca byte bidang kode dalam R8, dan perintah KBP8 mentransfer kontrol ke prosesor VCA. Pawang tahu bahwa R7 berisi nomor satu kurang dari alamat bidang parameter kata yang sedang diproses.
Perintah Fβ³ dengan kode 25 "dirapikan" di tumpukan. Faktanya adalah bahwa eForth menyimpan dua elemen teratas dari tumpukan data secara langsung dalam register X dan Y dari tumpukan MK-161. Solusi semacam itu mempercepat pekerjaan, tetapi membuatnya perlu untuk memastikan bahwa data penting ini tidak hilang.
Masih harus dipahami bagaimana penerjemah alamat mengeksekusi primitif.
NPrime: Fβ³ 6 9210 8 Fβ³ 8
Perintah KIP6 membaca byte kedua dari token primitif. Perintah RRP9210 P8 membaca alamat primitif ini dari tabel tblTokens (lihat 2.2 dan 3.1.1), dan KBP8 mentransfer kontrol ke primitif ini.
Seperti di atas, Fβ³ menghapus kelebihan dari tumpukan, mengembalikan konten register X dan Y.
Penerjemah alamat eForth sangat kecil sehingga digandakan beberapa kali dalam memori program. Salinan utama dijalankan oleh perintah K BP 9, yang melengkapi sebagian besar primitif.
Sebagai latihan, saya sarankan mempelajari implementasi kata EXECUTE, ditempatkan setelah label EXECU. Ini adalah varian INEXT, yang membaca token bukan dari kode dijahit, tetapi mengambilnya dari tumpukan data.
3.3 Penangan VCA
Empat varietas VCA memiliki empat penangan yang berbeda: DOLST, DOVAR, DOCON, dan DOCONM. Kita telah melihat di atas bahwa penerjemah alamat sebelum memanggil pawang meninggalkan dalam R7 alamat bidang kode dari kata yang sedang diproses.
eForth.f mempelajari alamat penangan ini dengan membaca header kernel dari file eForth0.mkp. Ini membantunya untuk mengkompilasi VCA untuk Electronics MK-161 dengan benar dengan menempatkan hasilnya di file eForth.mkb.
3.3.1 Kata Colon: DOLST dan EXIT
Topik penting berikutnya setelah INEXT adalah apa yang dilakukan penerjemah internal ketika menemukan token kata yang didefinisikan melalui titik dua. Bidang kode kata seperti itu berisi angka 2, jadi INEXT mentransfer kontrol ke penangan DOLST, yang melakukan pekerjaan yang diperlukan untuk mulai menafsirkan daftar token baru.
DOLST: 6 2 Fβ³ 7 6 Fβ³ INEXT:
Daftar 2, seperti yang telah kita bahas (lihat 2.1), berisi pointer stack return RP. Perintah IP6 KP2 menuliskan nilai R6, Interpretation Pointer (IP), ke tumpukan kembali. Nantinya ini akan membantu untuk mengingat posisi saat ini dalam daftar token lama, di mana INEXT menemukan kata titik dua. Sekarang IP7 P6 mengatur ulang IP ke awal daftar baru.
Segera setelah kode DOLST, kode INEXT ditempatkan, yang akan mengeksekusi kata pertama dari daftar token baru. Seperti di tempat lain, perintah F membantu menjaga dua elemen teratas dari tumpukan data.
Kata Colon biasanya diakhiri dengan token EXITT, yang melakukan sebaliknya, dibandingkan dengan DOLST - ia mengambil nilai IP lama dari tumpukan kembali dan kembali ke interpretasi dari daftar token lama.
EXITT: 02 6 x 1 2 + 2 Fβ³ INEXT:
Perintah RKIP02 P6 membaca nilai IP lama dari atas tumpukan kembali (lihat 2.1). Setelah itu, perintah Cx 1 IP2 + P2 mengoreksi nilai RP, meningkatkannya dengan satu. Perintah Fβ³ mengembalikan tumpukan, setelah itu INEXT mengeksekusi kata berikutnya dari daftar token lama.
Tentu saja, INEXT tidak dapat digunakan setelah DOLST dan setelah EXITT secara bersamaan. Untuk melakukan ini, saya menerapkan satu trik kuno dari zaman Uni Soviet. Anda juga bisa menguasainya dengan memeriksa baris yang sesuai di file eForth0.mkl.
3.3.2 DOVAR, penangan variabel dan array
Kata-kata yang dihasilkan oleh kata-kata BUAT dan VARIABEL menggunakan penangan DOVAR yang sama. Pawang ini mendorong pada stack alamat variabel yang terletak di bidang parameter, yang langsung muncul setelah byte bidang kode. Variabel VARIABEL menempati 2 byte, dan array yang dibuat menggunakan CREATE mengandung sebanyak byte yang diinginkan oleh programmer.
DOVAR: β 3 x 1 7 + 9
Perintah β KP3 menyimpan konten register Y di tumpukan data.Pada saat yang sama, nomor dari atas tumpukan dimasukkan ke RY, membebaskan RX ke nilai baru. Setelah perintah Cx 1 IP7 +, nilai baru ini di bagian atas tumpukan menjadi alamat bidang parameter kata yang dapat dieksekusi. KBP9 mentransfer kontrol ke INEXT, tanpa trik apa pun, beralih ke kata berikutnya.
3.3.3 Penangan Konstan: DOCON dan DOCONM
Tidak seperti DOVAR,
pengendali konstan mengakses bidang parameter dari kata itu sendiri. DOCON membaca nilai konstan 16-bit darinya. Nilai ini selalu positif.
DOCON: β 3 β 7 5 x 256 5 Γ 5 + 9
Perintah β KP3 β simpan RY di tumpukan data. Tapi kali ini, bagian atas tumpukan data kembali ke RX. Perintah IP7 P5 memaksanya kembali ke RY, sambil mempersiapkan register pointer R5 untuk membaca nilai konstanta. Selanjutnya, Cx 256 menggantikan sampah di register X dengan nomor 256.
Instrumen KIP5 Γ KIP5 + membaca konstanta dari bidang parameter ke atas tumpukan data, yaitu di RX. Seperti yang kita ingat, di MK-161 byte pertama selalu tinggi. Ini dikalikan dengan 256, setelah itu byte terkecil dari konstanta ditambahkan ke produk. Semua pekerjaan selesai, KBP9 mentransfer kontrol ke kata berikutnya.
DOCONM bekerja dengan cara yang persis sama, hanya tanda konstan setelah membaca perubahan yang berlawanan. Konstanta negatif diimplementasikan pada MK-161 sebagai prosesor terpisah demi kecepatan:
DOCONM: β 3 β 7 5 x 256 5 Γ 5 + /-/ 9
Sekarang kita telah benar-benar mengetahui bagaimana eForth mengeksekusi kodenya pada MK-161 Electronics dari area data, bahkan menyentuh topik yang lebih dalam dari string literal (lihat 3.1.5).
Dalam artikel kedua seri ini, saya akan berbicara tentang penerjemah βteksβ eksternal, menganalisis, tabel tajuk dan pengenalan nama. Bagian penerjemah ini mengharuskan saya untuk mengembangkan solusi yang jauh lebih radikal, dengan latar belakang yang dibahas di atas adalah Benteng tradisional, tua dan baik.
Pemrograman Happy Fort!
Sastra
- Dr. Chen-Hanson Ting. eForth dan Zen - Edisi ke-3, 2017. Tersedia di Amazon Kindle.
- Baranov S.N., Nozdrunov N.R. Bahasa Fort dan implementasinya. - L.: Teknik mesin. Leningrad Departemen, 1988.
- Semenov Yu.A. Pemrograman dalam bahasa FORT. - M.: Radio dan komunikasi, 1991.
- ANS Keempat standar. X3.215-1994. Terjemahan
- Dokumentasi SP-Forth .
- Offete Store (Prosiding Dr. Chen-Hanson Ting) , tempat Anda dapat mengunduh 86eForth v5.2 untuk Windows, dokumentasi dalam bahasa Inggris.
Ilustrasi video
Keempat video kecil ini dilanjutkan. Video pertama di awal artikel.
Bagian 2 dari 5. Tes TEST-TEST4 dari buku "eForth and Zen", edisi ke-3, pada MK-161.
Bagian 3 dari 5. LIHAT dekompiler.
Bagian 4 dari 5. Breakpoint BYE, terminal RS-232 dan akses jarak jauh ke MK-161.
Bagian 5 dari 5. Kata penutup.