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