venerdì 13 luglio 2018

CC65 Mandelbrot (per pigri) modalita' testo

Devo ammettere che scoprire CC65 e' stato un bel passo avanti...prima avevo due opzioni sul C64: o fare i programmi in BASIC (molto molto lenti) oppure farli in Assembler. CC65 e' invece un cross compiler indirizzato al 6503 che usa la sintassi C. Il vantaggio e' che mentre il BASIC e' un linguaggio interpretato (quindi il sistema deve ogni volta effettuare la conversione in linguaggio macchina nonostante il codice sia in ogni caso tokenizzato), con CC65 si ha gia' codice macchina (anche se ovviamente non ottimizzato)


Mandelbrot modalita' testuale su C64Debugger

per esempio si puo' fare il classico Hello World e compilarlo in questo modo

cl65 -O -l hello.lst -vm -m hello -o hello.prg -t c64 hello.c

il codice generato non e' esattamente compatto (sono circa 3Kb). Inoltre e' da notare che non e' disponibile il tipo dati float

In ogni caso con poco sforzo e' possibile generare un insieme di Mandelbrot (non sono ancora riuscito a gestire la modalita' grafica via TGI)

------------------------------------------------------

#include <stdlib.h>
#include <conio.h>
#include <cc65.h>

#define SCREEN_X        40
#define SCREEN_Y        25

#define maxiterations   25
#define fpshift         (10)
#define tofp(_x)        ((_x)<<fpshift)  bitwise shift left
#define fromfp(_x)      ((_x)>>fpshift)
#define fpabs(_x)       (abs(_x))

#define mulfp(_a,_b)    ((((signed long)_a)*(_b))>>fpshift)
#define divfp(_a,_b)    ((((signed long)_a)<<fpshift)/(_b))


#pragma static-locals (1);



void mandelbrot (signed short x1, signed short y1, signed short x2,
                 signed short y2)
{
    // le variabili register sono quelle che il compilatore mette in pagina zero
    // e quindi quelle a piu' rapido accesso
    register unsigned char count;
    register signed short r, r1, i;
    register signed short xs, ys, xx, yy;
    register signed short x, y;

    /* Calc stepwidth */
    xs = ((x2 - x1) / (SCREEN_X));
    ys = ((y2 - y1) / (SCREEN_Y));

    yy = y1;
    for (y = 0; y < (SCREEN_Y); y++) {
        yy += ys;
        xx = x1;
        for (x = 0; x < (SCREEN_X); x++) {
            xx += xs;
            /* Do iterations */
            r = 0;
            i = 0;
            for (count = 0; (count < maxiterations) &&
                 (fpabs (r) < tofp (2)) && (fpabs (i) < tofp (2));
                 ++count) {
                r1 = (mulfp (r, r) - mulfp (i, i)) + xx;
                /* i = (mulfp(mulfp(r,i),tofp(2)))+yy; */
                i = (((signed long) r * i) >> (fpshift - 1)) + yy;
                r = r1;
            }
            if (count == maxiterations) {
                 cprintf("*");
            } else {
                 cprintf(" ");
          }
            /* Set pixel */
            //tgi_setpixel (x, y);
        }
    }
}

int main (void)
{
    clrscr ();
    mandelbrot (tofp (-2), tofp (-2), tofp (2), tofp (2));
    cgetc ();
    return 0;
}

Nessun commento:

Posta un commento

Alpine Linux 2024 su IBM A31

Ho provato a far resuscitare un IBM A31 destinato alla discarica. La macchina ha processore P4, 256 Mb di RAM, la batteria CMOS morta ed e&#...