commodore.gen.tr

Diğer Nostaljik Bilgisayarlar => Amstrad - Yazılım => Konuyu başlatan: DoctorCPC üzerinde Eylül 10, 2018, 05:35:13 ÖÖ



Konu Başlığı: CPC ile C Programlama
Gönderen: DoctorCPC üzerinde Eylül 10, 2018, 05:35:13 ÖÖ
Aşağıdaki linkten sunumları ve dosyaları indirebilirsiniz. CPC Turkey Meeting'de workshop olarak yaptım. referansım cpcmania.com

http://volkanatasever.com/post/2018/09/10/AmstradSchneider-CPC-ile-C-Programlama.aspx (http://volkanatasever.com/post/2018/09/10/AmstradSchneider-CPC-ile-C-Programlama.aspx)


Konu Başlığı: Ynt: CPC ile C Programlama
Gönderen: wizofwor üzerinde Eylül 10, 2018, 10:17:00 ÖÖ
İndirme bağlantılarını bir kontrol edebilir misin. IIS şimdiye kadar karşılaştığım en manasız hatalardan birini veriyor.

Alıntı
HTTP Error 404.11 - Not Found
The request filtering module is configured to deny a request that contains a double escape sequence.

Kodlara bakamadım ama pixel boyama ve resim gösterme örnekleri olduğuna göre aradığım detay bilgi sende olabilir. Bildiğin gibi C yapısında code, data, heap ve stack segmentlerimiz var. İlk iki segment statik, heap ve stack segmentlerimiz dinamik. 8 bit sistemlerimizin işleyişi grafik verisinin belli bir adrese kopyalanmasını gerektiriyor. Sanıyorum bunun için kullanılacak en iyi yöntem grafik verisini başlangıç adresi sistemin tanıdığı grafik belleği olarak olacak tanımlanmış bir array içine kopyalamak.

Sorum şu: Grafik arrayinin data segmenti içine düşmediği durumda heap ve stack tarafından ezilmemesini nasıl sağlıyoruz?


Konu Başlığı: Ynt: CPC ile C Programlama
Gönderen: DoctorCPC üzerinde Eylül 10, 2018, 10:45:22 ÖÖ
dostum 2. piksel basma ile ilgili örneklere bakabilirsin şu anda çooook ilerlemedim. öğrendiğimi paylaştım henüz.ama orada cevaplarının olacağını düşünüyorum. video belleği nyapısındanda bahsedildi.


Konu Başlığı: Ynt: CPC ile C Programlama
Gönderen: i_r_on üzerinde Eylül 10, 2018, 11:04:46 ÖÖ
@wizofwor : malloc'u customize edip belleği belirlediğin bölgeden ayırabilirsin belki. Muhtemelen link aşamasında vereceğin flag'ler ile de ayarlanabilir ancak kullanmadığım için çok fikrim yok.


Konu Başlığı: Ynt: CPC ile C Programlama
Gönderen: Levent (Lvnt) üzerinde Eylül 10, 2018, 11:13:19 ÖÖ
@DoctorCPC: dersler 404 verip açmıyor

@wizofwor: c'nin segment sistemi her yerde yok, aslında dos/win16 dışında gördüğümü hatırlamıyorum. Microsoft icadı birşeydir belki.

C segment sözdizimi yokken elle (inline asm ile) bank switching yapılıyordur sanırım, ya da belki compilerin bank switch sözdizimi vardır. Sorunun cevabı, compiler değişken stack heap vb mümkün olduğunca ayrı tutuyordur olabilir, örnek programda çıkar belki.


Konu Başlığı: Ynt: CPC ile C Programlama
Gönderen: DoctorCPC üzerinde Eylül 10, 2018, 11:21:57 ÖÖ
Lvnt dostum evet açılmıyor 1-2 saate editlerim.


Konu Başlığı: Ynt: CPC ile C Programlama
Gönderen: DoctorCPC üzerinde Eylül 10, 2018, 11:33:47 ÖÖ
editledim şu anda linkler çalışıyor


Konu Başlığı: Ynt: CPC ile C Programlama
Gönderen: wizofwor üzerinde Eylül 10, 2018, 12:27:08 ÖS
@wizofwor : malloc'u customize edip belleği belirlediğin bölgeden ayırabilirsin belki. Muhtemelen link aşamasında vereceğin flag'ler ile de ayarlanabilir ancak kullanmadığım için çok fikrim yok.

Aslında nihai çözüm işi linker ile halletmek gibi o detaya mümkün olduğunca girmemeye çalışıyorum. Linkler düzeldiyse akşam şu örneklere biraz bakayım.


Konu Başlığı: Ynt: CPC ile C Programlama
Gönderen: DoctorCPC üzerinde Eylül 10, 2018, 12:46:50 ÖS
düzeldi dostum istediğin gibi pixel basıp silebiliyorsun fakat c compiler doğrudan cpcnin grafik belleğini bilmez bunun için birkaç asm rutinine ihtiyaç var. bunları projeye eklediğinde bir CPC kütüphanesi oluşturmuş oluyorsun ve ekledikçe ekleyebilirsin ardından C ile sınırsız projende çağırıp çalıştırabilirsin.

bu arada unutmadan Z80 ile uygulamaları derlediğinde 0. adresten başlar ama mutlaka tüm cpc uygulamaları 0x100 adresinden başlamalıdır.

Video moda göre her byte 2,4 veya 8 piksel gösterebilir ekranda. Video memory’nin ilk byte’ı ekranın yukarı sol köşesinden başlar. Sonra byte sağ alt değildir. Amstrad CPC dizaynı dev bir sürpriz yapmıştır. Yapı daha karmaşık ve eğlencelidir grafik programcılar için.

Üç video modunun yüksekliği 200 satırdır, böylece bu adresler her üç mod için de sabitlenir. Bu 200 satırın her biri, moda bağlı olarak genişliği 160, 320 veya 640 pikselleri temsil eden 80 bayttır. Daha önce de söylediğimiz gibi, her bayt, moda bağlı olarak ekranın 2, 4 ya da 8 pikselini temsil eder, fakat daha da karmaşıklaştırmak için, her bir pikselin bitleri aşağıdaki gibi bayt olarak düzenlenir:





Konu Başlığı: Ynt: CPC ile C Programlama
Gönderen: wizofwor üzerinde Eylül 10, 2018, 13:37:02 ÖS
Pixel boyama örneğin üzerinden gidiyorum.

unsigned char *pScreen = (unsigned char *)0xc000

burada 0xc000 adresini grafik belleği olarak kullanmak üzere tanımladın. Daha sonra döngü içinde:

pScreen[nByte] = ... ile pixel datasını belleğe yerleştiriyorsun. Programı derlerken:

sdcc -mz80 --code-loc 0x6038 --data-loc 0 --no-std-crt0 crt0_cpc.rel pixel01.c

ile text segmentin (kodun) başlangıç adresini 0x6038 olacağını söylüyorsun.

Bu durumda grafik belleği büyük ihtimalle heap segmentinin üstünde kalıyor olmalı.









Konu Başlığı: Ynt: CPC ile C Programlama
Gönderen: DoctorCPC üzerinde Eylül 10, 2018, 13:54:25 ÖS
0xC000 yani ekranın sol üst kısmını gösteriyor. çünkü ilk satır ilk sütun yani 1. pixel C000'dan başlıyor.

pscreen ile adresi
pscree[nbyte]ile içindeki değeri değiştiriyoruz.
ekranın sıralı yani satır satır gitmesi için formül şu;

Address = 0xC000 + ((Line / 8) * 80) + ((Line % 8) * 2048)

aşağıdaki metotla lineadressi bulabiliyoruz;
unsigned char *GetLineAddress(unsigned char nLine)
{
  return (unsigned char *)0xC000 + ((nLine / 8) * 80) + ((nLine % 8) * 2048);
}

bu sayede 2. örnekte çizgi parçalı değil satır satır randomize pikseller işlenerek aşağıya doğru dolduruluyor. lineer gitmesi için yukarıdaki formülü uygulamak gerekiyor. aksi takdirde parçalı ekran doluyor anladığım kadarıyla böylece lineer olmuyor.

mode 0 ve mode 1 deki bilgi aşağıdaki gibi;

    In Mode 2, set pixel x=81, y=7 to color 1: First look at the table line 7 (start counting from 0) and the address is F800, as in mode 2 each byte is 8 pixels, to move to the byte where the 81 pixel horizontal is, we increase the direction 81/8 = 10 and we have 1 of rest , add 10 to the direction and gives us F80A, now in that direction to write the pixel 1 we have set to 1 bit 6.
    In Mode 1, set pixel x=50, y=22 to color 3: The direction of line 22 in the table is F0A0, to move to the pixel 50, add to the address 50/4 = 12 and we left over 2, the sum gives F0AC, and put the color 3 to the pixel 2 of the direction, we must set to 1 bits 5 and 1.

soldan sağa sütün aşağı indirerek sırayla sütunları boyamak içinde son örneğe bakabilirsiniz.


Konu Başlığı: Ynt: CPC ile C Programlama
Gönderen: Levent (Lvnt) üzerinde Eylül 10, 2018, 14:04:35 ÖS
@wizofwor: 64k düz adres alanı olarak değil banked olarak erişiliyor olmalı. 16-bit (64k) adres alanı içinde ram belli yerlerdedir, diğer yerlerde video ses vb aygıt alanları da vardır.


Konu Başlığı: Ynt: CPC ile C Programlama
Gönderen: wizofwor üzerinde Eylül 10, 2018, 14:40:18 ÖS
@Levent: sdcc ve CPC bellek yapısı hakkında hiç bilgim yok. Bir miktar C64 üzerinde cc65 tecrübe etmiştim. cc65'de (c64_hi_tga) driverını yüklediğinde senin söylediğin gibi belli bir adresi grafik belleği olarak tanımlıyor ve kullanıyor. Dokümantasyonda I/O alanının altı demiş. Herhalde 0xc000-0xd000 arasından bahsediyor. Ancak driver kullandığında bu adreslere müdahale etme şansın yok. Her şey otomatik halledilmiş oluyor.


Konu Başlığı: Ynt: CPC ile C Programlama
Gönderen: DoctorCPC üzerinde Eylül 10, 2018, 14:59:45 ÖS
piksel boyarken aslında burada yaptığı çok birşey yok herşey net. video belleğin adresine erişiyor isim yazınca pointerlarda adrese direkt erişiyorsun. pscreen[deger]yazdığı zamanda içine değer atıyor. bunlar randomize oluyor. klasik C mantığı. yani başka işte heap vs gerekli olurmu bilmem ama burada bunlara gerek yok.
*pscreen yani bu bir pointer
pscreen dediğimiz anda adreside alabilir adresi değiştirebilirizde
pscreen[deger] dediğimiz anda pscreen deki o andaki adrese değeri atıyoruz.
zaten 3 örnektede adresleri farklı boyadığı için farklı bir efekt çıkıyor. adres değiştiriyor randomize boyuyor ve bunu döngüyle tüm ekranın piksel sayısı kadar yapıyor ve o da belli. mode 2 de mode 1 de ve mode 0 da var. ama renk kısıtı var modelarda. onun içinde modelara göre 3 farklı formülümüz var.


Konu Başlığı: Ynt: CPC ile C Programlama
Gönderen: wizofwor üzerinde Eylül 11, 2018, 00:31:15 ÖÖ
@DoctorCPC:

Senin pixel boyama örneğini cc65 formatına çevirdim. İlk olarak SCREEN_RAM ($0400) alanını manipüle etmeyi denedim. Burada sorunsuz çalıştı. Ancak bitmap moda geçtiğimde. Varsayılan bitmap ram adresi ($2000) proramın olduğu segmentle çakıştığı için program runtime'da çakıldı. Çözüm olarak aşağıdaki gibi bir linker config dosyası kullanmam gerekti.

Kod:
FEATURES {
    STARTADDRESS: default = $0801;
}
SYMBOLS {
    __LOADADDR__:  type = import;
    __EXEHDR__:    type = import;
    __STACKSIZE__: type = weak, value = $0800; # 2k stack
    __HIMEM__:     type = weak, value = $D000;
}
MEMORY {
    ZP:       file = "", define = yes, start = $0002,           size = $001A;
    LOADADDR: file = %O,               start = %S - 2,          size = $0002;
    HEADER:   file = %O, define = yes, start = %S,              size = $000D;
    MAIN:     file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __HEADER_LAST__;
    BSS:      file = "",               start = __ONCE_RUN__,    size = __HIMEM__ - __STACKSIZE__ - __ONCE_RUN__;
}
SEGMENTS {
    ZEROPAGE: load = ZP,       type = zp;
    LOADADDR: load = LOADADDR, type = ro;
    EXEHDR:   load = HEADER,   type = ro;
    STARTUP:  load = MAIN,     type = ro;
    LOWCODE:  load = MAIN,     type = ro,  optional = yes;
#   CODE:     load = MAIN,     type = ro;
    CODE:     load = MAIN, start=$4000     type = ro;
    RODATA:   load = MAIN,     type = ro;
    DATA:     load = MAIN,     type = rw;
    INIT:     load = MAIN,     type = rw;
    ONCE:     load = MAIN,     type = ro,  define   = yes;
    BSS:      load = BSS,      type = bss, define   = yes;
}
FEATURES {
    CONDES: type    = constructor,
            label   = __CONSTRUCTOR_TABLE__,
            count   = __CONSTRUCTOR_COUNT__,
            segment = ONCE;
    CONDES: type    = destructor,
            label   = __DESTRUCTOR_TABLE__,
            count   = __DESTRUCTOR_COUNT__,
            segment = RODATA;
    CONDES: type    = interruptor,
            label   = __INTERRUPTOR_TABLE__,
            count   = __INTERRUPTOR_COUNT__,
            segment = RODATA,
            import  = __CALLIRQ__;
}

Dosya örneğini olarak cc65'in standart konfigürasyonlarından C64.cfg dosyasını kullandım. Sadece aşağıdaki satırı ilave ettim.

Kod:
CODE:     load = MAIN, start=$4000     type = ro;

Programın son hali de aşağıdaki gibi oldu:

Kod:
#include <stdlib.h>

void main()
{
  unsigned char *pScreen = (unsigned char *)0x2000;
  unsigned char *pColor = (unsigned char *)0x0400;
  unsigned int nByte = 0;

  // Switch to bitmap mode
  __asm__("lda #$3b");
  __asm__("sta $d011");
  __asm__("lda #$08");
  __asm__("sta $d016");

  __asm__("lda $d018");
  __asm__("ora #$8");
  __asm__("sta $d018");


  for(nByte =0; nByte < 0x3ff; nByte++)
  pColor[nByte] = (unsigned char)(0x0f);

  for(nByte = 0; nByte < 0x1fff; nByte++)
    pScreen[nByte] = (unsigned char)(rand() % 256);

  // Wait for space key
  __asm__("_label:      ");
  __asm__("   lda $dc01 ");
  __asm__("   cmp #$ef  ");
  __asm__("   bne _label");

  // Switch back to text mode
  for(nByte =0; nByte < 0x3ff; nByte++)
  pColor[nByte] = (unsigned char)(0x20);

  __asm__("lda #$1b");
  __asm__("sta $d011");
  __asm__("lda #$8");
  __asm__("sta $d016");

}


Konu Başlığı: Ynt: CPC ile C Programlama
Gönderen: i_r_on üzerinde Eylül 11, 2018, 01:11:54 ÖÖ
C'nin bu statik linkleme yapısı C64'de programlamaya pek müsait değil gibi... sen daha bunun üstüne bir sürü loading yapıp data ve kod load edeceksin belki. özellikle de oyun yapıyorsan oyunun bölümüne göre kod / grafik için bellek ihtiyacın değişecek.

Çakma bir yöntem ama heap'in alayını boyutuna ve sırasına dikkat ederek allocate etsen ve her şeyi free yapıp statik adreslemek istediğin kısmı free etmesen iş görür mü acaba?

C64'de malloc çok mantıklı gelmiyor bana, sprite'lar için yapma ihtiyacın oldu diyelim, bunları koyacağın adres de statik.

Şu ablanın (ya da abinin) açtığı bulguda enteresan bilgiler var bu arada,

https://github.com/cc65/cc65/issues/655



Konu Başlığı: Ynt: CPC ile C Programlama
Gönderen: wizofwor üzerinde Eylül 11, 2018, 13:39:12 ÖS
Tam aksine detaylara yeterince hakim olunursa çok güzel şeyler yapılabilir fikrindeyim. Zira bu tip durumlarda derleyici hata vermiyor. Her şeyi yapmakta serbestsin. İşler karışırsa runtime'da patlıyorsun.