some tests
[megadrive.git] / testpico / main.c
CommitLineData
ffd4b35c 1/*
2 * This software is released into the public domain.
3 * See UNLICENSE file in top level directory.
4 */
5#include <stdlib.h>
6#include <stdarg.h>
7
8#define u8 unsigned char
9#define u16 unsigned short
10#define u32 unsigned int
11
12#define noinline __attribute__((noinline))
13#define unused __attribute__((unused))
14#define _packed __attribute__((packed))
15
16#define mem_barrier() \
17 asm volatile("":::"memory")
18
19#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
20
21#include "asmtools.h"
22
23#define VDP_DATA_PORT 0xC00000
24#define VDP_CTRL_PORT 0xC00004
25
26#define TILE_MEM_END 0xB000
27
28#define FONT_LEN 128
29#define TILE_FONT_BASE (TILE_MEM_END / 32 - FONT_LEN)
30
31/* note: using ED menu's layout here.. */
32#define WPLANE (TILE_MEM_END + 0x0000)
33#define HSCRL (TILE_MEM_END + 0x0800)
34#define SLIST (TILE_MEM_END + 0x0C00)
35#define APLANE (TILE_MEM_END + 0x1000)
36#define BPLANE (TILE_MEM_END + 0x3000)
37
38#define read8(a) \
39 *((volatile u8 *) (a))
40#define read16(a) \
41 *((volatile u16 *) (a))
42#define read32(a) \
43 *((volatile u32 *) (a))
44#define write8(a, d) \
45 *((volatile u8 *) (a)) = (d)
46#define write16(a, d) \
47 *((volatile u16 *) (a)) = (d)
48#define write32(a, d) \
49 *((volatile u32 *) (a)) = (d)
50
51#define write16_z80le(a, d) \
52 ((volatile u8 *)(a))[0] = (u8)(d), \
53 ((volatile u8 *)(a))[1] = ((d) >> 8)
54
55static inline u16 read16_z80le(const void *a_)
56{
57 volatile const u8 *a = (volatile const u8 *)a_;
58 return a[0] | ((u16)a[1] << 8);
59}
60
61#define CTL_WRITE_VRAM(adr) \
62 (((0x4000 | ((adr) & 0x3FFF)) << 16) | ((adr) >> 14) | 0x00)
63#define CTL_WRITE_VSRAM(adr) \
64 (((0x4000 | ((adr) & 0x3FFF)) << 16) | ((adr) >> 14) | 0x10)
65#define CTL_WRITE_CRAM(adr) \
66 (((0xC000 | ((adr) & 0x3FFF)) << 16) | ((adr) >> 14) | 0x00)
67#define CTL_READ_VRAM(adr) \
68 (((0x0000 | ((adr) & 0x3FFF)) << 16) | ((adr) >> 14) | 0x00)
69#define CTL_READ_VSRAM(adr) \
70 (((0x0000 | ((adr) & 0x3FFF)) << 16) | ((adr) >> 14) | 0x10)
71#define CTL_READ_CRAM(adr) \
72 (((0x0000 | ((adr) & 0x3FFF)) << 16) | ((adr) >> 14) | 0x20)
73
74#define CTL_WRITE_DMA 0x80
75
76#define VDP_setReg(r, v) \
77 write16(VDP_CTRL_PORT, 0x8000 | ((r) << 8) | ((v) & 0xff))
78
79enum {
80 VDP_MODE1 = 0x00,
81 VDP_MODE2 = 0x01,
82 VDP_NT_SCROLLA = 0x02,
83 VDP_NT_WIN = 0x03,
84 VDP_NT_SCROLLB = 0x04,
85 VDP_SAT_BASE = 0x05,
86 VDP_BACKDROP = 0x07,
87 VDP_MODE3 = 0x0b,
88 VDP_MODE4 = 0x0c,
89 VDP_HSCROLL = 0x0d,
90 VDP_AUTOINC = 0x0f,
91 VDP_SCROLLSZ = 0x10,
92 VDP_DMA_LEN0 = 0x13,
93 VDP_DMA_LEN1 = 0x14,
94 VDP_DMA_SRC0 = 0x15,
95 VDP_DMA_SRC1 = 0x16,
96 VDP_DMA_SRC2 = 0x17,
97};
98
99#define VDP_MODE1_PS 0x04
100#define VDP_MODE1_IE1 0x10 // h int
101#define VDP_MODE2_MD 0x04
102#define VDP_MODE2_PAL 0x08 // 30 col
103#define VDP_MODE2_DMA 0x10
104#define VDP_MODE2_IE0 0x20 // v int
105#define VDP_MODE2_DISP 0x40
106
107/* cell counts */
108#define LEFT_BORDER 1 /* lame TV */
109#define PLANE_W 64
110#define PLANE_H 32
111#define CSCREEN_H 28
112
113/* data.s */
114extern const u32 font_base[];
115extern const u8 z80_test[];
116extern const u8 z80_test_end[];
117
118static int text_pal;
119
120static noinline void VDP_drawTextML(const char *str, u16 plane_base,
121 u16 x, u16 y)
122{
123 const u8 *src = (const u8 *)str;
124 u16 basetile = text_pal << 13;
125 int max_len = 40 - LEFT_BORDER;
126 int len;
127 u32 addr;
128
129 x += LEFT_BORDER;
130
131 for (len = 0; str[len] && len < max_len; len++)
132 ;
133 if (len > (PLANE_W - x))
134 len = PLANE_W - x;
135
136 addr = plane_base + ((x + (PLANE_W * y)) << 1);
137 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(addr));
138
139 while (len-- > 0) {
140 write16(VDP_DATA_PORT,
141 basetile | ((*src++) - 32 + TILE_FONT_BASE / 32));
142 }
143}
144
145static int printf_ypos;
146
147static void printf_line(int x, const char *buf)
148{
149 u32 addr;
150 int i;
151
152 VDP_drawTextML(buf, APLANE, x, printf_ypos++ & (PLANE_H - 1));
153
154 if (printf_ypos >= CSCREEN_H) {
155 /* clear next line */
156 addr = APLANE;
157 addr += (PLANE_W * (printf_ypos & (PLANE_H - 1))) << 1;
158 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(addr));
159 for (i = 0; i < 40 / 2; i++)
160 write32(VDP_DATA_PORT, 0);
161
162 /* scroll plane */
163 write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
164 write16(VDP_DATA_PORT, (printf_ypos - CSCREEN_H + 1) * 8);
165 }
166}
167
168#define PRINTF_LEN 40
169
170static int printf_xpos;
171
172static noinline int printf(const char *fmt, ...)
173{
174 static const char hexchars[] = "0123456789abcdef";
175 char c, buf[PRINTF_LEN + 11 + 1];
176 const char *s;
177 va_list ap;
178 int ival;
179 u32 uval;
180 int d = 0;
181 int i, j;
182
183 va_start(ap, fmt);
184 for (d = 0; *fmt; ) {
185 int prefix0 = 0;
186 int fwidth = 0;
187
188 c = *fmt++;
189 if (d < PRINTF_LEN)
190 buf[d] = c;
191
192 if (c != '%') {
193 if (c == '\n') {
194 buf[d] = 0;
195 printf_line(printf_xpos, buf);
196 d = 0;
197 printf_xpos = 0;
198 continue;
199 }
200 d++;
201 continue;
202 }
203 if (d >= PRINTF_LEN)
204 continue;
205
206 if (*fmt == '0') {
207 prefix0 = 1;
208 fmt++;
209 }
210
211 while ('1' <= *fmt && *fmt <= '9') {
212 fwidth = fwidth * 10 + *fmt - '0';
213 fmt++;
214 }
215
216 switch (*fmt++) {
217 case '%':
218 d++;
219 break;
220 case 'd':
221 case 'i':
222 ival = va_arg(ap, int);
223 if (ival < 0) {
224 buf[d++] = '-';
225 ival = -ival;
226 }
227 for (i = 1000000000; i >= 10; i /= 10)
228 if (ival >= i)
229 break;
230 for (; i >= 10; i /= 10) {
231 buf[d++] = '0' + ival / i;
232 ival %= i;
233 }
234 buf[d++] = '0' + ival;
235 break;
236 case 'x':
237 uval = va_arg(ap, int);
238 while (fwidth > 1 && uval < (1 << (fwidth - 1) * 4)) {
239 buf[d++] = prefix0 ? '0' : ' ';
240 fwidth--;
241 }
242 for (j = 1; j < 8 && uval >= (1 << j * 4); j++)
243 ;
244 for (j--; j >= 0; j--)
245 buf[d++] = hexchars[(uval >> j * 4) & 0x0f];
246 break;
247 case 's':
248 s = va_arg(ap, char *);
249 while (*s && d < PRINTF_LEN)
250 buf[d++] = *s++;
251 break;
252 default:
253 // don't handle, for now
254 d++;
255 va_arg(ap, void *);
256 break;
257 }
258 }
259 buf[d] = 0;
260 va_end(ap);
261
262 if (d != 0) {
263 // line without \n
264 VDP_drawTextML(buf, APLANE, printf_xpos,
265 printf_ypos & (PLANE_H - 1));
266 printf_xpos += d;
267 }
268
269 return d; // wrong..
270}
271
272static const char *exc_names[] = {
273 NULL,
274 NULL,
275 "Bus Error",
276 "Address Error",
277 "Illegal Instruction",
278 "Zero Divide",
279 "CHK Instruction",
280 "TRAPV Instruction",
281 "Privilege Violation", /* 8 8 */
282 "Trace",
283 "Line 1010 Emulator",
284 "Line 1111 Emulator",
285 NULL,
286 NULL,
287 NULL,
288 "Uninitialized Interrupt",
289 NULL, /* 10 16 */
290 NULL,
291 NULL,
292 NULL,
293 NULL,
294 NULL,
295 NULL,
296 NULL,
297 "Spurious Interrupt", /* 18 24 */
298 "l1 irq",
299 "l2 irq",
300 "l3 irq",
301 "l4 irq",
302 "l5 irq",
303 "l6 irq",
304 "l7 irq",
305};
306
307struct exc_frame {
308 u32 dr[8];
309 u32 ar[8];
310 u16 ecxnum; // from handler
311 union {
312 struct {
313 u16 sr;
314 u32 pc;
315 } g _packed;
316 struct {
317 u16 fc;
318 u32 addr;
319 u16 ir;
320 u16 sr;
321 u32 pc;
322 } bae _packed; // bus/address error frame
323 };
324} _packed;
325
326int xtttt(void) { return sizeof(struct exc_frame); }
327
328void exception(const struct exc_frame *f)
329{
330 int i;
331
332 while (read16(VDP_CTRL_PORT) & 2)
333 ;
334 VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
335 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DISP);
336 /* adjust scroll */
337 write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
338 write16(VDP_DATA_PORT,
339 printf_ypos >= CSCREEN_H ?
340 (printf_ypos - CSCREEN_H + 1) * 8 : 0);
341
342 printf("exception %i ", f->ecxnum);
343 if (f->ecxnum < ARRAY_SIZE(exc_names) && exc_names[f->ecxnum] != NULL)
344 printf("(%s)", exc_names[f->ecxnum]);
345 if (f->ecxnum < 4)
346 printf(" (%s)", (f->bae.fc & 0x10) ? "r" : "w");
347 printf(" \n");
348
349 if (f->ecxnum < 4) {
350 printf(" PC: %08x SR: %04x \n", f->bae.pc, f->bae.sr);
351 printf("addr: %08x IR: %04x FC: %02x \n",
352 f->bae.addr, f->bae.ir, f->bae.fc);
353 }
354 else {
355 printf(" PC: %08x SR: %04x \n", f->g.pc, f->g.sr);
356 }
357 for (i = 0; i < 8; i++)
358 printf(" D%d: %08x A%d: %08x \n", i, f->dr[i], i, f->ar[i]);
359 printf(" \n");
360}
361
362// ---
363
364static void setup_default_palette(void)
365{
366 write32(VDP_CTRL_PORT, CTL_WRITE_CRAM(0));
367 write32(VDP_DATA_PORT, 0);
368 write32(VDP_CTRL_PORT, CTL_WRITE_CRAM(15 * 2)); // font normal
369 write16(VDP_DATA_PORT, 0xeee);
370 write32(VDP_CTRL_PORT, CTL_WRITE_CRAM(31 * 2)); // green
371 write16(VDP_DATA_PORT, 0x0e0);
372 write32(VDP_CTRL_PORT, CTL_WRITE_CRAM(47 * 2)); // red
373 write16(VDP_DATA_PORT, 0x00e);
374}
375
376static void do_setup_dma(const void *src_, u16 words)
377{
378 u32 src = (u32)src_;
379 // VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA);
380 VDP_setReg(VDP_DMA_LEN0, words);
381 VDP_setReg(VDP_DMA_LEN1, words >> 8);
382 VDP_setReg(VDP_DMA_SRC0, src >> 1);
383 VDP_setReg(VDP_DMA_SRC1, src >> 9);
384 VDP_setReg(VDP_DMA_SRC2, src >> 17);
385 // write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(addr) | CTL_WRITE_DMA);
386}
387
388static void t_dma_zero_wrap_early(void)
389{
390 const u32 *src = (const u32 *)0x3c0000;
391 u32 *ram = (u32 *)0xff0000;
392
393 do_setup_dma(src + 4, 2);
394 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0) | CTL_WRITE_DMA);
395 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0) | CTL_WRITE_DMA);
396
397 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0));
398 ram[0] = read32(VDP_DATA_PORT);
399 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0xfffc));
400 ram[1] = read32(VDP_DATA_PORT);
401}
402
403static void t_dma_zero_fill_early(void)
404{
405 u32 *ram = (u32 *)0xff0000;
406
407 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0));
408 write32(VDP_DATA_PORT, 0);
409 write32(VDP_DATA_PORT, 0);
410 write32(VDP_DATA_PORT, 0);
411 write32(VDP_DATA_PORT, 0);
412
413 VDP_setReg(VDP_AUTOINC, 1);
414 VDP_setReg(VDP_DMA_SRC2, 0x80);
415 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(1) | CTL_WRITE_DMA);
416 write16(VDP_DATA_PORT, 0x1122);
417 ram[2] = read16(VDP_CTRL_PORT);
418 while (read16(VDP_CTRL_PORT) & 2)
419 ;
420
421 VDP_setReg(VDP_AUTOINC, 2);
422 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0));
423 ram[3] = read32(VDP_DATA_PORT);
424}
425
426#define expect(ok_, v0_, v1_) \
427if ((v0_) != (v1_)) { \
428 printf("%s: %08x %08x\n", #v0_, v0_, v1_); \
429 ok_ = 0; \
430}
431
432static int t_dma_zero_wrap(void)
433{
434 const u32 *src = (const u32 *)0x3c0000;
435 const u32 *ram = (const u32 *)0xff0000;
436 int ok = 1;
437
438 expect(ok, ram[0], src[5 + 0x10000/4]);
439 expect(ok, ram[1], src[4]);
440 return ok;
441}
442
443static int t_dma_zero_fill(void)
444{
445 const u32 *ram = (const u32 *)0xff0000;
446 u32 v0 = ram[2] & 2;
447 int ok = 1;
448
449 expect(ok, v0, 2);
450 expect(ok, ram[3], 0x11111111);
451 return ok;
452}
453
454static int t_dma_ram_wrap(void)
455{
456 u32 *ram = (u32 *)0xff0000;
457 u32 saved, v0, v1;
458 int ok = 1;
459
460 saved = read32(&ram[0x10000/4 - 1]);
461 ram[0x10000/4 - 1] = 0x01020304;
462 ram[0] = 0x05060708;
463 do_setup_dma(&ram[0x10000/4 - 1], 4);
464 mem_barrier();
465 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100) | CTL_WRITE_DMA);
466
467 mem_barrier();
468 write32(&ram[0x10000/4 - 1], saved);
469
470 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
471 v0 = read32(VDP_DATA_PORT);
472 v1 = read32(VDP_DATA_PORT);
473
474 expect(ok, v0, 0x01020304);
475 expect(ok, v1, 0x05060708);
476 return ok;
477}
478
479// test no src reprogram, only len0
480static int t_dma_multi(void)
481{
482 const u32 *src = (const u32 *)0x3c0000;
483 u32 v0, v1;
484 int ok = 1;
485
486 do_setup_dma(src, 2);
487 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100) | CTL_WRITE_DMA);
488 VDP_setReg(VDP_DMA_LEN0, 2);
489 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x104) | CTL_WRITE_DMA);
490
491 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
492 v0 = read32(VDP_DATA_PORT);
493 v1 = read32(VDP_DATA_PORT);
494
495 expect(ok, v0, src[0]);
496 expect(ok, v1, src[1]);
497 return ok;
498}
499
500static int t_dma_cram_wrap(void)
501{
502 u32 *ram = (u32 *)0xff0000;
503 u32 v0, v1;
504 int ok = 1;
505
506 write32(VDP_CTRL_PORT, CTL_WRITE_CRAM(0));
507 write32(VDP_DATA_PORT, 0);
508
509 ram[0] = 0x0ec20ec4;
510 ram[1] = 0x0ec60ec8;
511 mem_barrier();
512 do_setup_dma(ram, 4);
513 write32(VDP_CTRL_PORT, CTL_WRITE_CRAM(0x7c | 0xff81) | CTL_WRITE_DMA);
514
515 write32(VDP_CTRL_PORT, CTL_READ_CRAM(0x7c));
516 v0 = read32(VDP_DATA_PORT) & 0x0eee0eee;
517 write32(VDP_CTRL_PORT, CTL_READ_CRAM(0));
518 v1 = read32(VDP_DATA_PORT) & 0x0eee0eee;
519
520 setup_default_palette();
521
522 expect(ok, v0, ram[0]);
523 expect(ok, v1, ram[1]);
524 return ok;
525}
526
527static int t_dma_vsram_wrap(void)
528{
529 u32 *ram32 = (u32 *)0xff0000;
530 u16 *ram16 = (u16 *)0xff0000;
531 u32 v0, v1;
532 int ok = 1;
533 int i;
534
535 write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
536 write32(VDP_DATA_PORT, 0);
537
538 for (i = 0; i < 0x48/2; i++)
539 ram16[i] = i + 1;
540 mem_barrier();
541 do_setup_dma(ram16, 0x48/2);
542 write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0x3c | 0xff81) | CTL_WRITE_DMA);
543
544 write32(VDP_CTRL_PORT, CTL_READ_VSRAM(0x3c));
545 v0 = read32(VDP_DATA_PORT) & 0x03ff03ff;
546 write32(VDP_CTRL_PORT, CTL_READ_VSRAM(0));
547 v1 = read32(VDP_DATA_PORT) & 0x03ff03ff;
548
549 write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
550 write32(VDP_DATA_PORT, 0);
551
552 expect(ok, v0, ram32[0]);
553 expect(ok, v1, ram32[0x48/4 - 1]);
554 return ok;
555}
556
557static int t_dma_and_data(void)
558{
559 const u32 *src = (const u32 *)0x3c0000;
560 u32 v0;
561 int ok = 1;
562
563 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
564 write32(VDP_DATA_PORT, 0);
565
566 do_setup_dma(src, 2);
567 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0xfc) | CTL_WRITE_DMA);
568 write32(VDP_DATA_PORT, 0x5ec8a248);
569
570 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
571 v0 = read32(VDP_DATA_PORT);
572
573 expect(ok, v0, 0x5ec8a248);
574 return ok;
575}
576
577static int t_dma_fill3_odd(void)
578{
579 u32 v0, v1, v2;
580 int ok = 1;
581
582 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
583 write32(VDP_DATA_PORT, 0);
584 write32(VDP_DATA_PORT, 0);
585 write32(VDP_DATA_PORT, 0);
586
587 VDP_setReg(VDP_AUTOINC, 3);
588 VDP_setReg(VDP_DMA_LEN0, 3);
589 VDP_setReg(VDP_DMA_SRC2, 0x80);
590 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x101) | CTL_WRITE_DMA);
591 write16(VDP_DATA_PORT, 0x1122);
592 while (read16(VDP_CTRL_PORT) & 2)
593 ;
594
595 VDP_setReg(VDP_AUTOINC, 2);
596 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
597 v0 = read32(VDP_DATA_PORT);
598 v1 = read32(VDP_DATA_PORT);
599 v2 = read32(VDP_DATA_PORT);
600
601 expect(ok, v0, 0x22110000);
602 expect(ok, v1, 0x00111100);
603 expect(ok, v2, 0x00000011);
604 return ok;
605}
606
607static int t_dma_fill3_even(void)
608{
609 u32 v0, v1, v2;
610 int ok = 1;
611
612 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
613 write32(VDP_DATA_PORT, 0);
614 write32(VDP_DATA_PORT, 0);
615 write32(VDP_DATA_PORT, 0);
616
617 VDP_setReg(VDP_AUTOINC, 3);
618 VDP_setReg(VDP_DMA_LEN0, 3);
619 VDP_setReg(VDP_DMA_SRC2, 0x80);
620 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100) | CTL_WRITE_DMA);
621 write16(VDP_DATA_PORT, 0x1122);
622 while (read16(VDP_CTRL_PORT) & 2)
623 ;
624
625 VDP_setReg(VDP_AUTOINC, 2);
626 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
627 v0 = read32(VDP_DATA_PORT);
628 v1 = read32(VDP_DATA_PORT);
629 v2 = read32(VDP_DATA_PORT);
630
631 expect(ok, v0, 0x11221100);
632 expect(ok, v1, 0x00000011);
633 expect(ok, v2, 0x11000000);
634 return ok;
635}
636
637static unused int t_dma_fill3_vsram(void)
638{
639 u32 v0, v1, v2;
640 int ok = 1;
641
642 write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
643 write32(VDP_DATA_PORT, 0);
644 write32(VDP_DATA_PORT, 0);
645 write32(VDP_DATA_PORT, 0);
646
647 write16(VDP_DATA_PORT, 0x0111);
648 write16(VDP_DATA_PORT, 0x0222);
649 write16(VDP_DATA_PORT, 0x0333);
650
651 VDP_setReg(VDP_AUTOINC, 3);
652 VDP_setReg(VDP_DMA_LEN0, 3);
653 VDP_setReg(VDP_DMA_SRC2, 0x80);
654 write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(1) | CTL_WRITE_DMA);
655 write16(VDP_DATA_PORT, 0x0102);
656 while (read16(VDP_CTRL_PORT) & 2)
657 ;
658
659 VDP_setReg(VDP_AUTOINC, 2);
660 write32(VDP_CTRL_PORT, CTL_READ_VSRAM(0));
661 v0 = read32(VDP_DATA_PORT);
662 v1 = read32(VDP_DATA_PORT);
663 v2 = read32(VDP_DATA_PORT);
664
665 write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
666 write32(VDP_DATA_PORT, 0);
667
668 expect(ok, v0, 0x01020000);
669 expect(ok, v1, 0x01110111);
670 expect(ok, v2, 0x00000111);
671 return ok;
672}
673
674static int t_dma_fill_dis(void)
675{
676 u32 v0, v1;
677 int ok = 1;
678
679 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
680 write32(VDP_DATA_PORT, 0);
681 write32(VDP_DATA_PORT, 0);
682
683 VDP_setReg(VDP_DMA_LEN0, 1);
684 VDP_setReg(VDP_DMA_SRC2, 0x80);
685 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100) | CTL_WRITE_DMA);
686 VDP_setReg(VDP_MODE2, VDP_MODE2_MD);
687 write16(VDP_DATA_PORT, 0x1122);
688 while (read16(VDP_CTRL_PORT) & 2)
689 ;
690
691 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
692 write16(VDP_DATA_PORT, 0x3344);
693 while (read16(VDP_CTRL_PORT) & 2)
694 ;
695
696 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
697 v0 = read32(VDP_DATA_PORT);
698 v1 = read32(VDP_DATA_PORT);
699
700 expect(ok, v0, 0);
701 expect(ok, v1, 0);
702 return ok;
703}
704
705static int t_dma_fill_src(void)
706{
707 const u32 *src = (const u32 *)0x3c0000;
708 u32 v0, v1;
709 int ok = 1;
710
711 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
712 write32(VDP_DATA_PORT, 0);
713
714 // do_setup_dma(src, 2); // hang, can't write src2 twice
715 VDP_setReg(VDP_DMA_LEN0, 2);
716 VDP_setReg(VDP_DMA_SRC0, (u32)src >> 1);
717 VDP_setReg(VDP_DMA_SRC1, (u32)src >> 9);
718 VDP_setReg(VDP_DMA_SRC2, 0x80);
719 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100) | CTL_WRITE_DMA);
720 write16(VDP_DATA_PORT, 0x1122);
721 while (read16(VDP_CTRL_PORT) & 2)
722 ;
723
724 VDP_setReg(VDP_DMA_LEN0, 2);
725 VDP_setReg(VDP_DMA_SRC2, (u32)src >> 17);
726 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x104) | CTL_WRITE_DMA);
727
728 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
729 v0 = read32(VDP_DATA_PORT);
730 v1 = read32(VDP_DATA_PORT);
731
732 expect(ok, v0, 0x11220011);
733 expect(ok, v1, src[1]);
734 return ok;
735}
736
737/* z80 tests assume busreq state */
738static int t_z80mem_long_mirror(void)
739{
740 u8 *zram = (u8 *)0xa00000;
741 int ok = 1;
742
743 write8(&zram[0x1100], 0x11);
744 write8(&zram[0x1101], 0x22);
745 write8(&zram[0x1102], 0x33);
746 write8(&zram[0x1103], 0x44);
747 mem_barrier();
748 write32(&zram[0x3100], 0x55667788);
749 mem_barrier();
750
751 expect(ok, zram[0x1100], 0x55);
752 expect(ok, zram[0x1101], 0x22);
753 expect(ok, zram[0x1102], 0x77);
754 expect(ok, zram[0x1103], 0x44);
755 return ok;
756}
757
758static int t_z80mem_vdp_r(void)
759{
760 u8 *zram = (u8 *)0xa00000;
761 int ok = 1;
762
763 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
764 write32(VDP_DATA_PORT, 0x11223344);
765 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
766
767 zram[0x1000] = 1; // cp
768 zram[0x1001] = 2; // len
769 write16_z80le(&zram[0x1002], 0x7f00); // src
770 write16_z80le(&zram[0x1004], 0x1006); // dst
771 zram[0x1006] = zram[0x1007] = zram[0x1008] = 0x5a;
772 mem_barrier();
773 write16(0xa11100, 0x000);
774 burn10((98 + 40*2 + 27) * 15 / 7 * 2 / 10);
775
776 write16(0xa11100, 0x100);
777 while (read16(0xa11100) & 0x100)
778 ;
779
780 expect(ok, zram[0x1000], 0);
781 expect(ok, zram[0x1006], 0x11);
782 expect(ok, zram[0x1007], 0x44);
783 expect(ok, zram[0x1008], 0x5a);
784 return ok;
785}
786
787static unused int t_z80mem_vdp_w(void)
788{
789 u8 *zram = (u8 *)0xa00000;
790 u32 v0;
791 int ok = 1;
792
793 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
794 write32(VDP_DATA_PORT, 0x11223344);
795 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
796
797 zram[0x1000] = 1; // cp
798 zram[0x1001] = 2; // len
799 write16_z80le(&zram[0x1002], 0x1006); // src
800 write16_z80le(&zram[0x1004], 0x7f00); // dst
801 zram[0x1006] = 0x55;
802 zram[0x1007] = 0x66;
803 mem_barrier();
804 write16(0xa11100, 0x000);
805 burn10((98 + 40*2 + 27) * 15 / 7 * 2 / 10);
806
807 write16(0xa11100, 0x100);
808 while (read16(0xa11100) & 0x100)
809 ;
810
811 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
812 v0 = read32(VDP_DATA_PORT);
813
814 expect(ok, zram[0x1000], 0);
815 expect(ok, v0, 0x55556666);
816 return ok;
817}
818
819static const struct {
820 int (*test)(void);
821 const char *name;
822} g_tests[] = {
823 { t_dma_zero_wrap, "dma zero len + wrap" },
824 { t_dma_zero_fill, "dma zero len + fill" },
825 { t_dma_ram_wrap, "dma ram wrap" },
826 { t_dma_multi, "dma multi" },
827 { t_dma_cram_wrap, "dma cram wrap" },
828 { t_dma_vsram_wrap, "dma vsram wrap" },
829 { t_dma_and_data, "dma and data" },
830 { t_dma_fill3_odd, "dma fill3 odd" },
831 { t_dma_fill3_even, "dma fill3 even" },
832 // { t_dma_fill3_vsram, "dma fill3 vsram" }, // later
833 { t_dma_fill_dis, "dma fill disabled" },
834 { t_dma_fill_src, "dma fill src incr" },
835 { t_z80mem_long_mirror, "z80 ram long mirror" },
836 { t_z80mem_vdp_r, "z80 vdp read" },
837 // { t_z80mem_vdp_w, "z80 vdp write" }, // hang
838};
839
840static void setup_z80(void)
841{
842 u8 *zram = (u8 *)0xa00000;
843 int i, len;
844
845 /* z80 */
846 write16(0xa11100, 0x100);
847 write16(0xa11200, 0x100);
848
849 while (read16(0xa11100) & 0x100)
850 ;
851
852 // load the default test program, clear it's data
853 len = z80_test_end - z80_test;
854 for (i = 0; i < len; i++)
855 write8(&zram[i], z80_test[i]);
856 for (i = 0x1000; i < 0x1007; i++)
857 write8(&zram[i], 0);
858}
859
860int main()
861{
862 int passed = 0;
863 int ret;
864 int i;
865
866 setup_z80();
867
868 /* setup VDP */
869 while (read16(VDP_CTRL_PORT) & 2)
870 ;
871
872 VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
873 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA);
874 VDP_setReg(VDP_MODE3, 0x00);
875 VDP_setReg(VDP_MODE4, 0x81);
876 VDP_setReg(VDP_NT_SCROLLA, APLANE >> 10);
877 VDP_setReg(VDP_NT_SCROLLB, BPLANE >> 13);
878 VDP_setReg(VDP_SAT_BASE, SLIST >> 9);
879 VDP_setReg(VDP_HSCROLL, HSCRL >> 10);
880 VDP_setReg(VDP_AUTOINC, 2);
881 VDP_setReg(VDP_SCROLLSZ, 0x01);
882 VDP_setReg(VDP_BACKDROP, 0);
883
884 // early tests
885 t_dma_zero_wrap_early();
886 t_dma_zero_fill_early();
887
888 /* pattern 0 */
889 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0));
890 for (i = 0; i < 32 / 4; i++)
891 write32(VDP_DATA_PORT, 0);
892
893 /* clear name tables */
894 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(APLANE));
895 for (i = 0; i < PLANE_W * PLANE_H / 2; i++)
896 write32(VDP_DATA_PORT, 0);
897
898 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(BPLANE));
899 for (i = 0; i < PLANE_W * PLANE_H / 2; i++)
900 write32(VDP_DATA_PORT, 0);
901
902 /* SAT, h. scroll */
903 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(SLIST));
904 write32(VDP_DATA_PORT, 0);
905
906 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(HSCRL));
907 write32(VDP_DATA_PORT, 0);
908
909 /* scroll plane vscroll */
910 write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
911 write32(VDP_DATA_PORT, 0);
912 printf_ypos = 1;
913
914 /* load font */
915 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(TILE_FONT_BASE));
916 for (i = 0; i < FONT_LEN * 32 / 4; i++)
917 write32(VDP_DATA_PORT, font_base[i]);
918
919 /* set colors */
920 setup_default_palette();
921
922 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
923
924 printf("\n");
925 printf("MD version: %02x\n", read8(0xa10001));
926
927 for (i = 0; i < ARRAY_SIZE(g_tests); i++) {
928 // print test number if we haven't scrolled away
929 if (printf_ypos < CSCREEN_H) {
930 int old_ypos = printf_ypos;
931 printf_ypos = 0;
932 text_pal = 0;
933 printf("%02d/%02d", i, ARRAY_SIZE(g_tests));
934 printf_ypos = old_ypos;
935 printf_xpos = 0;
936 }
937 text_pal = 2;
938 ret = g_tests[i].test();
939 if (ret != 1)
940 printf("failed %d: %s\n", i, g_tests[i].name);
941 else
942 passed++;
943 }
944
945 text_pal = 0;
946 printf("%d/%d passed.\n", passed, ARRAY_SIZE(g_tests));
947
948 printf_ypos = 0;
949 printf(" ");
950
951 for (;;)
952 ;
953
954 return 0;
955}
956
957// vim:ts=4:sw=4:expandtab