Merhaba, Ziyaretçi. Lütfen giriş yapın veya üye olun.

Kullanıcı adınızı, parolanızı ve aktif kalma süresini giriniz

  Gelişmiş Arama
insanın içinde varsa, commodore.gen.tr açığa çıkarır bunu.. bir nevi retro olaylarının dolunayıyız.(Arda)
Sayfa: [1] 2   Aşağı git
Yazdır
Gönderen Konu: CPC ile C Programlama  (Okunma Sayısı 2335 defa)
0 Üye ve 2 Ziyaretçi konuyu incelemekte.
DoctorCPC
Uzman
*****
Mesaj Sayısı: 432



Üyelik Bilgileri WWW
« : 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
Logged

Amstrad CPC 6128 - MotherX4 Board, ZMEM 1MB RAM, M4 Wifi, 3,5'' floppy,3'' floppy, Gotek CPC,1084S-P1 Monitor,Tape Player, PS2 Mouse Adaptor/
Schneider CPC 6128, Gt65 Monitor/
Amstrad CPC 464, Schneider Ctm 640 monitor/
Amiga 600, 3.1Rom, Gotek, 8GB CF HDD, PS2 Mouse,PCMCIA 16MB Card
wizofwor
Genel Yönetici
*****
Mesaj Sayısı: 3.964


Gosub ile gidilen yerden goto ile dönen adam


Üyelik Bilgileri WWW
« Yanıtla #1 : 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?
« Son Düzenleme: Eylül 10, 2018, 10:35:50 ÖÖ Gönderen: wizofwor » Logged

DoctorCPC
Uzman
*****
Mesaj Sayısı: 432



Üyelik Bilgileri WWW
« Yanıtla #2 : 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.
Logged

Amstrad CPC 6128 - MotherX4 Board, ZMEM 1MB RAM, M4 Wifi, 3,5'' floppy,3'' floppy, Gotek CPC,1084S-P1 Monitor,Tape Player, PS2 Mouse Adaptor/
Schneider CPC 6128, Gt65 Monitor/
Amstrad CPC 464, Schneider Ctm 640 monitor/
Amiga 600, 3.1Rom, Gotek, 8GB CF HDD, PS2 Mouse,PCMCIA 16MB Card
i_r_on
Uzman
*****
Mesaj Sayısı: 2.857



Üyelik Bilgileri WWW
« Yanıtla #3 : 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.
Logged

Every imagination is one's self reflection but not every self reflection is imagination. <I.R.on - 2001>

twitter | blog
Levent (Lvnt)
Uzman
*****
Mesaj Sayısı: 1.595



Üyelik Bilgileri
« Yanıtla #4 : 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.
« Son Düzenleme: Eylül 10, 2018, 11:15:49 ÖÖ Gönderen: Levent (Lvnt) » Logged

Use the brute force, Luke
DoctorCPC
Uzman
*****
Mesaj Sayısı: 432



Üyelik Bilgileri WWW
« Yanıtla #5 : Eylül 10, 2018, 11:21:57 ÖÖ »

Lvnt dostum evet açılmıyor 1-2 saate editlerim.
Logged

Amstrad CPC 6128 - MotherX4 Board, ZMEM 1MB RAM, M4 Wifi, 3,5'' floppy,3'' floppy, Gotek CPC,1084S-P1 Monitor,Tape Player, PS2 Mouse Adaptor/
Schneider CPC 6128, Gt65 Monitor/
Amstrad CPC 464, Schneider Ctm 640 monitor/
Amiga 600, 3.1Rom, Gotek, 8GB CF HDD, PS2 Mouse,PCMCIA 16MB Card
DoctorCPC
Uzman
*****
Mesaj Sayısı: 432



Üyelik Bilgileri WWW
« Yanıtla #6 : Eylül 10, 2018, 11:33:47 ÖÖ »

editledim şu anda linkler çalışıyor
Logged

Amstrad CPC 6128 - MotherX4 Board, ZMEM 1MB RAM, M4 Wifi, 3,5'' floppy,3'' floppy, Gotek CPC,1084S-P1 Monitor,Tape Player, PS2 Mouse Adaptor/
Schneider CPC 6128, Gt65 Monitor/
Amstrad CPC 464, Schneider Ctm 640 monitor/
Amiga 600, 3.1Rom, Gotek, 8GB CF HDD, PS2 Mouse,PCMCIA 16MB Card
wizofwor
Genel Yönetici
*****
Mesaj Sayısı: 3.964


Gosub ile gidilen yerden goto ile dönen adam


Üyelik Bilgileri WWW
« Yanıtla #7 : 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.
Logged

DoctorCPC
Uzman
*****
Mesaj Sayısı: 432



Üyelik Bilgileri WWW
« Yanıtla #8 : 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:





* cpc1.jpg (134.63 KB, 340x533 - Görüntüleme: 552 kez.)

* cpc.jpg (165.28 KB, 1184x404 - Görüntüleme: 514 kez.)
Logged

Amstrad CPC 6128 - MotherX4 Board, ZMEM 1MB RAM, M4 Wifi, 3,5'' floppy,3'' floppy, Gotek CPC,1084S-P1 Monitor,Tape Player, PS2 Mouse Adaptor/
Schneider CPC 6128, Gt65 Monitor/
Amstrad CPC 464, Schneider Ctm 640 monitor/
Amiga 600, 3.1Rom, Gotek, 8GB CF HDD, PS2 Mouse,PCMCIA 16MB Card
wizofwor
Genel Yönetici
*****
Mesaj Sayısı: 3.964


Gosub ile gidilen yerden goto ile dönen adam


Üyelik Bilgileri WWW
« Yanıtla #9 : 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ı.







Logged

DoctorCPC
Uzman
*****
Mesaj Sayısı: 432



Üyelik Bilgileri WWW
« Yanıtla #10 : 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 / Karizmatik * 80) + ((Line % Karizmatik * 2048)

aşağıdaki metotla lineadressi bulabiliyoruz;
unsigned char *GetLineAddress(unsigned char nLine)
{
  return (unsigned char *)0xC000 + ((nLine / Karizmatik * 80) + ((nLine % Karizmatik * 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.
Logged

Amstrad CPC 6128 - MotherX4 Board, ZMEM 1MB RAM, M4 Wifi, 3,5'' floppy,3'' floppy, Gotek CPC,1084S-P1 Monitor,Tape Player, PS2 Mouse Adaptor/
Schneider CPC 6128, Gt65 Monitor/
Amstrad CPC 464, Schneider Ctm 640 monitor/
Amiga 600, 3.1Rom, Gotek, 8GB CF HDD, PS2 Mouse,PCMCIA 16MB Card
Levent (Lvnt)
Uzman
*****
Mesaj Sayısı: 1.595



Üyelik Bilgileri
« Yanıtla #11 : 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.
Logged

Use the brute force, Luke
wizofwor
Genel Yönetici
*****
Mesaj Sayısı: 3.964


Gosub ile gidilen yerden goto ile dönen adam


Üyelik Bilgileri WWW
« Yanıtla #12 : 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.
Logged

DoctorCPC
Uzman
*****
Mesaj Sayısı: 432



Üyelik Bilgileri WWW
« Yanıtla #13 : 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.
Logged

Amstrad CPC 6128 - MotherX4 Board, ZMEM 1MB RAM, M4 Wifi, 3,5'' floppy,3'' floppy, Gotek CPC,1084S-P1 Monitor,Tape Player, PS2 Mouse Adaptor/
Schneider CPC 6128, Gt65 Monitor/
Amstrad CPC 464, Schneider Ctm 640 monitor/
Amiga 600, 3.1Rom, Gotek, 8GB CF HDD, PS2 Mouse,PCMCIA 16MB Card
wizofwor
Genel Yönetici
*****
Mesaj Sayısı: 3.964


Gosub ile gidilen yerden goto ile dönen adam


Üyelik Bilgileri WWW
« Yanıtla #14 : 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");

}
« Son Düzenleme: Eylül 11, 2018, 13:36:35 ÖS Gönderen: wizofwor » Logged

Sayfa: [1] 2   Yukarı git
Yazdır
Gitmek istediğiniz yer: