--- /dev/null
+/*****************************************************************************
+ * fire test program for cc65. *
+ * *
+ * (w)2002 by groepaz/hitmen *
+ * *
+ * Cleanup and porting by Ullrich von Bassewitz. *
+ * *
+ *****************************************************************************/
+
+
+
+/* sync page-flipping to vertical blank */
+//#define DOVSYNC
+
+#include <stdlib.h>
+#include <string.h> /* for memset */
+#include <time.h>
+#include <conio.h>
+
+
+
+#if defined(__C64__)
+# define BUFFER 0x0400
+# define SCREEN1 0xE000
+# define SCREEN2 0xE400
+# define CHARSET 0xE800
+# define COLORRAM 0xD800
+# define outb(addr,val) (*(addr)) = (val)
+# define inb(addr) (*(addr))
+#elif defined(__C128__)
+# define SCREEN1 0xE000
+# define SCREEN2 0xE400
+# define CHARSET 0xE800
+# define COLORRAM 0xD800
+# define outb(addr,val) (*(addr)) = (val)
+# define inb(addr) (*(addr))
+#elif defined(__CBM510__)
+# define BUFFER 0xF800
+# define SCREEN1 0xF000
+# define SCREEN2 0xF400
+# define CHARSET 0xE000
+# define COLORRAM 0xD400
+# define outb(addr,val) pokebsys ((unsigned)(addr), val)
+# define inb(addr) peekbsys ((unsigned)(addr))
+#endif
+
+
+
+/* Values for the VIC address register to switch between the two pages */
+#define PAGE1 ((SCREEN1 >> 6) & 0xF0) | ((CHARSET >> 10) & 0x0E)
+#define PAGE2 ((SCREEN2 >> 6) & 0xF0) | ((CHARSET >> 10) & 0x0E)
+
+
+
+/* Use static local variables for speed */
+#pragma staticlocals (1);
+
+
+
+#ifdef DOVSYNC
+# define waitvsync() while(VIC.ctrl1 < 0x80) {}
+#else
+# define waitvsync()
+#endif
+
+
+
+static void makechar (void)
+{
+ char *font;
+
+ static const unsigned char bittab[8] = {
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
+ };
+ unsigned char i, ii, b;
+ int c;
+ int s,bc;
+
+ gotoxy (0, 1);
+
+ for (font = (char*)CHARSET; font != (char*)(CHARSET+(1*8)); ++font) {
+ *font = 0x00;
+ }
+ for (font = (char*)(CHARSET+(64*8)); font != (char*)(CHARSET+(256*8)); ++font) {
+ *font = 0xff;
+ }
+
+
+ for (c = 0; c < 0x40; ++c) {
+ s = c;
+ bc = 0;
+ for (i = 0; i < 8; i++){
+ b = 0;
+ for (ii = 0; ii < 8; ii++) {
+ bc += s;
+ if (bc > 0x3f) {
+ bc = bc - 0x40;
+ b += bittab[(ii + (i & 1)) & 0x7];
+ }
+ }
+ ((unsigned char*)CHARSET + (1 * 8)) [(c * 8) + i] = b;
+ }
+ if ((c & 0x07) == 0) {
+ cputc ('.');
+ }
+ }
+}
+
+
+
+static void fire (unsigned screenbase)
+{
+ register char* screen;
+ register char* buffer;
+ register char c;
+
+ screen = (char*) screenbase;
+ buffer = (char*) BUFFER;
+
+ while (buffer != (char*) (BUFFER + (24 * 40))) {
+ c = (buffer[40-1] + buffer[40-1] + buffer[40] + buffer[41]) / 4;
+ if (c > 2) {
+ c -= 3;
+ }
+ *screen = *buffer = c;
+ ++screen;
+ ++buffer;
+ }
+
+ screen = (char*) (screenbase + (23 * 40));
+ buffer = (char*) (BUFFER + (23 * 40));
+
+ for(; buffer != (char*)(BUFFER+(25*40)); ++screen, ++buffer) {
+ *screen = *buffer = 0x30 + (inb (&SID.noise) >> 4);
+ }
+}
+
+
+
+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;
+ int i;
+
+#if defined(__C64__)
+ unsigned char block;
+#endif
+#if defined(__C128__)
+ unsigned char block;
+ unsigned char initflag;
+ unsigned char graphflag;
+#endif
+
+ /* Noise on channel 3 for random numbers */
+ outb (&SID.v3.freq, 0xffff);
+ outb (&SID.v3.ctrl, 0x80);
+
+ clrscr ();
+ cprintf ("Making charset, mompls");
+ makechar ();
+
+ /* Set the border and background colors */
+ border = bordercolor (COLOR_BLACK);
+ background = bgcolor (COLOR_BLACK);
+ text = textcolor (COLOR_BLACK);
+ clrscr ();
+
+ for(i = 0; i != 0x400; i++) {
+ *((char *)(i + BUFFER)) = 0;
+ *((char *)(i + SCREEN1)) = 0;
+ *((char *)(i + SCREEN2)) = 0;
+ outb ((char*)(i + COLORRAM), COLOR_YELLOW);
+ }
+
+#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 interupt 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 */
+ v = inb (&VIC.addr);
+
+ /* Run the demo until a key was hit */
+ t = clock ();
+ while (!kbhit()) {
+ /* Build page 1, then make it visible */
+ fire (SCREEN1);
+ waitvsync ();
+ outb (&VIC.addr, PAGE1);
+
+ /* Build page 2, then make it visible */
+ fire (SCREEN2);
+ waitvsync ();
+ outb (&VIC.addr, PAGE2);
+
+ /* Count frames */
+ f += 2;
+ }
+ t = clock() - t;
+
+ /* Switch back the VIC screen */
+ outb (&VIC.addr, v);
+
+#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);
+
+ /* Wait for a key, then end */
+ cputsxy (0, 4, "Press any key when done...");
+ (void) cgetc ();
+
+ /* Done */
+ return EXIT_SUCCESS;
+}
+
+
+