cc65/targettest/mul-test.c

171 lines
3.9 KiB
C

/* mul-test.c -- Test the multiplication operator. */
#include <time.h>
#include <conio.h>
#include <ctype.h>
/* Number of elements in the progress bar. Use a power of 2, to avoid the
** multiplication (which is about to be tested).
*/
#define BAR_ELEMENTS 32U
#if defined(__CBM__)
static const unsigned char revers_bar[8] = {
0, 0, 0, 0, 0, 1, 1, 1
};
static const unsigned char small_bar[8] = {
' ', 0xa5, 0xb4, 0xb5, 0xa1, 0xb6, 0xaa, 0xa7
};
#elif defined(__ATARI__)
#endif
/* Screen co-ordinates for the progress meter */
static unsigned char Width, Height;
static unsigned char X, Y;
static void ProgressMeter (unsigned Val)
/* Print the progress bar. */
{
gotoxy (X, Y);
cprintf (" %5lu/65536\r\n", (unsigned long) Val);
revers (1);
cclear (Val / (unsigned)(65536U / BAR_ELEMENTS));
/* Commodore and Atari computers can show eight times greater precision. */
#if defined(__CBM__)
Val = (Val / (unsigned)(65536U / BAR_ELEMENTS / 8)) % 8;
revers (revers_bar[Val]);
cputc (small_bar[Val]);
#elif defined(__ATARI__)
#endif
revers (0);
}
int main(void)
{
char C;
/* Clock variables */
clock_t Ticks;
clock_t Wait;
unsigned Days;
unsigned Hours;
unsigned Minu;
unsigned Sec;
unsigned Milli;
/* Actual test variables */
register unsigned lhs = 0;
register unsigned rhs = 0;
register unsigned res;
/* Clear the screen, and output an informational message. */
clrscr ();
screensize (&Width, &Height);
cprintf ("This program does an exhaustive test of\r\n"
"the multiplication routine. It runs for\r\n"
"several days; so, please wait very\r\n"
"patiently (or, speed up your emulator).\r\n"
"\n"
"Progress: ");
/* Remember the current position for the progress bar */
X = wherex ();
Y = wherey ();
/* Mark the maximum limit of the bar. */
revers (1);
cputcxy (BAR_ELEMENTS, Y, ' ');
cputcxy (BAR_ELEMENTS, Y + 1, ' ');
revers (0);
/* [Targets that have clock() will define CLOCKS_PER_SEC.] */
#ifdef CLOCKS_PER_SEC
/* Start timing the test. */
Ticks = clock();
#endif
do {
/* Update the progress bar */
ProgressMeter (lhs);
/* Enable this to test the progress-meter code.
** (And, run emulators at their maximun speed.)
*/
#if 0
continue;
#endif
/* Do one row of tests */
res = 0;
do {
if (lhs * rhs != res) {
#ifdef CLOCKS_PER_SEC
Wait = clock ();
#endif
gotoxy (0, Y+3);
cprintf ("Error on %u * %u: %u != %u\r\n", lhs, rhs, lhs * rhs, res);
cprintf ("Press a key -- 'Q' to quit. ");
cursor (1);
C = toupper (cgetc ());
cclearxy (0, Y+3, Width);
cclearxy (0, Y+4, Width);
#ifdef CLOCKS_PER_SEC
/* Don't time the user's interaction. */
Ticks += clock () - Wait;
#endif
if (C == 'Q') {
goto Done;
}
}
if (kbhit () && toupper (cgetc ()) == 'Q') {
goto Done;
}
res += lhs;
} while (++rhs != 0);
} while (++lhs != 0);
Done:
#ifdef CLOCKS_PER_SEC
/* Calculate the time used */
Ticks = clock() - Ticks;
Milli = ((Ticks % CLOCKS_PER_SEC) * 1000) / CLOCKS_PER_SEC;
Sec = (unsigned) (Ticks / CLOCKS_PER_SEC);
Minu = Sec / 60;
Hours = Minu / 60;
Days = Hours / 24;
Hours %= 24;
Minu %= 60;
Sec %= 60;
/* Print the time used */
gotoxy (0, Y+3);
cprintf ("Time used:\r\n"
" %u days,\r\n"
" %u hours,\r\n"
" %u minutes,\r\n"
" %u.%03u seconds.\n", Days, Hours, Minu, Sec, Milli);
#endif
cprintf ("\rTap a key, to exit. ");
cgetc();
return 0;
}