mirror of
https://github.com/cc65/cc65.git
synced 2024-12-23 04:30:10 +00:00
311 lines
7.7 KiB
C
311 lines
7.7 KiB
C
/* Test that the cpeek...() functions are the inverses of cputc(),
|
|
** revers(), and textcolor() for the full range of character codes.
|
|
**
|
|
** 2017-07-15, Greg King
|
|
** 2017-12-12, Groepaz
|
|
*/
|
|
|
|
#include <conio.h>
|
|
#include <cc65.h>
|
|
|
|
/* Standard location of the screen */
|
|
|
|
#if defined(__C128__) || defined(__C64__)
|
|
/* only 40-column screen */
|
|
# define SCREEN_RAM ((unsigned char*)0x0400)
|
|
#elif defined(__C16__) /* Plus4 also */
|
|
# define SCREEN_RAM ((unsigned char*)0x0C00)
|
|
#elif defined(__CBM510__)
|
|
# define SCREEN_RAM ((unsigned char*)0xF000)
|
|
# define COLOR_RAM ((unsigned char*)0xd400)
|
|
#elif defined(__CBM610__)
|
|
# define SCREEN_RAM ((unsigned char*)0xD000)
|
|
#elif defined(__PET__)
|
|
# define SCREEN_RAM ((unsigned char*)0x8000)
|
|
#elif defined(__VIC20__)
|
|
# define SCREEN_RAM ((unsigned char*)0x1000)
|
|
#else
|
|
# error This program cannot test that target.
|
|
# define SCREEN_RAM ((unsigned char*)0)
|
|
#endif
|
|
|
|
static unsigned char width;
|
|
|
|
|
|
/* Move the cursor backward one char with
|
|
** the recognition of a row change.
|
|
*/
|
|
static void chBack (void)
|
|
{
|
|
unsigned char y = wherey ();
|
|
unsigned char x = wherex ();
|
|
|
|
if (x == 0) {
|
|
x = width;
|
|
--y;
|
|
}
|
|
--x;
|
|
|
|
gotoxy (x, y);
|
|
}
|
|
|
|
|
|
/* Move the cursor forward one char with
|
|
** the recognition of a row change.
|
|
*/
|
|
static void chForth (void)
|
|
{
|
|
unsigned char y = wherey ();
|
|
unsigned char x = wherex ();
|
|
|
|
if (++x >= width) {
|
|
x = 0;
|
|
++y;
|
|
}
|
|
|
|
gotoxy (x, y);
|
|
}
|
|
|
|
|
|
/* A hack to get an unmodified byte from the
|
|
** screen memory at the current cursor position.
|
|
*/
|
|
static unsigned char peekChWithoutTranslation (void)
|
|
{
|
|
#if defined(__CBM610__)
|
|
return peekbsys ((unsigned)&SCREEN_RAM[wherey () * width + wherex ()]);
|
|
#else
|
|
return SCREEN_RAM[wherey () * width + wherex ()];
|
|
#endif
|
|
}
|
|
|
|
/* as above, but for color ram */
|
|
static unsigned char peekColWithoutTranslation (void)
|
|
{
|
|
#if defined(__CBM610__) || defined (__PET__)
|
|
return COLOR_WHITE;
|
|
#elif defined(__C128__) || defined(__C64__) || defined(__VIC20__) || defined(__CBM510__)
|
|
return COLOR_RAM[wherey () * width + wherex ()] & 0x0f;
|
|
#else
|
|
return COLOR_RAM[wherey () * width + wherex ()];
|
|
#endif
|
|
}
|
|
|
|
|
|
/* A test which outputs the given char, reads it back from
|
|
** screen memory, outputs the returned char at the next position,
|
|
** then compares the two screen memory bytes for identity.
|
|
**
|
|
** Note: cpeekc() must be tested indirectly because some platforms "fold" their
|
|
** character code-set into a smaller screen code-set. Therefore, cpeekc() might
|
|
** return an equivalent, but not equal, character to the one that was cputc().
|
|
*/
|
|
static unsigned char testCPeekC (char ch)
|
|
{
|
|
unsigned char ch2_a, ch2_b, ch2_c;
|
|
|
|
/* Test the given char-code, but not the
|
|
** special characters NEWLINE and RETURN
|
|
** (they don't put anything on the screen).
|
|
*/
|
|
if (('\n' == ch) || ('\r' == ch)
|
|
) {
|
|
return 1;
|
|
}
|
|
|
|
/* toggle revers mode every few chars so cpeekc gets tested for both */
|
|
revers ((ch >> 3) & 1);
|
|
|
|
/* output additional space every now and then, that way not only even or only
|
|
odd half of the character cell will be tested */
|
|
#if defined(__C64__)
|
|
if ((width == 80) && ((ch % 17) == 0)) {
|
|
cputc(' ');
|
|
}
|
|
#endif
|
|
|
|
/* Output the char to the screen. */
|
|
cputc (ch);
|
|
|
|
/* Move the cursor pos. to the previous output. */
|
|
chBack ();
|
|
|
|
/* Get back the written char without any translation. */
|
|
ch2_b = peekChWithoutTranslation ();
|
|
|
|
/* Get back the written char,
|
|
** including the translation, screen-code -> text.
|
|
*/
|
|
ch2_a = cpeekc ();
|
|
|
|
/* Move the cursor to the following writing position. */
|
|
chForth ();
|
|
|
|
/* Output again the char which was read back by cpeekc(). */
|
|
cputc (ch2_a);
|
|
|
|
/* Move the cursor pos. to the second output. */
|
|
chBack ();
|
|
|
|
/* Get back the second written char without any translation;
|
|
** and, compare it to the first untranslated char.
|
|
*/
|
|
ch2_c = peekChWithoutTranslation ();
|
|
if ((ch2_c != ch2_b)
|
|
#if defined(__C128__) || defined(__C64__)
|
|
/* VDC memory is not accessible, soft80 has no "videoram" */
|
|
&& (width == 40)
|
|
#endif
|
|
){
|
|
/* The test was NOT succesful.
|
|
** Output a diagnostic; and, return FAILURE.
|
|
*/
|
|
revers(0);
|
|
cprintf ("\r\nError on char: %#x was %#x instead.", ch, ch2_a);
|
|
cprintf ("\r\nRaw screen codes: %#x, %#x.", ch2_b, ch2_c);
|
|
cprintf ("\r\nscreen width: %#d", width);
|
|
return 0;
|
|
}
|
|
|
|
/* The test was succesful.
|
|
** Move the cursor to the following writing position.
|
|
*/
|
|
chForth ();
|
|
return 1;
|
|
}
|
|
|
|
static unsigned char testCPeekCol (char ch)
|
|
{
|
|
unsigned char ch2_a, ch2_b, ch2_c;
|
|
|
|
/* Output the char to the screen. */
|
|
textcolor (ch);
|
|
cputc ('*');
|
|
|
|
/* Move the cursor pos. to the previous output. */
|
|
chBack ();
|
|
|
|
/* Get back the written char without any translation. */
|
|
ch2_b = peekColWithoutTranslation ();
|
|
|
|
/* Get back the written char,
|
|
** including the translation, screen-code -> text.
|
|
*/
|
|
ch2_a = cpeekcolor ();
|
|
|
|
/* Move the cursor to the following writing position. */
|
|
chForth ();
|
|
|
|
/* Output again the char which was read back by cpeekc(). */
|
|
textcolor (ch2_a);
|
|
cputc ('x');
|
|
|
|
/* Move the cursor pos. to the second output. */
|
|
chBack ();
|
|
|
|
/* Get back the second written char without any translation;
|
|
** and, compare it to the first untranslated char.
|
|
*/
|
|
ch2_c = peekColWithoutTranslation ();
|
|
if ((ch2_c != ch2_b)
|
|
#if defined(__C128__)
|
|
/* VDC memory is not accessible */
|
|
&& (width == 40)
|
|
#endif
|
|
){
|
|
/* The test was NOT succesful.
|
|
** Output a diagnostic; and, return FAILURE.
|
|
*/
|
|
revers(0);
|
|
cprintf ("\r\nError on color: %#x was %#x instead.", ch, ch2_a);
|
|
cprintf ("\r\nRaw color codes: %#x, %#x.", ch2_b, ch2_c);
|
|
return 0;
|
|
}
|
|
|
|
/* The test was succesful.
|
|
** Move the cursor to the following writing position.
|
|
*/
|
|
chForth ();
|
|
return 1;
|
|
}
|
|
|
|
/* The main code initiates the screen for the tests, and sets the reverse flag.
|
|
** Then, it calls testCPeekC() for every char within 0..255.
|
|
** Then, it calls testCPeekCol() for each color
|
|
** Returns zero for success, one for failure.
|
|
*/
|
|
int main (void)
|
|
{
|
|
unsigned char i, c1, c2;
|
|
char s[10];
|
|
int ret = 0;
|
|
|
|
clrscr ();
|
|
revers (0);
|
|
textcolor(1);
|
|
bgcolor(0);
|
|
screensize (&width, &i);
|
|
|
|
#if defined(__VIC20__)
|
|
/* The VIC-20's screen is too small to hold the full test. */
|
|
i = 2;
|
|
#else
|
|
i = 0;
|
|
#endif
|
|
do {
|
|
if (!testCPeekC (i)) {
|
|
ret = 1;
|
|
goto exiterror;
|
|
}
|
|
} while (++i != 0); /* will wrap around when finished */
|
|
|
|
#if defined(__VIC20__)
|
|
cgetc();
|
|
#endif
|
|
|
|
/* test colors */
|
|
#if defined(__VIC20__)
|
|
clrscr ();
|
|
#endif
|
|
revers (0);
|
|
textcolor(1);
|
|
|
|
#if defined (__CBM610__) || defined (__PET__)
|
|
cprintf("\n\rno COLOR_RAM\n\r");
|
|
#elif defined (__C128__) || defined (__C64__)
|
|
if (width == 40) {
|
|
cprintf("\n\rCOLOR_RAM at $%04x\n\r", COLOR_RAM);
|
|
} else {
|
|
cprintf("\n\rno COLOR_RAM\n\r");
|
|
}
|
|
#else
|
|
cprintf("\n\rCOLOR_RAM at $%04x\n\r", COLOR_RAM);
|
|
#endif
|
|
|
|
do {
|
|
if (!testCPeekCol (i)) {
|
|
ret = 1;
|
|
goto exiterror;
|
|
}
|
|
} while (++i != 16); /* max 16 colors */
|
|
|
|
/* test revers */
|
|
textcolor(1); cputc('\n'); cputc('\r');
|
|
revers(0); cputc('x'); chBack (); c1 = cpeekrevers(); chForth();
|
|
revers(1); cputc('X'); chBack (); c2 = cpeekrevers(); chForth();
|
|
cputc('\n'); cputc('\r');
|
|
revers(c1); cputc('o');
|
|
revers(c2); cputc('O');
|
|
|
|
/* test cpeeks() */
|
|
revers(0);
|
|
cprintf("\n\rtest1234"); gotox(0); cpeeks(s, 8); cputs("\n");
|
|
cputs(s);
|
|
|
|
exiterror:
|
|
if (doesclrscrafterexit()) {
|
|
cgetc();
|
|
}
|
|
return ret;
|
|
}
|