1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-27 00:29:31 +00:00
cc65/samples/fire.c
uz ed2767e65f Changed names of the pragmas to be identical to the corresponding command line
options. This should make use easier. The old names of the pragmas are still
available but will cause warnings.


git-svn-id: svn://svn.cc65.org/cc65/trunk@4364 b7a2c559-68d2-44c3-8de9-860c34a00d81
2009-10-14 12:55:15 +00:00

264 lines
6.7 KiB
C

/*****************************************************************************
* fire test program for cc65. *
* *
* (w)2002 by groepaz/hitmen *
* *
* Cleanup and porting by Ullrich von Bassewitz. *
* 2004-06-08, Greg King *
* *
*****************************************************************************/
/* 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 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(__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 static-locals (1);
#ifdef DOVSYNC
# define waitvsync() while ((signed char)VIC.ctrl1 >= 0)
#else
# define waitvsync()
#endif
static void makechar (void)
{
static const unsigned char bittab[8] = {
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
};
register char *font;
register unsigned char i, ii, b, bc;
unsigned char c;
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) {
bc = 0;
for (i = 0; i < 8; i++){
b = 0;
for (ii = 0; ii < 8; ii++) {
bc += c;
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 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 */
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;
}