/* 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 #include /* 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; }