*Jika parameter program pengguna menunjuk ke sebagian memori di halaman 3 (halaman terakhir), ada konflik karena kernel akan selalu memetakan halaman RAM -nya di dalam halaman yang sama persis ini selama syscall. Dengan demikian, itu akan memetakan kembali halaman 3 ke halaman 2 (halaman ketiga) untuk mengakses parameter program. Tentu saja, jika parameternya adalah petunjuk, mereka akan dimodifikasi untuk membiarkannya menunjuk ke alamat virtual baru (dengan kata lain, pointer akan dikurangi dengan 16kb untuk membiarkannya menunjuk ke halaman 2).
Untuk dapat port Komputer OS 8-bit ke Z80 yang tidak memiliki MMU/Memory Mapper yang diatur seperti yang ditunjukkan di atas, kernel memiliki mode baru yang dapat dipilih melalui menuconfig : NO-MMU.
Dalam mode ini, kode OS masih diharapkan dipetakan pada 16kb pertama memori, dari 0x0000 hingga 0x3FFF dan sisanya diharapkan menjadi RAM.
Idealnya, RAM 48kb harus dipetakan mulai dari 0x4000 dan akan naik ke 0xFFFF , tetapi dalam praktiknya, dimungkinkan untuk mengkonfigurasi kernel untuk mengharapkan kurang dari itu. Untuk melakukannya, dua entri dalam menuconfig harus dikonfigurasi dengan tepat:
KERNEL_STACK_ADDR : Ini menandai akhir dari area ram kernel, dan, seperti namanya, akan menjadi bagian bawah tumpukan kernel.KERNEL_RAM_START : Ini menandai alamat mulai dari kernel ram di mana tumpukan, semua variabel yang digunakan oleh kernel dan pengemudi akan disimpan. Tentu saja, harus cukup besar untuk menyimpan semua data ini. Untuk informasi, ukuran bagian BSS kernel saat ini sekitar 1kb. Kedalaman tumpukan tergantung pada implementasi driver target. Mengalokasikan 1KB untuk tumpukan harus lebih dari cukup selama tidak ada buffer (besar) disimpan di atasnya. Secara keseluruhan mengalokasikan setidaknya 3KB untuk domba kernel harus aman dan tahan masa depan.Singkatnya, berikut adalah diagram untuk menunjukkan penggunaan memori:
Mengenai program pengguna, alamat tumpukan akan selalu diatur ke KERNEL_RAM_START - 1 oleh kernel sebelum dieksekusi. Ini juga sesuai dengan alamat byte terakhirnya yang tersedia di ruang alamat yang dapat digunakan. Ini berarti bahwa suatu program dapat menentukan ukuran RAM yang tersedia dengan melakukan SP - 0x4000 , yang memberikan, dalam perakitan:
ld hl, 0
add hl, sp
ld bc, -0x4000
add hl, bc
; HL contains the size of the available RAM for the program, which includes the program's code and its stack.
Z80 menyajikan beberapa register tujuan umum, tidak semuanya digunakan dalam kernel, berikut adalah ruang lingkup masing-masing:
| Daftar | Cakupan |
|---|---|
| AF, BC, DE, HL | Sistem & Aplikasi |
| Af ', bc', de ', hl' | Penangan interupsi |
| IX, IY | Aplikasi (tidak digunakan di OS) |
Ini berarti bahwa OS tidak akan mengubah register IX dan IY, sehingga mereka dapat digunakan secara bebas dalam aplikasi.
Register alternatif (nama diikuti oleh ' ) hanya dapat digunakan dalam penangan interupsi 1 . Aplikasi tidak boleh menggunakan register ini. Jika karena alasan tertentu, Anda masih harus menggunakannya, harap pertimbangkan untuk menonaktifkan interupsi selama mereka digunakan:
my_routine:
di ; disable interrupt
ex af, af' ; exchange af with alternate af' registers
[...] ; use af'
ex af, af' ; exchange them back
ei ; re-enable interrupts
Perlu diingat bahwa menonaktifkan interupsi terlalu lama bisa berbahaya karena sistem tidak akan menerima sinyal dari perangkat keras (timer, keyboard, gpio ...)
Z80 menyediakan 8 vektor reset yang berbeda, karena sistem ini dimaksudkan untuk selalu disimpan di halaman virtual pertama memori, ini semua disediakan untuk OS:
| Vektor | Penggunaan |
|---|---|
| $ 00 | Reset perangkat lunak |
| $ 08 | Syscall |
| $ 10 | Melompat ke alamat di HL (dapat digunakan untuk memanggil HL) |
| $ 18 | Tidak digunakan |
| $ 20 | Tidak digunakan |
| $ 28 | Tidak digunakan |
| $ 30 | Tidak digunakan |
| $ 38 | Dicadangkan untuk Mode Interuprik 1, dapat digunakan dengan implementasi target |
Ketika program pengguna dieksekusi, kernel mengalokasikan 3 halaman RAM (48KB), membaca file biner untuk mengeksekusi dan memuatnya mulai dari alamat virtual 0x4000 secara default. Alamat virtual titik entri ini dapat dikonfigurasi melalui menuconfig dengan opsi KERNEL_INIT_EXECUTABLE_ADDR , tetapi perlu diingat bahwa program yang ada tidak akan berfungsi lagi tanpa dikompilasi ulang karena tidak dapat dipindahkan saat runtime.
Seperti dijelaskan di bawah ini, Syscall exec mengambil dua parameter: nama file biner untuk dieksekusi dan parameter.
Parameter ini harus berupa string yang diakhiri nol yang akan disalin dan ditransmisikan ke biner untuk dieksekusi melalui register DE dan BC :
DE berisi alamat string. String ini akan disalin ke ruang memori program baru, biasanya di atas tumpukan.BC berisi panjang string itu (jadi, tidak termasuk null-byte). Jika BC adalah 0, DE harus dibuang oleh program pengguna. Sistem bergantung pada syscall untuk melakukan permintaan antara program pengguna dan kernel. Dengan demikian, ini akan menjadi cara untuk melakukan operasi pada perangkat keras. Operasi yang mungkin tercantum dalam tabel di bawah ini.
| Num | Nama | Param. 1 | Param. 2 | Param. 3 |
|---|---|---|---|---|
| 0 | membaca | u8 dev | U16 buf | Ukuran U16 |
| 1 | menulis | u8 dev | U16 buf | Ukuran U16 |
| 2 | membuka | U16 Nama | Bendera U8 | |
| 3 | menutup | u8 dev | ||
| 4 | dstat | u8 dev | U16 DST | |
| 5 | Stat | U16 Nama | U16 DST | |
| 6 | mencari | u8 dev | Offset U32 | u8 dari mana |
| 7 | ioctl | u8 dev | u8 cmd | u16 arg |
| 8 | mkdir | Jalur U16 | ||
| 9 | chdir | Jalur U16 | ||
| 10 | Curdir | Jalur U16 | ||
| 11 | OpenDir | Jalur U16 | ||
| 12 | readdir | u8 dev | U16 DST | |
| 13 | rm | Jalur U16 | ||
| 14 | gunung | u8 dev | Surat U8 | U8 fs |
| 15 | KELUAR | kode u8 | ||
| 16 | EXEC | U16 Nama | u16 argv | |
| 17 | dup | u8 dev | u8 ndev | |
| 18 | msleep | durasi U16 | ||
| 19 | setTime | ID U8 | waktu u16 | |
| 20 | Getikan waktu | ID U8 | waktu u16 | |
| 21 | setDate | Tanggal U16 | ||
| 22 | Getdate | Tanggal U16 | ||
| 23 | peta | U16 DST | U24 SRC | |
| 24 | menukar | u8 dev | u8 ndev |
Silakan periksa bagian di bawah ini untuk informasi lebih lanjut tentang masing -masing panggilan ini dan parameternya.
Catatan : Beberapa syscall mungkin tidak diimplementasikan. Misalnya, pada komputer di mana direktori tidak didukung, syscall terkait direktori dapat dihilangkan.
Untuk melakukan syscall, nomor operasi harus disimpan dalam register L , parameter harus disimpan mengikuti aturan ini:
| Nama parameter di API | Daftar Z80 |
|---|---|
| u8 dev | H |
| u8 ndev | E |
| Bendera U8 | H |
| u8 cmd | C |
| Surat U8 | D |
| kode u8 | H |
| U8 fs | E |
| ID U8 | H |
| u8 dari mana | A |
| U16 buf | DE |
| Ukuran U16 | BC |
| U16 Nama | BC |
| U16 DST | DE |
| u16 arg | DE |
| Jalur U16 | DE |
| u16 argv | DE |
| durasi U16 | DE |
| waktu u16 | DE |
| Tanggal U16 | DE |
| U24 SRC | HBC |
| Offset U32 | BCDE |
Dan akhirnya, kode harus melakukan instruksi RST $08 (silakan periksa vektor reset).
Nilai yang dikembalikan ditempatkan di A. Arti dari nilai itu khusus untuk setiap panggilan, silakan periksa dokumentasi rutinitas terkait untuk informasi lebih lanjut.
Untuk memaksimalkan kompatibilitas program pengguna dengan kernel OS 8-bit semangat, terlepas dari apakah kernel dikompilasi dalam mode MMU atau NO-MMU, batasan parameter syscall adalah sama:
Buffer apa pun yang diteruskan ke syscall tidak boleh melintasi halaman virtual 16kb
Dengan kata lain, jika buffer buf ukuran n terletak di halaman virtual i , byte terakhirnya, diarahkan oleh buf + n - 1 , juga harus ditempatkan di halaman yang sama persis i .
Misalnya, jika read syscall dipanggil dengan:
DE = 0x4000 dan BC = 0x1000 , parameternya benar , karena buffer yang ditunjuk oleh DE cocok ke halaman 1 (dari 0x4000 hingga 0x7FFF )DE = 0x4000 dan BC = 0x4000 , parameternya benar , karena buffer yang ditunjuk oleh DE pas ke halaman 1 (dari 0x4000 hingga 0x7FFF )DE = 0x7FFF dan BC = 0x2 , parameternya salah , karena buffer yang ditunjuk oleh DE adalah di antara halaman 1 dan halaman2.exec Meskipun semangat 8-bit OS adalah sistem operasi mono-tasking, ia dapat mengeksekusi dan menyimpan beberapa program dalam memori. Ketika suatu program A mengeksekusi program B berkat syscall exec , itu harus memberikan parameter mode yang dapat berupa EXEC_OVERRIDE_PROGRAM atau EXEC_PRESERVE_PROGRAM :
EXEC_OVERRIDE_PROGRAM : Opsi ini memberi tahu kernel bahwa program A tidak perlu dieksekusi lagi, jadi program B akan dimuat dalam ruang alamat yang sama dengan program A. Dengan kata lain, program B akan dimuat di dalam halaman RAM yang sama dengan program A, itu akan menimpanya.EXEC_PRESERVE_PROGRAM : Opsi ini memberi tahu kernel bahwa program A perlu disimpan di RAM sampai Program B menyelesaikan eksekusi dan memanggil Syscall exit . Untuk melakukannya, kernel akan mengalokasikan 3 halaman memori baru ( 16KB * 3 = 48KB ) di mana ia menyimpan program yang baru dimuat B. Setelah program B keluar, kernel membebaskan halaman yang dialokasikan sebelumnya untuk program B, halaman memori pemesanan Program A, dan memberikan kembali tangan untuk memprogram A. Jika diperlukan, nilai ekstit B's Retrieve B Retrieve B. Kedalaman pohon eksekusi didefinisikan dalam menuconfig , berkat opsi CONFIG_KERNEL_MAX_NESTED_PROGRAMS . Ini mewakili jumlah maksimum program yang dapat disimpan dalam RAM pada satu waktu. Misalnya, jika kedalamannya 3, program A dapat memanggil program B, program B dapat menghubungi program C, tetapi program C tidak dapat menghubungi program lain. Namun, jika suatu program memanggil exec dengan EXEC_OVERRIDE_PROGRAM , kedalaman tidak bertambah karena program baru yang dimuat akan menimpa yang saat ini. Dengan demikian, jika kita mengambil kembali contoh sebelumnya, Program C dapat memanggil program jika dan hanya jika itu memanggil Syscall exec dalam mode EXEC_OVERRIDE_PROGRAM .
Hati-hati, saat menjalankan sub-program, seluruh tabel perangkat yang dibuka, (termasuk file, direktori, dan driver), direktori saat ini, dan register CPU akan dibagikan .
Ini berarti bahwa jika program A membuka file dengan Descriptor 3, Program B akan mewarisi indeks ini, dan dengan demikian, juga dapat membaca, menulis, atau bahkan menutup deskriptor itu. Secara timbal balik, jika B membuka file, direktori, atau driver dan keluar tanpa menutupnya, program A juga akan memiliki akses ke sana. Dengan demikian, pedoman umum untuk diikuti adalah bahwa sebelum keluar, suatu program harus selalu menutup deskriptor yang dibuka. Satu -satunya saat tabel perangkat yang dibuka dan direktori saat ini diatur ulang adalah ketika program awal (program A dalam contoh sebelumnya) keluar. Dalam hal ini, kernel akan menutup semua deskriptor di tabel perangkat yang dibuka, membuka kembali input dan output standar, dan memuat ulang program awal.
Ini juga berarti bahwa ketika memanggil Syscall exec dalam program perakitan, pada keberhasilan, semua register, kecuali HL, harus dianggap diubah karena mereka akan digunakan oleh subprogram. Jadi, jika Anda ingin melestarikan AF , BC , DE , IX atau IY , mereka harus didorong pada tumpukan sebelum memohon exec .
Syscalls semuanya didokumentasikan dalam file header yang disediakan untuk perakitan dan C, Anda akan menemukan file header ini di kernel_headers/ Direktori, periksa file ReadMe -nya untuk informasi lebih lanjut.
Seorang pengemudi terdiri dari struktur yang berisi:
SER0 , SER1 , I2C0 , dll. Karakter non-ASCII diizinkan tetapi tidak disarankan.init , dipanggil ketika kernel sepatu bot.read rutin, di mana parameter dan alamat pengembalian sama dengan pada tabel Syscall.write , sama seperti di atas.open , sama seperti di atas.close , sama seperti di atas.seek rutin, sama seperti di atas.ioctl , sama seperti di atas.deinit , dipanggil saat menurunkan driver.Berikut adalah contoh pendaftaran pengemudi sederhana:
my_driver0_init:
; Register itself to the VFS
; Do something
xor a ; Success
ret
my_driver0_read:
; Do something
ret
my_driver0_write :
; Do something
ret
my_driver0_open :
; Do something
ret
my_driver0_close :
; Do something
ret
my_driver0_seek :
; Do something
ret
my_driver0_ioctl :
; Do something
ret
my_driver0_deinit :
; Do something
ret
SECTION DRV_VECTORS
DEFB "DRV0"
DEFW my_driver0_init
DEFW my_driver0_read
DEFW my_driver0_write
DEFW my_driver0_open
DEFW my_driver0_close
DEFW my_driver0_seek
DEFW my_driver0_ioctl
DEFW my_driver0_deinit Mendaftarkan pengemudi terdiri dari menempatkan informasi ini (struktur) di dalam bagian yang disebut DRV_VECTORS . Perintah ini sangat penting karena ketergantungan pengemudi apa pun harus diselesaikan pada waktu kompilasi. Misalnya, jika pengemudi A tergantung pada driver B , maka struktur B harus diletakkan di hadapan A di bagian DRV_VECTORS .
Saat boot, komponen driver akan menelusuri seluruh bagian DRV_VECTORS dan menginisialisasi driver satu per satu dengan memanggil init rutin mereka. Jika rutin ini mengembalikan ERR_SUCCESS , driver akan terdaftar dan program pengguna dapat membukanya, membaca, menulis, ioctl, dll ...
Pengemudi dapat disembunyikan untuk program, ini berguna untuk driver disk yang hanya boleh diakses oleh lapisan sistem file kernel. Untuk melakukannya, rutinitas init harus mengembalikan ERR_DRIVER_HIDDEN .
Karena komunikasi antara aplikasi dan perangkat keras semuanya dilakukan melalui syscall yang dijelaskan di atas, kita memerlukan lapisan antara aplikasi pengguna dan kernel yang akan menentukan apakah kita perlu memanggil driver atau sistem file. Sebelum menunjukkan hierarki arsitektur semacam itu, mari kita bicara tentang disk dan pengemudi.
Lapisan yang berbeda dapat dilihat seperti ini:
Flowchart TD;
Aplikasi (Program Pengguna)
VFS (sistem file virtual)
DSK (modul disk)
DRV (Implementasi Driver: Video, Keyboard, Serial, dll ...)
FS (sistem file)
Sysdis (Syscall Dispatcher)
HW (perangkat keras)
Waktu (Modul Waktu & Tanggal)
mem (modul memori)
Loader (Modul Loader)
Aplikasi -Syscall/RST 8 -> Sysdis;
sysdis --getDate/time-> time;
sysdis --mount-> dsk;
Sysdis -> VFS;
Sysdis --pet-> mem;
Sysdis -Exec/Exit -> Loader;
VFS -> DSK & DRV;
dsk <--> fs;
fs -> drv;
DRV -> HW;
Zeal 8-bit OS mendukung hingga 26 disk sekaligus. Disk dilambangkan dengan surat, dari A ke Z. Adalah tanggung jawab pengemudi disk untuk memutuskan di mana harus memasang disk dalam sistem.
Drive pertama, A , adalah istimewa karena merupakan tempat di mana sistem akan mencari preferensi atau konfigurasi.
Dalam aplikasi, path mungkin:
my_dir2/file1.txt/my_dir1/my_dir2/file1.txtB:/your_dir1/your_dir2/file2.txt Meskipun OS sepenuhnya dapat ROM dan tidak memerlukan sistem file atau disk untuk boot, segera setelah akan mencoba memuat program awal, yang disebut init.bin secara default, itu akan memeriksa disk default dan meminta file itu. Dengan demikian, bahkan penyimpanan paling dasar membutuhkan sistem file, atau yang serupa.
"Sistem file" pertama, yang sudah diimplementasikan, disebut "Rawtable". Seperti namanya, itu mewakili suksesi file, bukan direktori, di perangkat penyimpanan, tanpa urutan tertentu. Batas ukuran nama file sama dengan kernel: 16 karakter, termasuk opsional . dan ekstensi. Jika kami ingin membandingkannya dengan kode C, itu akan menjadi array struktur yang mendefinisikan setiap file, diikuti oleh konten file dalam urutan yang sama. Kode Sumber Packer Romdisk tersedia di packer/ pada akar repo ini. Periksa readme untuk info lebih lanjut tentang hal itu.
Sistem file kedua, yang juga diimplementasikan, dinamai Zealfs. Tujuan utamanya adalah untuk tertanam di penyimpanan yang sangat kecil, dari 8kb hingga 64kb. Ini dapat dibaca dan dapat ditulis, mendukung file dan direktori. Info lebih lanjut tentang hal itu di repositori khusus.
Sistem file ketiga yang akan menyenangkan untuk dimiliki pada OS 8-bit Zeal adalah FAT16. Sangat terkenal, sudah didukung oleh hampir semua sistem operasi desktop, dapat digunakan pada compactflash dan bahkan kartu SD, ini hampir harus dimiliki. Itu belum diimplementasikan, tetapi direncanakan. FAT16 tidak sempurna meskipun karena tidak disesuaikan untuk penyimpanan kecil, inilah mengapa Zelfs diperlukan.
OS 8-bit semangat didasarkan pada dua komponen utama: kernel dan kode target. Kernel saja tidak melakukan apa -apa. Target perlu mengimplementasikan driver, beberapa makro MMU yang digunakan di dalam kernel dan skrip linker. Script Linker cukup sederhana, daftar bagian dalam urutan yang harus ditautkan dalam biner akhir oleh z80asm Assembler.
Kernel saat ini menggunakan bagian berikut, yang harus dimasukkan dalam skrip linker apa pun:
RST_VECTORS : berisi vektor resetSYSCALL_TABLE : Berisi tabel di mana alamat rutin Syscall i disimpan di Indeks i , harus disejajarkan pada 256SYSCALL_ROUTINES : berisi dispatcher syscall, dipanggil dari vektor resetKERNEL_TEXT : berisi kode kernelKERNEL_STRLIB : Berisi rutin terkait string yang digunakan dalam kernelKERNEL_DRV_VECTORS : mewakili array driver untuk diinisialisasi, periksa bagian driver untuk lebih jelasnya.KERNEL_BSS : Berisi data yang digunakan oleh kode kernel, harus dalam RAMDRIVER_BSS : Tidak digunakan secara langsung oleh kernel, itu harus ditentukan dan digunakan dalam pengemudi. Kernel akan mengaturnya ke 0s pada boot, itu harus lebih besar dari 2 byte Seperti yang dikatakan sebelumnya, dukungan komputer 8-bit semangat masih sebagian tetapi cukup untuk menjalankan program baris perintah. Romdisk dibuat sebelum kernel dibangun, ini dilakukan dalam script.sh yang ditentukan dalam target/zeal8bit/unit.mk .
Skrip itu akan menyusun program init.bin dan menanamkannya di dalam romdisk yang akan digabungkan dengan biner OS yang dikompilasi. Biner terakhir dapat langsung ditebak ke NOR Flash.
Apa yang masih perlu diimplementasikan, tanpa urutan tertentu:
Port cepat ke komputer TRS-80 Model-I telah dibuat untuk menunjukkan cara port dan mengonfigurasi OS 8-bit Zeal ke target yang tidak memiliki MMU.
Port ini agak sederhana karena hanya menunjukkan spanduk boot di layar, tidak lebih. Untuk melakukannya, hanya driver video untuk mode teks yang diimplementasikan.
Untuk memiliki port yang lebih menarik, fitur -fitur berikut perlu diimplementasikan:
init.bin /romdisk, bisa hanya baca, jadi bisa disimpan di romPort ke lampu agon bertenaga EZ80, ditulis dan dikelola oleh Shawn Sijnstra. Jangan ragu untuk menggunakan garpu itu untuk bug/permintaan spesifik agon. Ini menggunakan kernel non-MMU, dan mengimplementasikan sebagian besar fitur yang didukung oleh implementasi komputer 8-bit semangat.
Port ini membutuhkan loader untuk biner untuk disimpan dan dieksekusi dari lokasi yang benar. Biner adalah Osbootz, tersedia di sini.
Perhatikan bahwa port menggunakan mode terminal untuk menyederhanakan keyboard I/O. Ini juga berarti bahwa fungsi tanggal tidak tersedia.
Fitur penting lainnya:
Untuk Port Zeal 8-bit OS MMU versi ke mesin lain, pastikan Anda memiliki mapper memori terlebih dahulu yang membagi ruang alamat 64kB Z80 menjadi 4 halaman 16kb untuk versi MMU.
Untuk Port No-MMU Zeal 8-bit OS, pastikan RAM tersedia dari Alamat Virtual 0x4000 dan di atasnya. Kasus yang paling ideal adalah memiliki ROM adalah 16KB pertama untuk OS dan RAM di sisa 48KB untuk program pengguna dan kernel RAM.
Jika target Anda kompatibel, ikuti instruksi:
Kconfig di root repo ini, dan tambahkan entri ke opsi config TARGET dan config COMPILATION_TARGET . Ambil yang sudah ada sebagai contoh.target/ untuk target Anda, namanya harus sama dengan yang ditentukan dalam opsi config TARGET baru.unit.mk baru. Ini adalah file yang harus berisi semua file sumber untuk dirakit atau yang akan disertakan.unit.mk Anda, untuk melakukannya, Anda dapat mengisi variabel make berikut:SRCS : Daftar file yang akan dirakit. Biasanya, ini adalah pengemudi (wajib)INCLUDES : Direktori yang berisi file header yang dapat disertakanPRECMD : perintah bash yang akan dieksekusi sebelum kernel mulai membangunPOSTCMD : Perintah bash yang akan dieksekusi setelah gedung kernel selesaimmu_h.asm yang akan dimasukkan oleh kernel untuk mengonfigurasi dan menggunakan MMU. Periksa target/zeal8bit/include/mmu_h.asm agar terlihat seperti itu.zos_disks_mount , berisi file init.bin , dimuat dan dieksekusi oleh kernel saat boot.zos_vfs_set_stdout .Untuk changelog lengkap, silakan periksa halaman rilis.
Kontribusi dipersilakan! Jangan ragu untuk memperbaiki bug apa pun yang mungkin Anda lihat atau temui, atau terapkan fitur apa pun yang menurut Anda penting.
Untuk berkontribusi:
(*) Pesan komit yang baik adalah sebagai berikut:
Module: add/fix/remove a from b
Explanation on what/how/why
Misalnya:
Disks: implement a get_default_disk routine
It is now possible to retrieve the default disk of the system.
Didistribusikan di bawah lisensi Apache 2.0. Lihat file LICENSE untuk informasi lebih lanjut.
Anda bebas menggunakannya untuk penggunaan pribadi dan komersial, boilerplate yang ada di setiap file tidak boleh dihapus.
Untuk saran atau permintaan apa pun, Anda dapat menghubungi saya di kontak [at] Zeal8bit [dot] com
Untuk permintaan fitur, Anda juga dapat membuka masalah atau permintaan tarik.
Mereka tidak akan dianggap sebagai non-volatile. Dengan kata lain, penangan interupsi tidak boleh membuat asumsi bahwa data yang ditulisnya di dalam register alternatif akan disimpan sampai waktu berikutnya disebut. ↩