]> git.sur5r.net Git - cc65/blob - testcode/lib/mul-test.c
Added C64 Chameleon accelerator code and documentation.
[cc65] / testcode / lib / mul-test.c
1 /* mul-test.c -- Test the multiplication operator. */
2
3 #include <time.h>
4 #include <conio.h>
5 #include <ctype.h>
6
7
8 /* Number of elements in the progress bar. Use a power of 2, to avoid the
9 ** multiplication (which is about to be tested).
10 */
11 #define BAR_ELEMENTS    32U
12
13 #if defined(__CBM__)
14 static const unsigned char revers_bar[8] = {
15     0, 0, 0, 0, 0, 1, 1, 1
16 };
17 static const unsigned char small_bar[8] = {
18     ' ', 0xa5, 0xb4, 0xb5, 0xa1, 0xb6, 0xaa, 0xa7
19 };
20
21 #elif defined(__ATARI__)
22 #endif
23
24 /* Screen co-ordinates for the progress meter */
25 static unsigned char Width, Height;
26 static unsigned char X, Y;
27
28 static void ProgressMeter (unsigned Val)
29 /* Print the progress bar. */
30 {
31     gotoxy (X, Y);
32     cprintf (" %5lu/65536\r\n", (unsigned long) Val);
33     revers (1);
34     cclear (Val / (unsigned)(65536U / BAR_ELEMENTS));
35
36 /* Commodore and Atari computers can show eight times greater precision. */
37 #if defined(__CBM__)
38     Val = (Val / (unsigned)(65536U / BAR_ELEMENTS / 8)) % 8;
39     revers (revers_bar[Val]);
40     cputc (small_bar[Val]);
41
42 #elif defined(__ATARI__)
43 #endif
44
45     revers (0);
46 }
47
48
49
50 int main(void)
51 {
52     char C;
53
54     /* Clock variables */
55     clock_t Ticks;
56     clock_t Wait;
57     unsigned Days;
58     unsigned Hours;
59     unsigned Minu;
60     unsigned Sec;
61     unsigned Milli;
62
63     /* Actual test variables */
64     register unsigned lhs = 0;
65     register unsigned rhs = 0;
66     register unsigned res;
67
68     /* Clear the screen, and output an informational message. */
69     clrscr ();
70     screensize (&Width, &Height);
71     cprintf ("This program does an exhaustive test of\r\n"
72              "the multiplication routine. It runs for\r\n"
73              "several days; so, please wait very\r\n"
74              "patiently (or, speed up your emulator).\r\n"
75              "\n"
76              "Progress: ");
77
78     /* Remember the current position for the progress bar */
79     X = wherex ();
80     Y = wherey ();
81
82     /* Mark the maximum limit of the bar. */
83     revers (1);
84     cputcxy (BAR_ELEMENTS, Y, ' ');
85     cputcxy (BAR_ELEMENTS, Y + 1, ' ');
86     revers (0);
87
88 /* [Targets that have clock() will define CLOCKS_PER_SEC.] */
89 #ifdef CLOCKS_PER_SEC
90
91     /* Start timing the test. */
92     Ticks = clock();
93 #endif
94
95     do {
96
97         /* Update the progress bar */
98         ProgressMeter (lhs);
99
100 /* Enable this to test the progress-meter code.
101 ** (And, run emulators at their maximun speed.)
102 */
103 #if 0
104         continue;
105 #endif
106
107         /* Do one row of tests */
108         res = 0;
109         do {
110             if (lhs * rhs != res) {
111 #ifdef CLOCKS_PER_SEC
112                 Wait = clock ();
113 #endif
114                 gotoxy (0, Y+3);
115                 cprintf ("Error on %u * %u: %u != %u\r\n", lhs, rhs, lhs * rhs, res);
116                 cprintf ("Press a key -- 'Q' to quit. ");
117                 cursor (1);
118                 C = toupper (cgetc ());
119                 cclearxy (0, Y+3, Width);
120                 cclearxy (0, Y+4, Width);
121
122 #ifdef CLOCKS_PER_SEC
123
124                 /* Don't time the user's interaction. */
125                 Ticks += clock () - Wait;
126 #endif
127
128                 if (C == 'Q') {
129                     goto Done;
130                 }
131             }
132
133             if (kbhit () && toupper (cgetc ()) == 'Q') {
134                 goto Done;
135             }
136
137             res += lhs;
138         } while (++rhs != 0);
139
140     } while (++lhs != 0);
141
142 Done:
143 #ifdef CLOCKS_PER_SEC
144
145     /* Calculate the time used */
146     Ticks = clock() - Ticks;
147     Milli = ((Ticks % CLOCKS_PER_SEC) * 1000) / CLOCKS_PER_SEC;
148     Sec = (unsigned) (Ticks / CLOCKS_PER_SEC);
149     Minu = Sec / 60;
150     Hours = Minu / 60;
151     Days = Hours / 24;
152     Hours %= 24;
153     Minu %= 60;
154     Sec %= 60;
155
156     /* Print the time used */
157     gotoxy (0, Y+3);
158     cprintf ("Time used:\r\n"
159              " %u days,\r\n"
160              " %u hours,\r\n"
161              " %u minutes,\r\n"
162              " %u.%03u seconds.\n", Days, Hours, Minu, Sec, Milli);
163 #endif
164
165     cprintf ("\rTap a key, to exit. ");
166     cgetc();
167     return 0;
168 }
169
170