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