Emulatör Yapısı
CHIP-8'in tüm sistem özelliklerini biliyoruz. Bunların hepsini
emulator.rs
içerisinde yeni bir yapı içerisinde tanımlayalım,
bu sefer yapımızı tanımlarken içerisinde elemanları olan bir yapı
tanımlayacağız:
pub struct Emulator {
/// Bellek 4KB
memory: [u8; 4096],
/// Genel amaçlı registerlar
v: [u8; 16],
/// Bellek adresini tutmaya yarayan register
i: u16,
/// Program sayacı (program counter)
pc: u16,
/// Stack
stack: [u16; 16],
/// Stack'ın en üstünü tutan stack pointeri
sp: u8,
/// Gecikme zamanlayıcısı
delay_timer: u8,
/// Ses zamanlayıcısı
sound_timer: u8,
/// Görüntü yapısı
display: Display,
/// Klavye yapısı
keyboard: Keyboard,
}
Rust static ve strong yazılımlı bir dil olduğundan, tüm alanların tipleri de tanımlanmak zorundadır. Diğer dillerin aksine tip tanımlamaları sağ tarafta yer alır.
Yeni Bir Emulator Instance'ı Oluşturulması
Öncelikle Emulator
yapımızı, varsayılan değerleriyle bir instance'ını
oluşturan yeni bir fonksiyon tanımlayalım.
impl Emulator {
pub fn new() -> Emulator {
let mut emulator = Emulator {
memory: [0; 4096],
v: [0; 16],
i: 0x200,
pc: 0x200,
stack: [0; 16],
sp: 0,
delay_timer: 0,
sound_timer: 0,
display: Display::new(),
keyboard: Keyboard::new(),
};
for (i, font) in FONTSET.iter().enumerate() {
emulator.memory[i] = *font;
}
emulator
}
}
Değişken tanımlamaları let
anahtar kelimesi ile yapılır. Rust'ta her
değişken varsayılan olarak immutable (içeriği değiştirilemez) haldedir. Biz
fonksiyonumuzun devamında, emülatör belleğine font setini yükleyeceğimizden
içeriği değiştirilebilir bir değişkene ihtiyacımız var. Bu nedenle let
tanımlamamızın ardından mut
anahtar kelimesini kullanıyoruz. mut
anahtar kelimesi o değişkeni mutable (içeriği değiştirilebilir) duruma
getirmektedir. CHIP-8 programları belleğin 0x200
alanından
başlayacağından, I ve PC registerları 0x200 yapılır. Onun dışında her alan
0 olacak şekilde bir Emulator instance'ı oluşturulur.
Şu an için Display
ve Keyboard
yapılarını görmezden gelin. Görüntü ve
klavye işlemlerinin yapıldığı bu yapılar ileride anlatılacaktır.
for (i, font) in FONTSET.iter().enumerate() {
emulator.memory[i] = *font;
}
CHIP-8: 0 dan F'e olmak üzere 5 byte uzunluğunda sprite gösterme özelliğine
sahiptir (16*5=80). Bu font bilgisi daha önce tanımlanmış bir değişken
üzerinden emülatör belleğine yüklenir. FONTSET
array'ının içeriğini
kaynak kodlarında
görebilirsiniz. Rust'ta arraylar
Iterator
özelliğine sahip olduğundan iter()
metodu yardımıyla kolayca
iterator'e dönüştürülebilir. enumerate
metodu ise aynı Python'da olduğu
gibi item ile birlikte iterasyon sayacını döner. Bu metod sayaç ve item
değerlerini dönen bir tuple olduğundan, for döngüsü tuple değişken
tanımlamalarıyla kullanılır.
Son olarak fonksiyonumuz içerisinde yer alan emulator
satırı,
fonksiyonumuzdan emulator
değişkenimizin dönmesine yarar.