Son yaptığım geliştirmelerle ilgili detaylı bilgi vermemiştim. Kısa bir özet geçeyim.
C64'e veri göndermeyi hallettiğim noktada işin bir de geriye Arduino'ya veri gönderme kısmı vardı. Bunun için aklımda daha önceden kartuş i/o bölgesine yaptığım okumaları belli bir düzende yapmak ve arduino'nun da LORAM sinyalini dinlemesi ile gönderilen bilgiye ulaşmasını sağlamak vardı. Bir nevi covert channel communication*, sinsi ama yavaş. Sonra aklıma hali hazırda kullandığım interrupt'ları kullanmak geldi.
Hali hazırda IRQ ve/veya NMI interrupt'larını hem Arduino tarafından üretip 6510'da yakalayabiliyorum veya 6510'da üretip Arduino'da yakalayabiliyorum. Transfer sırasında Arduino'da bu pinlerin bağlı olduğu io pinleri output iken, transfer sonrası input'a çekiyorum.
Arduino uno üzerinde kullanılabilecek 2 tane interrupt pin'i var. 2 veya 3 no'lu pinler. NMI'ı menü aktifken arduino'dan c64'e transfer de yaparım düşüncesi ile IRQ kullanmaya karar verdim.
Bu noktada aklıma ilk gelen çözüm raster interrupt'larını kullanmak oldu. Öncelikle çok da hızlı olmayacak bir çözüm üstünden gittim. Başlangıçta seçim listesinde kaçıncı sayfada, hangi prg'yi seçti gibi bilgiler iletileceği için çok hızlı bir çözüme de gerek yok çünkü. (Disk dump etme gibi bir ihtiyaç olursa işler değişir.)
Öncelikle tek byte transfer edeyim dedim sırf çalıştığını göreyim diye. Elimde olan istediğim raster'da IRQ yaratabilmek, bununla ayrıca arduino'yu da interrupt edebiliyorum. Boş boş duruyor zaten bir şey yapmıyor
Gönderimi sağlayabilmek için c64 tarafında bir durum makinesi (state machine) kurdum. Belki daha basit bir kodlama ile yapılabilirdi ancak bu şekilde işin içinden çıktım. Akla gelen ilk implementasyon çalışmayınca sağlama almaya çalışıyor insan. Durum makinesinin özel bir kolu olan transducer (geçişlerde bir de çıkış veren durum makinesi) mantığını kullandım.
Durumlar :
S0 : Başlangıç durumu,
S1 : 0 state'i
S2 : 1 state'i
Çıktılar :
A : Bir sonraki IRQ 0. satırda,
B : Bir sonraki IRQ 160. satırda
Durum geçişleri şu şekilde,
S0'da iken
- Son bit 0 ise S1 state'ine geç, Çıktı : A
- Son bit 1 ise S2 state'ine geç, Çıktı : B
S1'de iken
- Sıradaki bit 0 ise S1 state'inde kal, Çıktı : A
- Sıradaki bit 1 ise S2 state'ine geç, Çıktı : B
S2'de iken
- Sıradaki bit 0 ise S1 state'ine geç, Çıktı : B
- Sıradaki bit 1 ise S2 state'inde kal, Çıktı : A
S0 state'ini interrupt'ları set eden ön taraftaki kod oluşturuyor, S1 state'i bir irq rutini, S2 state'i ise diğer bir IRQ rutini. Efektif olarak yapılan şey ise 0 bilgisi gönderilecekse IRQ oluşturulduktan sonra tam bir ekran taraması bekleniyor (1000 / 50 = 20ms), 1 bilgisi gönderilecekse yarım ekran taraması bekleniyor (20 / 2 = 10ms) . Arduino gelen interrupt'lar arasındaki zamanı ölçüp 1 mi gönderilmiş 0 mı gönderilmiş anlıyor.
Tabii işler teorideki gibi pratikte yolunda gitmiyor, ilk gönderilen bit için raster'a senkronize olmak lazım yahut ilk gelen interrupt bilgisini başlangıç kabul edip çöpe atmak lazım. Bu yüzden ilk biti her zaman 1 gönderdim ve ve özellikle başlatma işini 161. satırda yaptım. (Raster interrupt için kullanılan satırı set ettiğimiz register aslında 9 bit, 0-319 arası değer alıyor, low byte'daki 0 değeri iki değişik satırda geçebilirken 160 değerinin bir de 8. biti (0'dan başlarsak) 1 olan bir değeri bulunmadığı için)
Malesef arduino tarafında kabak gibi 10ms ve 20ms yansımıyor, ciddi bir interrupt latency oluştuğu için bu değerlerin kontrolünü yaparken 15'ten büyükse 0, küçükse 1 demek zorunda kaldım. Belki benim kodumda da sorun olabilir tabii onu incelemem lazım ancak bu düşük hassasiyet bu yöntemle yapılacak daha yüksek hızlı veri transferi için ciddi bir engel.
Sonrasında menüyü biraz şenlendirmek istedim ve hvsc içinden beğendiğim bir sid'i çalmaya karar verdim. Bu noktada arduino IRQ'ya kulak kesildiği için raster interrupt'larını yahut irq yaratan CIA timer'ı kullanmak resmin dışında kaldı. İmdadıma NMI yetişti, CIA 2 üstünden timer ile NMI üretilebiliyor. Biraz nette dolaşıp sağdan soldan topladığım bilgilerle 50hz'lik bir NMI interrupt'ı üretip müzik konusunu da hallettim.
Sd karttaki dosyaları browse etmek için menünün talep ettiği veri aktarımı yapmak istiyorum. Bu sırada aklıma başka bir şey gelmez ise müziği kesip NMI handler'ı transfer işinde kullanmam gerekecek gibi gözüküyor.
Sd kart browse etme çözümünde arduino menüyü C64'e ilk gönderdiğinde sd kart içerisindeki ilk 24 entry'i de programın sonuna iliştirip gönderecek. Kullanıcı bir sonraki sayfaya geçmek istediğinde, bir dizinin içine girmek istediğinde c64 üstte anlattığım yöntemle bu bilgiyi arduino'ya iletecek ve soft nmi vektörünü kartuş bölgesindeki transfer için kullandığım handler'a işaret ettirecek. Arduino ise EXROM hattını low'a çekip kartuştaki rom'u devreye alacak ve kendisine iletilen bilgilerle veri transferini gerçekleştirecek. Bunlar yapılırken c64 reset edilmeyecek ancak ekran kapanacak. Transfer edilecek data max 1k / 2k seviyelerinde olacağı için işlem 1 saniyenin çok çok altında bitecek.
Bu arada arada Arduino tarafında sd karttan okuma yaparken byte byte okumadan 512'şer byte okumaya çevirdim. 3sn.'de yüklemesi yapılan bir oyun (30k) 2sn'de yüklenmeye başladı.