]> git.sur5r.net Git - cc65/blobdiff - samples/plasma.c
atari5200: implement bgcolor() and textcolor()
[cc65] / samples / plasma.c
index e81bc427d9e8d6397664cbebcb35faa8cadd0abe..ac17265f3791d01c858e9538ed7c5ac177fda3a7 100644 (file)
-/*****************************************************************************\r
- * plasma test program for cc65.                                             *\r
- *                                                                           *\r
- * (w)2001 by groepaz/hitmen                                                 *\r
- *                                                                           *\r
- * Cleanup and porting by Ullrich von Bassewitz.                            *\r
- *                                                                           *\r
- *****************************************************************************/\r
-\r
-\r
-\r
-#include <stdlib.h>\r
-#include <time.h>\r
-#include <conio.h>\r
-\r
-\r
-\r
-#if defined(__C64__)\r
-#  define SCREEN1               0xE000\r
-#  define SCREEN2               0xE400\r
-#  define CHARSET               0xE800\r
-#  define outb(addr,val)               (*(addr)) = (val)\r
-#  define inb(addr)             (*(addr))\r
-#elif defined(__CBM510__)\r
-#  define SCREEN1               0xF000\r
-#  define SCREEN2               0xF400\r
-#  define CHARSET               0xE000\r
-#  define outb(addr,val)       pokebsys ((unsigned)(addr), val)\r
-#  define inb(addr)             peekbsys ((unsigned)(addr))\r
-#endif\r
-\r
-\r
-\r
-/* Values for the VIC address register to switch between the two pages */\r
-#define PAGE1                   ((SCREEN1 >> 6) & 0xF0) | ((CHARSET >> 10) & 0x0E)\r
-#define PAGE2                   ((SCREEN2 >> 6) & 0xF0) | ((CHARSET >> 10) & 0x0E)\r
-\r
-\r
-\r
-/* Use static local variables for speed */\r
-#pragma staticlocals (1);\r
-\r
-\r
-\r
-static const unsigned char sinustable[0x100] = {\r
-    0x80, 0x7d, 0x7a, 0x77, 0x74, 0x70, 0x6d, 0x6a,\r
-    0x67, 0x64, 0x61, 0x5e, 0x5b, 0x58, 0x55, 0x52,\r
-    0x4f, 0x4d, 0x4a, 0x47, 0x44, 0x41, 0x3f, 0x3c,\r
-    0x39, 0x37, 0x34, 0x32, 0x2f, 0x2d, 0x2b, 0x28,\r
-    0x26, 0x24, 0x22, 0x20, 0x1e, 0x1c, 0x1a, 0x18,\r
-    0x16, 0x15, 0x13, 0x11, 0x10, 0x0f, 0x0d, 0x0c,\r
-    0x0b, 0x0a, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04,\r
-    0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,\r
-    0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03,\r
-    0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0a,\r
-    0x0b, 0x0c, 0x0d, 0x0f, 0x10, 0x11, 0x13, 0x15,\r
-    0x16, 0x18, 0x1a, 0x1c, 0x1e, 0x20, 0x22, 0x24,\r
-    0x26, 0x28, 0x2b, 0x2d, 0x2f, 0x32, 0x34, 0x37,\r
-    0x39, 0x3c, 0x3f, 0x41, 0x44, 0x47, 0x4a, 0x4d,\r
-    0x4f, 0x52, 0x55, 0x58, 0x5b, 0x5e, 0x61, 0x64,\r
-    0x67, 0x6a, 0x6d, 0x70, 0x74, 0x77, 0x7a, 0x7d,\r
-    0x80, 0x83, 0x86, 0x89, 0x8c, 0x90, 0x93, 0x96,\r
-    0x99, 0x9c, 0x9f, 0xa2, 0xa5, 0xa8, 0xab, 0xae,\r
-    0xb1, 0xb3, 0xb6, 0xb9, 0xbc, 0xbf, 0xc1, 0xc4,\r
-    0xc7, 0xc9, 0xcc, 0xce, 0xd1, 0xd3, 0xd5, 0xd8,\r
-    0xda, 0xdc, 0xde, 0xe0, 0xe2, 0xe4, 0xe6, 0xe8,\r
-    0xea, 0xeb, 0xed, 0xef, 0xf0, 0xf1, 0xf3, 0xf4,\r
-    0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfa, 0xfb, 0xfc,\r
-    0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff,\r
-    0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfd,\r
-    0xfd, 0xfc, 0xfb, 0xfa, 0xfa, 0xf9, 0xf8, 0xf6,\r
-    0xf5, 0xf4, 0xf3, 0xf1, 0xf0, 0xef, 0xed, 0xeb,\r
-    0xea, 0xe8, 0xe6, 0xe4, 0xe2, 0xe0, 0xde, 0xdc,\r
-    0xda, 0xd8, 0xd5, 0xd3, 0xd1, 0xce, 0xcc, 0xc9,\r
-    0xc7, 0xc4, 0xc1, 0xbf, 0xbc, 0xb9, 0xb6, 0xb3,\r
-    0xb1, 0xae, 0xab, 0xa8, 0xa5, 0xa2, 0x9f, 0x9c,\r
-    0x99, 0x96, 0x93, 0x90, 0x8c, 0x89, 0x86, 0x83\r
-};\r
-\r
-\r
-\r
-static unsigned char *scrn;\r
-\r
-\r
-\r
-static void doplasma (void)\r
-{\r
-    unsigned char xbuf[40];\r
-    unsigned char ybuf[25];\r
-    unsigned char i,ii;\r
-    unsigned char c1a,c1b;\r
-    unsigned char c2a,c2b;\r
-    unsigned char c1A,c1B;\r
-    unsigned char c2A,c2B;\r
-\r
-    c1a = c1A;\r
-    c1b = c1B;\r
-    for (ii = 0; ii < 25; ++ii) {\r
-        ybuf[ii] = (sinustable[c1a] + sinustable[c1b]);\r
-        c1a += 4;\r
-       c1b += 9;\r
-    }\r
-    c1A += 3;\r
-    c1B -= 5;\r
-    c2a = c2A;\r
-    c2b = c2B;\r
-    for (i = 0; i < 40; ++i) {\r
-        xbuf[i] = (sinustable[c2a] + sinustable[c2b]);\r
-        c2a += 3;\r
-       c2b += 7;\r
-    }\r
-    c2A += 2;\r
-    c2B -= 3;\r
-    for (ii = 0; ii < 25; ++ii) {\r
-        for (i = 0; i < 40; ++i, ++scrn) {\r
-            *scrn = (xbuf[i] + ybuf[ii]);\r
-        }\r
-    }\r
-}\r
-\r
-\r
-\r
-static void makechar (void)\r
-{\r
-    static const unsigned char bittab[8] = {\r
-       0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80\r
-    };\r
-    unsigned char i, ii, b, s;\r
-    unsigned c;\r
-\r
-    gotoxy (0, 1);\r
-    for (c = 0; c < 0x100; ++c) {\r
-       s = sinustable[c];\r
-        for (i = 0; i < 8; ++i){\r
-            b = 0;\r
-            for (ii = 0; ii < 8; ++ii) {\r
-                if ((rand() & 0xFF) > s) {\r
-                   b |= bittab[ii];\r
-               }\r
-            }\r
-            ((unsigned char*)CHARSET) [(c*8) + i] = b;\r
-        }\r
-       if ((c & 0x07) == 0) {\r
-           cputc ('.');\r
-       }\r
-    }\r
-}\r
-\r
-\r
-\r
-int main (void)\r
-{\r
-    unsigned char border;\r
-    unsigned char background;\r
-    unsigned char text;\r
-    unsigned char v;\r
-    clock_t       t;\r
-    unsigned long f = 0;\r
-    unsigned long sec;\r
-    unsigned      sec10;\r
-    unsigned long fps;\r
-    unsigned      fps10;\r
-\r
-\r
-    clrscr ();\r
-    cprintf ("Making charset, mompls");\r
-    makechar();\r
-\r
-    /* Set the border and background colors */\r
-    border     = bordercolor (COLOR_BLUE);\r
-    background = bgcolor (COLOR_BLUE);\r
-    text       = textcolor (COLOR_BLACK);\r
-    clrscr ();\r
-\r
-#if defined(__C64__)\r
-    /* Move the VIC 16K block */\r
-    outb (&CIA2.pra, 0x00);\r
-#endif\r
-\r
-    /* Remember the VIC address register */\r
-    v = inb (&VIC.addr);\r
-\r
-    /* Run the demo until a key was hit */\r
-    t = clock ();\r
-    while (!kbhit()) {\r
-       /* Build page 1, then make it visible */\r
-        scrn = (unsigned char*)SCREEN1;\r
-        doplasma();\r
-       outb (&VIC.addr, PAGE1);\r
-\r
-       /* Build page 2, then make it visible */\r
-        scrn = (unsigned char*)SCREEN2;\r
-        doplasma();\r
-       outb (&VIC.addr, PAGE2);\r
-\r
-       /* Count frames */\r
-        f += 2;\r
-    };\r
-    t = clock() - t;\r
-\r
-    /* Switch back the VIC screen */\r
-    outb (&VIC.addr, v);\r
-\r
-#if defined(__C64__)\r
-    /* Move back the VIC 16K block */\r
-    outb (&CIA2.pra, 0x03);\r
-#endif\r
-\r
-    /* Fetch the character from the keyboard buffer and discard it */\r
-    (void) cgetc();\r
-\r
-    /* Reset screen colors */\r
-    bordercolor (border);\r
-    bgcolor (background);\r
-    textcolor (text);\r
-    clrscr();\r
-\r
-    /* Calculate stats */\r
-    sec   = (t * 10) / CLK_TCK;\r
-    sec10 = sec % 10;\r
-    sec  /= 10;\r
-    fps   = (f * (CLK_TCK * 10)) / t;\r
-    fps10 = fps % 10;\r
-    fps  /= 10;\r
-\r
-    /* Output stats */\r
-    gotoxy (0, 0); cprintf ("time  : %lu.%us", sec, sec10);\r
-    gotoxy (0, 1); cprintf ("frames: %lu", f);\r
-    gotoxy (0, 2); cprintf ("fps   : %lu.%u", fps, fps10);\r
-\r
-    /* Wait for a key, then end */\r
-    cputsxy (0, 4, "Press any key when done...");\r
-    (void) cgetc ();\r
-\r
-    /* Done */\r
-    return EXIT_SUCCESS;\r
-}\r
-\r
-\r
+/*****************************************************************************\
+** plasma test program for cc65.                                             **
+**                                                                           **
+** (w)2001 by groepaz/hitmen                                                 **
+**                                                                           **
+** Cleanup and porting by Ullrich von Bassewitz.                             **
+**                                                                           **
+\*****************************************************************************/
+
+
+
+#include <stdlib.h>
+#include <time.h>
+#include <conio.h>
+#include <cc65.h>
+
+
+
+#if defined(__C64__) || defined(__C128__)
+#  define SCREEN1               0xE000
+#  define SCREEN2               0xE400
+#  define CHARSET               0xE800
+#  define outb(addr,val)        (*(addr)) = (val)
+#  define inb(addr)             (*(addr))
+#elif defined(__CBM510__)
+#  define SCREEN1               0xF000
+#  define SCREEN2               0xF400
+#  define CHARSET               0xE000
+#  define outb(addr,val)        pokebsys ((unsigned)(addr), val)
+#  define inb(addr)             peekbsys ((unsigned)(addr))
+#elif defined(__PLUS4__)
+#  define SCREEN1               0x6400
+#  define SCREEN2               0x6C00
+#  define CHARSET               0x7000
+#  define outb(addr,val)        (*(addr)) = (val)
+#  define inb(addr)             (*(addr))
+#endif
+
+
+
+/* Values for the VIC address register to switch between the two pages */
+#if defined(__PLUS4__)
+#define PAGE1                   ((SCREEN1 >> 8) & 0xF8)
+#define PAGE2                   ((SCREEN2 >> 8) & 0xF8)
+#define CHARADR                 ((CHARSET >> 8) & 0xFC)
+#else
+#define PAGE1                   ((SCREEN1 >> 6) & 0xF0) | ((CHARSET >> 10) & 0x0E)
+#define PAGE2                   ((SCREEN2 >> 6) & 0xF0) | ((CHARSET >> 10) & 0x0E)
+#endif
+
+
+
+/* Use static local variables for speed */
+#pragma static-locals (1);
+
+
+
+static const unsigned char sinustable[0x100] = {
+    0x80, 0x7d, 0x7a, 0x77, 0x74, 0x70, 0x6d, 0x6a,
+    0x67, 0x64, 0x61, 0x5e, 0x5b, 0x58, 0x55, 0x52,
+    0x4f, 0x4d, 0x4a, 0x47, 0x44, 0x41, 0x3f, 0x3c,
+    0x39, 0x37, 0x34, 0x32, 0x2f, 0x2d, 0x2b, 0x28,
+    0x26, 0x24, 0x22, 0x20, 0x1e, 0x1c, 0x1a, 0x18,
+    0x16, 0x15, 0x13, 0x11, 0x10, 0x0f, 0x0d, 0x0c,
+    0x0b, 0x0a, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04,
+    0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03,
+    0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0a,
+    0x0b, 0x0c, 0x0d, 0x0f, 0x10, 0x11, 0x13, 0x15,
+    0x16, 0x18, 0x1a, 0x1c, 0x1e, 0x20, 0x22, 0x24,
+    0x26, 0x28, 0x2b, 0x2d, 0x2f, 0x32, 0x34, 0x37,
+    0x39, 0x3c, 0x3f, 0x41, 0x44, 0x47, 0x4a, 0x4d,
+    0x4f, 0x52, 0x55, 0x58, 0x5b, 0x5e, 0x61, 0x64,
+    0x67, 0x6a, 0x6d, 0x70, 0x74, 0x77, 0x7a, 0x7d,
+    0x80, 0x83, 0x86, 0x89, 0x8c, 0x90, 0x93, 0x96,
+    0x99, 0x9c, 0x9f, 0xa2, 0xa5, 0xa8, 0xab, 0xae,
+    0xb1, 0xb3, 0xb6, 0xb9, 0xbc, 0xbf, 0xc1, 0xc4,
+    0xc7, 0xc9, 0xcc, 0xce, 0xd1, 0xd3, 0xd5, 0xd8,
+    0xda, 0xdc, 0xde, 0xe0, 0xe2, 0xe4, 0xe6, 0xe8,
+    0xea, 0xeb, 0xed, 0xef, 0xf0, 0xf1, 0xf3, 0xf4,
+    0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfa, 0xfb, 0xfc,
+    0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfd,
+    0xfd, 0xfc, 0xfb, 0xfa, 0xfa, 0xf9, 0xf8, 0xf6,
+    0xf5, 0xf4, 0xf3, 0xf1, 0xf0, 0xef, 0xed, 0xeb,
+    0xea, 0xe8, 0xe6, 0xe4, 0xe2, 0xe0, 0xde, 0xdc,
+    0xda, 0xd8, 0xd5, 0xd3, 0xd1, 0xce, 0xcc, 0xc9,
+    0xc7, 0xc4, 0xc1, 0xbf, 0xbc, 0xb9, 0xb6, 0xb3,
+    0xb1, 0xae, 0xab, 0xa8, 0xa5, 0xa2, 0x9f, 0x9c,
+    0x99, 0x96, 0x93, 0x90, 0x8c, 0x89, 0x86, 0x83
+};
+
+
+
+static void doplasma (register unsigned char* scrn)
+{
+    unsigned char xbuf[40];
+    unsigned char ybuf[25];
+    unsigned char c1a,c1b;
+    unsigned char c2a,c2b;
+    unsigned char c1A,c1B;
+    unsigned char c2A,c2B;
+    register unsigned char i, ii;
+
+    c1a = c1A;
+    c1b = c1B;
+    for (ii = 0; ii < 25; ++ii) {
+        ybuf[ii] = (sinustable[c1a] + sinustable[c1b]);
+        c1a += 4;
+        c1b += 9;
+    }
+    c1A += 3;
+    c1B -= 5;
+    c2a = c2A;
+    c2b = c2B;
+    for (i = 0; i < 40; ++i) {
+        xbuf[i] = (sinustable[c2a] + sinustable[c2b]);
+        c2a += 3;
+        c2b += 7;
+    }
+    c2A += 2;
+    c2B -= 3;
+    for (ii = 0; ii < 25; ++ii) {
+        /* Unrolling the following loop will give a speed increase of
+        ** nearly 100% (~24fps), but it will also increase the code
+        ** size a lot.
+        */
+        for (i = 0; i < 40; ++i, ++scrn) {
+            *scrn = (xbuf[i] + ybuf[ii]);
+        }
+    }
+}
+
+
+
+static void makechar (void)
+{
+    static const unsigned char bittab[8] = {
+        0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
+    };
+    unsigned char i, ii, b, s;
+    unsigned c;
+
+    gotoxy (0, 1);
+    for (c = 0; c < 0x100; ++c) {
+        s = sinustable[c];
+        for (i = 0; i < 8; ++i){
+            b = 0;
+            for (ii = 0; ii < 8; ++ii) {
+                if ((rand() & 0xFF) > s) {
+                    b |= bittab[ii];
+                }
+            }
+            ((unsigned char*)CHARSET) [(c*8) + i] = b;
+        }
+        if ((c & 0x07) == 0) {
+            cputc ('.');
+        }
+    }
+}
+
+
+
+int main (void)
+{
+    unsigned char border;
+    unsigned char background;
+    unsigned char text;
+    unsigned char v;
+    clock_t       t;
+    unsigned long f = 0;
+    unsigned long sec;
+    unsigned      sec10;
+    unsigned long fps;
+    unsigned      fps10;
+
+
+#if defined(__C64__)
+    unsigned char block;
+#endif
+#if defined(__C128__)
+    unsigned char block;
+    unsigned char initflag;
+    unsigned char graphflag;
+#endif
+#if defined(__PLUS4__)
+    unsigned int i;
+    unsigned char v2;
+#endif
+
+    clrscr ();
+    cprintf ("Making charset, mompls");
+    makechar();
+
+    /* Set the border and background colors */
+    border     = bordercolor (COLOR_BLUE);
+    background = bgcolor (COLOR_BLUE);
+    text       = textcolor (COLOR_BLACK);
+    clrscr ();
+
+#if defined(__C64__) || defined(__C128__)
+    /* Move the VIC 16K block */
+    block = inb (&CIA2.pra);
+    outb (&CIA2.pra, (block & 0xFC) | ((SCREEN1 >> 14) ^ 0x03));
+#endif
+#if defined(__C128__)
+    /* Save and change some flags, so that kernal/basic interrupt handler will
+    ** not interfere with our routine.
+    */
+    initflag = *(unsigned char*) 0xA04;
+    *(unsigned char*) 0xA04 &= 0xFE;
+    graphflag = *(unsigned char*) 0xD8;
+    *(unsigned char*) 0xD8 = 0xFF;
+#endif
+
+    /* Remember the VIC address register */
+#if defined(__PLUS4__)
+    v = inb (&TED.char_addr);
+    v2 = inb (&TED.video_addr);
+#else
+    v = inb (&VIC.addr);
+#endif
+
+#if defined(__PLUS4__)
+    for (i=0;i<1000;i++) {
+        ((unsigned char *) (SCREEN1-0x0400))[i] = 0;
+        ((unsigned char *) (SCREEN2-0x0400))[i] = 0;
+    }
+    outb (&TED.char_addr, CHARADR);
+#endif
+
+    /* Run the demo until a key was hit */
+    t = clock ();
+    while (!kbhit()) {
+        /* Build page 1, then make it visible */
+        doplasma ((unsigned char*)SCREEN1);
+#if defined(__PLUS4__)
+        outb (&TED.video_addr, PAGE1);
+#else
+        outb (&VIC.addr, PAGE1);
+#endif
+
+        /* Build page 2, then make it visible */
+        doplasma ((unsigned char*)SCREEN2);
+#if defined(__PLUS4__)
+        outb (&TED.video_addr, PAGE2);
+#else
+        outb (&VIC.addr, PAGE2);
+#endif
+
+        /* Count frames */
+        f += 2;
+    }
+    t = clock() - t;
+
+    /* Switch back the VIC screen */
+#if defined(__PLUS4__)
+    outb (&TED.video_addr, v2);
+    outb (&TED.char_addr, v);
+#else
+    outb (&VIC.addr, v);
+#endif
+
+#if defined(__C64__) || defined(__C128__)
+    /* Move back the VIC 16K block */
+    outb (&CIA2.pra, block);
+#endif
+#if defined(__C128__)
+    /* Restore the flags */
+    *(unsigned char*) 0xA04 = initflag;
+    *(unsigned char*) 0xD8  = graphflag;
+#endif
+
+    /* Fetch the character from the keyboard buffer and discard it */
+    (void) cgetc();
+
+    /* Reset screen colors */
+    bordercolor (border);
+    bgcolor (background);
+    textcolor (text);
+    clrscr ();
+
+    /* Calculate stats */
+    sec   = (t * 10) / CLK_TCK;
+    sec10 = sec % 10;
+    sec  /= 10;
+    fps   = (f * (CLK_TCK * 10)) / t;
+    fps10 = fps % 10;
+    fps  /= 10;
+
+    /* Output stats */
+    gotoxy (0, 0); cprintf ("time  : %lu.%us", sec, sec10);
+    gotoxy (0, 1); cprintf ("frames: %lu", f);
+    gotoxy (0, 2); cprintf ("fps   : %lu.%u", fps, fps10);
+
+    if (doesclrscrafterexit ()) {
+        cputsxy (0, 4, "Press any key when done...");
+        (void) cgetc ();
+    }
+
+    /* Done */
+    return EXIT_SUCCESS;
+}