Büyük bir tasarım hatası yapmışım. Aslında başta özellikle dikkat etmiştim, ya 6510 kullanırım ya da 65c02 demiştim sonra nerede gördüysem artık UM6502'lerin de adres bus'ı tristate edebildiğini yanlış bir şekilde okumuştum. Çünkü sonradan datasheet'i inceleyince böyle olmadığını gördüm. Ancak kafamda uzak bir köşeye atmış olacağım bu bilgiyi ki iş gerçek teste gelince meseleye uyandım. Elimdeki UM6502 address bus'ı tristate edemiyor.
6502 işlemci doğuşundan beri böyle aslında, sonradan 6510 c64 için yapılırken address bus'ı tristate edebilme özelliği ve c64'te PLA'ya bağlanan özel bir i/o port'u eklenmiş. 6502'nin tasarımcılarından biri olan Bill Mencsh Western Design Center firmasının başında hala 6502'nin onunla uyumlu ve gelişmiş bir versiyonu olan 65c02'yi üretmeye devam ediyor. Daha çok IP core (Intellectual property core) olarak kullanılsa da çip olarak üretimi ve satışı da mevcut.
Bu arada bilmeyenler için Tristate'in ne demek olduğunu biraz açayım. Bilgisayar mimarilerinde belli devre elemanları arasındaki bağlantılar ortak kullanılan elemanlar söz konusu olduğunda ortak kullanılmak durumunda kalıyorlar. En çok rastlanılan örneği ise tahmin edilebileceği gibi bellek.
İşlemci belleğin adres hatlarını kontrol ediyor yani sürüyor. 6502 örneğinde TTL seviyesinde düşük yahut yüksek seviyede gerilim uyguluyor yani. Şimdi işlemci bunu yaparken devredeki başka bir elemanın, dur kardeşim belleği hep sen mi kullanacaksın, biraz da biz faydalanalım şu kaynaktan deyip o hata bağlandığında işler karışıyor. Hatların lojik durumu belirsiz bir hale geliyor.
Tam bu noktada işte devre elemanlarının bağlantılarını Tristate edebilme özelliği işe yarıyor. Bir elemanın bağlantısını tristate etmesi demek o bağlantının ulaştığı devre elemanı ile arasındaki hattı açık hale getirmesi demek. Yani hattın ortasından bir switch ile bağlantı kesilmiş gibi oluyor.
C64'te örneğin belleğe ulaşmak isteyen iki temel eleman var. Bunlar işlemci 6510 ve görüntü işlemcisi olan VIC-II çipi. Bugün bile paylaşımlı ekran kartı dediğimiz olayda işlemci ile ekran kartı belleği paylaşıyorlar yani sıra ile erişiyorlar. 6510 ve VIC-II örneğinde bu çipler üzerinde belleğe erişimi senkronize eden pin'ler mevcut. 6510 üzerinde RDY ve AEC, VIC-II üzerinde de BA (Bus access) ve AEC pin'leri. Bu pinler vasıtası ile birbirlerine sıra vererek kardeş kardeşi belleğe erişiyorlar. Biri belleğe erişirken diğeri adres bağlantılarını koparıyor yani tristate ediyor.
Gelelim benim soruna. Benim devremde de Pic (counter'lar ile adresleyerek ) belleğe erişiyor, aynı şekilde 6502 de belleğe erişiyor. Ben her ne kadar 6502 kafasına göre takılsın diye counter'ların çıkışını tristate etsem de, Pic bellekle takılmaya çalıştığında 6502 ona posta koyuyor.
Çözüm? 6502'nin belleğe erişimini de 74s244 tristate buffer'lar ile açık/kapalı hale getirilebilecek şekilde PIC'in kontrol etmesini sağlamak.
Aslında iş bu noktaya geldiğinde ilk mesajımda verdiğim örnek projeye göre tasarım epey kötü bir noktaya geldi.
Diğer projede eleman 6502 ile sadece databus üzerinden bağlantı kurup pic bellekmişçesine 6502'yi kandırmış. Adres bus'a hiç dokunmamış. Ama onun da handikapı şu, 6502'ye saat sinyalini her zaman kendisi vermek durumunda kalıyor. Sid'i transfer etmek için belleği doldurma aşamasında 6502'yi yavaşlatması ve kontrol etmesi gerekiyor. Harici bir clock sinyali kullansa bunu yapması mümkün değil. 6502 resetlendikten hemen sonra hot reset vektörünü data bus'a yükleyip ardından 6502'nin erişeceği her adresi bildiği için sırayla data bus üzerinden 6502'ye erişmek istediği datayı veriyor. Ta ki belleğe sid'i ve player'ını transfer edene dek.
Tristate buffer'ı o bellek işe karışmasın diye başlangıçtaki bu transfer esnasında kullanıyor. Yani bellek ile 6502 arasındaki databus'ın bağlantısını kesip pic'in data bus'ı güvenle sürmesini sağlıyor.
Bir ince nokta daha. Sizce 8Mhz pic mi harici belleğe daha hızlı erişiyor yoksa 1 Mhz 6502 mi? Cevap : 1Mhz'lik 6502 daha hızlı erişiyor. Pic'in bir komutunun çalışma süresi 4 cycle. 6502'nin belleğe erişen komutlarının çalışma süresi de 5-6 cycle. Ancak 6502 tasarımı itibariyle sürekli belleğe erişirken pic ile o tasarımın karşılığı olarak program yazmanız gerekiyor. Pic üzerinde 24 i/o pin'ini bellek erişimine ayırmış olsanız ve ekstradan da kontrol sinyalleri için i/o pin'leri ayırmış olsanız belleğe erişmek için bunların set edilmesi, data bus olarak ayırdığınız pin'lerin okunması falan derken sadece tek bir adresin okunması için rahat 8-10 komut vermeniz lazım. 6502 ise bu işi 1-2 cycle'da hallediyor.
8 komut * 4 pic cycle = 64 pic cycle = 8 6502 cycle
Neyse, ileride tasarım değişikliğine gitmem gerekiyor ancak şimdilik mecbur 6502'nin adres hatlarını tristate etme yoluna gideceğim. Tristate edilmeyi bekleyen bir hat daha var: 6502'nin R-/W çıkışı. Uyuz olduğum nokta burası. Tek bir hat için 8 tristate buffer'ı olan ekstra bir 74S244 daha kullanacağım.
Bu arada 6502'nin çok az kullanılan enteresan bir giriş hattı var. S.O. (Set Overflow) pini. Buraya logic 1 verdiğinizde işlemcinin statü register'ı üzerindeki overflow bit'i 1 oluyor. Bu özellik 1541 sürücülerinde 3 cycle'lık bir döngü içinde dışarıdan gelecek bir haberi beklemek için kullanılmış. 6502 ile en sıkı döngü bu pin vasıtası ile yaratılabiliyor.
Şu şekilde,
Dışarıdan S.O. pin'i set edilip 3 cycle'lık bu loop'tan çıkılabiliyor. Bu şekilde çok hızlı cevap verilmesi gereken bir dış habere hemen cevap verilebiliyor.
Amacı dışında bu pini data transferi için de kullanabileceğimi düşündüm. Belki sırf enteresanlık olsun diye daha sonra bununla da bir deneme yapabilirim.
Veri transferi şu şekilde yapılacak. Pic'ten 6502'ye sadece reset bacağı ve s.o. bacağı bağlı olacak. Veri transferi için gereken kodu içeren ufak bir eprom 6502'ye bağlanacak. Kod overflow flag'i set eden aritmetik bir işlem içermeyecek, başlangıçta pic'ten gelecek bir 1 sinyalini bekleyecek. Belirli bir süre sonunda 1 gelmemişse 0 kabul edilecek, 1 gelirse 1 olarak işlem görecek. Arada belirlenmiş bir protokole göre önce başlangıç adresi sonrasında da sid datası bu yöntemle transfer edilecek.
Oldukça yavaş kalacak bir yöntem aslında. 40 cycle ile bir bit transfer etsek.
Ortalama 4k boyutundaki bir sid'i transfer etmek için :
40 cycle * 8 bit * 4096 byte = 1310720 cycle.
Eh o kadar da yavaş değil gibi sanki, saniyede 1 milyon cycle'dan 1.31 sn. gibi bir süre yapıyor.
74S244'leri devreye yerleştirebilmek için mecbur devreyi bozuyorum çünkü klasik aldığım kablolar yine bitti. Artık ya herro ya merro. Eprom'dan sid çalan test devresine dönüş yok.