Gambar 1: Komputer relay BrainfuckPC di latar belakang pembuatnyaMelanjutkan tradisi mulia dari intisari tahunan proyek komputer saya yang paling gila, saya sajikan kepada Anda artikel ketiga dan
terakhir tentang proyek komputer relay BrainfuckPC.
Dalam seri sebelumnya:
Setelah sepuluh tahun bermimpi dan berefleksi, lebih dari dua tahun kerja dan perakitan yang tidak tergesa-gesa, saya dapat mengatakan dengan yakin bahwa proyek komputer relay telah terjadi. Terlepas dari kenyataan bahwa komputer tidak berguna dari sudut pandang praktis, dan juga sering crash, itu telah menjadi titik awal untuk selanjutnya, proyek cyber yang tidak kalah gila.
Di bawah pemotong adalah blok relai dering, perhitungan relai tercepat di dunia, penutup, indikator vakum, dan banyak lagi.
Brainfuck bahasa pemrograman
Bahasa pemrograman brainfuck mungkin adalah bahasa pemrograman esoterik paling populer di dunia. Dan pada saat yang sama,
Turing yang asli adalah rawa yang lengkap . Hanya 8 instruksi di mana Anda dapat menulis apa pun, tetapi untuk waktu yang sangat lama.
Sebagai contoh, saya butuh tiga hari untuk menulis dan men-debug program divisi 355/113, yang mencetak 6 tempat desimal ke terminal.
Gambar 2: instruksi bahasa brainfuckSeluruh sintaks bahasa dibangun di sekitar RAM untuk 30 ribu sel memori, dengan kapasitas 8 bit.
- Dengan dua instruksi + dan -, kami mengubah nilai dalam sel data saat ini dengan satu naik atau turun.
- Dengan dua instruksi < dan > kita mengubah pointer ke sel data saat ini dengan satu, sehingga bergerak ke kiri atau ke kanan melalui memori.
- Dua instruksi lagi [ dan ] - memungkinkan kami untuk mengatur loop. Segala sesuatu di dalam kurung adalah badan loop. Loop bersarang diizinkan. Logika instruksi sederhana - jika nilai sel data saat ini tidak sama dengan nol - kita akan melakukan satu iterasi dari loop, jika itu sama, maka kita keluar dari loop.
- Dua instruksi terakhir . dan , - memungkinkan Anda untuk menampilkan nilai sel saat ini di konsol, atau memasukkan RAM-nya. Dengan demikian interaktivitas tercapai.
Ya, ini lebih dari cukup untuk menulis program apa pun. Keberadaan kompiler C
di brainfuck tampaknya mengisyaratkan hal ini. Tetapi kepadatan kode tidak ada. Untuk melakukan operasi sederhana, seperti menambahkan nilai dua sel memori, Anda perlu menjalankan ratusan instruksi brainfuck.
brainfuck ++
Mari kita coba untuk meningkatkan kepadatan kode setidaknya sedikit. Saat mempelajari program yang ditulis dalam bahasa ini, Anda dapat memperhatikan bahwa sebagian besar terdiri dari urutan instruksi yang sama
+ - <> . Ini membawa banyak orang pada ide melipat urutan instruksi seperti itu menjadi satu dan mendapatkan sedikit peningkatan produktivitas, yang dari satu program ke program lainnya dapat mencapai puluhan persen, dan memberikan peningkatan kecepatan ganda. Misalnya, kami mengganti 10 operasi kenaikan dengan operasi +10. 20 operasi memindahkan pointer ke kanan ke operasi> 20 dan seterusnya.
Gambar 3: instruksi bahasa Brainfuck ++Dari teori ke praktik
Seperti yang Anda pahami, orang tidak bisa hanya mengambil dan menulis dalam bahasa brainfuck operasi Rb = Ra + Rb, di mana Ra dan Rb adalah sel memori. Yang bisa kita lakukan adalah mengubah isi sel menjadi konstanta dan memeriksa apakah itu nol. Akibatnya, untuk menjumlahkan dua angka, yang tersisa bagi kita adalah melakukan +1 untuk sel Rb dan -1 untuk sel Ra, hingga isi sel Ra menjadi nol. Kami menulis ini dalam bentuk kode di C:
void addMov(Memory &mem, uint16_t RbPos) { while (*mem) { mem += RbPos; (*mem)++; mem -= RbPos; (*mem)--; } }
Akibatnya, nilai lama akan muncul di sel RbPos plus apa yang ada di alamat sumber. kelas Memory - wadah dengan sel integer 65k. Properti utamanya adalah bahwa melimpahnya nilai pointer akan mengembalikannya ke awal array. Seperti di perangkat keras asli saya.
Kerugian dari fungsi yang dijelaskan adalah hilangnya nilai asli - itu akan diatur ulang ke nol. Tambahkan variabel Rc lain untuk menyimpannya:
void addCpy(Memory &mem, uint16_t RbPos, uint16_t RcPos) { while (*mem) { mem += RbPos; (*mem)++; mem -= RbPos; (*mem)--; mem += RcPos; (*mem)++; mem -= RcPos; } }
Akibatnya, istilah yang disalin akan terletak di sel RcPos. Nah, jika dulu ada nol.
Karena notasi yang saya gunakan sangat mirip dengan brainfuck ++ - kami hanya menulis ulang fungsi kami dalam karakter bfpp, mengambil RbPos untuk 4 dan RcPos untuk 5 sebagai contoh:
[
>>>>
+
<<<<
-
>>>>>
+
<<<<<
]
Setelah menggambarkan semua primitif, Anda dapat mulai menggabungkan mereka ke dalam struktur yang lebih kompleks dan mendapatkan program fungsionalitas yang diperlukan. Sebagai hasilnya, Anda bisa mendapatkan program yang membagi 355 dengan 113 (atau angka lain di atas satu sama lain dalam 16 bit)
Program titik mengambang class Memory { public: Memory() { memset(m_mem, 0, sizeof(m_mem)); memPtr = 0; } Memory& operator += (uint16_t ptr) { memPtr += ptr; return *this; } Memory& operator -= (uint16_t ptr) { memPtr -= ptr; return *this; } uint16_t& operator [] (uint16_t ptr) { return this->m_mem[ptr]; } Memory& operator = (uint16_t ptr) { memPtr = ptr; return *this; } uint16_t & operator * () { return m_mem[memPtr]; } Memory& operator ++ () { memPtr++; return *this; } Memory& operator -- () { memPtr--; return *this; } private: uint16_t memPtr; uint16_t m_mem[65536]; }; void calcPi() { Memory mem; *mem = 22; mem += 1; *mem = 7; while (*mem) { mem += 1; (*mem)++; mem -= 1; (*mem)--; mem += 2; (*mem)++; mem -= 2; }
Relay Arsitektur Komputer
Elemen sentral dari prosesor relay adalah penambah penuh 16-bit dengan carry paralel. Dua register terhubung pada input. TMP adalah register sementara di mana nilai lama ditempatkan, dan CMD adalah register perintah di mana instruksi dan konstanta dimana nilai lama akan diubah disimpan.
Oleh karena itu, saya dapat melakukan operasi brainfuck ++ yang dioptimalkan, dan pada saat yang sama mendapatkan lompatan bersyarat penuh - Lompat Jika Nol dan Lompat Jika Tidak Nol ke sisi program mana pun.
Hasil dari operasi penjumlahan dapat diunggah ke salah satu register konteks - AP - dengan jumlah sel data saat ini, atau IP - dengan jumlah instruksi saat ini. Selain itu, hasilnya dapat diunggah ke sel RAM saat ini, jika menyangkut instruksi
+ dan
-
Gbr. 4: Relay arsitektur komputer dalam operasi. Tahap memuat instruksi baru digantikan oleh tahap pelaksanaannya.Pertama-tama, kita perlu menghitung jumlah instruksi selanjutnya - mis. melakukan operasi IP ++. Untuk melakukan ini, satu ditambahkan ke nilai lama register IP, hasilnya ditulis kembali ke register IP, dan instruksi selanjutnya dimuat di alamat baru ini, dalam register CMD.
Langkah kedua adalah pelaksanaan instruksi yang baru dimuat. Jika bekerja dengan penambah, proses pelaksanaannya terlihat mirip dengan proses memuat instruksi baru - nilai lama ada di register sementara, kami menambahkan konstanta yang terletak di bit yang lebih rendah dari register CMD, dan menulis hasilnya kembali ke register atau sel data saat ini.
Dengan demikian, instruksi dieksekusi dalam satu tick dari clock generator. Di depan yang jatuh, kami memuat instruksi berikutnya, pada peningkatan - kami menjalankannya.
bukan bug, tetapi fiturDan di sini satu fitur terungkap. Setelah menyalakan komputer, depan pertama clock generator akan meningkat, dan karena itu - kita harus menjalankan instruksi saat ini, yang belum ada yang dimuat ke dalam register CMD - ada nol.
Ikuti instruksi kosong dan ... lakukan IP ++!
Akibatnya, sel memori nol dari program berisi nol dan tidak akan pernah dieksekusi. Instruksi pertama yang dimuat dari memori akan menjadi instruksi pada 0x0001.
Set instruksi
Gbr. 5: Relay set instruksi komputerInstruksi 16-bit, di mana 4 bit orde tinggi bertanggung jawab untuk jenis instruksi dan orde 12 bit adalah payload. Dalam kebanyakan kasus ini adalah konstanta.
- Instruksi NOP - diabaikan.
- Instruksi CTRLIO adalah instruksi khusus yang perilakunya dikodekan oleh bitmask payload. Pertama-tama, ia mengimplementasikan perintah untuk menulis ke konsol dan membaca dari konsol (dalam mode sinkron atau asinkron). Kedua, ini memungkinkan Anda untuk mengatur mode pengoperasian mesin 16-bit atau 8-bit. Dan ketiga, menggunakan instruksi CTRLIO.HALT, Anda dapat menghentikan mesin. Yang lucu adalah topeng itu bit
non-blocking. Anda dapat mengaturnya setidaknya sekaligus, tetapi perilaku mesin tidak akan ditentukan. - Instruksi ADD adalah operasi sel data. Mengubah nilai dalam sel dengan nilai konstanta. Dalam hal ini, bit 12 adalah bit yang ditandatangani dan disalin ke bit 13-15. Oleh karena itu, instruksi 0x2ffe berubah menjadi operasi * AP + = 0x0ffe, dan instruksi 0x3ffe berubah menjadi * AP + = 0xfffe. Operasi pengurangan diganti dengan penambahan dengan angka negatif.
- Instruksi ADA - mengimplementasikan operasi AP + = const dan memungkinkan Anda menavigasi memori.
- Instruksi JZ dan JNZ bersyarat. Bergantung pada Z-flag, Anda bisa melompati beberapa instruksi ke depan atau ke belakang, atau tetap di tempatnya. Bergantung pada mode operasi mesin - 16 atau 8 bit, status Z-flag ditentukan oleh byte data yang paling tidak signifikan atau keseluruhan kata.
Spesifikasi teknis
BrainfuckPC adalah komputer 16-bit dengan prosesor reed relay, arsitektur Von Neumann, dan set instruksi Brainfuck ++
- Total jumlah relay: 578 buah
- Jumlah total elemen logika: 157 buah
- Lebar Bus Alamat: 16 bit
- Mengatasi: kata demi kata
- RAM: 128KB (64 Kslov)
- Lebar Bus Data: 16bit / 8bit
- Frekuensi jam (saat ini / maksimum): 25Hz / 40Hz
- Konsumsi Daya: 70W
- Dimensi keseluruhan: 110kh650kh140mm
- Berat: 15kg
Awalnya, diasumsikan bahwa komputer akan beroperasi pada frekuensi hingga 100 Hz ... Dan ini - selama satu menit - 4 oktaf piano. Sayangnya, tes pertama menunjukkan bahwa 40Hz adalah langit-langit, tetapi ada banyak hal ini untuk rangkaian relay. Terlebih lagi ketika clocking eksternal diperlukan untuk menerapkan dua pulsa per siklus - karena kekhasan sirkuit sinkronisasi dengan sinyal eksternal. 80Hz untuk musik sudah merupakan sesuatu.
Komposisi Komputer
Gbr. 6: Komponen utama komputer relai.Mari kita lihat lebih dekat komputer. Hampir seluruh volume mesin ditempati oleh unit prosesor relay. Saat ini, semuanya pas dalam lima blok, tetapi ada ruang untuk enam - jadi jika Anda benar-benar ingin, maka nanti fungsi prosesor dapat diperluas.
Setiap blok berisi 32 modul, di masing-masing modul ada 3 atau 4 reed relay RES55 dan RES64. Catu daya setiap unit adalah 5V, 3A.
Gbr. 7: Serangkaian blok dan modul prosesor estafet, siap dipasang pada bingkai.Setiap modul disatukan. 60x44mm, konektor 16-pin. Ketika merakit blok logika, saya memasukkan modul yang diperlukan ke slot gratis dan mem-flash koneksi.
Gbr. 8: Modul D-flip-flop diperiksa untuk operabilitas.Baris tengah - blok penambah dan register blok. Di atas dan di bawahnya terdapat kait 16-bit berdasarkan RES43, yang mengalihkan aliran data di antara blok. Semua data berputar di sini.
Baris bawah adalah deretan blok logika prosesor. Sekarang dua blok sebagian terisi, tetapi jika Anda benar-benar ingin, maka memodifikasi dan memperluas fungsi karena ruang kosong lebih dari mungkin.
Gbr. 9: Bingkai dirakit dari lembaran aluminium 2mm, dari bawah pemotongan laser. Dalam foto - bingkai sudah dilas dan prima, siap untuk melukis.Bagian atas adalah indikator. Di sebelah kiri adalah blok status mesin - indikator berdasarkan pada IV-6 menampilkan jumlah sel memori saat ini dan malam instruksi saat ini, instruksi itu sendiri, dan konter umum dari instruksi yang dieksekusi. Yang terakhir ini sangat berguna, karena jika emulator, misalnya, mengatakan bahwa hingga karakter pertama di konsol Anda perlu menjalankan 30 ribu instruksi, penghitung akan dengan jelas menunjukkan di mana mesin sekarang dan kapan akan selesai menghitung.
Gbr. 10: Tampilan akhir area indikator. Dalam proses pembuatannya.Di sebelah kanan adalah kartu memori - elemen paling kontroversial dari mesin. Walaupun saya percaya bahwa komputer masih relay, prosesornya pasti 100% relay. Pinggirannya lebih modern. Secara khusus, RAM adalah chip memori statis. Namun demikian, hampir semua pencipta komputer relay modern.
Gbr. 11: Programmer. 16 jalur alamat, 16 jalur data, daya, ground, dan jalur baca tulis. Total 36 kontak.Karena memori program dan data dibagikan, seseorang atau sesuatu, setiap kali Anda menyalakan komputer, harus memuat program ke dalam RAM. Tugas ini ditugaskan untuk programmer. Saat ini, programmer berada di papan memori itu sendiri. Sekarang dia memiliki dua tugas.
- Unduh program dalam RAM, karena setiap kali Anda menyalakan daya untuk melakukannya secara manual menggunakan sakelar sakelar adalah kemalasan basi, meskipun kemungkinan ini ada.
- Monitor keadaan wilayah memori tertentu dan tampilkan pada matriks LED 32x16.
Ini tidak mempengaruhi prosesor, dan untuk melihat secara real time apa yang terjadi pada RAM sangat berguna saat debugging. Selanjutnya, ketika programmer berada di luar, panel LED akan melayani salah satu modul indikator. Dia sudah tahu alamatnya, masih memberinya input data.
Gbr. 12: Blokir diagram periferal prosesor.Jadi dalam waktu dekat sirkuit periferal prosesor akan terlihat seperti. Hanya chip memori dan sirkuit pencocokan sinyal dengan sirkuit relai yang akan tetap berada di papan memori.
Melalui konektor pemrograman 36-pin, Anda dapat menghubungkan programmer dan mengunduh firmware ke komputer. Selain programmer, memiliki konverter antarmuka yang diperlukan, Anda dapat menggunakan perangkat lain. Setidaknya pembaca tape punch (omong-omong, saya punya satu, lengkap dengan punch punch dan bahkan satu gulungan tape), bahkan sebuah panel dengan sakelar sakelar.
Akibatnya, logika relai menyediakan antarmuka tertentu, dan konverter antarmuka bisa berupa apa saja. Omong-omong, konektor antarmuka paralel akan kompatibel dengan LPT ...
Demonstrasi pekerjaan dan status saat ini
Pertama-tama, program Hello World dari artikel wikipedia dieksekusi di komputer.
Kode sumber adalah sebagai berikut:
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++
.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.
------.--------.>+.>.
Berkat panel LED, Anda dapat melihat dengan jelas bagaimana data berubah:
Meskipun pada frekuensi 25 Hz sulit untuk melacak apa yang terjadi di RAM.
Tugas yang lebih berguna dan praktis adalah menghitung tanda-tanda angka Pi setelah titik desimal. Jelas bahwa komputer modern telah memecahkan masalah ini
hingga 31,4 triliun karakter . Tetapi fakta bahwa BrainfuckPC mampu melakukan operasi ini menunjukkan bahwa komputer relay tidak 100% tidak berguna, tetapi hanya 99,9.
Pertama-tama, saya menemukan
algoritma perhitungan yang sudah jadi yang ditulis dalam brainfuck .
> ++++ (4 digits)
[<+>>>>>>>>++++++++++<<<<<<<-]>+++++[<+++++++++>-]+>>>>>>+[<<+++[>>[-<]<[>]<-]>>
[>+>]<[<]>]>[[->>>>+<<<<]>>>+++>-]<[<<<<]<<<<<<<<+[->>>>>>>>>>>>[<+[->>>>+<<<<]>
>>>>]<<<<[>>>>>[<<<<+>>>>-]<<<<<-[<<++++++++++>>-]>>>[<<[<+<<+>>>-]<[>+<-]<++<<+
>>>>>>-]<<[-]<<-<[->>+<-[>>>]>[[<+>-]>+>>]<<<<<]>[-]>+<<<-[>>+<<-]<]<<<<+>>>>>>>
>[-]>[<<<+>>>-]<<++++++++++<[->>+<-[>>>]>[[<+>-]>+>>]<<<<<]>[-]>+>[<<+<+>>>-]<<<
<+<+>>[-[-[-[-[-[-[-[-[-<->[-<+<->>]]]]]]]]]]<[+++++[<<<++++++++<++++++++>>>>-]<
<<<+<->>>>[>+<<<+++++++++<->>>-]<<<<<[>>+<<-]+<[->-<]>[>>.<<<<[+.[-]]>>-]>[>>.<<
-]>[-]>[-]>>>[>>[<<<<<<<<+>>>>>>>>-]<<-]]>>[-]<<<[-]<<<<<<<<]++++++++++.
Satu masalah - walaupun dikatakan bahwa program ini jauh lebih cepat daripada beberapa program lain, masih menghitung karakter berikutnya, ini sangat lambat.
Gambar 13: Waktu yang diperlukan untuk menampilkan N digit Pi setelah titik desimal.4 tempat desimal harus menunggu hampir satu setengah jam ...
Gbr. 14: - Pi = 3! - Sungguh kasar!Namun, bahkan dua karakter tidak benar-benar dapat disimpulkan, sebagai gantinya, komputer menyatakan bahwa Pi berusia 4 dan menyelesaikan pekerjaan.
Gbr. 15: Dia jelas tahu tentang lelucon yang di bawah darurat militer, pi bisa naik hingga empat.Saya memutuskan untuk pergi ke arah lain dan menulis kalkulator pecahan
. Akurasi - 6 tempat desimal! Ini adalah hasil paling akurat untuk pecahan dengan jumlah ukuran yang memadai.
Setelah tiga malam tanpa tidur, saya menulis sebuah program di brainfuck, yang mampu membagi dua angka menjadi satu sama lain dan mengeluarkan hasilnya dengan titik apung ke terminal. Vonis emulator adalah sebagai berikut - ini akan membutuhkan 60 ribu instruksi untuk dieksekusi. Terakhir, 10 ribu per tanda:
Gbr. 16: Waktu yang diperlukan untuk menampilkan tempat desimal berikutnya saat menghitung fraksi.Seberapa cepat nilai-nilai selanjutnya akan muncul. Saya harus mengatakan dengan sangat cepat dibandingkan dengan program sebelumnya!
Tapi kebahagiaan berumur pendek - komputer mulai gagal dalam mode 16-bit. Diagnostik menunjukkan bahwa kartu memori bodoh - terus-menerus menetapkan bit ke-13. Saya akan membuat kartu memori baru dan semuanya akan berlalu, tetapi untuk saat ini saya akan membatasi diri untuk sebagian
dua tempat desimal dan mode operasi 8 bit. Yang paling penting, hanya membutuhkan 1.600 instruksi yang harus diikuti! Pada frekuensi 25 Hz, ini hanya lebih dari satu menit.
Berulang kali dan dengan peluit, komputer mengatasi tugas itu.
Dilanjutkan ...
Sekarang di komputer Anda dapat menjalankan program yang tidak memerlukan input pengguna. Sejauh ini, saya belum pernah mengacaukan instruksi CTRLIO.CIN :) Dan saya tidak akan melakukan ini dalam waktu dekat. Komputer saat ini 98% selesai. Dan setelah dua tahun bekerja, banyak proyek telah terakumulasi yang sedang menunggu saat ketika saya akan menghadapinya.
Karena itu, saya beralih ke proyek lain
Pertama-tama, ini adalah komputer tabung berdasarkan decatron komutator. Saya sudah memiliki pukulan dan decatron sendiri (meskipun sebagian besar A101 - komputer akan keluar lebih lambat daripada relay pada mereka - kita perlu A103). Bahkan 700 tabung vakum sudah tersedia dan banyak lagi ...

Saya telah menyiapkan memori untuk itu -
16 buah kubus memori terintegrasi untuk 128 kata masing-masing 16-bit. Di dalam - pelat ferit multi-lubang, semacam cabang memori pada cincin ferit.
Saya juga tidak melupakan pneumonia - teman saya Anton terlibat dalam alam. eksperimen, tetapi lebih pada waktu berikutnya.
... meninggalkan ketidaksempurnaan berikut. Saya akan menyelesaikan bagian dari masalah untuk festival pada akhir Mei, bagian - tidak:
- Kartu memori baru yang hanya memasang chip RAM dan harness-nya. Ada papan sirkuit untuk kartu memori, papan sirkuit belum bercerai. Di rumah, akan terlalu malas untuk melakukannya (dua arah yang cukup padat), oleh karena itu saya akan memasukkan papan ini dalam urutan ketika saya memesan papan untuk beberapa proyek lain - jam mekanis pada relay dan pneumoscope.
- Seiring dengan papan memori baru, indikator dial, perangkat keras tampilan terminal normal dan logika independen untuk memperbarui panel LED akan datang.
- Programmer, atau lebih tepatnya, pengembangan firmware untuk itu. Secara umum, jika Anda memiliki kartu memori lama, itu berlebihan, tetapi karena konektor pemrograman tersedia, Anda sudah dapat memuat program dengan itu.
- Logika waktu. Di sini saya benar-benar malas, karena secara harfiah mengikat 3 modul logis. Saya pasti akan melakukannya untuk festival pada akhir Mei.
- Instruksi membaca dari konsol. Itu terikat dengan logika waktu (dalam operasi sinkron, komputer harus menghentikan operasi dan menunggu data tiba).
- Kirim permintaan ke Guinness Book of Records ... Sebagai prosesor relay tercepat dan pada saat yang sama membaca paling lambat. 16 milliFlops bukan untuk Anda untuk "Tuck a Fur Coat into Underpants" (dari komentar di youtube).

Semua dokumentasi di komputer relay ada di dalam
repositori di GitHub , dan Anda dapat memonitor statusnya di jejaring sosial apa pun menggunakan tautan di profil saya.
UPD: Saya menolak untuk berpartisipasi dalam festival.
Namun - pada 25-26 Mei, di Moskow, di wilayah Pabrik Roti, festival produksi kerajinan pertama dan Antifactory budaya DIY akan diadakan. Saya akan hadir di sana dengan komputer relay dan saya akan membawa controller relay untuk autowatering juga. Masuk ke acara ini gratis, jadi Anda akan berada di Moskwa hari ini - jangan lewatkan kesempatan untuk melihat monster relai saya hidup. Jika saya membuatnya aman dan sehat, saya pasti akan menunjukkannya dalam pekerjaan.