]> git.sur5r.net Git - cc65/blob - samples/fire.c
goto.c warning fix for implicit truncation
[cc65] / samples / fire.c
1 /*****************************************************************************\
2 ** fire test program for cc65.                                               **
3 **                                                                           **
4 ** (w)2002 by groepaz/hitmen                                                 **
5 **                                                                           **
6 ** Cleanup and porting by Ullrich von Bassewitz.                             **
7 ** 2004-06-08, Greg King                                                     **
8 **                                                                           **
9 \*****************************************************************************/
10
11
12
13 /* sync page-flipping to vertical blank */
14 /* #define DOVSYNC */
15
16 #include <stdlib.h>
17 #include <string.h> /* for memset */
18 #include <time.h>
19 #include <conio.h>
20 #include <cbm.h>
21
22
23
24 #if defined(__C64__)
25 #  define BUFFER                0x0400
26 #  define SCREEN1               0xE000
27 #  define SCREEN2               0xE400
28 #  define CHARSET               0xE800
29 #  define COLORRAM              0xD800
30 #  define outb(addr,val)        (*(addr) = (val))
31 #  define inb(addr)             (*(addr))
32 #elif defined(__C128__)
33 #  define BUFFER                0x0400
34 #  define SCREEN1               0xE000
35 #  define SCREEN2               0xE400
36 #  define CHARSET               0xE800
37 #  define COLORRAM              0xD800
38 #  define outb(addr,val)        (*(addr) = (val))
39 #  define inb(addr)             (*(addr))
40 #elif defined(__CBM510__)
41 #  define BUFFER                0xF800
42 #  define SCREEN1               0xF000
43 #  define SCREEN2               0xF400
44 #  define CHARSET               0xE000
45 #  define COLORRAM              0xD400
46 #  define outb(addr,val)        pokebsys ((unsigned)(addr), val)
47 #  define inb(addr)             peekbsys ((unsigned)(addr))
48 #endif
49
50
51
52 /* Values for the VIC address register to switch between the two pages */
53 #define PAGE1                   ((SCREEN1 >> 6) & 0xF0) | ((CHARSET >> 10) & 0x0E)
54 #define PAGE2                   ((SCREEN2 >> 6) & 0xF0) | ((CHARSET >> 10) & 0x0E)
55
56
57
58 /* Use static local variables for speed */
59 #pragma static-locals (1);
60
61
62
63 #ifdef DOVSYNC
64 #  define WAITVSYNC() waitvsync()
65 #else
66 #  define WAITVSYNC()
67 #endif
68
69
70
71 static void makechar (void)
72 {
73     static const unsigned char bittab[8] = {
74         0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
75     };
76     register char *font;
77     register unsigned char i, ii, b, bc;
78     unsigned char c;
79
80     gotoxy (0, 1);
81
82     for (font = (char*)CHARSET; font != (char*)(CHARSET+(1*8)); ++font) {
83         *font = 0x00;
84     }
85     for (font = (char*)(CHARSET+(64*8)); font != (char*)(CHARSET+(256*8)); ++font) {
86         *font = 0xff;
87     }
88
89
90     for (c = 0; c < 0x40; ++c) {
91         bc = 0;
92         for (i = 0; i < 8; i++){
93             b = 0;
94             for (ii = 0; ii < 8; ii++) {
95                 bc += c;
96                 if (bc > 0x3f) {
97                     bc = bc - 0x40;
98                     b += bittab[(ii + (i & 1)) & 0x7];
99                 }
100             }
101             ((unsigned char*)CHARSET + (1 * 8)) [(c * 8) + i] = b;
102         }
103         if ((c & 0x07) == 0) {
104             cputc ('.');
105         }
106     }
107 }
108
109
110
111 static void fire (unsigned screenbase)
112 {
113     register char* screen;
114     register char* buffer;
115     register char c;
116
117     screen = (char*) screenbase;
118     buffer = (char*) BUFFER;
119
120     while (buffer != (char*) (BUFFER + (24 * 40))) {
121         c = (buffer[40-1] + buffer[40-1] + buffer[40] + buffer[41]) / 4;
122         if (c > 2) {
123             c -= 3;
124         }
125         *screen = *buffer = c;
126         ++screen;
127         ++buffer;
128     }
129
130     screen = (char*) (screenbase + (23 * 40));
131     buffer = (char*) (BUFFER + (23 * 40));
132
133     for(; buffer != (char*)(BUFFER+(25*40)); ++screen, ++buffer) {
134         *screen = *buffer = 0x30 + (inb (&SID.noise) >> 4);
135     }
136 }
137
138
139
140 int main (void)
141 {
142     unsigned char border;
143     unsigned char background;
144     unsigned char text;
145     unsigned char v;
146     clock_t       t;
147     unsigned long f = 0;
148     unsigned long sec;
149     unsigned      sec10;
150     unsigned long fps;
151     unsigned      fps10;
152     int           i;
153
154 #if defined(__C64__)
155     unsigned char block;
156 #endif
157 #if defined(__C128__)
158     unsigned char block;
159     unsigned char initflag;
160     unsigned char graphflag;
161 #endif
162
163     /* Noise on channel 3 for random numbers  */
164     outb (&SID.v3.freq, 0xffff);
165     outb (&SID.v3.ctrl, 0x80);
166
167     clrscr ();
168     cprintf ("Making charset, mompls");
169     makechar ();
170
171     /* Set the border and background colors */
172     border     = bordercolor (COLOR_BLACK);
173     background = bgcolor (COLOR_BLACK);
174     text       = textcolor (COLOR_BLACK);
175     clrscr ();
176
177     for(i = 0; i != 0x400; i++) {
178         *((char *)(i + BUFFER))  = 0;
179         *((char *)(i + SCREEN1)) = 0;
180         *((char *)(i + SCREEN2)) = 0;
181         outb ((char*)(i + COLORRAM), COLOR_YELLOW);
182     }
183
184 #if defined(__C64__) || defined(__C128__)
185     /* Move the VIC 16K block */
186     block = inb (&CIA2.pra);
187     outb (&CIA2.pra, (block & 0xFC) | ((SCREEN1 >> 14) ^ 0x03));
188 #endif
189 #if defined(__C128__)
190     /* Save and change some flags, so that kernal/basic interrupt handler will
191     ** not interfere with our routine.
192     */
193     initflag = *(unsigned char*) 0xA04;
194     *(unsigned char*) 0xA04 &= 0xFE;
195     graphflag = *(unsigned char*) 0xD8;
196     *(unsigned char*) 0xD8 = 0xFF;
197 #endif
198
199     /* Remember the VIC address register */
200     v = inb (&VIC.addr);
201
202     /* Run the demo until a key was hit */
203     t = clock ();
204     while (!kbhit()) {
205         /* Build page 1, then make it visible */
206         fire (SCREEN1);
207         WAITVSYNC ();
208         outb (&VIC.addr, PAGE1);
209
210         /* Build page 2, then make it visible */
211         fire (SCREEN2);
212         WAITVSYNC ();
213         outb (&VIC.addr, PAGE2);
214
215         /* Count frames */
216         f += 2;
217     }
218     t = clock() - t;
219
220     /* Switch back the VIC screen */
221     outb (&VIC.addr, v);
222
223 #if defined(__C64__) || defined(__C128__)
224     /* Move back the VIC 16K block */
225     outb (&CIA2.pra, block);
226 #endif
227 #if defined(__C128__)
228     /* Restore the flags */
229     *(unsigned char*) 0xA04 = initflag;
230     *(unsigned char*) 0xD8  = graphflag;
231 #endif
232
233     /* Fetch the character from the keyboard buffer and discard it */
234     (void) cgetc();
235
236     /* Reset screen colors */
237     bordercolor (border);
238     bgcolor (background);
239     textcolor (text);
240     clrscr ();
241
242     /* Calculate stats */
243     sec   = (t * 10) / CLK_TCK;
244     sec10 = sec % 10;
245     sec  /= 10;
246     fps   = (f * (CLK_TCK * 10)) / t;
247     fps10 = fps % 10;
248     fps  /= 10;
249
250     /* Output stats */
251     gotoxy (0, 0); cprintf ("time  : %lu.%us", sec, sec10);
252     gotoxy (0, 1); cprintf ("frames: %lu", f);
253     gotoxy (0, 2); cprintf ("fps   : %lu.%u", fps, fps10);
254
255     /* Wait for a key, then end */
256     cputsxy (0, 4, "Press any key when done...");
257     (void) cgetc ();
258
259     /* Done */
260     return EXIT_SUCCESS;
261 }
262
263
264