29fee321e0f707e79b000976a77ec318ac24a76a
[megadrive.git] / testpico / main.c
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 #include "common.h"
8 #include "asmtools.h"
9
10 #define VDP_DATA_PORT    0xC00000
11 #define VDP_CTRL_PORT    0xC00004
12 #define VDP_HV_COUNTER   0xC00008
13
14 #define TILE_MEM_END     0xB000
15
16 #define FONT_LEN         128
17 #define TILE_FONT_BASE   (TILE_MEM_END - FONT_LEN * 32)
18
19 /* note: using ED menu's layout here.. */
20 #define WPLANE           (TILE_MEM_END + 0x0000)
21 #define HSCRL            (TILE_MEM_END + 0x0800)
22 #define SLIST            (TILE_MEM_END + 0x0C00)
23 #define APLANE           (TILE_MEM_END + 0x1000)
24 #define BPLANE           (TILE_MEM_END + 0x3000)
25
26 #define write16_z80le(a, d) \
27     ((volatile u8 *)(a))[0] = (u8)(d), \
28     ((volatile u8 *)(a))[1] = ((d) >> 8)
29
30 static inline u16 read16_z80le(const void *a_)
31 {
32     volatile const u8 *a = (volatile const u8 *)a_;
33     return a[0] | ((u16)a[1] << 8);
34 }
35
36 #define CTL_WRITE_VRAM(adr) \
37     (((0x4000 | ((adr) & 0x3FFF)) << 16) | ((adr) >> 14) | 0x00)
38 #define CTL_WRITE_VSRAM(adr) \
39     (((0x4000 | ((adr) & 0x3FFF)) << 16) | ((adr) >> 14) | 0x10)
40 #define CTL_WRITE_CRAM(adr) \
41     (((0xC000 | ((adr) & 0x3FFF)) << 16) | ((adr) >> 14) | 0x00)
42 #define CTL_READ_VRAM(adr) \
43     (((0x0000 | ((adr) & 0x3FFF)) << 16) | ((adr) >> 14) | 0x00)
44 #define CTL_READ_VSRAM(adr) \
45     (((0x0000 | ((adr) & 0x3FFF)) << 16) | ((adr) >> 14) | 0x10)
46 #define CTL_READ_CRAM(adr) \
47     (((0x0000 | ((adr) & 0x3FFF)) << 16) | ((adr) >> 14) | 0x20)
48
49 #define CTL_WRITE_DMA 0x80
50
51 #define VDP_setReg(r, v) \
52     write16(VDP_CTRL_PORT, 0x8000 | ((r) << 8) | ((v) & 0xff))
53
54 enum {
55     VDP_MODE1 = 0x00,
56     VDP_MODE2 = 0x01,
57     VDP_NT_SCROLLA = 0x02,
58     VDP_NT_WIN = 0x03,
59     VDP_NT_SCROLLB = 0x04,
60     VDP_SAT_BASE = 0x05,
61     VDP_BACKDROP = 0x07,
62     VDP_MODE3 = 0x0b,
63     VDP_MODE4 = 0x0c,
64     VDP_HSCROLL = 0x0d,
65     VDP_AUTOINC = 0x0f,
66     VDP_SCROLLSZ = 0x10,
67     VDP_DMA_LEN0 = 0x13,
68     VDP_DMA_LEN1 = 0x14,
69     VDP_DMA_SRC0 = 0x15,
70     VDP_DMA_SRC1 = 0x16,
71     VDP_DMA_SRC2 = 0x17,
72 };
73
74 #define VDP_MODE1_PS   0x04
75 #define VDP_MODE1_IE1  0x10 // h int
76 #define VDP_MODE2_MD   0x04
77 #define VDP_MODE2_PAL  0x08 // 30 col
78 #define VDP_MODE2_DMA  0x10
79 #define VDP_MODE2_IE0  0x20 // v int
80 #define VDP_MODE2_DISP 0x40
81 #define VDP_MODE2_128K 0x80
82
83 #define SR_PAL        (1 << 0)
84 #define SR_DMA        (1 << 1)
85 #define SR_HB         (1 << 2)
86 #define SR_VB         (1 << 3)
87 #define SR_ODD        (1 << 4)
88 #define SR_C          (1 << 5)
89 #define SR_SOVR       (1 << 6)
90 #define SR_F          (1 << 7)
91 #define SR_FULL       (1 << 8)
92 #define SR_EMPT       (1 << 9)
93
94 /* cell counts */
95 #define LEFT_BORDER 1   /* lame TV */
96 #define PLANE_W 64
97 #define PLANE_H 32
98 #define CSCREEN_H 28
99
100 /* data.s */
101 extern const u32 font_base[];
102 extern const u8 z80_test[];
103 extern const u8 z80_test_end[];
104
105 static int text_pal;
106
107 static noinline void VDP_drawTextML(const char *str, u16 plane_base,
108     u16 x, u16 y)
109 {
110     const u8 *src = (const u8 *)str;
111     u16 basetile = text_pal << 13;
112     int max_len = 40 - LEFT_BORDER;
113     int len;
114     u32 addr;
115
116     x += LEFT_BORDER;
117
118     for (len = 0; str[len] && len < max_len; len++)
119         ;
120     if (len > (PLANE_W - x))
121         len = PLANE_W - x;
122
123     addr = plane_base + ((x + (PLANE_W * y)) << 1);
124     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(addr));
125
126     while (len-- > 0) {
127         write16(VDP_DATA_PORT,
128             basetile | ((*src++) - 32 + TILE_FONT_BASE / 32));
129     }
130 }
131
132 static int printf_ypos;
133
134 static void printf_line(int x, const char *buf)
135 {
136     u32 addr;
137     int i;
138
139     VDP_drawTextML(buf, APLANE, x, printf_ypos++ & (PLANE_H - 1));
140
141     if (printf_ypos >= CSCREEN_H) {
142         /* clear next line */
143         addr = APLANE;
144         addr += (PLANE_W * (printf_ypos & (PLANE_H - 1))) << 1;
145         write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(addr));
146         for (i = 0; i < 40 / 2; i++)
147             write32(VDP_DATA_PORT, 0);
148
149         /* scroll plane */
150         write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
151         write16(VDP_DATA_PORT, (printf_ypos - CSCREEN_H + 1) * 8);
152     }
153 }
154
155 #define PRINTF_LEN 40
156
157 static int printf_xpos;
158
159 static noinline int printf(const char *fmt, ...)
160 {
161     static const char hexchars[] = "0123456789abcdef";
162     char c, buf[PRINTF_LEN + 11 + 1];
163     const char *s;
164     va_list ap;
165     int ival;
166     u32 uval;
167     int d = 0;
168     int i, j;
169
170     va_start(ap, fmt);
171     for (d = 0; *fmt; ) {
172         int prefix0 = 0;
173         int fwidth = 0;
174
175         c = *fmt++;
176         if (d < PRINTF_LEN)
177             buf[d] = c;
178
179         if (c != '%') {
180             if (c == '\n') {
181                 buf[d] = 0;
182                 printf_line(printf_xpos, buf);
183                 d = 0;
184                 printf_xpos = 0;
185                 continue;
186             }
187             d++;
188             continue;
189         }
190         if (d >= PRINTF_LEN)
191             continue;
192
193         if (*fmt == '0') {
194             prefix0 = 1;
195             fmt++;
196         }
197
198         while ('1' <= *fmt && *fmt <= '9') {
199             fwidth = fwidth * 10 + *fmt - '0';
200             fmt++;
201         }
202
203         switch (*fmt++) {
204         case '%':
205             d++;
206             break;
207         case 'd':
208         case 'i':
209             ival = va_arg(ap, int);
210             if (ival < 0) {
211                 buf[d++] = '-';
212                 ival = -ival;
213             }
214             for (i = 1000000000; i >= 10; i /= 10)
215                 if (ival >= i)
216                     break;
217             for (; i >= 10; i /= 10) {
218                 buf[d++] = '0' + ival / i;
219                 ival %= i;
220             }
221             buf[d++] = '0' + ival;
222             break;
223         case 'x':
224             uval = va_arg(ap, int);
225             while (fwidth > 1 && uval < (1 << (fwidth - 1) * 4)) {
226                 buf[d++] = prefix0 ? '0' : ' ';
227                 fwidth--;
228             }
229             for (j = 1; j < 8 && uval >= (1 << j * 4); j++)
230                 ;
231             for (j--; j >= 0; j--)
232                 buf[d++] = hexchars[(uval >> j * 4) & 0x0f];
233             break;
234         case 's':
235             s = va_arg(ap, char *);
236             while (*s && d < PRINTF_LEN)
237                 buf[d++] = *s++;
238             break;
239         default:
240             // don't handle, for now
241             d++;
242             va_arg(ap, void *);
243             break;
244         }
245     }
246     buf[d] = 0;
247     va_end(ap);
248
249     if (d != 0) {
250         // line without \n
251         VDP_drawTextML(buf, APLANE, printf_xpos,
252             printf_ypos & (PLANE_H - 1));
253         printf_xpos += d;
254     }
255
256     return d; // wrong..
257 }
258
259 static const char *exc_names[] = {
260     NULL,
261     NULL,
262     "Bus Error",
263     "Address Error",
264     "Illegal Instruction",
265     "Zero Divide",
266     "CHK Instruction",
267     "TRAPV Instruction",
268     "Privilege Violation",  /*  8  8 */
269     "Trace",
270     "Line 1010 Emulator",
271     "Line 1111 Emulator",
272     NULL,
273     NULL,
274     NULL,
275     "Uninitialized Interrupt",
276     NULL,                   /* 10 16 */
277     NULL,
278     NULL,
279     NULL,
280     NULL,
281     NULL,
282     NULL,
283     NULL,
284     "Spurious Interrupt",   /* 18 24 */
285     "l1 irq",
286     "l2 irq",
287     "l3 irq",
288     "l4 irq",
289     "l5 irq",
290     "l6 irq",
291     "l7 irq",
292 };
293
294 struct exc_frame {
295     u32 dr[8];
296     u32 ar[8];
297     u16 ecxnum; // from handler
298     union {
299         struct {
300             u16 sr;
301             u32 pc;
302         } g _packed;
303         struct {
304             u16 fc;
305             u32 addr;
306             u16 ir;
307             u16 sr;
308             u32 pc;
309         } bae _packed; // bus/address error frame
310     };
311 } _packed;
312
313 void exception(const struct exc_frame *f)
314 {
315     int i;
316
317     while (read16(VDP_CTRL_PORT) & 2)
318         ;
319     VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
320     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DISP);
321     /* adjust scroll */
322     write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
323     write16(VDP_DATA_PORT,
324       printf_ypos >= CSCREEN_H ?
325         (printf_ypos - CSCREEN_H + 1) * 8 : 0);
326
327     printf("exception %i ", f->ecxnum);
328     if (f->ecxnum < ARRAY_SIZE(exc_names) && exc_names[f->ecxnum] != NULL)
329         printf("(%s)", exc_names[f->ecxnum]);
330     if (f->ecxnum < 4)
331         printf(" (%s)", (f->bae.fc & 0x10) ? "r" : "w");
332     printf("    \n");
333
334     if (f->ecxnum < 4) {
335         printf("  PC: %08x SR: %04x    \n", f->bae.pc, f->bae.sr);
336         printf("addr: %08x IR: %04x FC: %02x   \n",
337                f->bae.addr, f->bae.ir, f->bae.fc);
338     }
339     else {
340         printf("  PC: %08x SR: %04x    \n", f->g.pc, f->g.sr);
341     }
342     for (i = 0; i < 8; i++)
343         printf("  D%d: %08x A%d: %08x    \n", i, f->dr[i], i, f->ar[i]);
344     printf("                       \n");
345 }
346
347 // ---
348
349 static void setup_default_palette(void)
350 {
351     write32(VDP_CTRL_PORT, CTL_WRITE_CRAM(0));
352     write32(VDP_DATA_PORT, 0);
353     write32(VDP_CTRL_PORT, CTL_WRITE_CRAM(15 * 2)); // font normal
354     write16(VDP_DATA_PORT, 0xeee);
355     write32(VDP_CTRL_PORT, CTL_WRITE_CRAM(31 * 2)); // green
356     write16(VDP_DATA_PORT, 0x0e0);
357     write32(VDP_CTRL_PORT, CTL_WRITE_CRAM(47 * 2)); // red
358     write16(VDP_DATA_PORT, 0x00e);
359 }
360
361 static void do_setup_dma(const void *src_, u16 words)
362 {
363     u32 src = (u32)src_;
364     // VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA);
365     VDP_setReg(VDP_DMA_LEN0, words);
366     VDP_setReg(VDP_DMA_LEN1, words >> 8);
367     VDP_setReg(VDP_DMA_SRC0, src >> 1);
368     VDP_setReg(VDP_DMA_SRC1, src >> 9);
369     VDP_setReg(VDP_DMA_SRC2, src >> 17);
370     // write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(addr) | CTL_WRITE_DMA);
371 }
372
373 static void vdp_wait_for_fifo_empty(void)
374 {
375     while (!(read16(VDP_CTRL_PORT) & 0x200))
376         /* fifo not empty */;
377 }
378
379 static void vdp_wait_for_dma_idle(void)
380 {
381     while (read16(VDP_CTRL_PORT) & 2)
382         /* dma busy */;
383 }
384
385 static void vdp_wait_for_line_0(void)
386 {
387     // in PAL vcounter reports 0 twice in a frame,
388     // so wait for vblank to clear first
389     while (!(read16(VDP_CTRL_PORT) & 8))
390         /* not blanking */;
391     while (read16(VDP_CTRL_PORT) & 8)
392         /* blanking */;
393     while (read8(VDP_HV_COUNTER) != 0)
394         ;
395 }
396
397 static void t_dma_zero_wrap_early(void)
398 {
399     const u32 *src = (const u32 *)0x3c0000;
400     u32 *ram = (u32 *)0xff0000;
401
402     do_setup_dma(src + 4, 2);
403     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0) | CTL_WRITE_DMA);
404     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0) | CTL_WRITE_DMA);
405
406     write32(VDP_CTRL_PORT, CTL_READ_VRAM(0));
407     ram[0] = read32(VDP_DATA_PORT);
408     write32(VDP_CTRL_PORT, CTL_READ_VRAM(0xfffc));
409     ram[1] = read32(VDP_DATA_PORT);
410 }
411
412 static void t_dma_zero_fill_early(void)
413 {
414     u32 *ram = (u32 *)0xff0000;
415
416     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0));
417     write32(VDP_DATA_PORT, 0);
418     write32(VDP_DATA_PORT, 0);
419     write32(VDP_DATA_PORT, 0);
420     write32(VDP_DATA_PORT, 0);
421
422     VDP_setReg(VDP_AUTOINC, 1);
423     VDP_setReg(VDP_DMA_SRC2, 0x80);
424     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(1) | CTL_WRITE_DMA);
425     write16(VDP_DATA_PORT, 0x1122);
426     ram[2] = read16(VDP_CTRL_PORT);
427     vdp_wait_for_dma_idle();
428
429     VDP_setReg(VDP_AUTOINC, 2);
430     write32(VDP_CTRL_PORT, CTL_READ_VRAM(0));
431     ram[3] = read32(VDP_DATA_PORT);
432 }
433
434 #define expect(ok_, v0_, v1_) \
435 if ((v0_) != (v1_)) { \
436     printf("%s: %08x %08x\n", #v0_, v0_, v1_); \
437     ok_ = 0; \
438 }
439
440 #define expect_range(ok_, v0_, vmin_, vmax_) \
441 if ((v0_) < (vmin_) || (v0_) > (vmax_)) { \
442     printf("%s: %02x /%02x-%02x\n", #v0_, v0_, vmin_, vmax_); \
443     ok_ = 0; \
444 }
445
446 #define expect_bits(ok_, v0_, val_, mask_) \
447 if (((v0_) & (mask_)) != (val_)) { \
448     printf("%s: %04x & %04x != %04x\n", #v0_, v0_, mask_, val_); \
449     ok_ = 0; \
450 }
451
452 static int t_dma_zero_wrap(void)
453 {
454     const u32 *src = (const u32 *)0x3c0000;
455     const u32 *ram = (const u32 *)0xff0000;
456     int ok = 1;
457
458     expect(ok, ram[0], src[5 + 0x10000/4]);
459     expect(ok, ram[1], src[4]);
460     return ok;
461 }
462
463 static int t_dma_zero_fill(void)
464 {
465     const u32 *ram = (const u32 *)0xff0000;
466     u32 v0 = ram[2] & 2;
467     int ok = 1;
468
469     expect(ok, v0, 2);
470     expect(ok, ram[3], 0x11111111);
471     return ok;
472 }
473
474 static int t_dma_ram_wrap(void)
475 {
476     u32 *ram = (u32 *)0xff0000;
477     u32 saved, v0, v1;
478     int ok = 1;
479
480     saved = read32(&ram[0x10000/4 - 1]);
481     ram[0x10000/4 - 1] = 0x01020304;
482     ram[0] = 0x05060708;
483     do_setup_dma(&ram[0x10000/4 - 1], 4);
484     mem_barrier();
485     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100) | CTL_WRITE_DMA);
486
487     mem_barrier();
488     write32(&ram[0x10000/4 - 1], saved);
489
490     write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
491     v0 = read32(VDP_DATA_PORT);
492     v1 = read32(VDP_DATA_PORT);
493
494     expect(ok, v0, 0x01020304);
495     expect(ok, v1, 0x05060708);
496     return ok;
497 }
498
499 // test no src reprogram, only len0
500 static int t_dma_multi(void)
501 {
502     const u32 *src = (const u32 *)0x3c0000;
503     u32 v0, v1;
504     int ok = 1;
505
506     do_setup_dma(src, 2);
507     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100) | CTL_WRITE_DMA);
508     VDP_setReg(VDP_DMA_LEN0, 2);
509     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x104) | CTL_WRITE_DMA);
510
511     write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
512     v0 = read32(VDP_DATA_PORT);
513     v1 = read32(VDP_DATA_PORT);
514
515     expect(ok, v0, src[0]);
516     expect(ok, v1, src[1]);
517     return ok;
518 }
519
520 static int t_dma_cram_wrap(void)
521 {
522     u32 *ram = (u32 *)0xff0000;
523     u32 v0, v1;
524     int ok = 1;
525
526     write32(VDP_CTRL_PORT, CTL_WRITE_CRAM(0));
527     write32(VDP_DATA_PORT, 0);
528
529     ram[0] = 0x0ec20ec4;
530     ram[1] = 0x0ec60ec8;
531     mem_barrier();
532     do_setup_dma(ram, 4);
533     write32(VDP_CTRL_PORT, CTL_WRITE_CRAM(0x7c | 0xff81) | CTL_WRITE_DMA);
534
535     write32(VDP_CTRL_PORT, CTL_READ_CRAM(0x7c));
536     v0 = read32(VDP_DATA_PORT) & 0x0eee0eee;
537     write32(VDP_CTRL_PORT, CTL_READ_CRAM(0));
538     v1 = read32(VDP_DATA_PORT) & 0x0eee0eee;
539
540     setup_default_palette();
541
542     expect(ok, v0, ram[0]);
543     expect(ok, v1, ram[1]);
544     return ok;
545 }
546
547 static int t_dma_vsram_wrap(void)
548 {
549     u32 *ram32 = (u32 *)0xff0000;
550     u16 *ram16 = (u16 *)0xff0000;
551     u32 v0, v1;
552     int ok = 1;
553     int i;
554
555     write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
556     write32(VDP_DATA_PORT, 0);
557
558     for (i = 0; i < 0x48/2; i++)
559         ram16[i] = i + 1;
560     mem_barrier();
561     do_setup_dma(ram16, 0x48/2);
562     write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0x3c | 0xff81) | CTL_WRITE_DMA);
563
564     write32(VDP_CTRL_PORT, CTL_READ_VSRAM(0x3c));
565     v0 = read32(VDP_DATA_PORT) & 0x03ff03ff;
566     write32(VDP_CTRL_PORT, CTL_READ_VSRAM(0));
567     v1 = read32(VDP_DATA_PORT) & 0x03ff03ff;
568
569     write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
570     write32(VDP_DATA_PORT, 0);
571
572     expect(ok, v0, ram32[0]);
573     expect(ok, v1, ram32[0x48/4 - 1]);
574     return ok;
575 }
576
577 static int t_dma_and_data(void)
578 {
579     const u32 *src = (const u32 *)0x3c0000;
580     u32 v0, v1;
581     int ok = 1;
582
583     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
584     write32(VDP_DATA_PORT, 0);
585
586     do_setup_dma(src, 2);
587     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0xfc) | CTL_WRITE_DMA);
588     write32(VDP_DATA_PORT, 0x5ec8a248);
589
590     write32(VDP_CTRL_PORT, CTL_READ_VRAM(0xfc));
591     v0 = read32(VDP_DATA_PORT);
592     v1 = read32(VDP_DATA_PORT);
593
594     expect(ok, v0, src[0]);
595     expect(ok, v1, 0x5ec8a248);
596     return ok;
597 }
598
599 static int t_dma_short_cmd(void)
600 {
601     const u32 *src = (const u32 *)0x3c0000;
602     u32 v0, v1, v2;
603     int ok = 1;
604
605     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x3ff4));
606     write32(VDP_DATA_PORT, 0x10111213);
607     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0xfff0));
608     write32(VDP_DATA_PORT, 0x20212223);
609     write32(VDP_DATA_PORT, 0x30313233);
610     vdp_wait_for_fifo_empty();
611
612     do_setup_dma(src, 2);
613     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0xfff0) | CTL_WRITE_DMA);
614     write16(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x3ff4) >> 16);
615     write32(VDP_DATA_PORT, 0x40414243);
616
617     write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x3ff4));
618     v0 = read32(VDP_DATA_PORT);
619     write32(VDP_CTRL_PORT, CTL_READ_VRAM(0xfff0));
620     v1 = read32(VDP_DATA_PORT);
621     v2 = read32(VDP_DATA_PORT);
622
623     expect(ok, v0, 0x10111213);
624     expect(ok, v1, src[0]);
625     expect(ok, v2, 0x40414243);
626     return ok;
627 }
628
629 static int t_dma_fill3_odd(void)
630 {
631     u32 v0, v1, v2;
632     int ok = 1;
633
634     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
635     write32(VDP_DATA_PORT, 0);
636     write32(VDP_DATA_PORT, 0);
637     write32(VDP_DATA_PORT, 0);
638     vdp_wait_for_fifo_empty();
639
640     VDP_setReg(VDP_AUTOINC, 3);
641     VDP_setReg(VDP_DMA_LEN0, 3);
642     VDP_setReg(VDP_DMA_SRC2, 0x80);
643     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x101) | CTL_WRITE_DMA);
644     write16(VDP_DATA_PORT, 0x1122);
645     vdp_wait_for_dma_idle();
646
647     VDP_setReg(VDP_AUTOINC, 2);
648     write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
649     v0 = read32(VDP_DATA_PORT);
650     v1 = read32(VDP_DATA_PORT);
651     v2 = read32(VDP_DATA_PORT);
652
653     expect(ok, v0, 0x22110000);
654     expect(ok, v1, 0x00111100);
655     expect(ok, v2, 0x00000011);
656     return ok;
657 }
658
659 static int t_dma_fill3_even(void)
660 {
661     u32 v0, v1, v2;
662     int ok = 1;
663
664     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
665     write32(VDP_DATA_PORT, 0);
666     write32(VDP_DATA_PORT, 0);
667     write32(VDP_DATA_PORT, 0);
668     vdp_wait_for_fifo_empty();
669
670     VDP_setReg(VDP_AUTOINC, 3);
671     VDP_setReg(VDP_DMA_LEN0, 3);
672     VDP_setReg(VDP_DMA_SRC2, 0x80);
673     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100) | CTL_WRITE_DMA);
674     write16(VDP_DATA_PORT, 0x1122);
675     vdp_wait_for_dma_idle();
676
677     VDP_setReg(VDP_AUTOINC, 2);
678     write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
679     v0 = read32(VDP_DATA_PORT);
680     v1 = read32(VDP_DATA_PORT);
681     v2 = read32(VDP_DATA_PORT);
682
683     expect(ok, v0, 0x11221100);
684     expect(ok, v1, 0x00000011);
685     expect(ok, v2, 0x11000000);
686     return ok;
687 }
688
689 static unused int t_dma_fill3_vsram(void)
690 {
691     u32 v0, v1, v2;
692     int ok = 1;
693
694     write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
695     write32(VDP_DATA_PORT, 0);
696     write32(VDP_DATA_PORT, 0);
697     write32(VDP_DATA_PORT, 0);
698
699     write16(VDP_DATA_PORT, 0x0111);
700     write16(VDP_DATA_PORT, 0x0222);
701     write16(VDP_DATA_PORT, 0x0333);
702     vdp_wait_for_fifo_empty();
703
704     VDP_setReg(VDP_AUTOINC, 3);
705     VDP_setReg(VDP_DMA_LEN0, 3);
706     VDP_setReg(VDP_DMA_SRC2, 0x80);
707     write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(1) | CTL_WRITE_DMA);
708     write16(VDP_DATA_PORT, 0x0102);
709     vdp_wait_for_dma_idle();
710
711     VDP_setReg(VDP_AUTOINC, 2);
712     write32(VDP_CTRL_PORT, CTL_READ_VSRAM(0));
713     v0 = read32(VDP_DATA_PORT);
714     v1 = read32(VDP_DATA_PORT);
715     v2 = read32(VDP_DATA_PORT);
716
717     write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
718     write32(VDP_DATA_PORT, 0);
719
720     expect(ok, v0, 0x01020000);
721     expect(ok, v1, 0x01110111);
722     expect(ok, v2, 0x00000111);
723     return ok;
724 }
725
726 static int t_dma_fill_dis(void)
727 {
728     u32 v0, v1;
729     int ok = 1;
730
731     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
732     write32(VDP_DATA_PORT, 0);
733     write32(VDP_DATA_PORT, 0);
734
735     VDP_setReg(VDP_DMA_LEN0, 1);
736     VDP_setReg(VDP_DMA_SRC2, 0x80);
737     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100) | CTL_WRITE_DMA);
738     VDP_setReg(VDP_MODE2, VDP_MODE2_MD);
739     write16(VDP_DATA_PORT, 0x1122);
740     vdp_wait_for_dma_idle();
741
742     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
743     write16(VDP_DATA_PORT, 0x3344);
744     vdp_wait_for_dma_idle();
745
746     write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
747     v0 = read32(VDP_DATA_PORT);
748     v1 = read32(VDP_DATA_PORT);
749
750     expect(ok, v0, 0);
751     expect(ok, v1, 0);
752     return ok;
753 }
754
755 static int t_dma_fill_src(void)
756 {
757     const u32 *src = (const u32 *)0x3c0000;
758     u32 v0, v1;
759     int ok = 1;
760
761     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
762     write32(VDP_DATA_PORT, 0);
763
764     // do_setup_dma(src, 2); // hang, can't write src2 twice
765     VDP_setReg(VDP_DMA_LEN0, 2);
766     VDP_setReg(VDP_DMA_SRC0, (u32)src >> 1);
767     VDP_setReg(VDP_DMA_SRC1, (u32)src >> 9);
768     VDP_setReg(VDP_DMA_SRC2, 0x80);
769     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100) | CTL_WRITE_DMA);
770     write16(VDP_DATA_PORT, 0x1122);
771     vdp_wait_for_dma_idle();
772
773     VDP_setReg(VDP_DMA_LEN0, 2);
774     VDP_setReg(VDP_DMA_SRC2, (u32)src >> 17);
775     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x104) | CTL_WRITE_DMA);
776
777     write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
778     v0 = read32(VDP_DATA_PORT);
779     v1 = read32(VDP_DATA_PORT);
780
781     expect(ok, v0, 0x11220011);
782     expect(ok, v1, src[1]);
783     return ok;
784 }
785
786 // (((a & 2) >> 1) ^ 1) | ((a & $400) >> 9) | (a & $3FC) | ((a & $1F800) >> 1)
787 static int t_dma_128k(void)
788 {
789     u16 *ram = (u16 *)0xff0000;
790     u32 v0, v1;
791     int ok = 1;
792
793     ram[0] = 0x5a11;
794     ram[1] = 0x5a22;
795     ram[2] = 0x5a33;
796
797     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
798     write32(VDP_DATA_PORT, 0x01020304);
799     write32(VDP_DATA_PORT, 0x05060708);
800     vdp_wait_for_fifo_empty();
801
802     mem_barrier();
803     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_128K);
804     do_setup_dma(ram, 3);
805     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100) | CTL_WRITE_DMA);
806     vdp_wait_for_fifo_empty();
807
808     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
809     write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
810     v0 = read32(VDP_DATA_PORT);
811     v1 = read32(VDP_DATA_PORT);
812
813     expect(ok, v0, 0x22110304);
814     expect(ok, v1, 0x05330708);
815     return ok;
816 }
817
818 static int t_vdp_128k_b16(void)
819 {
820     u32 v0, v1;
821     int ok = 1;
822
823     VDP_setReg(VDP_AUTOINC, 0);
824     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x8100));
825     write32(VDP_DATA_PORT, 0x01020304);
826     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x10100));
827     write32(VDP_DATA_PORT, 0x05060708);
828     vdp_wait_for_fifo_empty();
829
830     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_128K);
831     write16(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100) >> 16); // note: upper cmd
832     write32(VDP_DATA_PORT, 0x11223344);
833     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x10102));
834     write32(VDP_DATA_PORT, 0x55667788);
835     vdp_wait_for_fifo_empty();
836
837     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
838     write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x8100));
839     v0 = read16(VDP_DATA_PORT);
840     write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x0100));
841     v1 = read16(VDP_DATA_PORT);
842
843     VDP_setReg(VDP_AUTOINC, 2);
844
845     expect(ok, v0, 0x8844);
846     expect(ok, v1, 0x0708);
847     return ok;
848 }
849
850 static unused int t_vdp_128k_b16_inc(void)
851 {
852     u32 v0, v1;
853     int ok = 1;
854
855     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0));
856     write32(VDP_DATA_PORT, 0x01020304);
857     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x8000));
858     write32(VDP_DATA_PORT, 0x05060708);
859     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0xfffe));
860     write32(VDP_DATA_PORT, 0x090a0b0c);
861     vdp_wait_for_fifo_empty();
862
863     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_128K);
864     write16(VDP_CTRL_PORT, CTL_WRITE_VRAM(0) >> 16); // note: upper cmd
865     write16(VDP_DATA_PORT, 0x1122);
866     vdp_wait_for_fifo_empty();
867
868     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
869     write32(VDP_CTRL_PORT, CTL_READ_VRAM(0));
870     v0 = read32(VDP_DATA_PORT);
871     write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x8000));
872     v1 = read32(VDP_DATA_PORT);
873     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0));
874     write32(VDP_DATA_PORT, 0);
875     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x8000));
876     write32(VDP_DATA_PORT, 0);
877
878     expect(ok, v0, 0x0b0c0304); // XXX: no 22 anywhere?
879     expect(ok, v1, 0x05060708);
880     return ok;
881 }
882
883 static int t_vdp_reg_cmd(void)
884 {
885     u32 v0;
886     int ok = 1;
887
888     VDP_setReg(VDP_AUTOINC, 0);
889     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
890     write32(VDP_DATA_PORT, 0x01020304);
891     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
892     write32(VDP_DATA_PORT, 0x05060708);
893
894     VDP_setReg(VDP_AUTOINC, 2);
895     write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x0100));
896     v0 = read16(VDP_DATA_PORT);
897
898     expect(ok, v0, 0x0304);
899     return ok;
900 }
901
902 static int t_vdp_sr_vb(void)
903 {
904     u16 sr[4];
905     int ok = 1;
906
907     while (read8(VDP_HV_COUNTER) != 242)
908         ;
909     sr[0] = read16(VDP_CTRL_PORT);
910     VDP_setReg(VDP_MODE2, VDP_MODE2_MD);
911     sr[1] = read16(VDP_CTRL_PORT);
912     while (read8(VDP_HV_COUNTER) != 4)
913         ;
914     sr[2] = read16(VDP_CTRL_PORT);
915     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
916     sr[3] = read16(VDP_CTRL_PORT);
917
918     expect_bits(ok, sr[0], SR_VB, SR_VB);
919     expect_bits(ok, sr[1], SR_VB, SR_VB);
920     expect_bits(ok, sr[2], SR_VB, SR_VB);
921     expect_bits(ok, sr[3], 0, SR_VB);
922     return ok;
923 }
924
925 /* z80 tests assume busreq state */
926 static int t_z80mem_long_mirror(void)
927 {
928     u8 *zram = (u8 *)0xa00000;
929     int ok = 1;
930
931     write8(&zram[0x1100], 0x11);
932     write8(&zram[0x1101], 0x22);
933     write8(&zram[0x1102], 0x33);
934     write8(&zram[0x1103], 0x44);
935     mem_barrier();
936     write32(&zram[0x3100], 0x55667788);
937     mem_barrier();
938
939     expect(ok, zram[0x1100], 0x55);
940     expect(ok, zram[0x1101], 0x22);
941     expect(ok, zram[0x1102], 0x77);
942     expect(ok, zram[0x1103], 0x44);
943     return ok;
944 }
945
946 static int t_z80mem_noreq_w(void)
947 {
948     u8 *zram = (u8 *)0xa00000;
949     int ok = 1;
950
951     write8(&zram[0x1100], 0x11);
952     mem_barrier();
953     write16(0xa11100, 0x000);
954     write8(&zram[0x1100], 0x22);
955     mem_barrier();
956
957     write16(0xa11100, 0x100);
958     while (read16(0xa11100) & 0x100)
959         ;
960
961     expect(ok, zram[0x1100], 0x11);
962     return ok;
963 }
964
965 #define Z80_CP_CYCLES(b) (118 + ((b) - 1) * 21 + 26 + 17)
966
967 static int t_z80mem_vdp_r(void)
968 {
969     u8 *zram = (u8 *)0xa00000;
970     int ok = 1;
971
972     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
973     write32(VDP_DATA_PORT, 0x11223344);
974     write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
975
976     zram[0x1000] = 1; // cp
977     write16_z80le(&zram[0x1002], 0x7f00); // src
978     write16_z80le(&zram[0x1004], 0x1100); // dst
979     write16_z80le(&zram[0x1006], 2); // len
980     zram[0x1100] = zram[0x1101] = zram[0x1102] = 0x5a;
981     mem_barrier();
982     write16(0xa11100, 0x000);
983     burn10(Z80_CP_CYCLES(2) * 15 / 7 * 2 / 10);
984
985     write16(0xa11100, 0x100);
986     while (read16(0xa11100) & 0x100)
987         ;
988
989     expect(ok, zram[0x1000], 0);
990     expect(ok, zram[0x1100], 0x11);
991     expect(ok, zram[0x1101], 0x44);
992     expect(ok, zram[0x1102], 0x5a);
993     return ok;
994 }
995
996 static unused int t_z80mem_vdp_w(void)
997 {
998     u8 *zram = (u8 *)0xa00000;
999     u32 v0;
1000     int ok = 1;
1001
1002     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
1003     write32(VDP_DATA_PORT, 0x11223344);
1004     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
1005     vdp_wait_for_fifo_empty();
1006
1007     zram[0x1000] = 1; // cp
1008     write16_z80le(&zram[0x1002], 0x1100); // src
1009     write16_z80le(&zram[0x1004], 0x7f00); // dst
1010     write16_z80le(&zram[0x1006], 2); // len
1011     zram[0x1100] = 0x55;
1012     zram[0x1101] = 0x66;
1013     mem_barrier();
1014     write16(0xa11100, 0x000);
1015     burn10(Z80_CP_CYCLES(2) * 15 / 7 * 2 / 10);
1016
1017     write16(0xa11100, 0x100);
1018     while (read16(0xa11100) & 0x100)
1019         ;
1020
1021     write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
1022     v0 = read32(VDP_DATA_PORT);
1023
1024     expect(ok, zram[0x1000], 0);
1025     expect(ok, v0, 0x55556666);
1026     return ok;
1027 }
1028
1029 static int t_tim_loop(void)
1030 {
1031     u8 vcnt;
1032     int ok = 1;
1033
1034     vdp_wait_for_line_0();
1035     burn10(488*220/10);
1036     vcnt = read8(VDP_HV_COUNTER);
1037     mem_barrier();
1038
1039     //expect_range(ok, vcnt, 0x80, 0x80);
1040     expect(ok, vcnt, 223);
1041     return ok;
1042 }
1043
1044 #define Z80_RD_V_CYCLES(b) (132 + (b) * 38 + 50 + 17)
1045
1046 // 80 80 91 95-96
1047 static void z80_read_loop(u8 *zram, u16 src)
1048 {
1049     const int pairs = 512 + 256;
1050
1051     zram[0x1000] = 2; // read loop, save vcnt
1052     write16_z80le(&zram[0x1002], src); // src
1053     write16_z80le(&zram[0x1004], 0x1100); // vcnt dst
1054     write16_z80le(&zram[0x1006], pairs); // reads/2
1055     zram[0x1100] = 0;
1056     mem_barrier();
1057
1058     vdp_wait_for_line_0();
1059     write16(0xa11100, 0x000);
1060     burn10(Z80_RD_V_CYCLES(pairs) * 15 / 7 * 4 / 10);
1061
1062     write16(0xa11100, 0x100);
1063     while (read16(0xa11100) & 0x100)
1064         ;
1065 }
1066
1067 static int t_tim_z80_ram(void)
1068 {
1069     u8 *zram = (u8 *)0xa00000;
1070     int ok = 1;
1071
1072     z80_read_loop(zram, 0);
1073
1074     expect(ok, zram[0x1000], 0);
1075     expect_range(ok, zram[0x1100], 0x80, 0x80);
1076     return ok;
1077 }
1078
1079 static int t_tim_z80_ym(void)
1080 {
1081     u8 *zram = (u8 *)0xa00000;
1082     int ok = 1;
1083
1084     z80_read_loop(zram, 0x4000);
1085
1086     expect(ok, zram[0x1000], 0);
1087     expect_range(ok, zram[0x1100], 0x80, 0x80);
1088     return ok;
1089 }
1090
1091 static int t_tim_z80_vdp(void)
1092 {
1093     u8 *zram = (u8 *)0xa00000;
1094     int ok = 1;
1095
1096     z80_read_loop(zram, 0x7f08);
1097
1098     expect(ok, zram[0x1000], 0);
1099 #ifndef PICO
1100     expect_range(ok, zram[0x1100], 0x91, 0x91);
1101 #else
1102     expect_range(ok, zram[0x1100], 0x8e, 0x91);
1103 #endif
1104     return ok;
1105 }
1106
1107 static int t_tim_z80_bank_rom(void)
1108 {
1109     u8 *zram = (u8 *)0xa00000;
1110     int i, ok = 1;
1111
1112     for (i = 0; i < 17; i++)
1113         write8(0xa06000, 0); // bank 0
1114
1115     z80_read_loop(zram, 0x8000);
1116
1117     expect(ok, zram[0x1000], 0);
1118 #ifndef PICO
1119     expect_range(ok, zram[0x1100], 0x95, 0x96);
1120 #else
1121     expect_range(ok, zram[0x1100], 0x93, 0x96);
1122 #endif
1123     return ok;
1124 }
1125
1126 /* borderline too slow */
1127 #if 0
1128 static void test_vcnt_vb(void)
1129 {
1130     const u32 *srhv = (u32 *)0xc00006; // to read SR and HV counter
1131     u32 *ram = (u32 *)0xff0000;
1132     u16 vcnt, vcnt_expect = 0;
1133     u16 sr, count = 0;
1134     u32 val, old;
1135
1136     vdp_wait_for_line_0();
1137     old = read32(srhv);
1138     *ram++ = old;
1139     for (;;) {
1140         val = read32(srhv);
1141         vcnt = val & 0xff00;
1142         if (vcnt == vcnt_expect)
1143             continue;
1144         sr = val >> 16;
1145         if (vcnt == 0 && !(sr & SR_VB)) // not VB
1146             break; // wrapped to start of frame
1147 //        count++;
1148         vcnt_expect += 0x100;
1149         if (vcnt == vcnt_expect && !((sr ^ (old >> 16)) & SR_VB)) {
1150             old = val;
1151             continue;
1152         }
1153         // should have a vcnt jump here
1154         *ram++ = old;
1155         *ram++ = val;
1156         vcnt_expect = vcnt;
1157         old = val;
1158     }
1159     *ram++ = val;
1160     *ram = count;
1161     mem_barrier();
1162 }
1163 #endif
1164
1165 static int t_tim_vcnt(void)
1166 {
1167     const u32 *ram32 = (u32 *)0xff0000;
1168     const u8 *ram = (u8 *)0xff0000;
1169     u8 pal = read8(0xa10001) & 0x40;
1170     u8 vc_jmp_b = pal ? 0x02 : 0xea;
1171     u8 vc_jmp_a = pal ? 0xca : 0xe5;
1172     u16 lines = pal ? 313 : 262;
1173     int ok = 1;
1174
1175     test_vcnt_vb();
1176     expect(ok, ram[0*4+2], 0); // line 0
1177     expect_bits(ok, ram[0*4+1], 0, SR_VB);
1178     expect(ok, ram[1*4+2], 223); // last no blank
1179     expect_bits(ok, ram[1*4+1], 0, SR_VB);
1180     expect(ok, ram[2*4+2], 224); // 1st blank
1181     expect_bits(ok, ram[2*4+1], SR_VB, SR_VB);
1182     expect(ok, ram[3*4+2], vc_jmp_b); // before jump
1183     expect_bits(ok, ram[3*4+1], SR_VB, SR_VB);
1184     expect(ok, ram[4*4+2], vc_jmp_a); // after jump
1185     expect_bits(ok, ram[4*4+1], SR_VB, SR_VB);
1186     expect(ok, ram[5*4+2], 0xfe); // before vb clear
1187     expect_bits(ok, ram[5*4+1], SR_VB, SR_VB);
1188     expect(ok, ram[6*4+2], 0xff); // after vb clear
1189     expect_bits(ok, ram[6*4+1], 0, SR_VB);
1190     expect(ok, ram[7*4+2], 0); // next line 0
1191     expect_bits(ok, ram[7*4+1], 0, SR_VB);
1192     expect(ok, ram32[8], lines - 1);
1193     return ok;
1194 }
1195
1196 static int t_tim_hblank_h40(void)
1197 {
1198     const u8 *r = (u8 *)0xff0000;
1199     int ok = 1;
1200
1201     test_hb();
1202
1203     // set: 0-2
1204     expect_bits(ok, r[2], SR_HB, SR_HB);
1205     expect_bits(ok, r[5], SR_HB, SR_HB);
1206     // <wait>
1207     expect_bits(ok, r[7], SR_HB, SR_HB);
1208     // clear: 8-11
1209     expect_bits(ok, r[12], 0, SR_HB);
1210     return ok;
1211 }
1212
1213 static int t_tim_hblank_h32(void)
1214 {
1215     const u8 *r = (u8 *)0xff0000;
1216     int ok = 1;
1217
1218     VDP_setReg(VDP_MODE4, 0x00);
1219     test_hb();
1220     VDP_setReg(VDP_MODE4, 0x81);
1221
1222 #ifndef PICO
1223     expect_bits(ok, r[0], 0, SR_HB);
1224 #endif
1225     // set: 1-4
1226     expect_bits(ok, r[4], SR_HB, SR_HB);
1227     expect_bits(ok, r[5], SR_HB, SR_HB);
1228     // <wait>
1229     expect_bits(ok, r[8], SR_HB, SR_HB);
1230     // clear: 9-11
1231     expect_bits(ok, r[12], 0, SR_HB);
1232     return ok;
1233 }
1234
1235 static int t_tim_vdp_as_vram_w(void)
1236 {
1237     int ok = 1;
1238     u8 vcnt;
1239
1240     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
1241     vdp_wait_for_line_0();
1242     write16_x16(VDP_DATA_PORT, 112*18 / 16, 0);
1243     vcnt = read8(VDP_HV_COUNTER);
1244     mem_barrier();
1245
1246     expect(ok, vcnt, 112*2-1);
1247     return ok;
1248 }
1249
1250 static int t_tim_vdp_as_cram_w(void)
1251 {
1252     int ok = 1;
1253     u8 vcnt;
1254
1255     write32(VDP_CTRL_PORT, CTL_WRITE_CRAM(0));
1256     vdp_wait_for_line_0();
1257     write16_x16(VDP_DATA_PORT, 112*18 / 16, 0);
1258     vcnt = read8(VDP_HV_COUNTER);
1259     mem_barrier();
1260
1261     setup_default_palette();
1262
1263 #ifndef PICO
1264     expect(ok, vcnt, 112);
1265 #else
1266     expect_range(ok, vcnt, 111, 112);
1267 #endif
1268     return ok;
1269 }
1270
1271 static int t_irq_hint(void)
1272 {
1273     u16 *ram = (u16 *)0xfff000;
1274     u8 *ram8 = (u8 *)0xfff000;
1275     u16 v_p, cnt_p;
1276     int ok = 1;
1277
1278     // for more fun, disable the display
1279     VDP_setReg(VDP_MODE2, VDP_MODE2_MD);
1280
1281     ram[0] = ram[1] = ram[2] = 0;
1282     memcpy_((void *)0xff0100, test_hint, test_hint_end - test_hint);
1283     VDP_setReg(10, 0);
1284     while (read8(VDP_HV_COUNTER) != 100)
1285         ;
1286     while (read8(VDP_HV_COUNTER) != 229)
1287         ;
1288     // take the pending irq
1289     VDP_setReg(VDP_MODE1, VDP_MODE1_PS | VDP_MODE1_IE1);
1290     move_sr(0x2000);
1291     burn10(488 * 2 / 10);
1292     move_sr(0x2700);
1293     v_p = ram8[2];
1294     cnt_p = ram[0];
1295     ram[0] = ram[1] = ram[2] = 0;
1296     // count irqs
1297     move_sr(0x2000);
1298     while (read8(VDP_HV_COUNTER) != 4)
1299         ;
1300     while (read8(VDP_HV_COUNTER) != 228)
1301         ;
1302     move_sr(0x2700);
1303     VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
1304     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
1305
1306     expect(ok, v_p, 229);      // pending irq trigger
1307     expect(ok, cnt_p, 1);
1308     expect(ok, ram[0], 225);   // count
1309     expect(ok, ram8[2], 0);    // first line
1310     expect(ok, ram8[4], 224);  // last line
1311     return ok;
1312 }
1313
1314 static int t_irq_ack_v_h(void)
1315 {
1316     u16 *ram = (u16 *)0xfff000;
1317     u8 *ram8 = (u8 *)0xfff000;
1318     u16 s0, s1, s2;
1319     int ok = 1;
1320
1321     ram[0] = ram[1] = ram[2] =
1322     ram[4] = ram[5] = ram[6] = 0;
1323     memcpy_((void *)0xff0100, test_hint, test_hint_end - test_hint);
1324     memcpy_((void *)0xff0140, test_vint, test_vint_end - test_vint);
1325     VDP_setReg(10, 0);
1326     VDP_setReg(VDP_MODE1, VDP_MODE1_PS | VDP_MODE1_IE1);
1327     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_IE0);
1328     while (read8(VDP_HV_COUNTER) != 100)
1329         ;
1330     while (read8(VDP_HV_COUNTER) != 226)
1331         ;
1332     s0 = read16(VDP_CTRL_PORT);
1333     s1 = move_sr_and_read(0x2500, VDP_CTRL_PORT);
1334     burn10(666 / 10);
1335     s2 = move_sr_and_read(0x2000, VDP_CTRL_PORT);
1336     burn10(488 / 10);
1337     move_sr(0x2700);
1338     VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
1339     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
1340
1341     expect(ok, ram[4], 1);     // vint count
1342     expect(ok, ram8[10], 226); // vint line
1343     expect(ok, ram[0], 1);     // hint count
1344     expect(ok, ram8[2], 228);  // hint line
1345     expect_bits(ok, s0, SR_F, SR_F);
1346     expect_bits(ok, s1, 0, SR_F);
1347     expect_bits(ok, s2, 0, SR_F);
1348     return ok;
1349 }
1350
1351 static int t_irq_ack_v_h_2(void)
1352 {
1353     u16 *ram = (u16 *)0xfff000;
1354     u8 *ram8 = (u8 *)0xfff000;
1355     u16 s0, s1;
1356     int ok = 1;
1357
1358     ram[0] = ram[1] = ram[2] =
1359     ram[4] = ram[5] = ram[6] = 0;
1360     memcpy_((void *)0xff0100, test_hint, test_hint_end - test_hint);
1361     memcpy_((void *)0xff0140, test_vint, test_vint_end - test_vint);
1362     VDP_setReg(10, 0);
1363     while (read8(VDP_HV_COUNTER) != 100)
1364         ;
1365     while (read8(VDP_HV_COUNTER) != 226)
1366         ;
1367     s0 = read16(VDP_CTRL_PORT);
1368     test_v_h_2();
1369     s1 = read16(VDP_CTRL_PORT);
1370     VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
1371     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
1372
1373     expect(ok, ram[4], 2);     // vint count
1374     expect(ok, ram8[10], 226); // vint line
1375     expect(ok, ram[0], 1);     // hint count
1376     expect(ok, ram8[2], 227);  // hint line
1377     expect_bits(ok, s0, SR_F, SR_F);
1378     expect_bits(ok, s1, 0, SR_F);
1379     return ok;
1380 }
1381
1382 static int t_irq_ack_h_v(void)
1383 {
1384     u16 *ram = (u16 *)0xfff000;
1385     u8 *ram8 = (u8 *)0xfff000;
1386     u16 s0, s1, s[4];
1387     int ok = 1;
1388
1389     ram[0] = ram[1] = ram[2] =
1390     ram[4] = ram[5] = ram[6] = 0;
1391     memcpy_((void *)0xff0100, test_hint, test_hint_end - test_hint);
1392     memcpy_((void *)0xff0140, test_vint, test_vint_end - test_vint);
1393     VDP_setReg(10, 0);
1394     while (read8(VDP_HV_COUNTER) != 100)
1395         ;
1396     while (read8(VDP_HV_COUNTER) != 226)
1397         ;
1398     s0 = read16(VDP_CTRL_PORT);
1399     VDP_setReg(VDP_MODE1, VDP_MODE1_PS | VDP_MODE1_IE1);
1400     move_sr(0x2000);
1401     burn10(666 / 10);
1402     s1 = read16(VDP_CTRL_PORT);
1403     write_and_read1(VDP_CTRL_PORT, 0x8000 | (VDP_MODE2 << 8)
1404                      | VDP_MODE2_MD | VDP_MODE2_IE0, s);
1405     move_sr(0x2700);
1406     VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
1407     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
1408
1409     expect(ok, ram[0], 1);     // hint count
1410     expect(ok, ram8[2], 226);  // hint line
1411     expect(ok, ram[4], 1);     // vint count
1412     expect(ok, ram8[10], 228); // vint line
1413     expect_bits(ok, s0, SR_F, SR_F);
1414     expect_bits(ok, s1, SR_F, SR_F);
1415     expect_bits(ok, s[0], SR_F, SR_F);
1416     expect_bits(ok, s[1], SR_F, SR_F);
1417     expect_bits(ok, s[2], 0, SR_F);
1418     expect_bits(ok, s[3], 0, SR_F);
1419     return ok;
1420 }
1421
1422 static int t_irq_ack_h_v_2(void)
1423 {
1424     u16 *ram = (u16 *)0xfff000;
1425     u8 *ram8 = (u8 *)0xfff000;
1426     u16 s0, s1;
1427     int ok = 1;
1428
1429     ram[0] = ram[1] = ram[2] =
1430     ram[4] = ram[5] = ram[6] = 0;
1431     memcpy_((void *)0xff0100, test_hint, test_hint_end - test_hint);
1432     memcpy_((void *)0xff0140, test_vint, test_vint_end - test_vint);
1433     VDP_setReg(10, 0);
1434     while (read8(VDP_HV_COUNTER) != 100)
1435         ;
1436     while (read8(VDP_HV_COUNTER) != 226)
1437         ;
1438     s0 = read16(VDP_CTRL_PORT);
1439     test_h_v_2();
1440     s1 = read16(VDP_CTRL_PORT);
1441     VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
1442     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
1443
1444     expect(ok, ram[0], 2);     // hint count
1445     expect(ok, ram8[2], 226);  // hint first line
1446     expect(ok, ram8[4], 226);  // hint last line
1447     expect(ok, ram[4], 0);     // vint count
1448     expect(ok, ram8[10], 0);   // vint line
1449     expect_bits(ok, s0, SR_F, SR_F);
1450     expect_bits(ok, s1, 0, SR_F);
1451     return ok;
1452 }
1453
1454 static void t_irq_f_flag(void)
1455 {
1456     memcpy_((void *)0xff0140, test_f_vint, test_f_vint_end - test_f_vint);
1457     memset_((void *)0xff0000, 0, 10);
1458     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_IE0 | VDP_MODE2_DISP);
1459     test_f();
1460     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
1461 }
1462
1463 static int t_irq_f_flag_h40(void)
1464 {
1465     u8 f, *r = (u8 *)0xff0000;
1466     int ok = 1;
1467
1468     t_irq_f_flag();
1469
1470     expect_bits(ok, r[0], 0, SR_F);
1471     expect_bits(ok, r[1], 0, SR_F);
1472     expect_bits(ok, r[2], 0, SR_F);
1473     // hits 1-3 times in range 3-9, usually ~5
1474     f = r[3] | r[4] | r[5] | r[6] | r[7];
1475
1476     expect_bits(ok, r[10], 0, SR_F);
1477     expect_bits(ok, r[11], 0, SR_F);
1478     expect_bits(ok, f, SR_F, SR_F);
1479     return ok;
1480 }
1481
1482 static int t_irq_f_flag_h32(void)
1483 {
1484     u8 f, *r = (u8 *)0xff0000;
1485     int ok = 1;
1486
1487     VDP_setReg(VDP_MODE4, 0x00);
1488     t_irq_f_flag();
1489     VDP_setReg(VDP_MODE4, 0x81);
1490
1491     expect_bits(ok, r[0], 0, SR_F);
1492     expect_bits(ok, r[1], 0, SR_F);
1493     // hits 1-3 times in range 2-7, usually 3
1494     f = r[2] | r[3] | r[4] | r[5] | r[6] | r[7];
1495
1496     expect_bits(ok, r[8], 0, SR_F);
1497     expect_bits(ok, r[9], 0, SR_F);
1498     expect_bits(ok, r[10], 0, SR_F);
1499     expect_bits(ok, r[11], 0, SR_F);
1500     expect_bits(ok, f, SR_F, SR_F);
1501     return ok;
1502 }
1503
1504 // 32X
1505
1506 static int t_32x_init(void)
1507 {
1508     void (*do_32x_enable)(void) = (void *)0xff0040;
1509     u32 M_OK = MKLONG('M','_','O','K');
1510     u32 S_OK = MKLONG('S','_','O','K');
1511     u32 *r = (u32 *)0xa15100;
1512     u16 *r16 = (u16 *)r;
1513     int ok = 1;
1514
1515     expect(ok, r16[0x00/2], 0x82);
1516     expect(ok, r16[0x02/2], 0);
1517     expect(ok, r16[0x04/2], 0);
1518     expect(ok, r16[0x06/2], 0);
1519     expect(ok, r[0x14/4], 0);
1520     expect(ok, r[0x18/4], 0);
1521     expect(ok, r[0x1c/4], 0);
1522     write32(&r[0x20/4], 0); // master resp
1523     write32(&r[0x24/4], 0); // slave resp
1524
1525     // could just set RV, but BIOS reads ROM, so can't
1526     memcpy_(do_32x_enable, x32x_enable,
1527             x32x_enable_end - x32x_enable);
1528     do_32x_enable();
1529
1530     expect(ok, r16[0x00/2], 0x83);
1531     expect(ok, r16[0x02/2], 0);
1532     expect(ok, r16[0x04/2], 0);
1533     expect(ok, r16[0x06/2], 1); // RV
1534     expect(ok, r[0x14/4], 0);
1535     expect(ok, r[0x18/4], 0);
1536     expect(ok, r[0x1c/4], 0);
1537     expect(ok, r[0x20/4], M_OK);
1538     while (!read16(&r16[0x24/2]))
1539         ;
1540     expect(ok, r[0x24/4], S_OK);
1541     return ok;
1542 }
1543
1544 static void x32_cmd(enum x32x_cmd cmd, u16 is_slave)
1545 {
1546     u16 v, *r = (u16 *)0xa15120;
1547     u16 cmd_s = cmd | (is_slave << 15);
1548     write16(r, cmd_s);
1549     mem_barrier();
1550     while ((v = read16(r)) == cmd_s)
1551         burn10(1);
1552     if (v != 0)
1553         printf("cmd clr: %x\n", v);
1554 }
1555
1556 static int t_32x_echo(void)
1557 {
1558     u16 *r = (u16 *)0xa15120;
1559     int ok = 1;
1560
1561     write16(&r[0x02/2], 0x1234);
1562     x32_cmd(CMD_ECHO, 0);
1563     expect(ok, r[0x04/2], 0x1234);
1564     write16(&r[0x02/2], 0x2345);
1565     // mysteriously broken (random hangs)
1566     //x32_cmd(CMD_ECHO, 1);
1567     //expect(ok, r[0x04/2], 0x8345);
1568     return ok;
1569 }
1570
1571 static int t_32x_md_rom(void)
1572 {
1573     u32 *rl = (u32 *)0;
1574     int ok = 1;
1575
1576     expect(ok, rl[0x004/4], 0x880200);
1577     expect(ok, rl[0x100/4], 0x53454741);
1578     expect(ok, rl[0x70/4], 0);
1579     write32(&rl[0x70/4], ~0);
1580     write32(&rl[0x78/4], ~0);
1581     mem_barrier();
1582     expect(ok, rl[0x70/4], ~0);
1583     expect(ok, rl[0x78/4], 0x8802ae);
1584     // not tested: with RV 0x880000/0x900000 hangs
1585     return ok;
1586 }
1587
1588 enum {
1589     T_MD = 0,
1590     T_32 = 1, // 32X
1591 };
1592
1593 static const struct {
1594     u8 type;
1595     int (*test)(void);
1596     const char *name;
1597 } g_tests[] = {
1598 #if 0
1599     { T_MD, t_dma_zero_wrap,       "dma zero len + wrap" },
1600     { T_MD, t_dma_zero_fill,       "dma zero len + fill" },
1601     { T_MD, t_dma_ram_wrap,        "dma ram wrap" },
1602     { T_MD, t_dma_multi,           "dma multi" },
1603     { T_MD, t_dma_cram_wrap,       "dma cram wrap" },
1604     { T_MD, t_dma_vsram_wrap,      "dma vsram wrap" },
1605     { T_MD, t_dma_and_data,        "dma and data" },
1606     { T_MD, t_dma_short_cmd,       "dma short cmd" },
1607     { T_MD, t_dma_fill3_odd,       "dma fill3 odd" },
1608     { T_MD, t_dma_fill3_even,      "dma fill3 even" },
1609 #ifndef PICO // later
1610     { T_MD, t_dma_fill3_vsram,     "dma fill3 vsram" },
1611 #endif
1612     { T_MD, t_dma_fill_dis,        "dma fill disabled" },
1613     { T_MD, t_dma_fill_src,        "dma fill src incr" },
1614     { T_MD, t_dma_128k,            "dma 128k mode" },
1615     { T_MD, t_vdp_128k_b16,        "vdp 128k addr bit16" },
1616     // { t_vdp_128k_b16_inc,    "vdp 128k bit16 inc" }, // mystery
1617     { T_MD, t_vdp_reg_cmd,         "vdp reg w cmd reset" },
1618     { T_MD, t_vdp_sr_vb,           "vdp status reg vb" },
1619     { T_MD, t_z80mem_long_mirror,  "z80 ram long mirror" },
1620     { T_MD, t_z80mem_noreq_w,      "z80 ram noreq write" },
1621     { T_MD, t_z80mem_vdp_r,        "z80 vdp read" },
1622     // { t_z80mem_vdp_w,        "z80 vdp write" }, // hang
1623     { T_MD, t_tim_loop,            "time loop" },
1624     { T_MD, t_tim_z80_ram,         "time z80 ram" },
1625     { T_MD, t_tim_z80_ym,          "time z80 ym2612" },
1626     { T_MD, t_tim_z80_vdp,         "time z80 vdp" },
1627     { T_MD, t_tim_z80_bank_rom,    "time z80 bank rom" },
1628     { T_MD, t_tim_vcnt,            "time V counter" },
1629     { T_MD, t_tim_hblank_h40,      "time hblank h40" },
1630     { T_MD, t_tim_hblank_h32,      "time hblank h32" },
1631     { T_MD, t_tim_vdp_as_vram_w,   "time vdp vram w" },
1632     { T_MD, t_tim_vdp_as_cram_w,   "time vdp cram w" },
1633     { T_MD, t_irq_hint,            "irq4 / line" },
1634     { T_MD, t_irq_ack_v_h,         "irq ack v-h" },
1635     { T_MD, t_irq_ack_v_h_2,       "irq ack v-h 2" },
1636     { T_MD, t_irq_ack_h_v,         "irq ack h-v" },
1637     { T_MD, t_irq_ack_h_v_2,       "irq ack h-v 2" },
1638     { T_MD, t_irq_f_flag_h40,      "irq f flag h40" },
1639 #endif
1640     { T_MD, t_irq_f_flag_h32,      "irq f flag h32" },
1641
1642     // the first one enables 32X, so should be kept
1643     { T_32, t_32x_init,            "32x init" },
1644     { T_32, t_32x_echo,            "32x echo" },
1645     { T_32, t_32x_md_rom,          "32x rom" },
1646 };
1647
1648 static void setup_z80(void)
1649 {
1650     u8 *zram = (u8 *)0xa00000;
1651     int i, len;
1652
1653     /* z80 */
1654     write16(0xa11100, 0x100);
1655     write16(0xa11200, 0x100);
1656
1657     while (read16(0xa11100) & 0x100)
1658         ;
1659
1660     // load the default test program, clear it's data
1661     len = z80_test_end - z80_test;
1662     for (i = 0; i < len; i++)
1663         write8(&zram[i], z80_test[i]);
1664     for (i = 0x1000; i < 0x1007; i++)
1665         write8(&zram[i], 0);
1666
1667     // reset
1668     write16(0xa11200, 0x000);
1669     write16(0xa11100, 0x000);
1670     burn10(1);
1671     write16(0xa11200, 0x100);
1672     burn10(1);
1673
1674     // take back the bus
1675     write16(0xa11100, 0x100);
1676     while (read16(0xa11100) & 0x100)
1677         ;
1678 }
1679
1680 static void wait_next_vsync(void)
1681 {
1682     while (read16(VDP_CTRL_PORT) & 8)
1683         /* blanking */;
1684     while (!(read16(VDP_CTRL_PORT) & 8))
1685         /* not blanking */;
1686 }
1687
1688 static unused int hexinc(char *c)
1689 {
1690     (*c)++;
1691     if (*c > 'f') {
1692         *c = '0';
1693         return 1;
1694     }
1695     if (*c == '9' + 1)
1696         *c = 'a';
1697     return 0;
1698 }
1699
1700 int main()
1701 {
1702     int passed = 0;
1703     int skipped = 0;
1704     int have_32x;
1705     int ret;
1706     u8 v8;
1707     int i;
1708
1709     setup_z80();
1710
1711     /* io */
1712     write8(0xa10009, 0x40);
1713
1714     /* setup VDP */
1715     while (read16(VDP_CTRL_PORT) & 2)
1716         ;
1717
1718     VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
1719     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA);
1720     VDP_setReg(VDP_MODE3, 0x00);
1721     VDP_setReg(VDP_MODE4, 0x81);
1722     VDP_setReg(VDP_NT_SCROLLA, APLANE >> 10);
1723     VDP_setReg(VDP_NT_SCROLLB, BPLANE >> 13);
1724     VDP_setReg(VDP_SAT_BASE, SLIST >> 9);
1725     VDP_setReg(VDP_HSCROLL, HSCRL >> 10);
1726     VDP_setReg(VDP_AUTOINC, 2);
1727     VDP_setReg(VDP_SCROLLSZ, 0x01);
1728     VDP_setReg(VDP_BACKDROP, 0);
1729
1730     // early tests
1731     t_dma_zero_wrap_early();
1732     t_dma_zero_fill_early();
1733
1734     /* pattern 0 */
1735     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0));
1736     for (i = 0; i < 32 / 4; i++)
1737         write32(VDP_DATA_PORT, 0);
1738
1739     /* clear name tables */
1740     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(APLANE));
1741     for (i = 0; i < PLANE_W * PLANE_H / 2; i++)
1742         write32(VDP_DATA_PORT, 0);
1743
1744     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(BPLANE));
1745     for (i = 0; i < PLANE_W * PLANE_H / 2; i++)
1746         write32(VDP_DATA_PORT, 0);
1747
1748     /* SAT, h. scroll */
1749     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(SLIST));
1750     write32(VDP_DATA_PORT, 0);
1751
1752     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(HSCRL));
1753     write32(VDP_DATA_PORT, 0);
1754
1755     /* scroll plane vscroll */
1756     write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
1757     write32(VDP_DATA_PORT, 0);
1758     printf_ypos = 1;
1759
1760     /* load font */
1761     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(TILE_FONT_BASE));
1762     for (i = 0; i < FONT_LEN * 32 / 4; i++)
1763         write32(VDP_DATA_PORT, font_base[i]);
1764
1765     /* set colors */
1766     setup_default_palette();
1767
1768     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
1769
1770     have_32x = read32(0xa130ec) == MKLONG('M','A','R','S');
1771     v8 = read8(0xa10001);
1772     printf("MD version: %02x %s %s %s\n", v8,
1773         (v8 & 0x80) ? "world" : "jap",
1774         (v8 & 0x40) ? "pal" : "ntsc",
1775         have_32x ? "32X" : "");
1776
1777     for (i = 0; i < ARRAY_SIZE(g_tests); i++) {
1778         // print test number if we haven't scrolled away
1779         if (printf_ypos < CSCREEN_H) {
1780             int old_ypos = printf_ypos;
1781             printf_ypos = 0;
1782             printf("%02d/%02d", i, ARRAY_SIZE(g_tests));
1783             printf_ypos = old_ypos;
1784             printf_xpos = 0;
1785         }
1786         if ((g_tests[i].type & T_32) && !have_32x) {
1787             skipped++;
1788             continue;
1789         }
1790         ret = g_tests[i].test();
1791         if (ret != 1) {
1792             text_pal = 2;
1793             printf("failed %d: %s\n", i, g_tests[i].name);
1794             text_pal = 0;
1795         }
1796         else
1797             passed++;
1798     }
1799
1800     text_pal = 0;
1801     printf("%d/%d passed, %d skipped.\n",
1802            passed, ARRAY_SIZE(g_tests), skipped);
1803
1804     printf_ypos = 0;
1805     printf("     ");
1806
1807     while (!(get_input() & BTNM_A))
1808         wait_next_vsync();
1809
1810
1811     {
1812         char c[3] = { '0', '0', '0' };
1813         short hscroll = 0, vscroll = 0;
1814         short hsz = 1, vsz = 0;
1815         short cellmode = 0;
1816
1817         write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(APLANE));
1818
1819 #if 0
1820         for (i = 0, c[0] = 'a'; i < 8 * 1024 / 2; i++) {
1821             write16(VDP_DATA_PORT, (u16)c[0] - 32 + TILE_FONT_BASE / 32);
1822             c[0]++;
1823             if (c[0] == 'z' + 1)
1824                 c[0] = 'a';
1825         }
1826 #else
1827         for (i = 0; i < 8 * 1024 / 2 / 4; i++) {
1828             write16(VDP_DATA_PORT, (u16)'.'  - 32 + TILE_FONT_BASE / 32);
1829             write16(VDP_DATA_PORT, (u16)c[2] - 32 + TILE_FONT_BASE / 32);
1830             write16(VDP_DATA_PORT, (u16)c[1] - 32 + TILE_FONT_BASE / 32);
1831             write16(VDP_DATA_PORT, (u16)c[0] - 32 + TILE_FONT_BASE / 32);
1832             if (hexinc(&c[0]))
1833                 if (hexinc(&c[1]))
1834                     hexinc(&c[2]);
1835         }
1836 #endif
1837         while (get_input() & BTNM_A)
1838             wait_next_vsync();
1839
1840         wait_next_vsync();
1841         for (;;) {
1842             int b = get_input();
1843
1844             if (b & BTNM_C) {
1845                 hscroll = 1, vscroll = -1;
1846                 do {
1847                     wait_next_vsync();
1848                 } while (get_input() & BTNM_C);
1849                 cellmode ^= 1;
1850             }
1851             if (b & (BTNM_L | BTNM_R | BTNM_C)) {
1852                 hscroll += (b & BTNM_L) ? 1 : -1;
1853                 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(HSCRL));
1854                 write16(VDP_DATA_PORT, hscroll);
1855             }
1856             if (b & (BTNM_U | BTNM_D | BTNM_C)) {
1857                 vscroll += (b & BTNM_U) ? -1 : 1;
1858                 write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
1859                 if (cellmode) {
1860                     int end = (int)vscroll + 21;
1861                     for (i = vscroll; i < end; i++)
1862                         write32(VDP_DATA_PORT, i << 17);
1863                     VDP_setReg(VDP_MODE3, 0x04);
1864                 }
1865                 else {
1866                     write16(VDP_DATA_PORT, vscroll);
1867                     VDP_setReg(VDP_MODE3, 0x00);
1868                 }
1869             }
1870             if (b & BTNM_A) {
1871                 hsz = (hsz + 1) & 3;
1872                 do {
1873                     wait_next_vsync();
1874                 } while (get_input() & BTNM_A);
1875             }
1876             if (b & BTNM_B) {
1877                 vsz = (vsz + 1) & 3;
1878                 do {
1879                     wait_next_vsync();
1880                 } while (get_input() & BTNM_B);
1881             }
1882             VDP_setReg(VDP_SCROLLSZ, (vsz << 4) | hsz);
1883
1884             printf_xpos = 1;
1885             printf_ypos = 0;
1886             text_pal = 1;
1887             printf(" %d %d ", hsz, vsz);
1888
1889             wait_next_vsync();
1890         }
1891     }
1892
1893     for (;;)
1894         ;
1895
1896     return 0;
1897 }
1898
1899 // vim:ts=4:sw=4:expandtab