]> git.sur5r.net Git - cc65/blob - testcode/lib/cpeek-test.c
Add translation from PETSCII to screen codes.
[cc65] / testcode / lib / cpeek-test.c
1 /* Test that the cpeek...() functions are the inverses of cputc(),
2 ** revers(), and textcolor() for the full range of character codes.
3 **
4 ** 2017-07-15, Greg King
5 ** 2017-12-12, Groepaz
6 */
7
8 #include <conio.h>
9 #include <cc65.h>
10
11 /* Standard location of the screen */
12
13 #if defined(__C128__) || defined(__C64__)
14 /* only 40-column screen */
15 #  define SCREEN_RAM ((unsigned char*)0x0400)
16 #elif defined(__C16__)                  /* Plus4 also */
17 #  define SCREEN_RAM ((unsigned char*)0x0C00)
18 #elif defined(__CBM510__)
19 #  define SCREEN_RAM ((unsigned char*)0xF000)
20 #  define COLOR_RAM ((unsigned char*)0xd400)
21 #elif defined(__CBM610__)
22 #  define SCREEN_RAM ((unsigned char*)0xD000)
23 #elif defined(__PET__)
24 #  define SCREEN_RAM ((unsigned char*)0x8000)
25 #elif defined(__VIC20__)
26 #  define SCREEN_RAM ((unsigned char*)0x1000)
27 #else
28 #  error This program cannot test that target.
29 #  define SCREEN_RAM ((unsigned char*)0)
30 #endif
31
32 static unsigned char width;
33
34
35 /* Move the cursor backward one char with
36 ** the recognition of a row change.
37 */
38 static void chBack (void)
39 {
40     unsigned char y = wherey ();
41     unsigned char x = wherex ();
42
43     if (x == 0) {
44         x = width;
45         --y;
46     }
47     --x;
48
49     gotoxy (x, y);
50 }
51
52
53 /* Move the cursor forward one char with
54 ** the recognition of a row change.
55 */
56 static void chForth (void)
57 {
58     unsigned char y = wherey ();
59     unsigned char x = wherex ();
60
61     if (++x >= width) {
62         x = 0;
63         ++y;
64     }
65
66     gotoxy (x, y);
67 }
68
69
70 /* A hack to get an unmodified byte from the
71 ** screen memory at the current cursor position.
72 */
73 static unsigned char peekChWithoutTranslation (void)
74 {
75 #if defined(__CBM610__)
76     return peekbsys ((unsigned)&SCREEN_RAM[wherey () * width + wherex ()]);
77 #else
78     return SCREEN_RAM[wherey () * width + wherex ()];
79 #endif
80 }
81
82 /* as above, but for color ram */
83 static unsigned char peekColWithoutTranslation (void)
84 {
85 #if defined(__CBM610__) || defined (__PET__)
86     return COLOR_WHITE;
87 #elif defined(__C128__) || defined(__C64__) || defined(__VIC20__) || defined(__CBM510__)
88     return COLOR_RAM[wherey () * width + wherex ()] & 0x0f;
89 #else
90     return COLOR_RAM[wherey () * width + wherex ()];
91 #endif
92 }
93
94
95 /* A test which outputs the given char, reads it back from
96 ** screen memory, outputs the returned char at the next position,
97 ** then compares the two screen memory bytes for identity.
98 **
99 ** Note:  cpeekc() must be tested indirectly because some platforms "fold" their
100 ** character code-set into a smaller screen code-set.  Therefore, cpeekc() might
101 ** return an equivalent, but not equal, character to the one that was cputc().
102 */
103 static unsigned char testCPeekC (char ch)
104 {
105     unsigned char ch2_a, ch2_b, ch2_c;
106
107     /* Test the given char-code, but not the
108     ** special characters NEWLINE and RETURN
109     ** (they don't put anything on the screen).
110     */
111     if (('\n' == ch) || ('\r' == ch)
112         ) {
113         return 1;
114     }
115
116     /* toggle revers mode every few chars so cpeekc gets tested for both */
117     revers ((ch >> 3) & 1);
118
119     /* output additional space every now and then, that way not only even or only
120        odd half of the character cell will be tested */
121 #if defined(__C64__)
122     if ((width == 80) && ((ch % 17) == 0)) {
123         cputc(' ');
124     }
125 #endif
126
127     /* Output the char to the screen. */
128     cputc (ch);
129
130     /* Move the cursor pos. to the previous output. */
131     chBack ();
132
133     /* Get back the written char without any translation. */
134     ch2_b = peekChWithoutTranslation ();
135
136     /* Get back the written char,
137     ** including the translation, screen-code -> text.
138     */
139     ch2_a = cpeekc ();
140
141     /* Move the cursor to the following writing position. */
142     chForth ();
143
144     /* Output again the char which was read back by cpeekc(). */
145     cputc (ch2_a);
146
147     /* Move the cursor pos. to the second output. */
148     chBack ();
149
150     /* Get back the second written char without any translation;
151     ** and, compare it to the first untranslated char.
152     */
153     ch2_c = peekChWithoutTranslation ();
154     if ((ch2_c != ch2_b)
155 #if defined(__C128__) || defined(__C64__)
156         /* VDC memory is not accessible, soft80 has no "videoram" */
157         && (width == 40)
158 #endif
159         ){
160         /* The test was NOT succesful.
161         ** Output a diagnostic; and, return FAILURE.
162         */
163         revers(0);
164         cprintf ("\r\nError on char: %#x was %#x instead.", ch, ch2_a);
165         cprintf ("\r\nRaw screen codes: %#x, %#x.", ch2_b, ch2_c);
166         cprintf ("\r\nscreen width: %#d", width);
167         return 0;
168     }
169
170     /* The test was succesful.
171     ** Move the cursor to the following writing position.
172     */
173     chForth ();
174     return 1;
175 }
176
177 static unsigned char testCPeekCol (char ch)
178 {
179     unsigned char ch2_a, ch2_b, ch2_c;
180
181     /* Output the char to the screen. */
182     textcolor (ch);
183     cputc ('*');
184
185     /* Move the cursor pos. to the previous output. */
186     chBack ();
187
188     /* Get back the written char without any translation. */
189     ch2_b = peekColWithoutTranslation ();
190
191     /* Get back the written char,
192     ** including the translation, screen-code -> text.
193     */
194     ch2_a = cpeekcolor ();
195
196     /* Move the cursor to the following writing position. */
197     chForth ();
198
199     /* Output again the char which was read back by cpeekc(). */
200     textcolor (ch2_a);
201     cputc ('x');
202
203     /* Move the cursor pos. to the second output. */
204     chBack ();
205
206     /* Get back the second written char without any translation;
207     ** and, compare it to the first untranslated char.
208     */
209     ch2_c = peekColWithoutTranslation ();
210     if ((ch2_c != ch2_b)
211 #if defined(__C128__)
212         /* VDC memory is not accessible */
213         && (width == 40)
214 #endif
215         ){
216         /* The test was NOT succesful.
217         ** Output a diagnostic; and, return FAILURE.
218         */
219         revers(0);
220         cprintf ("\r\nError on color: %#x was %#x instead.", ch, ch2_a);
221         cprintf ("\r\nRaw color codes: %#x, %#x.", ch2_b, ch2_c);
222         return 0;
223     }
224
225     /* The test was succesful.
226     ** Move the cursor to the following writing position.
227     */
228     chForth ();
229     return 1;
230 }
231
232 /* The main code initiates the screen for the tests, and sets the reverse flag.
233 ** Then, it calls testCPeekC() for every char within 0..255.
234 ** Then, it calls testCPeekCol() for each color
235 ** Returns zero for success, one for failure.
236 */
237 int main (void)
238 {
239     unsigned char i, c1, c2;
240     char s[10];
241     int ret = 0;
242
243     clrscr ();
244     revers (0);
245     textcolor(1);
246     bgcolor(0);
247     screensize (&width, &i);
248
249 #if defined(__VIC20__)
250     /* The VIC-20's screen is too small to hold the full test. */
251     i = 2;
252 #else
253     i = 0;
254 #endif
255     do {
256         if (!testCPeekC (i)) {
257             ret = 1;
258             goto exiterror;
259         }
260     } while (++i != 0);         /* will wrap around when finished */
261
262 #if defined(__VIC20__)
263     cgetc();
264 #endif
265
266     /* test colors */
267 #if defined(__VIC20__)
268     clrscr ();
269 #endif
270     revers (0);
271     textcolor(1);
272
273 #if defined (__CBM610__) || defined (__PET__)
274     cprintf("\n\rno COLOR_RAM\n\r");
275 #elif defined (__C128__) || defined (__C64__)
276     if (width == 40) {
277         cprintf("\n\rCOLOR_RAM at $%04x\n\r", COLOR_RAM);
278     } else {
279         cprintf("\n\rno COLOR_RAM\n\r");
280     }
281 #else
282     cprintf("\n\rCOLOR_RAM at $%04x\n\r", COLOR_RAM);
283 #endif
284
285     do {
286         if (!testCPeekCol (i)) {
287             ret = 1;
288             goto exiterror;
289         }
290     } while (++i != 16);        /* max 16 colors */
291
292     /* test revers */
293     textcolor(1); cputc('\n'); cputc('\r');
294     revers(0); cputc('x'); chBack (); c1 = cpeekrevers(); chForth();
295     revers(1); cputc('X'); chBack (); c2 = cpeekrevers(); chForth();
296     cputc('\n'); cputc('\r');
297     revers(c1); cputc('o'); 
298     revers(c2); cputc('O'); 
299
300     /* test cpeeks() */
301     revers(0);
302     cprintf("\n\rtest1234"); gotox(0); cpeeks(s, 8); cputs("\n");
303     cputs(s);
304
305 exiterror:
306     if (doesclrscrafterexit()) {
307         cgetc();
308     }
309     return ret;
310 }