Bab 5: Sistem Operasi Commodore-64 dalam Bahasa Majelis

Bab 5 Sistem Operasi Commodore 64 Dalam Bahasa Majelis



5.1 Pendahuluan

Sistem operasi untuk komputer Commodore-64 dilengkapi dengan komputer dalam Read Only Memory (ROM). Jumlah lokasi byte memori untuk Commodore-64 berkisar dari $0000 hingga $FFFF (yaitu 000016 hingga FFFF16 yaitu 010 hingga 65,53510). Sistem operasinya mulai dari $E000 hingga $FFFF (yaitu 57,34410 hingga 65,53610).

Mengapa Mempelajari Sistem Operasi Commodore-64
Mengapa mempelajari Sistem Operasi Commodore-64 saat ini padahal itu adalah sistem operasi komputer yang dirilis pada tahun 1982? Nah, komputer Commodore-64 menggunakan Central Processing Unit 6510 yang merupakan upgrade (meski bukan upgrade besar) dari 6502 µP.







6502 µP masih diproduksi hingga saat ini dalam jumlah besar; tidak lagi untuk komputer rumah atau kantor tetapi untuk peralatan (perangkat) listrik dan elektronik. 6502 µP juga mudah dipahami dan dioperasikan dibandingkan dengan mikroprosesor lain pada masanya. Oleh karena itu, ini adalah salah satu mikroprosesor terbaik (jika bukan yang terbaik) yang digunakan untuk mengajarkan bahasa assembly.



65C02 µP, masih dari kelas mikroprosesor 6502, memiliki 66 instruksi bahasa assembly, yang semuanya bahkan dapat dihafal. Mikroprosesor modern memiliki banyak instruksi bahasa rakitan dan tidak dapat dipelajari dengan hati. Setiap µP memiliki bahasa rakitannya sendiri. Sistem operasi apa pun, baik baru atau lama, menggunakan bahasa assembly. Oleh karena itu, bahasa assembly 6502 baik digunakan untuk mengajarkan sistem operasi bagi pemula. Setelah mempelajari sistem operasi, seperti Commodore-64, sistem operasi modern dapat dengan mudah dipelajari menggunakan sistem operasi tersebut sebagai dasarnya.



Ini bukan sekedar pendapat penulis (saya sendiri). Ini adalah tren yang sedang berkembang di dunia. Semakin banyak artikel yang ditulis di Internet untuk meningkatkan sistem operasi Commodore-64 agar terlihat seperti sistem operasi modern. Sistem operasi modern dijelaskan dalam bab demi bab berikutnya.





Catatan : Commodore-64 OS (Kernal) masih berfungsi baik dengan perangkat input dan output modern (tidak semua).

Komputer Delapan-Bit
Dalam komputer mikro delapan bit seperti Commodore 64, informasi disimpan, ditransfer, dan dimanipulasi dalam bentuk kode biner delapan bit.



Peta Memori
Peta memori adalah skala yang membagi seluruh rentang memori menjadi rentang yang lebih kecil dengan ukuran berbeda dan menunjukkan apa (subrutin dan/atau variabel) yang termasuk dalam rentang tersebut. Variabel adalah label yang berhubungan dengan alamat memori tertentu yang mempunyai nilai. Label juga digunakan untuk mengidentifikasi awal subrutin. Namun dalam kasus ini, mereka dikenal sebagai nama subrutin. Subrutin dapat dengan mudah disebut sebagai rutinitas.

Peta memori (tata letak) pada bab sebelumnya kurang detail. Ini cukup sederhana. Peta memori komputer Commodore-64 dapat ditampilkan dengan tiga tingkat detail. Jika ditampilkan pada tingkat menengah, komputer Commodore-64 memiliki peta memori yang berbeda. Peta memori default komputer Commodore-64 pada tingkat menengah adalah:


Gambar 5.11 Peta Memori Komodor-64

Pada masa itu, ada bahasa komputer populer yang disebut BASIC. Banyak pengguna komputer yang perlu mengetahui beberapa perintah minimum bahasa BASIC seperti untuk memuat program dari disket (disk) ke memori, untuk menjalankan (mengeksekusi) suatu program di memori, dan untuk keluar (menutup) suatu program. Saat program BASIC berjalan, pengguna harus memasukkan data, baris demi baris. Hal ini tidak seperti saat ini ketika sebuah aplikasi (sejumlah program membentuk suatu aplikasi) ditulis dalam bahasa tingkat tinggi dengan windows dan pengguna hanya perlu memasukkan data yang berbeda di tempat-tempat khusus dalam sebuah jendela. Dalam beberapa kasus, gunakan mouse untuk memilih data yang dipesan sebelumnya. BASIC merupakan bahasa tingkat tinggi pada saat itu, namun cukup dekat dengan bahasa assembly.

Perhatikan bahwa sebagian besar memori digunakan oleh BASIC di peta memori default. BASIC memiliki perintah (instruksi) yang dijalankan oleh apa yang dikenal sebagai BASIC Interpreter. Faktanya, juru bahasa BASIC berada dalam ROM dari lokasi $A000 hingga $BFFF (inklusif) yang seharusnya merupakan area RAM. Ini adalah 8 Kbytes yang cukup besar pada saat itu! Ini sebenarnya ada di ROM di tempat seluruh memori. Ini memiliki ukuran yang sama dengan sistem operasi dari $E000 hingga $FFFF (inklusif). Program yang ditulis dalam BASIC juga ditempatkan pada kisaran $0200 hingga $BFFF.

RAM untuk program bahasa rakitan pengguna berkisar dari $C000 hingga $CFFF, hanya 4 Kbytes dari 64 Kbytes. Lantas, mengapa kita menggunakan atau mempelajari bahasa assembly? Sistem operasi baru dan lama menggunakan bahasa assembly. Sistem operasi Commodore-64 dalam ROM, dari $E000 hingga $FFFF. Itu ditulis dalam bahasa assembly 65C02 µP (6510 µP). Ini terdiri dari subrutin. Program pengguna dalam bahasa assembly perlu memanggil subrutin ini agar dapat berinteraksi dengan periferal (perangkat input dan output). Memahami sistem operasi Commodore-64 dalam bahasa assembly memungkinkan siswa untuk memahami sistem operasi dengan cepat, dengan cara yang tidak terlalu membosankan. Sekali lagi, pada masa itu, banyak program pengguna untuk Commodore-64 ditulis dalam BASIC dan bukan dalam bahasa assembly. Bahasa assembly pada masa itu lebih banyak digunakan oleh programmer sendiri untuk keperluan teknis.

Kernal, dieja sebagai K-e-r-n-a-l, adalah sistem operasi Commodore-64. Muncul dengan komputer Commodore-64 dalam ROM dan bukan dalam disk (atau disket). Kernal terdiri dari subrutin. Untuk mengakses periferal, program pengguna dalam bahasa rakitan (bahasa mesin) harus menggunakan subrutin ini. Kernal tidak sama dengan kernel yang dieja sebagai K-e-r-n-e-l pada sistem operasi modern, meskipun keduanya hampir sama.

Area memori dari $C000 (49,15210) hingga $CFFF (6324810) sebesar 4 Kbytes10 memori adalah RAM atau ROM. Jika itu adalah RAM, itu digunakan untuk mengakses periferal. Kalau ROM, digunakan untuk mencetak karakter di layar (monitor). Ini berarti karakter sedang dicetak di layar atau periferal sedang diakses dengan menggunakan bagian memori ini. Ada bank ROM (karakter ROM) di unit sistem (motherboard) yang dialihkan masuk dan keluar dari seluruh ruang memori untuk mencapai hal itu. Pengguna mungkin tidak menyadari peralihan tersebut.

Area memori mulai dari $0100 (256 10 ) menjadi $01FF (511 10 ) adalah tumpukan. Ini digunakan oleh sistem operasi dan program pengguna. Peran tumpukan telah dijelaskan di bab sebelumnya dari kursus karir online ini. Area memori mulai dari $0000 (0 10 ) menjadi $00FF (255 10 ) digunakan oleh sistem operasi. Banyak petunjuk yang diberikan di sana.

Tabel Lompat Kernal
Kernal mempunyai rutinitas yang dipanggil oleh pengguna program. Ketika versi baru dari OS keluar, alamat dari rutinitas ini berubah. Ini berarti bahwa program pengguna tidak dapat lagi bekerja dengan versi OS yang baru. Hal ini tidak terjadi karena Commodore-64 menyediakan tabel lompat. Tabel lompat adalah daftar 39 entri. Setiap entri dalam tabel memiliki tiga alamat (kecuali 6 byte terakhir) yang tidak pernah berubah bahkan dengan perubahan versi sistem operasi.

Alamat pertama dari sebuah entri memiliki instruksi JSR. Dua alamat berikutnya terdiri dari penunjuk dua byte. Pointer dua byte ini adalah alamat (atau alamat baru) dari rutin sebenarnya yang masih ada di ROM OS. Konten penunjuk dapat berubah dengan versi OS baru, namun tiga alamat untuk setiap entri tabel lompat tidak pernah berubah. Misalnya, pertimbangkan alamat $FF81, $FF82, dan $FF83. Ketiga alamat ini untuk rutinitas menginisialisasi sirkuit layar dan keyboard (register) motherboard. Alamat $FF81 selalu memiliki kode operasi (satu byte) JSR. Alamat $FF82 dan $FF83 memiliki alamat subrutin lama atau baru (masih dalam ROM OS) untuk melakukan inisialisasi. Pada suatu waktu, alamat $FF82 dan $FF83 memiliki konten (alamat) $FF5B yang dapat berubah dengan versi OS berikutnya. Namun, alamat tabel lompat $FF81, $FF82, dan $FF83 tidak pernah berubah.

Untuk setiap entri tiga alamat, alamat pertama dengan JSR memiliki label (nama). Label untuk $FF81 adalah PCINT. PCINT tidak pernah berubah. Jadi, untuk menginisialisasi register layar dan keyboard, programmer cukup mengetik “JSR PCINT” yang berfungsi untuk semua versi OS Commodore-64. Lokasi (alamat awal) dari subrutin sebenarnya, misalnya $FF5B, dapat berubah seiring waktu dengan sistem operasi yang berbeda. Ya, setidaknya ada dua instruksi JSR yang terlibat dalam program pengguna yang menggunakan ROM OS. Dalam program pengguna, ada instruksi JSR yang melompat ke entri di tabel lompat. Dengan pengecualian enam alamat terakhir dalam tabel lompat, alamat pertama dari entri dalam tabel lompat memiliki instruksi JSR. Di Kernal, beberapa subrutin dapat memanggil subrutin lainnya.

Tabel lompatan Kernal dimulai dari $FF81 (inklusif) naik ke atas dalam kelompok bertiga, kecuali untuk enam byte terakhir yang merupakan tiga penunjuk dengan alamat byte lebih rendah: $FFFA, $FFFC, dan $FFFE. Semua rutinitas ROM OS adalah kode yang dapat digunakan kembali. Jadi, pengguna tidak perlu menulis ulang.

Diagram Blok Unit Sistem Komodor-64
Diagram berikut ini lebih detail dibandingkan diagram pada bab sebelumnya:


Gambar 5.12 Diagram Blok Unit Sistem Commodore_64

ROM dan RAM ditampilkan sebagai satu blok di sini. Chip Antarmuka Video (IC) untuk menangani informasi ke layar, yang tidak ditampilkan di bab sebelumnya, ditampilkan di sini. Blok tunggal untuk perangkat input/output, yang ditunjukkan pada bab sebelumnya, ditampilkan di sini sebagai dua blok: CIA #1 dan CIA #2. CIA adalah singkatan dari Complex Interface Adapter. Masing-masing memiliki dua port delapan-bit paralel (jangan bingung dengan port eksternal pada permukaan vertikal unit sistem) yang disebut port A dan port B. CIA terhubung ke lima perangkat eksternal dalam situasi ini. Perangkat tersebut adalah keyboard, joystick, disk drive/printer, dan modem. Printer terhubung di bagian belakang disk drive. Ada juga Rangkaian Perangkat Antarmuka Suara dan Rangkaian Array Logika yang Dapat Diprogram yang tidak ditampilkan.

Namun, ada ROM Karakter yang dapat ditukar dengan kedua CIA ketika karakter dikirim ke layar dan tidak ditampilkan dalam diagram blok.

Alamat RAM dari $D000 hingga $DFFF untuk rangkaian input/output tanpa adanya ROM karakter memiliki peta memori detail berikut:

Tabel 5.11
Peta Memori Terperinci dari $D000 hingga $DFFF
Rentang Sub-alamat Sirkuit Ukuran (Byte)
D000 – D3FF VIC (Pengontrol Antarmuka Video (Chip)) 1K
H400 – D7FF SID (Sirkuit Suara) 1K
H800 – DBFF RAM berwarna 1K Camilan
DC00 – DCFF CIA #1 (Keyboard, Joystick) 256
DD00 – DDFF CIA #2 (Bus Serial, Port Pengguna/RS-232) 256
DE00 – DEF Buka Slot I/O #1 256
DF00 – DFFF Buka Slot I/O #2 256

5.2 Dua Adaptor Antarmuka Kompleks

Ada dua Sirkuit Terpadu (IC) tertentu di unit sistem Commodore-64, dan masing-masing disebut Adaptor Antarmuka Kompleks. Kedua chip ini digunakan untuk menghubungkan keyboard dan periferal lain ke mikroprosesor. Kecuali VIC dan layar, semua sinyal input/output antara mikroprosesor dan periferal melewati kedua IC ini. Dengan Commodore-64, tidak ada komunikasi langsung antara memori dan perangkat apa pun. Komunikasi antara memori dan perangkat apa pun melewati akumulator mikroprosesor, dan salah satunya adalah adaptor CIA (IC). IC tersebut disebut sebagai CIA #1 dan CIA #2. CIA adalah singkatan dari Complex Interface Adapter.

Setiap CIA memiliki 16 register. Dengan pengecualian register pengatur waktu/penghitung di CIA, setiap register memiliki lebar 8-bit dan memiliki alamat memori. Alamat register memori untuk CIA #1 berasal dari $DC00 (56320 10 ) menjadi $DC0F (56335 10 ). Alamat register memori untuk CIA #2 berasal dari $DD00 (56576 10 ) hingga $DD0F (56591 10 ). Meskipun register-register ini tidak ada dalam memori IC, mereka adalah bagian dari memori. Dalam peta memori perantara, area I/O dari $D000 hingga $DFFF mencakup alamat CIA dari $DC00 hingga $DC0F dan dari $DD00 hingga $DD0F. Sebagian besar area memori I/O RAM dari $D000 hingga $DFFF dapat ditukar dengan bank memori ROM karakter untuk karakter layar. Itulah sebabnya ketika karakter dikirim ke layar, periferal tidak dapat beroperasi; meskipun pengguna mungkin tidak menyadarinya karena pertukarannya cepat.

Ada dua register di CIA #1 yang disebut Port A dan Port B. Alamatnya masing-masing adalah $DC00 dan $DC01. Ada juga dua register di CIA #2 yang disebut Port A dan Port B. Tentu saja alamatnya berbeda; masing-masing adalah $DD00 dan $DD01.

Port A atau Port B di CIA adalah port paralel. Artinya dapat mengirimkan data ke perangkat dalam delapan bit sekaligus atau menerima data dari mikroprosesor dalam delapan bit sekaligus.

Terkait dengan port A atau port B adalah Data Direction Register (DDR). Register arah data untuk port A CIA #1 (DDRA1) berada di lokasi byte memori $DC02. Register arah data untuk port B CIA #1 (DDRB1) berada di lokasi byte memori $DC03. Register arah data untuk port A CIA #2 (DDRA2) berada di lokasi byte memori $DD02. Register arah data untuk port B CIA #2 (DDRB2) berada di lokasi byte memori $DD03.

Sekarang, setiap bit untuk port A atau port B dapat diatur oleh register arah data yang sesuai untuk menjadi input atau output. Input berarti informasi dikirim dari periferal ke mikroprosesor melalui CIA. Output berarti informasi berpindah dari mikroprosesor ke perangkat melalui CIA.

Jika sel dari port (register) akan dimasukkan, bit yang sesuai dalam register arah data adalah 0. Jika sel dari port (register) akan dikeluarkan, bit yang sesuai dalam register arah data adalah 1. Dalam kebanyakan kasus, semua 8-bit port diprogram menjadi input atau output. Saat komputer dihidupkan, port A diprogram untuk output dan port B diprogram untuk input. Kode berikut menjadikan CIA #1 port A sebagai output dan CIA #1 port B sebagai input:

LDA #$FF
STA DDRA1 ; $DC00 diarahkan oleh $DC02
LDA #$00
STA DDRB1 ; $DC01 diarahkan oleh $DC03

DDRA1 adalah label (nama variabel) untuk lokasi byte memori $DC02, dan DDRB1 adalah label (nama variabel) untuk lokasi byte memori $DC03. Instruksi pertama memuat 11111111 ke akumulator µP. Instruksi kedua menyalin ini ke register arah data port A CIA no. 1. Instruksi ketiga memuat 00000000 ke akumulator µP. Instruksi keempat menyalin ini ke register arah data port B CIA no. 1. Kode ini ada di salah satu subrutin dalam sistem operasi yang melakukan inisialisasi ini saat komputer dihidupkan.

Setiap CIA memiliki jalur permintaan layanan interupsi ke mikroprosesor. Yang dari CIA #1 ditujukan ke IRQ pin µP. Yang dari CIA #2 pergi ke NMI pin µP. Ingat itu NMI merupakan prioritas yang lebih tinggi dibandingkan IRQ .

5.3 Pemrograman Bahasa Rakitan Keyboard

Hanya ada tiga kemungkinan interupsi untuk Commodore-64: IRQ , BRK, dan NMI . Penunjuk tabel lompat untuk IRQ berada di alamat $FFFE dan $FFFF di ROM (sistem operasi) yang berhubungan dengan subrutin yang masih ada di OS (ROM). Penunjuk tabel lompat untuk BRK berada di alamat $FFFC dan $FFFD di OS yang sesuai dengan subrutin yang masih ada di OS (ROM). Penunjuk tabel lompat untuk NMI berada di alamat $FFFA dan $FFB di OS yang sesuai dengan subrutin yang masih ada di OS (ROM). Untuk IRQ , sebenarnya ada dua subrutin. Jadi, interupsi (instruksi) perangkat lunak BRK memiliki penunjuk tabel lompatnya sendiri. Penunjuk tabel lompat untuk IRQ mengarah ke kode yang memutuskan apakah interupsi perangkat keras atau interupsi perangkat lunak yang digunakan. Jika itu adalah interupsi perangkat keras, rutinitasnya IRQ disebut. Jika itu adalah interupsi perangkat lunak (BRK), maka rutin untuk BRK dipanggil. Di salah satu versi OS, subrutin untuk IRQ berada pada $EA31 dan subrutin untuk BRK berada pada $FE66. Alamat ini berada di bawah $FF81, sehingga bukan merupakan entri tabel lompat dan dapat berubah sesuai versi OS. Ada tiga rutinitas yang menarik dalam topik ini: rutinitas yang memeriksa apakah tombol ditekan atau BRK, rutinitas yang bernilai $FE43, dan rutinitas yang juga dapat berubah seiring dengan versi OS.

Komputer Commodore-64 tampak seperti mesin ketik besar (ke atas) tanpa bagian pencetakan (kepala dan kertas). Keyboardnya terhubung ke CIA #1. CIA #1 memindai keyboard setiap 1/60 detik tanpa gangguan pemrograman apa pun, secara default. Jadi, setiap 1/60 detik, CIA #1 mengirimkan IRQ ke μP. Hanya ada satu IRQ pin di µP yang hanya berasal dari CIA #1. Satu pin masukan dari NMI dari µP, yang berbeda dari IRQ , hanya berasal dari CIA #2 (lihat ilustrasi berikut). BRK sebenarnya adalah instruksi bahasa assembly yang dikodekan dalam program pengguna.

Jadi, setiap 1/60 detik, IRQ rutin yang ditunjuk oleh $FFFE dan $FFFF dipanggil. Rutin memeriksa apakah tombol ditekan atau instruksi BRK ditemukan. Jika sebuah tombol ditekan, rutinitas untuk menangani penekanan tombol akan dipanggil. Kalau instruksi BRK maka disebut rutinitas penanganan BRK. Jika bukan keduanya, tidak akan terjadi apa-apa. Mungkin tidak terjadi apa-apa, tapi CIA #1 mengirimkannya IRQ ke µP setiap 1/60 detik.

Antrean keyboard, juga dikenal sebagai buffer keyboard, adalah rentang lokasi byte RAM dari $0277 hingga $0280, inklusif; Semuanya 1010 byte. Ini adalah buffer Masuk Pertama Keluar Pertama. Artinya, karakter pertama yang datang adalah karakter pertama yang keluar. Karakter Eropa Barat membutuhkan satu byte.

Jadi, meskipun program tidak menggunakan karakter apa pun saat tombol ditekan, kode kunci tersebut masuk ke buffer ini (antrian). Buffer terus terisi hingga tersisa sepuluh karakter. Karakter apa pun yang ditekan setelah karakter kesepuluh tidak direkam. Hal ini diabaikan sampai setidaknya satu karakter diperoleh (dikonsumsi) dari antrian. Tabel lompat memiliki entri untuk subrutin yang mendapatkan karakter pertama dari antrian ke mikroprosesor. Artinya, dibutuhkan karakter pertama yang masuk ke antrian dan memasukkannya ke dalam akumulator µP. Subrutin tabel lompat untuk melakukan ini disebut GETIN (untuk Get-In). Byte pertama untuk entri tiga byte dalam tabel lompat diberi label sebagai GETIN (alamat $FFE4). Dua byte berikutnya adalah penunjuk (alamat) yang menunjuk ke rutinitas sebenarnya di ROM (OS). Merupakan tanggung jawab pemrogram untuk menyebut rutinitas ini. Jika tidak, buffer keyboard akan tetap penuh dan semua tombol yang baru saja ditekan akan diabaikan. Nilai yang masuk ke akumulator adalah nilai ASCII kunci yang sesuai.

Bagaimana cara kode kunci masuk ke antrian? Ada rutin tabel lompat yang disebut SCNKEY (untuk kunci pindai). Rutinitas ini dapat dipanggil melalui perangkat lunak dan perangkat keras. Dalam hal ini disebut dengan rangkaian elektronik (fisika) pada mikroprosesor ketika sinyal listrik IRQ rendah. Bagaimana tepatnya hal itu dilakukan tidak dibahas dalam kursus karir online ini.

Kode untuk memasukkan kode kunci pertama dari buffer keyboard ke akumulator A hanya satu baris:

MASUK

Jika buffer keyboard kosong, $00 ditempatkan di akumulator. Ingatlah bahwa kode ASCII untuk nol bukanlah $00; itu $30. $00 berarti Null. Dalam suatu program, mungkin ada suatu titik di mana program harus menunggu tombol ditekan. Kode untuk ini adalah:

TUNGGU JSR DAPATKAN
CMP #$00
katak tunggu

Pada baris pertama, “WAIT” adalah label yang mengidentifikasi alamat RAM dimana instruksi JSR dimasukkan (diketik). GETIN juga merupakan alamat. Ini adalah alamat byte pertama dari tiga byte yang sesuai di tabel lompat. Entri GETIN, serta semua entri dalam tabel lompat (kecuali tiga yang terakhir), terdiri dari tiga byte. Byte pertama dari entri adalah instruksi JSR. Dua byte berikutnya adalah alamat isi subrutin GETIN sebenarnya yang masih dalam ROM (OS) tetapi di bawah tabel lompat. Jadi, entri tersebut mengatakan untuk melompat ke subrutin GETIN. Jika antrian keyboard tidak kosong, GETIN memasukkan kode kunci ASCII dari antrian First-In-First-Out ke dalam akumulator. Jika antrian kosong, Null ($00) dimasukkan ke dalam akumulator.

Instruksi kedua membandingkan nilai akumulator dengan $00. Jika $00, berarti antrian keyboard kosong, dan instruksi CMP mengirimkan 1 ke flag Z register status prosesor (disebut register status). Jika nilai dalam A bukan $00, instruksi CMP mengirimkan 0 ke flag Z pada register status.

Instruksi ketiga yaitu “BEQ WAIT” mengirimkan program kembali ke instruksi pertama jika flag Z dari register status adalah 1. Instruksi pertama, kedua, dan ketiga dijalankan berulang kali hingga tombol pada keyboard ditekan. . Jika tombol tidak pernah ditekan, siklus akan berulang tanpa batas. Segmen kode seperti ini biasanya ditulis dengan segmen kode waktu yang keluar dari perulangan setelah beberapa waktu jika tombol tidak pernah ditekan (lihat pembahasan berikut).

Catatan : Keyboard adalah perangkat input default dan layar adalah perangkat output default.

5.4 Saluran, Nomor Perangkat, dan Nomor File Logis

Periferal yang digunakan bab ini untuk menjelaskan sistem operasi Commodore-64 adalah keyboard, layar (monitor), drive disk dengan disket, printer, dan modem yang terhubung melalui antarmuka RS-232C. Agar komunikasi dapat berlangsung antara perangkat ini dan unit sistem (mikroprosesor dan memori), suatu saluran harus dibuat.

Saluran terdiri dari buffer, nomor perangkat, nomor file logis, dan alamat sekunder opsional. Penjelasan istilah-istilah tersebut adalah sebagai berikut:

Sebuah Penyangga
Perhatikan dari bagian sebelumnya bahwa ketika sebuah tombol ditekan, kodenya harus menuju ke lokasi byte dalam RAM dari serangkaian sepuluh lokasi berturut-turut. Rangkaian sepuluh lokasi ini adalah buffer keyboard. Setiap perangkat input atau output (periferal) memiliki serangkaian lokasi berurutan dalam RAM yang disebut buffer.

Nomor perangkat
Dengan Commodore-64, perangkat apa pun diberikan nomor perangkat. Tabel berikut menunjukkan berbagai perangkat dan nomornya:

Tabel 5.41
Nomor Perangkat Komodor 64 dan Perangkatnya
Nomor Perangkat
0 Papan ketik
1 Penggerak Pita
2 Antarmuka RS 232C ke mis. sebuah modem
3 Layar
4 Pencetak #1
5 Pencetak #2
6 Plotter #1
7 Plotter #2
8 Disk Drive
9
¦
¦
¦
30
Dari 8 (inklusif) hingga 22 perangkat penyimpanan lebih banyak

Ada dua jenis port untuk komputer. Salah satu jenisnya adalah eksternal, pada permukaan vertikal unit sistem. Tipe lainnya adalah internal. Port internal ini adalah register. Commodore-64 memiliki empat port internal: port A dan port B untuk CIA 1 dan port A dan Port B untuk CIA 2. Ada satu port eksternal untuk Commodore-64 yang disebut Serial Port. Perangkat dengan nomor 3 ke atas terhubung ke port serial. Mereka terhubung secara rantai daisy (yang terhubung di belakang yang lain), yang masing-masing dapat diidentifikasi berdasarkan nomor perangkatnya. Perangkat dengan angka 8 ke atas umumnya adalah perangkat penyimpanan.

Catatan : Perangkat input default adalah keyboard dengan nomor perangkat 0. Perangkat output default adalah layar dengan nomor perangkat 3.

Nomor File Logis
Nomor file logis adalah nomor yang diberikan untuk perangkat (periferal) sesuai urutan pembukaannya untuk diakses. Mereka berkisar dari 010 hingga 255 10 .

Alamat Sekunder
Bayangkan dua file (atau lebih dari satu file) dibuka di disk. Untuk membedakan kedua file ini, alamat sekunder digunakan. Alamat sekunder adalah nomor yang bervariasi dari satu perangkat ke perangkat lainnya. Arti 3 sebagai alamat sekunder untuk printer berbeda dengan arti 3 sebagai alamat sekunder untuk drive disk. Artinya tergantung pada fitur-fitur seperti kapan suatu file dibuka untuk dibaca atau ketika suatu file dibuka untuk ditulis. Angka sekunder yang mungkin berasal dari 0 10 sampai 15 10 untuk setiap perangkat. Di banyak perangkat, angka 15 digunakan untuk mengirimkan perintah.

Catatan : Nomor perangkat juga dikenal sebagai alamat perangkat dan nomor sekunder juga dikenal sebagai alamat sekunder.

Mengidentifikasi Target Periferal
Untuk peta memori Commodore default, alamat memori dari $0200 hingga $02FF (halaman 2) hanya digunakan oleh sistem operasi dalam ROM (Kernal) dan bukan oleh sistem operasi plus bahasa BASIC. Padahal BASIC masih bisa menggunakan lokasi melalui ROM OS.

Modem dan printer adalah dua target periferal yang berbeda. Jika dua file dibuka dari disk, itu adalah dua target berbeda. Dengan peta memori default, ada tiga tabel (daftar) berurutan yang dapat dilihat sebagai satu tabel besar. Ketiga tabel ini menyimpan hubungan antara Nomor File Logis, Nomor Perangkat, dan Alamat Sekunder. Dengan itu, saluran tertentu atau target input/output dapat diidentifikasi. Ketiga tabel tersebut disebut Tabel File. Alamat RAM dan apa yang dimilikinya adalah:

$0259 — $0262: Tabel dengan label, LAT, hingga sepuluh nomor file logis aktif.
$0263 — $026C: Tabel dengan Label, FAT, hingga sepuluh nomor perangkat yang sesuai.
$026D — $0276: Tabel dengan Label, SAT, dari sepuluh alamat sekunder yang sesuai.

Di sini, “—” berarti “ke”, dan sebuah angka membutuhkan satu byte.

Pembaca mungkin bertanya, “Mengapa buffer untuk setiap perangkat tidak disertakan dalam mengidentifikasi saluran?” Jawabannya adalah dengan commodore-64, setiap perangkat eksternal (periferal) memiliki serangkaian byte tetap dalam RAM (peta memori). Tanpa ada saluran yang terbuka, posisi mereka masih ada di dalam memori. Buffer untuk keyboard, misalnya, ditetapkan dari $0277 menjadi $0280 (inklusif) untuk peta memori default.

Subrutin Kernal SETLFS dan SETNAM
SETLFS dan SETNAM adalah rutinitas Kernal. Saluran dapat dilihat sebagai file logis. Agar saluran dapat dibuka, nomor file logis, nomor perangkat, dan alamat sekunder opsional harus dibuat. Nama file opsional (teks) mungkin juga diperlukan. Rutin SETLFS menyiapkan nomor file logis, nomor perangkat, dan alamat sekunder opsional. Angka-angka ini dimasukkan ke dalam tabelnya masing-masing. Rutinitas SETNAM menyiapkan nama string untuk file yang mungkin wajib untuk satu saluran dan opsional untuk saluran lain. Ini terdiri dari sebuah pointer (alamat dua byte) di memori. Penunjuk menunjuk ke awal string (nama) yang mungkin berada di tempat lain di memori. Nama string diawali dengan byte yang memiliki panjang string, diikuti dengan teks (nama). Namanya maksimal enam belas byte (panjangnya).

Untuk memanggil rutin SETLFS, program pengguna harus melompat (JSR) ke alamat $FFBA dari tabel lompat OS di ROM untuk peta memori default. Ingatlah bahwa dengan pengecualian enam byte terakhir dari tabel lompat, setiap entri terdiri dari tiga byte. Byte pertama adalah instruksi JSR, yang kemudian melompat ke subrutin, dimulai pada alamat dalam dua byte berikutnya. Untuk memanggil rutin SETNAM, program pengguna harus melompat (JSR) ke alamat $FFBD dari tabel lompat OS di ROM. Penggunaan kedua rutinitas ini ditunjukkan pada pembahasan berikut.

5.5 Membuka Saluran, Membuka File Logis, Menutup File Logis, dan Menutup Semua Saluran I/O

Saluran terdiri dari buffer memori, nomor file logis, nomor perangkat (alamat perangkat), dan alamat sekunder opsional (nomor). File logis (abstraksi) yang diidentifikasi dengan nomor file logis dapat merujuk ke perangkat seperti printer, modem, drive disk, dll. Masing-masing perangkat yang berbeda ini harus memiliki nomor file logis yang berbeda. Ada banyak file di disk. File logis juga dapat merujuk ke file tertentu di disk. File tertentu juga memiliki nomor file logis yang berbeda dari nomor periferal seperti printer atau modem. Nomor file logis diberikan oleh programmer. Bisa berupa nomor apa saja mulai dari 010 ($00) hingga 25510 ($FF).

Rutin OS SETLFS
Rutinitas OS SETLFS yang diakses dengan melompat (JSR) ke tabel lompatan ROM OS di $FFBA menyiapkan saluran. Itu perlu memasukkan nomor file logis dalam tabel file yaitu LAT ($0259 — $0262). Itu perlu memasukkan nomor perangkat yang sesuai di tabel file yaitu FAT ($0263 — $026C). Jika akses file (perangkat) memerlukan nomor sekunder, ia perlu memasukkan alamat (nomor) sekunder yang sesuai dalam tabel file yaitu SAT ($026D — $0276).

Agar dapat beroperasi, subrutin SETLFS perlu mendapatkan nomor file logis dari akumulator µP; ia perlu mendapatkan nomor perangkat dari register µP X. Jika diperlukan oleh saluran, saluran perlu mendapatkan alamat sekunder dari register µP Y.

Nomor file logis ditentukan oleh programmer. Nomor file logis yang merujuk ke perangkat berbeda berbeda. Sekarang, sebelum memanggil rutin SETLFS, pemrogram harus memasukkan nomor file logis ke dalam akumulator µP. Nomor perangkat dibaca dari tabel (dokumen) seperti pada Tabel 5.41. Pemrogram juga harus memasukkan nomor perangkat ke dalam register µP X. Pemasok perangkat seperti printer, disk drive, dll. menyediakan kemungkinan alamat sekunder dan artinya untuk perangkat tersebut. Jika saluran memerlukan alamat sekunder, pemrogram perlu mendapatkannya dari dokumen yang disertakan dengan perangkat (periferal). Jika alamat sekunder (nomor) diperlukan, pemrogram harus memasukkannya ke dalam register µP Y sebelum memanggil subrutin SETLFS. Jika tidak diperlukan alamat sekunder, pemrogram harus memasukkan nomor $FF ke dalam register µP Y sebelum memanggil subrutin SETLFS.

Subrutin SETLFS dipanggil tanpa argumen apa pun. Argumennya sudah ada dalam tiga register 6502 µP. Setelah memasukkan nomor-nomor yang sesuai ke dalam register, rutin dipanggil dalam program hanya dengan baris berikut ini:

JSR SETLFS

Rutinitas menempatkan nomor-nomor yang berbeda dengan tepat ke dalam tabel file mereka.

Rutin OS SETNAM
Rutinitas OS SETNAM diakses dengan melompat (JSR) ke tabel lompatan OS ROM di $FFBD. Tidak semua tujuan memiliki nama file. Bagi yang memiliki tujuan (seperti file di disk), nama file harus diatur. Asumsikan nama filenya adalah “mydocum” yang terdiri dari 7 byte tanpa tanda kutip. Asumsikan bahwa nama ini ada di lokasi $C101 hingga $C107 (inklusif) dan panjang $07 ada di lokasi $C100. Alamat awal karakter string adalah $C101. Byte yang lebih rendah dari alamat awal adalah $01 dan byte yang lebih tinggi adalah $C1.

Sebelum memanggil rutin SETNAM, programmer harus memasukkan nomor $07 (panjang string) ke dalam akumulator µP. Byte yang lebih rendah dari alamat awal string $01 dimasukkan ke dalam register µP X. Byte yang lebih tinggi dari alamat awal string $C1 dimasukkan ke dalam register µP Y. Subrutin dipanggil secara sederhana dengan yang berikut ini:

JSR SETNAM

Rutin SETNAM mengasosiasikan nilai-nilai dari tiga register dengan saluran. Nilai-nilai tersebut tidak perlu tetap berada di register setelah itu. Jika saluran tidak memerlukan nama file, pemrogram harus memasukkan $00 ke dalam akumulator µP. Dalam hal ini, nilai-nilai yang ada di register X dan Y diabaikan.

Rutinitas OS TERBUKA
Rutinitas OS OPEN diakses dengan melompat (JSR) ke tabel lompatan OS ROM di $FFC0. Rutin ini menggunakan nomor file logis, nomor perangkat (dan buffer), kemungkinan alamat sekunder, dan kemungkinan nama file, untuk menyediakan koneksi antara komputer komodor dan file di perangkat eksternal atau perangkat eksternal itu sendiri.

Rutinitas ini, seperti semua rutinitas Commodore OS ROM lainnya, tidak memerlukan argumen apa pun. Meskipun menggunakan register µP, tidak ada register yang harus diisi dengan argumen (nilai) untuknya. Untuk mengkodekannya, cukup ketikkan yang berikut ini setelah SETLFS dan SETNAM dipanggil:

JSR TERBUKA

Kesalahan mungkin terjadi dengan rutinitas OPEN. Misalnya, file mungkin tidak ditemukan untuk dibaca. Ketika kesalahan terjadi, rutin gagal dan memasukkan nomor kesalahan yang sesuai ke dalam akumulator µP, dan menyetel flag carry (ke 1) dari register status µP. Tabel berikut memberikan nomor kesalahan dan artinya:

Tabel 5.51
Nomor Kernal Error dan Artinya pada Rutin OS ROM OPEN
Nomor Kesalahan Keterangan Contoh
1 TERLALU BANYAK FILE BUKA ketika sepuluh file sudah terbuka
2 FILE DIBUKA BUKA 1,3: BUKA 1,4
3 FILE TIDAK TERBUKA CETAK#5 tanpa BUKA
4 BERKAS TIDAK DITEMUKAN BEBAN “NONEXISTENF”,8
5 PERANGKAT TIDAK HADIR BUKA 11,11: CETAK#11
6 BUKAN MASUKAN FILE BUKA “SEQ,S,W”: DAPATKAN#8,X$
7 BUKAN FILE KELUARAN BUKA 1,0: CETAK#1
8 NAMA FILE HILANG BEBAN “”,8
9 PERANGKAT ILEGAL NO. BEBAN “PROGRAM”,3

Tabel ini disajikan sedemikian rupa sehingga pembaca mungkin melihatnya di banyak tempat lain.

Rutinitas OS CHKIN
Rutinitas OS CHKIN diakses dengan melompat (JSR) ke tabel lompatan OS ROM di $FFC6. Setelah membuka file (file logis), harus diputuskan apakah pembukaannya untuk input atau output. Rutinitas CHKIN menjadikan pembukaan saluran masukan. Rutin ini perlu membaca nomor file logis dari register µP X. Jadi, programmer harus memasukkan nomor file logis ke dalam register X sebelum memanggil rutin ini. Ini disebut secara sederhana sebagai:

JSR CHKIN

Rutinitas OS CHKOUT
Rutinitas OS CHKOUT diakses dengan melompat (JSR) ke tabel lompatan OS ROM di $FFC9. Setelah membuka file (file logis), harus diputuskan apakah pembukaannya untuk input atau output. Rutinitas CHKOUT menjadikan pembukaan saluran keluaran. Rutin ini perlu membaca nomor file logis dari register µP X. Jadi, programmer harus memasukkan nomor file logis ke dalam register X sebelum memanggil rutin ini. Ini disebut secara sederhana sebagai:

JSR CHKOUT

Rutinitas TUTUP OS
Rutinitas OS CLOSE diakses dengan melompat (JSR) ke tabel lompatan OS ROM di $FFC3. Setelah file logis dibuka dan byte dikirimkan, file logis harus ditutup. Menutup file logis akan membebaskan buffer di unit sistem untuk digunakan oleh beberapa file logis lain yang masih harus dibuka. Parameter terkait dalam tiga tabel file juga dihapus. Lokasi RAM untuk jumlah file yang dibuka dikurangi 1.

Ketika daya komputer dihidupkan, terjadi reset perangkat keras untuk mikroprosesor dan chip utama lainnya (sirkuit terintegrasi) pada motherboard. Dilanjutkan dengan inisialisasi beberapa lokasi memori RAM dan beberapa register pada beberapa chip pada motherboard. Dalam proses inisialisasi, lokasi memori byte alamat $0098 di halaman nol diberikan dengan label NFILES atau LDTND, bergantung pada versi sistem operasi. Saat komputer beroperasi, lokasi satu byte 8 bit ini menyimpan jumlah file logis yang dibuka, dan indeks alamat awal dari tiga tabel file berturut-turut. Dengan kata lain, byte ini memiliki jumlah file terbuka yang dikurangi 1 ketika file logis ditutup. Ketika file logis ditutup, akses ke perangkat terminal (tujuan) atau file sebenarnya di disk tidak lagi dimungkinkan.

Untuk menutup file logis, pemrogram harus memasukkan nomor file logis ke dalam akumulator µP. Ini adalah nomor file logis yang sama yang digunakan dalam membuka file. Rutinitas CLOSE membutuhkannya untuk menutup file tertentu. Seperti rutin OS ROM lainnya, rutin CLOSE tidak mengambil argumen, meskipun nilai yang digunakan dari akumulator agaknya merupakan argumen. Baris instruksi bahasa perakitan sederhana:

JSR TUTUP

Subrutin (rutin) bahasa rakitan 6502 khusus atau yang telah ditentukan sebelumnya tidak memerlukan argumen. Namun, argumennya muncul secara informal dengan memasukkan nilai-nilai yang akan digunakan subrutin dalam register mikroprosesor.

Rutinitas CLRCHN
Rutinitas OS CLRCHN diakses dengan melompat (JSR) ke tabel lompatan OS ROM di $FFCC. CLRCHN adalah singkatan CLeaR CHanneL. Ketika file logis ditutup, parameter nomor file logis, nomor perangkat, dan kemungkinan alamat sekundernya akan dihapus. Jadi, saluran untuk file logis dibersihkan.

Manual mengatakan bahwa rutinitas OS CLRCHN menghapus semua saluran yang terbuka dan mengembalikan nomor perangkat default dan default lainnya. Apakah ini berarti nomor perangkat periferal dapat diubah? Ya, kurang tepat. Selama inisialisasi sistem operasi, lokasi byte alamat $0099 diberikan dengan label DFLTI untuk menyimpan nomor perangkat input saat komputer beroperasi. Commodore-64 hanya dapat mengakses satu periferal dalam satu waktu. Selama inisialisasi sistem operasi, lokasi byte alamat $009A diberikan dengan label DFLTO untuk menyimpan nomor perangkat keluaran saat ini ketika komputer beroperasi.

Ketika subrutin CLRCHN dipanggil, ia menyetel variabel DFLTI ke 0 ($00) yang merupakan nomor perangkat input default (keyboard). Ini menetapkan variabel DFLTO ke 3 ($03) yang merupakan nomor perangkat keluaran default (layar). Variabel nomor perangkat lainnya juga disetel ulang dengan cara yang sama. Maksudnya mereset (atau mengembalikan) perangkat input/output ke normal (nilai default).

Manual Commodore-64 mengatakan bahwa setelah rutinitas CLRCHN dipanggil, file logis yang dibuka tetap terbuka dan masih dapat mengirimkan byte (data). Ini berarti bahwa rutin CLRCHN tidak menghapus entri terkait dalam tabel file. Nama CLRCHN agak ambigu maknanya.

5.6 Mengirim Karakter ke Layar

Sirkuit terpadu (IC) utama untuk menangani tampilan karakter dan grafik ke layar disebut Video Interface Controller (chip) yang disingkat VIC pada Commodore-64 (sebenarnya VIC II untuk VIC versi 2). Agar suatu informasi (nilai) dapat sampai ke layar, ia harus melewati VIC II sebelum mencapai layar.

Layar terdiri dari 25 baris dan 40 kolom sel karakter. Ini menghasilkan 40 x 25 = 1000 karakter yang dapat ditampilkan di layar. VIC II membaca 1000 memori RAM lokasi byte berturut-turut untuk karakter. 1000 lokasi ini digabungkan dikenal sebagai memori layar. Yang masuk ke 1000 lokasi ini adalah kode karakternya. Untuk Commodore-64, kode karakter berbeda dengan kode ASCII.

Kode karakter bukanlah pola karakter. Ada juga yang disebut ROM karakter. ROM karakter terdiri dari berbagai macam pola karakter, beberapa di antaranya sesuai dengan pola karakter pada keyboard. ROM karakter berbeda dengan memori layar. Ketika sebuah karakter akan ditampilkan di layar, kode karakter dikirim ke suatu posisi di antara 1000 posisi memori layar. Dari sana, pola yang sesuai dipilih dari ROM karakter yang akan ditampilkan di layar. Pemilihan pola yang benar dalam ROM karakter dari kode karakter dilakukan oleh VIC II (perangkat keras).

Banyak lokasi memori antara $D000 dan $DFFF memiliki dua tujuan: digunakan untuk menangani operasi input/output selain layar atau digunakan sebagai ROM karakter untuk layar. Dua blok memori menjadi perhatian. Salah satunya adalah RAM dan yang lainnya adalah ROM untuk ROM karakter. Pertukaran bank untuk menangani input/output atau pola karakter (ROM karakter) dilakukan oleh perangkat lunak (rutin OS dalam ROM dari $F000 hingga $FFFF).

Catatan : VIC memiliki register yang dialamatkan dengan alamat ruang memori dalam kisaran $D000 dan $DFFF.

Rutinitas CHROUT
Rutinitas OS CHROUT diakses dengan melompat (JSR) ke tabel lompatan OS ROM di $FFD2. Rutin ini, ketika dipanggil, mengambil byte yang dimasukkan pemrogram ke dalam akumulator µP dan mencetak di layar tempat kursor berada. Segmen kode untuk mencetak karakter “E”, misalnya adalah:

LDA #$05
CHROUT

0516 bukan kode ASCII untuk “E”. Commodore-64 memiliki kode karakternya sendiri untuk layar di mana $05 berarti “E”. Nomor #$05 ditempatkan di memori layar sebelum VIC mengirimkannya ke layar. Kedua baris pengkodean ini harus muncul setelah saluran diatur, file logis dibuka, dan rutinitas CHKOUT dipanggil untuk keluarannya. Kode lengkapnya adalah:

; Saluran pengaturan
LDA #$40 ; nomor file logis
LDX #$03 ; nomor perangkat untuk layar adalah $03
LDY #$FF ; tidak ada alamat sekunder
JSR SETLFS; pengaturan saluran yang tepat
; tidak ada SETNAM karena layar tidak memerlukan nama
;
; Buka file logis
JSR TERBUKA
; Atur saluran untuk keluaran
LDX #$40 ; nomor file logis
JSR CHKOUT
;
; Keluarkan karakter ke layar
LDA #$05
JSR CHROUT
; Tutup file logis
LDA #$40
JSR TUTUP

Pembukaan harus ditutup sebelum program lain dijalankan. Asumsikan bahwa pengguna komputer mengetikkan karakter ke keyboard saat diharapkan. Program berikut mencetak karakter dari keyboard ke layar:

; Saluran pengaturan
LDA #$40 ; nomor file logis
LDX #$03 ; nomor perangkat untuk layar adalah $03
LDY #$FF ; tidak ada alamat sekunder
JSR SETLFS; pengaturan saluran yang tepat
; tidak ada SETNAM karena layar tidak memerlukan nama
;
; Buka file logis
JSR TERBUKA
; Atur saluran untuk keluaran
LDX #$40 ; nomor file logis
JSR CHKOUT
;
; Masukkan karakter dari keyboard
TUNGGU JSR DAPATKAN; memasukkan $00 ke dalam A jika antrian keyboard kosong
CMP #$00 ; Jika $00 diberikan kepada A, maka Z adalah 1 dengan perbandingannya
BEQ TUNGGU; GETIN dari antrian lagi jika 0 masuk ke akumulator
BNE PRNSCRN ; buka PRNSCRN jika Z adalah 0, karena A tidak lagi memiliki $00
; Keluarkan karakter ke layar
PRNSCRN JSR CHROUT; kirim karakter di A ke layar
; Tutup file logis
LDA #$40
JSR TUTUP

Catatan : WAIT dan PRNSCRN adalah label yang mengidentifikasi alamat. Byte dari keyboard yang masuk ke akumulator µP adalah kode ASCII. Kode terkait yang akan dikirim ke layar oleh Commodore-64 harus berbeda. Hal ini tidak diperhitungkan dalam program sebelumnya demi kesederhanaan.

5.7 Mengirim dan Menerima Byte untuk Disk Drive

Ada dua Adaptor Antarmuka Kompleks di unit sistem (motherboard) Commodore-64 yang disebut VIA #1 dan CIA #2. Setiap CIA memiliki dua port paralel yang disebut Port A dan Port B. Terdapat port eksternal pada permukaan vertikal di belakang unit sistem Commodre-64 yang disebut port serial. Port ini memiliki 6 pin yang salah satunya untuk data. Data masuk atau keluar dari unit sistem secara seri, sedikit demi sedikit.

Delapan bit paralel dari Port A internal CIA #2, misalnya, dapat keluar dari unit sistem melalui port serial eksternal setelah diubah menjadi data serial oleh register geser di CIA. Data serial delapan bit dari port serial eksternal dapat masuk ke Port A internal CIA #2 setelah diubah menjadi data paralel oleh register geser di CIA.

Unit sistem Commodore-64 (unit dasar) menggunakan drive disk eksternal dengan disket. Printer dapat dihubungkan ke drive disk ini dengan cara rantai daisy (menghubungkan perangkat secara seri sebagai string). Kabel data untuk disk drive terhubung ke port serial eksternal unit sistem Commodore-64. Ini berarti printer rantai daisy juga terhubung ke port serial yang sama. Kedua perangkat ini diidentifikasi dengan dua nomor perangkat berbeda (biasanya masing-masing 8 dan 4).

Mengirim atau menerima data untuk disk drive mengikuti prosedur yang sama seperti yang dijelaskan sebelumnya. Itu adalah:

  • Menetapkan nama file logis (angka) yang sama dengan file disk sebenarnya menggunakan rutin SETNAM.
  • Membuka file logis menggunakan rutinitas OPEN.
  • Memutuskan apakah input atau output menggunakan rutinitas CHKOUT atau CHKIN.
  • Mengirim atau menerima data menggunakan instruksi STA dan/atau LDA.
  • Menutup file logis menggunakan rutinitas CLOSE.

File logis harus ditutup. Menutup file logis secara efektif menutup saluran tertentu. Saat menyiapkan saluran untuk drive disk, nomor file logis ditentukan oleh pemrogram. Ini adalah angka antara $00 dan $FF (inklusif). Ini tidak boleh berupa nomor yang telah dipilih untuk perangkat lain (atau file sebenarnya). Nomor perangkat adalah 8 jika hanya ada satu disk drive. Alamat sekunder (nomor) diperoleh dari manual drive disk. Program berikut menggunakan 2. Program menulis huruf “E” (ASCII) ke file di disk bernama “mydoc.doc”. Nama ini diasumsikan dimulai pada alamat memori $C101. Jadi, byte yang lebih rendah dari $01 harus berada di register X dan byte yang lebih tinggi dari $C1 harus berada di register Y sebelum rutin SETNAM dipanggil. Register A juga harus mempunyai nomor $09 sebelum rutin SETNAM dipanggil.

; Saluran pengaturan
LDA #$40 ; nomor file logis
LDX #$08 ; nomor perangkat untuk drive disk pertama
LDY #$02 ; alamat sekunder
JSR SETLFS; pengaturan saluran yang tepat
;
; File di disk drive memerlukan nama (sudah ada di memori)
LDA #$09
LDX #$01
LDY#$C1
JSR SETNAM
; Buka file logis
JSR TERBUKA
; Atur saluran untuk keluaran
LDX #$40 ; nomor file logis
JSR CHKOUT ;untuk menulis
;
; Keluaran karakter ke disk
LDA #$45
JSR CHROUT
; Tutup file logis
LDA #$40
JSR TUTUP

Untuk membaca satu byte dari disk ke dalam register µP Y, ulangi program sebelumnya dengan perubahan berikut: Daripada “JSR CHKOUT ; untuk menulis”, gunakan “JSR CHKIN ; untuk dibaca'. Ganti segmen kode untuk “; Output char ke disk” dengan yang berikut:

; Masukkan karakter dari disk
JSR CHRIS

Rutinitas OS CHRIN diakses dengan melompat (JSR) ke tabel lompatan OS ROM di $FFCF. Rutin ini, ketika dipanggil, mengambil satu byte dari saluran yang telah ditetapkan sebagai saluran masukan dan memasukkannya ke dalam register µP A. Rutinitas GETIN ROM OS juga dapat digunakan sebagai pengganti CHRIN.

Mengirim Byte ke Printer
Mengirim byte ke printer dilakukan dengan cara yang mirip dengan mengirim byte ke file di disk.

5.8 Rutinitas SIMPAN OS

Rutinitas OS SAVE diakses dengan melompat (JSR) ke tabel lompatan OS ROM di $FFD8. Rutin OS SAVE di ROM menyimpan (membuang) bagian memori ke disk sebagai file (dengan nama). Alamat awal bagian dalam memori harus diketahui. Alamat akhir bagian tersebut juga harus diketahui. Byte yang lebih rendah dari alamat awal ditempatkan di halaman nol dalam RAM pada alamat $002B. Byte yang lebih tinggi dari alamat awal ditempatkan di lokasi memori byte berikutnya di alamat $002C. Di halaman nol, label TXTTAB mengacu pada dua alamat ini, meskipun TXTTAB sebenarnya berarti alamat $002B. Byte yang lebih rendah dari alamat akhir ditempatkan di register µP X. Byte yang lebih tinggi dari alamat akhir ditambah 1 ditempatkan di register µP Y. Register µP A mengambil nilai $2B untuk TXTTAB ($002B). Dengan itu, rutin SAVE dapat dipanggil dengan yang berikut ini:

JSR SIMPAN

Bagian memori yang akan disimpan dapat berupa program bahasa assembly atau dokumen. Contoh dokumen dapat berupa surat atau esai. Untuk menggunakan rutin simpan, prosedur berikut harus diikuti:

  • Atur saluran menggunakan rutinitas SETLFS.
  • Tetapkan nama file logis (nomor) yang sama dengan file disk sebenarnya menggunakan rutin SETNAM.
  • Buka file logis menggunakan rutinitas OPEN.
  • Buatlah file untuk output menggunakan CHKOUT.
  • Kode untuk menyimpan file ada di sini yang diakhiri dengan “JSR SAVE”.
  • Tutup file logis menggunakan rutinitas CLOSE.

Program berikut menyimpan file yang dimulai dari lokasi memori $C101 hingga $C200:

; Saluran pengaturan
LDA #$40 ; nomor file logis
LDX #$08 ; nomor perangkat untuk drive disk pertama
LDY #$02 ; alamat sekunder
JSR SETLFS; pengaturan saluran yang tepat
;
; Nama untuk file di disk drive (sudah ada di memori seharga $C301)
LDA #$09 ; panjang nama file
LDX #$01
LDY #$C3
JSR SETNAM
; Buka file logis
JSR TERBUKA
; Atur saluran untuk keluaran
LDX #$40 ; nomor file logis
JSR CHKOUT; untuk menulis
;
; Keluaran file ke disk
LDA #$01
STA $2M ; TXTTAB
LDA #$C1
STA $2C
LDX #$00
LDY#$C2
LDA #$2M
JSR SIMPAN
; Tutup file logis
LDA #$40
JSR TUTUP

Perhatikan bahwa ini adalah program yang menyimpan bagian lain dari memori (bukan bagian program) ke dalam disk (disket untuk Commodore-64).

5.9 Rutinitas BEBAN OS

Rutinitas OS LOAD diakses dengan melompat (JSR) ke tabel lompatan OS ROM di $FFD5. Ketika suatu bagian (area besar) dari memori disimpan ke disk, bagian tersebut disimpan dengan header yang memiliki alamat awal bagian tersebut dalam memori. Subrutin OS LOAD memuat byte file ke dalam memori. Dengan operasi LOAD ini, nilai akumulator harus 010 ($00). Agar operasi LOAD membaca alamat awal di header file di disk dan memasukkan byte file ke dalam RAM yang dimulai dari alamat itu, alamat sekunder untuk saluran tersebut harus 1 atau 2 (program berikut menggunakan 2). Rutin ini mengembalikan alamat ditambah 1 lokasi RAM tertinggi yang dimuat. Artinya byte rendah dari alamat terakhir file di RAM ditambah 1 dimasukkan ke dalam register µP X, dan byte tinggi dari alamat terakhir file di RAM ditambah 1 dimasukkan ke dalam register µP Y.

Jika pemuatan tidak berhasil, register µP A menyimpan nomor kesalahan (mungkin 4, 5, 8 atau 9). Bendera C dari register status mikroprosesor juga disetel (dibuat 1). Jika pemuatan berhasil, nilai terakhir register A tidak penting.

Nah, pada bab sebelumnya kursus karir online ini, instruksi pertama program bahasa assembly ada di alamat RAM tempat program dimulai. Tidak harus seperti itu. Artinya instruksi pertama suatu program tidak harus berada di awal program di RAM. Instruksi awal untuk suatu program dapat berada di mana saja di dalam file di RAM. Pemrogram disarankan untuk memberi label awal pengajaran bahasa assembly dengan START. Dengan itu, setelah program dimuat, program dijalankan kembali (dieksekusi) dengan instruksi bahasa assembly berikut:

JSR MULAI

“JSR START” ada pada program bahasa assembly yang memuat program yang akan dijalankan. Bahasa rakitan yang memuat file bahasa rakitan lain dan menjalankan file yang dimuat memiliki prosedur kode berikut:

  • Atur saluran menggunakan rutinitas SETLFS.
  • Tetapkan nama file logis (nomor) yang sama dengan file disk sebenarnya menggunakan rutin SETNAM.
  • Buka file logis menggunakan rutinitas OPEN.
  • Jadikan itu file untuk input menggunakan CHKIN.
  • Kode untuk memuat file ada di sini dan diakhiri dengan “JSR LOAD”.
  • Tutup file logis menggunakan rutinitas CLOSE.

Program berikut memuat file dari disk dan menjalankannya:

; Saluran pengaturan
LDA #$40 ; nomor file logis
LDX #$08 ; nomor perangkat untuk drive disk pertama
LDY #$02 ; alamat sekunder
JSR SETLFS; pengaturan saluran yang tepat
;
; Nama untuk file di disk drive (sudah ada di memori seharga $C301)
LDA #$09 ; panjang nama file
LDX #$01
LDY#$C3
JSR SETNAM
; Buka file logis
JSR TERBUKA
; Atur saluran untuk input
LDX #$40 ; nomor file logis
JSR CHKIN ; untuk dibaca
;
; Masukkan file dari disk
LDA #$00
BEBAN JSR
; Tutup file logis
LDA #$40
JSR TUTUP
; Mulai program yang dimuat
JSR MULAI

5.10 Modem dan Standar RS-232

Modem adalah perangkat (periferal) yang mengubah bit dari komputer menjadi sinyal audio listrik yang sesuai untuk ditransmisikan melalui saluran telepon. Di sisi penerima, ada modem sebelum komputer penerima. Modem kedua ini mengubah sinyal audio listrik menjadi bit untuk komputer penerima.

Modem perlu dihubungkan ke komputer pada port eksternal (di permukaan vertikal komputer). Standar RS-232 mengacu pada jenis konektor tertentu yang menghubungkan modem ke komputer (di masa lalu). Dengan kata lain, banyak komputer di masa lalu memiliki port eksternal berupa konektor RS-232 atau konektor yang kompatibel dengan RS-232.

Unit Sistem Commodore-64 (komputer) memiliki port eksternal di permukaan vertikal belakangnya yang disebut port pengguna. Port pengguna ini kompatibel dengan RS-232. Perangkat modem dapat dihubungkan di sana. Commodore-64 berkomunikasi dengan modem melalui port pengguna ini. Sistem operasi ROM untuk Commodore-64 memiliki subrutin untuk berkomunikasi dengan modem yang disebut rutinitas RS-232. Rutinitas ini memiliki entri di tabel lompat.

Tingkat Baud
Byte delapan bit dari komputer diubah menjadi rangkaian delapan bit sebelum dikirim ke modem. Kebalikannya dilakukan dari modem ke komputer. Baud rate adalah jumlah bit yang ditransmisikan per detik, secara seri.

Bagian Bawah Memori
Istilah 'Bawah Memori' tidak mengacu pada lokasi byte memori dari alamat $0000. Ini mengacu pada lokasi RAM terendah di mana pengguna dapat mulai meletakkan data dan programnya. Secara default, itu adalah $0800. Ingat dari diskusi sebelumnya bahwa banyak lokasi antara $0800 dan $BFFF digunakan oleh bahasa komputer BASIC dan pemrogramnya (pengguna). Hanya lokasi alamat $C000 hingga $CFFF yang tersisa untuk digunakan untuk program dan data bahasa rakitan; ini adalah 4Kbytes dari 64 Kbytes memori.

Bagian Atas Memori
Pada masa itu, ketika klien membeli komputer Commodore-64, beberapa tidak dilengkapi dengan semua lokasi memori. Komputer tersebut memiliki ROM dengan sistem operasinya mulai dari $E000 hingga $FFFF. Mereka memiliki RAM mulai dari $0000 hingga batasnya, yang bukan $DFFF, di samping $E000. Batasannya di bawah $DFFF dan batas itu disebut “Top of Memory”. Jadi, top-of-memory tidak mengacu pada lokasi $FFFF.

Buffer Commodore-64 untuk Komunikasi RS-232
Transmisi Buffer
Buffer untuk transmisi (output) RS-232 membutuhkan 256 byte dari memori atas ke bawah. Penunjuk untuk buffer transmisi ini diberi label sebagai ROBUF. Penunjuk ini berada di halaman nol dengan alamat $00F9 diikuti oleh $00FA. ROBUF sebenarnya mengidentifikasi $00F9. Jadi, jika alamat awal buffer adalah $BE00, byte bawah $BE00, yaitu $00, ada di lokasi $00F9 dan byte tinggi $BE00, yaitu $BE, ada di $00FA lokasi.

Menerima Penyangga
Buffer untuk menerima RS-232 byte (input) membutuhkan 256 byte dari bagian bawah buffer transmisi. Pointer untuk buffer penerima ini diberi label RIBUF. Penunjuk ini berada di halaman nol dengan alamat $00F7 diikuti oleh $00F8. RIBUF sebenarnya mengidentifikasi $00F7. Jadi, jika alamat awal buffer adalah $BF00, byte bawah $BF00, yakni $00, ada di lokasi $00F7 dan byte tertinggi $BF00, yaitu $BF, ada di $00F8 lokasi. Jadi, 512 byte dari memori atas digunakan sebagai total buffer RAM RS-232.

Saluran RS-232
Ketika modem dihubungkan ke port pengguna (eksternal), komunikasi ke modem hanyalah komunikasi RS-232. Prosedur untuk memiliki saluran RS-232 yang lengkap hampir sama dengan pembahasan sebelumnya, namun dengan satu perbedaan penting: nama file adalah kode dan bukan string di memori. Kode $0610 adalah pilihan yang bagus. Ini berarti baud rate 300 bit/detik dan beberapa parameter teknis lainnya. Juga, tidak ada alamat sekunder. Perhatikan bahwa nomor perangkatnya adalah 2. Prosedur untuk menyiapkan saluran RS-232 yang lengkap adalah:

  • Setting saluran menggunakan rutin SETLFS.
  • Menetapkan nama file logis, $0610.
  • Membuka file logis menggunakan rutinitas OPEN.
  • Menjadikannya file untuk output menggunakan CHKOUT atau file untuk input menggunakan CHKIN.
  • Mengirim byte tunggal dengan CHROUT atau menerima byte tunggal dengan GETIN.
  • Menutup file logis menggunakan rutinitas CLOSE.

Rutinitas OS GETIN diakses dengan melompat (JSR) ke tabel lompatan OS ROM di $FFE4. Rutin ini, ketika dipanggil, mengambil byte yang dikirim ke buffer penerima dan menempatkannya (mengembalikannya) ke akumulator µP.

Program berikut mengirimkan byte “E” (ASCII) ke modem yang terhubung ke port pengguna yang kompatibel dengan RS-232:

; Saluran pengaturan
LDA #$40 ; nomor file logis
LDX #$02 ; nomor perangkat untuk RS-232
LDY #$FF ; tidak ada alamat sekunder
JSR SETLFS; pengaturan saluran yang tepat
;
; Nama untuk RS-232 adalah kode mis. $0610
LDA #$02 ; panjang kode adalah 2 byte
LDX #$10
LDY #$06
JSR SETNAM
;
; Buka file logis
JSR TERBUKA
; Atur saluran untuk keluaran
LDX #$40 ; nomor file logis
JSR CHKOUT
;
; Output char ke RS-232 mis. modem
LDA #$45
JSR CHROUT
; Tutup file logis
LDA #$40
JSR TUTUP

Untuk menerima byte, kodenya sangat mirip, kecuali “JSR CHKOUT” diganti dengan “JSR CHKIN” dan:

LDA #$45
JSR CHROUT

diganti dengan “JSR GETIN” dengan hasilnya ditempatkan ke dalam register A.

Pengiriman atau penerimaan byte secara terus menerus dilakukan melalui loop masing-masing untuk pengiriman atau penerimaan segmen kode.

Perhatikan bahwa input dan output dengan Commodore serupa untuk sebagian besar kasusnya kecuali untuk keyboard di mana beberapa rutinitas tidak dipanggil oleh pemrogram, namun dipanggil oleh sistem operasi.

5.11 Penghitungan dan Waktu

Perhatikan urutan penghitungan mundur yaitu:

2, 1, 0

Ini adalah penghitungan mundur dari 2 hingga 0. Sekarang, perhatikan urutan penghitungan mundur yang berulang:

2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0

Ini adalah penghitungan mundur berulang-ulang dari urutan yang sama. Urutan ini diulang empat kali. Empat kali berarti waktunya 4. Dalam satu urutan dihitung. Mengulangi urutan yang sama adalah pengaturan waktu.

Ada dua Adaptor Antarmuka Kompleks di unit sistem Commodore-64. Setiap CIA memiliki dua rangkaian counter/timer yang diberi nama Timer A (TA) dan Timer B (TB). Rangkaian pencacahan tidak berbeda dengan rangkaian pewaktuan. Counter atau timer di Commodore-64 mengacu pada hal yang sama. Faktanya, salah satu dari keduanya pada dasarnya mengacu pada satu register 16-bit yang selalu menghitung mundur hingga 0 pada pulsa jam sistem. Nilai yang berbeda dapat diatur ke dalam register 16-bit. Semakin besar nilainya, semakin lama waktu yang dibutuhkan untuk menghitung mundur hingga nol. Setiap kali salah satu pengatur waktu melewati angka nol, IRQ sinyal interupsi dikirim ke mikroprosesor. Ketika penghitungan turun melewati angka nol, maka disebut underflow.

Tergantung pada bagaimana rangkaian pengatur waktu diprogram, pengatur waktu dapat berjalan dalam mode satu kali atau dalam mode berkelanjutan. Dengan ilustrasi sebelumnya, mode satu kali berarti “lakukan 2, 1, 0” dan berhenti selama pulsa jam terus berlanjut. Mode berkelanjutan seperti “2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, dst.” yang dilanjutkan dengan pulsa jam. Artinya ketika melewati angka nol, jika tidak ada instruksi yang diberikan, urutan hitung mundur akan berulang. Angka terbesar biasanya jauh lebih besar dari 2.

Timer A (TA) dari CIA #1 dihasilkan IRQ secara berkala (durasi) untuk menyervis keyboard. Faktanya, ini sebenarnya adalah setiap 1/60 detik secara default. IRQ dikirim ke mikroprosesor setiap 1/60 detik. Hanya ketika IRQ dikirim agar program dapat membaca nilai kunci dari antrian keyboard (buffer). Ingatlah bahwa mikroprosesor hanya memiliki satu pin untuk IRQ sinyal. Mikroprosesor juga hanya memiliki satu pin untuk NMI sinyal. Sinyal ¯NMI ke mikroprosesor selalu berasal dari CIA #2.

Register pengatur waktu 16-bit memiliki dua alamat memori: satu untuk byte yang lebih rendah dan satu lagi untuk byte yang lebih tinggi. Setiap CIA memiliki dua sirkuit pengatur waktu. Kedua CIA itu identik. Untuk CIA #1, alamat untuk kedua pengatur waktu adalah: DC04 dan DC05 untuk TA dan DC06 dan DC07 untuk TB. Untuk CIA #2, alamat untuk kedua pengatur waktu adalah: DD04 dan DD05 untuk TA dan DD06 dan DD07 untuk TB.

Asumsikan bahwa nomor 25510 akan dikirim ke timer TA CIA #2 untuk menghitung mundur. 25510 = 00000000111111112 dalam enam belas bit. 00000000111111112 = $000FFF dalam heksadesimal. Dalam hal ini, $FF dikirim ke register di alamat $DD04, dan $00 dikirim ke register di alamat $DD05 – little endianness. Segmen kode berikut mengirimkan nomor ke register:

LDA #$FF
NEGARA $DD04
LDA #$00
NEGARA $DD05

Meskipun register di CIA memiliki alamat RAM, mereka secara fisik berada di CIA dan CIA adalah IC yang terpisah dari RAM atau ROM.

Bukan itu saja! Ketika penghitung waktu telah diberi nomor untuk menghitung mundur, seperti pada kode sebelumnya, penghitungan mundur tidak dimulai. Penghitungan mundur dimulai ketika byte delapan bit telah dikirim ke register kontrol yang sesuai untuk pengatur waktu. Bit pertama dari byte ini untuk register kontrol menunjukkan apakah penghitungan mundur harus dimulai atau tidak. Nilai 0 untuk bit pertama ini berarti berhenti menghitung mundur, sedangkan nilai 1 berarti mulai menghitung mundur. Selain itu, byte harus menunjukkan apakah penghitungan mundur dilakukan dalam mode satu kali (satu kali) atau dalam mode lari bebas (mode kontinu). Mode sekali tembak menghitung mundur dan berhenti ketika nilai register pengatur waktu menjadi nol. Dengan mode free running, penghitungan mundur diulang setelah mencapai 0. Bit keempat (indeks 3) dari byte yang dikirim ke register kontrol menunjukkan mode: 0 berarti mode free running dan 1 berarti mode one-shot.

Angka yang cocok untuk mulai menghitung dalam mode satu tembakan adalah 000010012 = $09 dalam heksadesimal. Angka yang cocok untuk mulai menghitung dalam mode lari bebas adalah 000000012 = $01 dalam heksadesimal. Setiap register pengatur waktu mempunyai register kendalinya sendiri. Di CIA #1, register kontrol untuk timer A memiliki alamat RAM DC0E16 dan register kontrol untuk timer B memiliki alamat RAM DC0F16. Dalam CIA #2, register kontrol untuk timer A memiliki alamat RAM DD0E16 dan register kontrol untuk timer B memiliki alamat RAM DD0F16. Untuk mulai menghitung mundur angka enam belas-bit di TA CIA #2, dalam mode satu tembakan, gunakan kode berikut:

LDA #$09
STA $DD0E

Untuk mulai menghitung mundur angka enam belas-bit di TA CIA #2, dalam mode lari bebas, gunakan kode berikut:

LDA #$01
STA $DD0E

5.12 Itu IRQ Dan NMI Permintaan

Mikroprosesor 6502 memiliki IRQ Dan NMI garis (pin). Baik CIA #1 dan CIA #2 masing-masing memiliki IRQ pin untuk mikroprosesor. Itu IRQ pin CIA #2 terhubung ke NMI pin µP. Itu IRQ pin CIA #1 terhubung ke IRQ pin µP. Hanya itulah dua jalur interupsi yang menghubungkan mikroprosesor. Sehingga IRQ pin CIA #2 adalah NMI sumber dan juga dapat dilihat sebagai garis ¯NMI.

CIA #1 memiliki lima kemungkinan sumber langsung yang menghasilkan IRQ sinyal untuk μP. CIA #2 memiliki struktur yang sama dengan CIA #1. Jadi, CIA #2 memiliki lima kemungkinan sumber langsung yang sama untuk menghasilkan sinyal interupsi kali ini yaitu NMI sinyal. Ingatlah bahwa ketika µP menerima NMI sinyal, jika sedang menangani IRQ permintaan, itu menangguhkannya dan menanganinya NMI meminta. Ketika selesai menangani NMI permintaan, kemudian melanjutkan penanganan IRQ meminta.

CIA #1 biasanya terhubung secara eksternal ke keyboard dan perangkat permainan seperti joystick. Keyboard menggunakan lebih banyak port A CIA #1 daripada port B. Perangkat permainan menggunakan lebih banyak port CIA #1 B daripada port A. CIA #2 biasanya terhubung secara eksternal ke disk drive (daisy dirantai ke printer) dan modemnya. Disk drive menggunakan lebih banyak port A CIA #2 (meskipun melalui port serial eksternal) dibandingkan port B. Modem (RS-232) menggunakan lebih banyak port B CIA #2 daripada port A.

Dengan semua itu, bagaimana unit sistem mengetahui apa penyebabnya IRQ atau NMI mengganggu? CIA #1 dan CIA #2 mempunyai lima sumber interupsi langsung. Jika sinyal interupsi ke µP adalah NMI , sumbernya adalah salah satu dari lima sumber langsung dari CIA #2. Jika sinyal interupsi ke µP adalah IRQ , sumbernya adalah salah satu dari lima sumber langsung dari CIA #1.

Pertanyaan berikutnya adalah, “Bagaimana unit sistem membedakan lima sumber langsung dari masing-masing CIA?” Setiap CIA memiliki register delapan bit yang disebut Interrupt Control Register (ICR). ICR melayani kedua pelabuhan CIA. Tabel berikut menunjukkan arti dari delapan bit register kontrol interupsi, mulai dari bit 0:

Tabel 5.13
Daftar Kontrol Interupsi
Indeks Bit Arti
0 Diatur (dibuat 1) oleh aliran bawah pengatur waktu A
1 Diatur oleh aliran bawah pengatur waktu B
2 Atur kapan jam Time-Of-Day sama dengan alarm
3 Atur ketika port serial penuh
4 Diatur oleh perangkat eksternal
5 Tidak digunakan (dibuat 0)
6 Tidak digunakan (dibuat 0)
7 Atur kapan salah satu dari lima bit pertama diatur

Seperti dapat dilihat dari tabel, masing-masing sumber langsung diwakili oleh salah satu dari lima bit pertama. Jadi, ketika sinyal interupsi diterima pada µP, kode harus dieksekusi untuk membaca isi register kontrol interupsi untuk mengetahui sumber interupsi secara pasti. Alamat RAM untuk ICR CIA #1 adalah DC0D16. Alamat RAM untuk ICR CIA #2 adalah DD0D16. Untuk membaca (mengembalikan) isi ICR CIA #1 ke akumulator µP, ketikkan instruksi berikut:

LDA$DC0D

Untuk membaca (mengembalikan) isi ICR CIA #2 ke akumulator µP, ketikkan instruksi berikut:

LDA $DD0D

5.13 Program Latar Belakang Berbasis Interupsi

Keyboard biasanya menginterupsi mikroprosesor setiap 1/60 detik. Bayangkan sebuah program sedang berjalan dan mencapai posisi menunggu tombol dari keyboard sebelum dapat melanjutkan dengan segmen kode di bawah ini. Asumsikan jika tidak ada tombol yang ditekan dari keyboard, program hanya melakukan putaran kecil, menunggu tombol. Bayangkan program sedang berjalan dan hanya mengharapkan tombol dari keyboard tepat setelah interupsi keyboard dikeluarkan. Pada titik itu, seluruh komputer secara tidak langsung berhenti dan tidak melakukan apa pun kecuali perulangan tunggu. Bayangkan tombol keyboard ditekan tepat sebelum interupsi keyboard berikutnya muncul. Ini berarti komputer tidak melakukan apa pun selama sekitar seperenam puluh detik! Itu adalah waktu yang lama bagi komputer untuk tidak melakukan apa pun, bahkan di zaman Commodore-64. Komputer bisa saja melakukan hal lain dalam waktu (durasi) tersebut. Ada banyak durasi seperti itu dalam suatu program.

Program kedua dapat ditulis untuk beroperasi pada durasi “idle” tersebut. Program seperti ini dikatakan berjalan di latar belakang program utama (atau program pertama). Cara mudah untuk melakukan ini adalah dengan memaksa penanganan interupsi BRK yang dimodifikasi ketika tombol diharapkan dari keyboard.

Penunjuk untuk Instruksi BRK
Pada lokasi RAM berturut-turut dari alamat $0316 dan $0317 adalah penunjuk (vektor) untuk rutinitas instruksi BRK yang sebenarnya. Penunjuk default diletakkan di sana ketika komputer dihidupkan oleh sistem operasi di ROM. Penunjuk default ini adalah alamat yang masih menunjuk ke pengendali instruksi BRK default di ROM OS. Pointernya adalah alamat 16-bit. Byte yang lebih rendah dari penunjuk ditempatkan di lokasi byte alamat $0306, dan byte penunjuk yang lebih tinggi ditempatkan di lokasi byte $0317.

Program kedua dapat ditulis sedemikian rupa sehingga ketika sistem dalam keadaan “idle”, beberapa kode dari program kedua dijalankan oleh sistem. Artinya program kedua harus terdiri dari subrutin. Ketika sistem dalam keadaan “idle” yang menunggu tombol dari keyboard, subrutin berikutnya untuk program kedua dijalankan. Interaksi manusia dengan komputer lebih lambat dibandingkan dengan pengoperasian unit sistem.

Sangat mudah untuk mengatasi masalah ini: Setiap kali komputer harus menunggu tombol dari keyboard, masukkan instruksi BRK ke dalam kode dan ganti penunjuk pada $0316 (dan $0317) dengan penunjuk subrutin berikutnya dari subrutin kedua ( adat) program. Dengan begitu, kedua program tersebut akan berjalan dalam durasi yang tidak lebih lama dari program utama yang dijalankan sendiri.

5.14 Perakitan dan Kompilasi

Assembler mengganti semua label dengan alamat. Program bahasa assembly biasanya ditulis untuk dimulai pada alamat tertentu. Hasil dari assembler (setelah dirakit) disebut “kode objek” dengan semuanya dalam biner. Hasilnya adalah file yang dapat dieksekusi jika file tersebut adalah program dan bukan dokumen. Sebuah dokumen tidak dapat dieksekusi.

Suatu aplikasi terdiri dari lebih dari satu program (bahasa rakitan). Biasanya ada program utama. Situasi di sini berbeda dengan situasi Program Latar Belakang Berbasis Interupsi. Semua program di sini merupakan program latar depan, namun ada program pertama atau program utama.

Kompiler diperlukan sebagai pengganti assembler ketika ada lebih dari satu program latar depan. Kompiler merakit setiap program menjadi kode objek. Namun, akan ada masalah: beberapa segmen kode akan tumpang tindih karena program tersebut mungkin ditulis oleh orang yang berbeda. Solusi yang dilakukan compiler adalah dengan menggeser semua program yang tumpang tindih kecuali yang pertama pada ruang memori, agar program tidak tumpang tindih. Sekarang, ketika menyangkut penyimpanan variabel, beberapa alamat variabel masih tumpang tindih. Solusinya disini adalah mengganti alamat yang tumpang tindih dengan alamat yang baru (kecuali program pertama) agar tidak tumpang tindih lagi. Dengan cara ini, program yang berbeda akan masuk ke dalam bagian (area) memori yang berbeda.

Dengan demikian, suatu rutinitas di satu program bisa saja disebut rutinitas di program lain. Jadi, kompiler melakukan penautan. Menghubungkan mengacu pada memiliki alamat awal subrutin dalam satu program dan kemudian memanggilnya di program lain; keduanya merupakan bagian dari aplikasi. Kedua program harus menggunakan alamat yang sama untuk ini. Hasil akhirnya adalah satu kode objek besar dengan semuanya dalam biner (bit).

5.15 Menyimpan, Memuat, dan Menjalankan Program

Bahasa assembly biasanya ditulis dalam beberapa program editor (yang mungkin disertakan dengan program assembler). Program editor menunjukkan di mana program dimulai dan diakhiri di memori (RAM). Rutinitas Kernal SAVE dari OS ROM Commodore-64 dapat menyimpan program di memori ke disk. Itu hanya membuang bagian (blok) memori yang mungkin berisi panggilan instruksi ke disk. Dianjurkan agar instruksi pemanggilan SAVE dipisahkan dari program yang sedang disimpan, sehingga ketika program dimuat ke dalam memori dari disk, program tersebut tidak akan menyimpan dirinya sendiri lagi ketika dijalankan. Memuat program bahasa rakitan dari disk merupakan tantangan yang berbeda karena program tidak dapat memuat dirinya sendiri.

Suatu program tidak dapat memuat dirinya sendiri dari disk ke tempat program dimulai dan diakhiri di RAM. Commodore-64 pada masa itu biasanya dilengkapi dengan penerjemah BASIC untuk menjalankan program bahasa BASIC. Ketika mesin (komputer) dihidupkan, diselesaikan dengan command prompt: READY. Dari sana, perintah atau instruksi BASIC dapat diketik dengan menekan tombol “Enter” setelah mengetik. Perintah BASIC (instruksi) untuk memuat file adalah:

BEBAN 'nama file',8,1

Perintahnya dimulai dengan kata cadangan BASIC yaitu LOAD. Ini diikuti dengan spasi dan kemudian nama file dalam tanda kutip ganda. Diikuti nomor perangkat 8 yang diawali dengan koma. Alamat sekunder untuk disk yaitu 1 diikuti, diawali dengan koma. Dengan file seperti itu, alamat awal program bahasa assembly ada di header file di disk. Ketika BASIC selesai memuat program, alamat RAM terakhir ditambah 1 program dikembalikan. Kata “return” di sini berarti byte bawah dari alamat terakhir ditambah 1 dimasukkan ke dalam register µP X, dan byte yang lebih tinggi dari alamat terakhir ditambah 1 dimasukkan ke dalam register µP Y.

Setelah memuat program, program tersebut harus dijalankan (dieksekusi). Pengguna program harus mengetahui alamat awal eksekusi di memori. Sekali lagi, program BASIC lain diperlukan di sini. Itu adalah perintah SYS. Setelah menjalankan perintah SYS, program bahasa assembly akan berjalan (dan berhenti). Saat dijalankan, jika ada input yang diperlukan dari keyboard, program bahasa assembly harus menunjukkannya kepada pengguna. Setelah pengguna mengetik data pada keyboard dan menekan tombol “Enter”, program bahasa assembly akan terus berjalan menggunakan entri keyboard tanpa gangguan dari interpreter BASIC.

Dengan asumsi alamat RAM awal eksekusi (berjalan) untuk Program Bahasa Majelis adalah C12316, C123 diubah ke basis sepuluh sebelum digunakan dengan perintah SYS. Konversi C12316 ke basis sepuluh adalah sebagai berikut:

Jadi, perintah BASIC SYS adalah:

SYS 49443

5.16 Booting untuk Komodor-64

Booting untuk Commodore-64 terdiri dari dua fase: fase reset perangkat keras dan fase inisialisasi sistem operasi. Sistem operasinya adalah Kernal di ROM (dan bukan di disk). Ada garis reset (sebenarnya RES ) yang terhubung ke pin pada 6502 µP, dan ke nama pin yang sama di semua kapal khusus seperti CIA 1, CIA 2, dan VIC II. Pada fase reset, karena baris ini, semua register di µP dan chip khusus direset ke 0 (dibuat nol untuk setiap bit). Selanjutnya, oleh perangkat keras mikroprosesor, penunjuk tumpukan dan register status prosesor diberikan dengan nilai awalnya di mikroprosesor. Penghitung program kemudian diberikan dengan nilai (alamat) di lokasi $FFFC dan $FFFD. Ingatlah bahwa penghitung program menyimpan alamat instruksi berikutnya. Konten (alamat) yang disimpan di sini adalah untuk subrutin yang memulai inisialisasi perangkat lunak. Semuanya sejauh ini dilakukan oleh perangkat keras mikroprosesor. Seluruh memori tidak tersentuh pada fase ini. Tahap inisialisasi berikutnya kemudian dimulai.

Inisialisasi dilakukan oleh beberapa rutinitas di ROM OS. Inisialisasi berarti memberikan nilai awal atau default ke beberapa register di chip khusus. Inisialisasi dimulai dengan memberikan nilai awal atau default ke beberapa register di chip khusus. IRQ , misalnya, harus mulai mengeluarkan setiap 1/60 detik. Jadi, pengatur waktu yang sesuai di CIA #1 harus disetel ke nilai defaultnya.

Selanjutnya, Kernal melakukan tes RAM. Ini menguji setiap lokasi dengan mengirimkan byte ke lokasi dan membacanya kembali. Kalau ada perbedaan, paling tidak lokasinya jelek. Kernal juga mengidentifikasi bagian atas memori dan bagian bawah memori dan menetapkan pointer yang sesuai di halaman 2. Jika bagian atas memori adalah $DFFF, $FF ditempatkan di lokasi $0283 dan $DF ditempatkan di lokasi byte $0284. Baik $0283 dan $0284 memiliki label HIRAM. Jika bagian bawah memori adalah $0800, $00 ditempatkan di lokasi $0281 dan $08 ditempatkan di lokasi $0282. Baik $0281 dan $0282 memiliki label LORAM. Tes RAM sebenarnya dimulai dari $0300 hingga memori teratas (RAM).

Terakhir, vektor input/output (pointer) diatur ke nilai defaultnya. Tes RAM sebenarnya dimulai dari $0300 hingga memori teratas (RAM). Artinya halaman 0, halaman 1, dan halaman 2 diinisialisasi. Halaman 0, khususnya, memiliki banyak petunjuk OS ROM dan halaman 2 memiliki banyak petunjuk BASIC. Petunjuk ini disebut sebagai variabel. Ingatlah bahwa halaman 1 adalah tumpukan. Pointer disebut variabel karena mempunyai nama (label). Pada tahap ini, memori layar untuk layar (monitor) dibersihkan. Ini berarti mengirimkan kode $20 untuk ruang (yang kebetulan sama dengan ASCII $20) ke 1000 lokasi layar RAM. Terakhir, Kernal memulai penerjemah BASIC untuk menampilkan prompt perintah BASIC yang READY di bagian atas monitor (layar).

5.17 Masalah

Pembaca disarankan untuk menyelesaikan semua permasalahan dalam satu bab sebelum melanjutkan ke bab berikutnya.

  1. Tulis kode bahasa assembly yang menjadikan semua bit port A CIA #2 sebagai output dan port CIA #2 B sebagai input.
  2. Tulis kode bahasa rakitan 6502 yang menunggu tombol keyboard hingga ditekan.
  3. Tulis program bahasa rakitan 6502 yang mengirimkan karakter “E” ke layar Commodore-64.
  4. Tulis program bahasa rakitan 6502 yang mengambil karakter dari keyboard dan mengirimkannya ke layar Commodore-64, mengabaikan kode kunci dan pengaturan waktu.
  5. Tulis program bahasa rakitan 6502 yang menerima byte dari disket Commodore-64.
  6. Tulis program bahasa rakitan 6502 yang menyimpan file ke disket Commodore-64.
  7. Tulis program bahasa rakitan 6502 yang memuat file program dari disket Commodore-64 dan memulainya.
  8. Tulis program bahasa rakitan 6502 yang mengirimkan byte 'E' (ASCII) ke modem yang terhubung ke port pengguna yang kompatibel dengan RS-232 di Commodore-64.
  9. Jelaskan bagaimana penghitungan dan pengaturan waktu dilakukan di komputer Commodore-64.
  10. Jelaskan bagaimana unit sistem Commodore-64 dapat mengidentifikasi 10 sumber permintaan interupsi langsung yang berbeda termasuk permintaan interupsi yang tidak dapat ditutup-tutupi.
  11. Jelaskan bagaimana program latar belakang dapat berjalan dengan program latar depan di komputer Commodore-64.
  12. Jelaskan secara singkat bagaimana program bahasa assembly dapat dikompilasi menjadi satu aplikasi untuk komputer Commodore-64.
  13. Jelaskan secara singkat proses booting komputer Commodore-64.