]> git.sur5r.net Git - cc65/blob - testcode/lib/cpeek-test.c
5f3bfc524821f38433818d0413da47edd38ad6df
[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     /* Output the char to the screen. */
117     cputc (ch);
118
119     /* Move the cursor pos. to the previous output. */
120     chBack ();
121
122     /* Get back the written char without any translation. */
123     ch2_b = peekChWithoutTranslation ();
124
125     /* Get back the written char,
126     ** including the translation, screen-code -> text.
127     */
128     ch2_a = cpeekc ();
129
130     /* Move the cursor to the following writing position. */
131     chForth ();
132
133     /* Output again the char which was read back by cpeekc(). */
134     cputc (ch2_a);
135
136     /* Move the cursor pos. to the second output. */
137     chBack ();
138
139     /* Get back the second written char without any translation;
140     ** and, compare it to the first untranslated char.
141     */
142     ch2_c = peekChWithoutTranslation ();
143     if ((ch2_c != ch2_b)
144 #if defined(__C128__)
145         /* VDC memory is not accessable */
146         && (width == 40)
147 #endif
148         ){
149         /* The test was NOT succesful.
150         ** Output a diagnostic; and, return FAILURE.
151         */
152         revers(0);
153         cprintf ("\r\nError on char: %#x was %#x instead.", ch, ch2_a);
154         cprintf ("\r\nRaw screen codes: %#x, %#x.", ch2_b, ch2_c);
155         cprintf ("\r\nscreen width: %#d", width);
156         return 0;
157     }
158
159     /* The test was succesful.
160     ** Move the cursor to the following writing position.
161     */
162     chForth ();
163     return 1;
164 }
165
166 static unsigned char testCPeekCol (char ch)
167 {
168     unsigned char ch2_a, ch2_b, ch2_c;
169
170     /* Output the char to the screen. */
171     textcolor (ch);
172     cputc ('*');
173
174     /* Move the cursor pos. to the previous output. */
175     chBack ();
176
177     /* Get back the written char without any translation. */
178     ch2_b = peekColWithoutTranslation ();
179
180     /* Get back the written char,
181     ** including the translation, screen-code -> text.
182     */
183     ch2_a = cpeekcolor ();
184
185     /* Move the cursor to the following writing position. */
186     chForth ();
187
188     /* Output again the char which was read back by cpeekc(). */
189     textcolor (ch2_a);
190     cputc ('x');
191
192     /* Move the cursor pos. to the second output. */
193     chBack ();
194
195     /* Get back the second written char without any translation;
196     ** and, compare it to the first untranslated char.
197     */
198     ch2_c = peekColWithoutTranslation ();
199     if ((ch2_c != ch2_b)
200 #if defined(__C128__)
201         /* VDC memory is not accessable */
202         && (width == 40)
203 #endif
204         ){
205         /* The test was NOT succesful.
206         ** Output a diagnostic; and, return FAILURE.
207         */
208         revers(0);
209         cprintf ("\r\nError on color: %#x was %#x instead.", ch, ch2_a);
210         cprintf ("\r\nRaw color codes: %#x, %#x.", ch2_b, ch2_c);
211         return 0;
212     }
213
214     /* The test was succesful.
215     ** Move the cursor to the following writing position.
216     */
217     chForth ();
218     return 1;
219 }
220
221 /* The main code initiates the screen for the tests, and sets the reverse flag.
222 ** Then, it calls testCPeekC() for every char within 0..255.
223 ** Then, it calls testCPeekCol() for each color
224 ** Returns zero for success, one for failure.
225 */
226 int main (void)
227 {
228     unsigned char i, c1, c2;
229     char s[10];
230     int ret = 0;
231
232     clrscr ();
233     revers (1);
234     textcolor(1);
235     bgcolor(0);
236     screensize (&width, &i);
237
238 #if defined(__VIC20__)
239     /* The VIC-20's screen is too small to hold the full test. */
240     i = 2;
241 #else
242     i = 0;
243 #endif
244     do {
245         if (!testCPeekC (i)) {
246             ret = 1;
247             goto exiterror;
248         }
249     } while (++i != 0);         /* will wrap around when finished */
250
251 #if defined(__VIC20__)
252     cgetc();
253 #endif
254
255     /* test colors */
256 #if defined(__VIC20__)
257     clrscr ();
258 #endif
259     revers (0);
260     textcolor(1);
261
262 #if defined (__CBM610__) || defined (__PET__)
263     cprintf("\n\rno COLOR_RAM\n\r");
264 #elif defined (__C128__)
265     if (width == 40) {
266         cprintf("\n\rCOLOR_RAM at $%04x\n\r", COLOR_RAM);
267     } else {
268         cprintf("\n\rno COLOR_RAM\n\r");
269     }
270 #else
271     cprintf("\n\rCOLOR_RAM at $%04x\n\r", COLOR_RAM);
272 #endif
273
274     do {
275         if (!testCPeekCol (i)) {
276             ret = 1;
277             goto exiterror;
278         }
279     } while (++i != 16);        /* max 16 colors */
280
281     /* test revers */
282     textcolor(1); cputc('\n'); cputc('\r');
283     revers(0); cputc('x'); chBack (); c1 = cpeekrevers(); chForth();
284     revers(1); cputc('X'); chBack (); c2 = cpeekrevers(); chForth();
285     cputc('\n'); cputc('\r');
286     revers(c1); cputc('o'); 
287     revers(c2); cputc('O'); 
288
289     /* test cpeeks() */
290     revers(0);
291     cprintf("\n\rtest1234"); gotox(0); cpeeks(s, 8); cputs("\n");
292     cputs(s);
293
294 exiterror:
295     if (doesclrscrafterexit()) {
296         cgetc();
297     }
298     return ret;
299 }