h-int reload test
[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 struct irq_test {
1272     u16 cnt;
1273     union {
1274         u16 hv;
1275         u8 v;
1276     } first, last;
1277 };
1278
1279 static int t_irq_hint(void)
1280 {
1281     struct irq_test *it = (void *)0xfff000;
1282     int ok = 1;
1283
1284     // for more fun, disable the display
1285     VDP_setReg(VDP_MODE2, VDP_MODE2_MD);
1286
1287     it->cnt = it->first.hv = it->last.hv = 0;
1288     memcpy_((void *)0xff0100, test_hint, test_hint_end - test_hint);
1289     VDP_setReg(10, 0);
1290     while (read8(VDP_HV_COUNTER) != 100)
1291         ;
1292     while (read8(VDP_HV_COUNTER) != 229)
1293         ;
1294     // take the pending irq
1295     VDP_setReg(VDP_MODE1, VDP_MODE1_PS | VDP_MODE1_IE1);
1296     move_sr(0x2000);
1297     burn10(488 * 2 / 10);
1298     move_sr(0x2700);
1299     expect(ok, it->first.v, 229);      // pending irq trigger
1300     expect(ok, it->cnt, 1);
1301
1302     // count irqs
1303     it->cnt = it->first.hv = it->last.hv = 0;
1304     move_sr(0x2000);
1305     while (read8(VDP_HV_COUNTER) != 4)
1306         ;
1307     while (read8(VDP_HV_COUNTER) != 228)
1308         ;
1309     move_sr(0x2700);
1310     expect(ok, it->cnt, 225);
1311     expect(ok, it->first.v, 0);
1312     expect(ok, it->last.v, 224);
1313
1314     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
1315
1316     // detect reload line
1317     it->cnt = it->first.hv = it->last.hv = 0;
1318     VDP_setReg(10, 17);
1319     move_sr(0x2000);
1320     while (read16(VDP_CTRL_PORT) & 8)
1321         /* blanking */;
1322     VDP_setReg(10, 255);
1323     while (read8(VDP_HV_COUNTER) != 228)
1324         ;
1325     move_sr(0x2700);
1326     expect(ok, it->cnt, 1);
1327     expect(ok, it->first.v, 17);
1328     expect(ok, it->last.v, 17);
1329
1330     VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
1331
1332     return ok;
1333 }
1334
1335 static int t_irq_ack_v_h(void)
1336 {
1337     u16 *ram = (u16 *)0xfff000;
1338     u8 *ram8 = (u8 *)0xfff000;
1339     u16 s0, s1, s2;
1340     int ok = 1;
1341
1342     ram[0] = ram[1] = ram[2] =
1343     ram[4] = ram[5] = ram[6] = 0;
1344     memcpy_((void *)0xff0100, test_hint, test_hint_end - test_hint);
1345     memcpy_((void *)0xff0140, test_vint, test_vint_end - test_vint);
1346     VDP_setReg(10, 0);
1347     /* ensure hcnt reload */
1348     while (!(read16(VDP_CTRL_PORT) & 8))
1349         /* not blanking */;
1350     while (read16(VDP_CTRL_PORT) & 8)
1351         /* blanking */;
1352     VDP_setReg(VDP_MODE1, VDP_MODE1_PS | VDP_MODE1_IE1);
1353     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_IE0);
1354     while (read8(VDP_HV_COUNTER) != 100)
1355         ;
1356     while (read8(VDP_HV_COUNTER) != 226)
1357         ;
1358     s0 = read16(VDP_CTRL_PORT);
1359     s1 = move_sr_and_read(0x2500, VDP_CTRL_PORT);
1360     burn10(666 / 10);
1361     s2 = move_sr_and_read(0x2000, VDP_CTRL_PORT);
1362     burn10(488 / 10);
1363     move_sr(0x2700);
1364     VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
1365     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
1366
1367     expect(ok, ram[4], 1);     // vint count
1368     expect(ok, ram8[10], 226); // vint line
1369     expect(ok, ram[0], 1);     // hint count
1370     expect(ok, ram8[2], 228);  // hint line
1371     expect_bits(ok, s0, SR_F, SR_F);
1372     expect_bits(ok, s1, 0, SR_F);
1373     expect_bits(ok, s2, 0, SR_F);
1374     return ok;
1375 }
1376
1377 static int t_irq_ack_v_h_2(void)
1378 {
1379     u16 *ram = (u16 *)0xfff000;
1380     u8 *ram8 = (u8 *)0xfff000;
1381     u16 s0, s1;
1382     int ok = 1;
1383
1384     ram[0] = ram[1] = ram[2] =
1385     ram[4] = ram[5] = ram[6] = 0;
1386     memcpy_((void *)0xff0100, test_hint, test_hint_end - test_hint);
1387     memcpy_((void *)0xff0140, test_vint, test_vint_end - test_vint);
1388     VDP_setReg(10, 0);
1389     while (read8(VDP_HV_COUNTER) != 100)
1390         ;
1391     while (read8(VDP_HV_COUNTER) != 226)
1392         ;
1393     s0 = read16(VDP_CTRL_PORT);
1394     test_v_h_2();
1395     s1 = read16(VDP_CTRL_PORT);
1396     VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
1397     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
1398
1399     expect(ok, ram[4], 2);     // vint count
1400     expect(ok, ram8[10], 226); // vint line
1401     expect(ok, ram[0], 1);     // hint count
1402     expect(ok, ram8[2], 227);  // hint line
1403     expect_bits(ok, s0, SR_F, SR_F);
1404     expect_bits(ok, s1, 0, SR_F);
1405     return ok;
1406 }
1407
1408 static int t_irq_ack_h_v(void)
1409 {
1410     u16 *ram = (u16 *)0xfff000;
1411     u8 *ram8 = (u8 *)0xfff000;
1412     u16 s0, s1, s[4];
1413     int ok = 1;
1414
1415     ram[0] = ram[1] = ram[2] =
1416     ram[4] = ram[5] = ram[6] = 0;
1417     memcpy_((void *)0xff0100, test_hint, test_hint_end - test_hint);
1418     memcpy_((void *)0xff0140, test_vint, test_vint_end - test_vint);
1419     VDP_setReg(10, 0);
1420     while (read8(VDP_HV_COUNTER) != 100)
1421         ;
1422     while (read8(VDP_HV_COUNTER) != 226)
1423         ;
1424     s0 = read16(VDP_CTRL_PORT);
1425     VDP_setReg(VDP_MODE1, VDP_MODE1_PS | VDP_MODE1_IE1);
1426     move_sr(0x2000);
1427     burn10(666 / 10);
1428     s1 = read16(VDP_CTRL_PORT);
1429     write_and_read1(VDP_CTRL_PORT, 0x8000 | (VDP_MODE2 << 8)
1430                      | VDP_MODE2_MD | VDP_MODE2_IE0, s);
1431     move_sr(0x2700);
1432     VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
1433     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
1434
1435     expect(ok, ram[0], 1);     // hint count
1436     expect(ok, ram8[2], 226);  // hint line
1437     expect(ok, ram[4], 1);     // vint count
1438     expect(ok, ram8[10], 228); // vint line
1439     expect_bits(ok, s0, SR_F, SR_F);
1440     expect_bits(ok, s1, SR_F, SR_F);
1441     expect_bits(ok, s[0], SR_F, SR_F);
1442     expect_bits(ok, s[1], SR_F, SR_F);
1443     expect_bits(ok, s[2], 0, SR_F);
1444     expect_bits(ok, s[3], 0, SR_F);
1445     return ok;
1446 }
1447
1448 static int t_irq_ack_h_v_2(void)
1449 {
1450     u16 *ram = (u16 *)0xfff000;
1451     u8 *ram8 = (u8 *)0xfff000;
1452     u16 s0, s1;
1453     int ok = 1;
1454
1455     ram[0] = ram[1] = ram[2] =
1456     ram[4] = ram[5] = ram[6] = 0;
1457     memcpy_((void *)0xff0100, test_hint, test_hint_end - test_hint);
1458     memcpy_((void *)0xff0140, test_vint, test_vint_end - test_vint);
1459     VDP_setReg(10, 0);
1460     while (read8(VDP_HV_COUNTER) != 100)
1461         ;
1462     while (read8(VDP_HV_COUNTER) != 226)
1463         ;
1464     s0 = read16(VDP_CTRL_PORT);
1465     test_h_v_2();
1466     s1 = read16(VDP_CTRL_PORT);
1467     VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
1468     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
1469
1470     expect(ok, ram[0], 2);     // hint count
1471     expect(ok, ram8[2], 226);  // hint first line
1472     expect(ok, ram8[4], 226);  // hint last line
1473     expect(ok, ram[4], 0);     // vint count
1474     expect(ok, ram8[10], 0);   // vint line
1475     expect_bits(ok, s0, SR_F, SR_F);
1476     expect_bits(ok, s1, 0, SR_F);
1477     return ok;
1478 }
1479
1480 static void t_irq_f_flag(void)
1481 {
1482     memcpy_((void *)0xff0140, test_f_vint, test_f_vint_end - test_f_vint);
1483     memset_((void *)0xff0000, 0, 10);
1484     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_IE0 | VDP_MODE2_DISP);
1485     test_f();
1486     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
1487 }
1488
1489 static int t_irq_f_flag_h40(void)
1490 {
1491     u8 f, *r = (u8 *)0xff0000;
1492     int ok = 1;
1493
1494     t_irq_f_flag();
1495
1496     expect_bits(ok, r[0], 0, SR_F);
1497     expect_bits(ok, r[1], 0, SR_F);
1498     expect_bits(ok, r[2], 0, SR_F);
1499     // hits 1-3 times in range 3-9, usually ~5
1500     f = r[3] | r[4] | r[5] | r[6] | r[7];
1501
1502     expect_bits(ok, r[10], 0, SR_F);
1503     expect_bits(ok, r[11], 0, SR_F);
1504     expect_bits(ok, f, SR_F, SR_F);
1505     return ok;
1506 }
1507
1508 static int t_irq_f_flag_h32(void)
1509 {
1510     u8 f, *r = (u8 *)0xff0000;
1511     int ok = 1;
1512
1513     VDP_setReg(VDP_MODE4, 0x00);
1514     t_irq_f_flag();
1515     VDP_setReg(VDP_MODE4, 0x81);
1516
1517     expect_bits(ok, r[0], 0, SR_F);
1518     expect_bits(ok, r[1], 0, SR_F);
1519     // hits 1-3 times in range 2-7, usually 3
1520     f = r[2] | r[3] | r[4] | r[5] | r[6] | r[7];
1521
1522     expect_bits(ok, r[8], 0, SR_F);
1523     expect_bits(ok, r[9], 0, SR_F);
1524     expect_bits(ok, r[10], 0, SR_F);
1525     expect_bits(ok, r[11], 0, SR_F);
1526     expect_bits(ok, f, SR_F, SR_F);
1527     return ok;
1528 }
1529
1530 // 32X
1531
1532 static int t_32x_init(void)
1533 {
1534     void (*do_32x_enable)(void) = (void *)0xff0040;
1535     u32 M_OK = MKLONG('M','_','O','K');
1536     u32 S_OK = MKLONG('S','_','O','K');
1537     u32 *r = (u32 *)0xa15100;
1538     u16 *r16 = (u16 *)r;
1539     int i, ok = 1;
1540
1541     //v1070 = read32(0x1070);
1542
1543     /* what does REN mean exactly?
1544      * Seems to be sometimes clear after reset */
1545     for (i = 0; i < 1000000; i++)
1546         if (read16(r16) & 0x80)
1547             break;
1548     expect(ok, r16[0x00/2], 0x82);
1549     expect(ok, r16[0x02/2], 0);
1550     expect(ok, r16[0x04/2], 0);
1551     expect(ok, r16[0x06/2], 0);
1552     expect(ok, r[0x14/4], 0);
1553     expect(ok, r[0x18/4], 0);
1554     expect(ok, r[0x1c/4], 0);
1555     write32(&r[0x20/4], 0); // master resp
1556     write32(&r[0x24/4], 0); // slave resp
1557     write32(&r[0x28/4], 0);
1558     write32(&r[0x2c/4], 0);
1559
1560     // could just set RV, but BIOS reads ROM, so can't
1561     memcpy_(do_32x_enable, x32x_enable,
1562             x32x_enable_end - x32x_enable);
1563     do_32x_enable();
1564
1565     expect(ok, r16[0x00/2], 0x83);
1566     expect(ok, r16[0x02/2], 0);
1567     expect(ok, r16[0x04/2], 0);
1568     expect(ok, r16[0x06/2], 1); // RV
1569     expect(ok, r[0x14/4], 0);
1570     expect(ok, r[0x18/4], 0);
1571     expect(ok, r[0x1c/4], 0);
1572     expect(ok, r[0x20/4], M_OK);
1573     while (!read16(&r16[0x24/2]))
1574         ;
1575     expect(ok, r[0x24/4], S_OK);
1576     write32(&r[0x20/4], 0);
1577     return ok;
1578 }
1579
1580 static void x32_cmd(enum x32x_cmd cmd, u32 a0, u32 a1, u16 is_slave)
1581 {
1582     u16 v, *r = (u16 *)0xa15120;
1583     u16 cmd_s = cmd | (is_slave << 15);
1584     int i;
1585
1586     write32(&r[4/2], a0);
1587     write32(&r[8/2], a1);
1588     mem_barrier();
1589     write16(r, cmd_s);
1590     mem_barrier();
1591     for (i = 0; i < 10000 && (v = read16(r)) == cmd_s; i++)
1592         burn10(1);
1593     if (v != 0) {
1594         printf("cmd clr: %x\n", v);
1595         mem_barrier();
1596         printf("c, e: %02x %02x\n", r[0x0c/2],  r[0x0e/2]);
1597         write16(r, 0);
1598     }
1599     v = read16(&r[1]);
1600     if (v != 0) {
1601         printf("cmd err: %x\n", v);
1602         write16(&r[1], 0);
1603     }
1604 }
1605
1606 static int t_32x_echo(void)
1607 {
1608     u16 *r = (u16 *)0xa15120;
1609     int ok = 1;
1610
1611     x32_cmd(CMD_ECHO, 0x12340000, 0, 0);
1612     expect(ok, r[0x06/2], 0x1234);
1613     x32_cmd(CMD_ECHO, 0x23450000, 0, 1);
1614     expect(ok, r[0x06/2], 0xa345);
1615     return ok;
1616 }
1617
1618 static int t_32x_md_bios(void)
1619 {
1620     void (*do_call_c0)(int a, int d) = (void *)0xff0040;
1621     u8 *rmb = (u8 *)0xff0000;
1622     u32 *rl = (u32 *)0;
1623     int ok = 1;
1624
1625     memcpy_(do_call_c0, test_32x_b_c0,
1626             test_32x_b_c0_end - test_32x_b_c0);
1627     write8(rmb, 0);
1628     do_call_c0(0xff0000, 0x5a);
1629
1630     expect(ok, rmb[0], 0x5a);
1631     expect(ok, rl[0x04/4], 0x880200);
1632     return ok;
1633 }
1634
1635 static int t_32x_md_rom(void)
1636 {
1637     u32 *rl = (u32 *)0;
1638     int ok = 1;
1639
1640     expect(ok, rl[0x004/4], 0x880200);
1641     expect(ok, rl[0x100/4], 0x53454741);
1642     expect(ok, rl[0x70/4], 0);
1643     write32(&rl[0x70/4], 0xa5123456);
1644     write32(&rl[0x78/4], ~0);
1645     mem_barrier();
1646     expect(ok, rl[0x78/4], 0x8802ae);
1647     expect(ok, rl[0x70/4], 0xa5123456);
1648     //expect(ok, rl[0x1070/4], v1070);
1649     write32(&rl[0x70/4], 0);
1650     // with RV 0x880000/0x900000 hangs, can't test
1651     return ok;
1652 }
1653
1654 static int t_32x_md_fb(void)
1655 {
1656     u8  *fbb = (u8 *)0x840000;
1657     u16 *fbw = (u16 *)fbb;
1658     u32 *fbl = (u32 *)fbb;
1659     u8  *fob = (u8 *)0x860000;
1660     u16 *fow = (u16 *)fob;
1661     u32 *fol = (u32 *)fob;
1662     int ok = 1;
1663
1664     fbl[0] = 0x12345678;
1665     fol[1] = 0x89abcdef;
1666     mem_barrier();
1667     expect(ok, fbw[1], 0x5678);
1668     expect(ok, fow[2], 0x89ab);
1669     fbb[0] = 0;
1670     fob[1] = 0;
1671     fbw[1] = 0;
1672     fow[2] = 0;
1673     fow[3] = 1;
1674     mem_barrier();
1675     fow[3] = 0x200;
1676     mem_barrier();
1677     expect(ok, fol[0], 0x12340000);
1678     expect(ok, fbl[1], 0x89ab0201);
1679     return ok;
1680 }
1681
1682 static int t_32x_sh_fb(void)
1683 {
1684     u32 *fbl = (u32 *)0x840000;
1685     int ok = 1;
1686
1687     fbl[0] = 0x12345678;
1688     fbl[1] = 0x89abcdef;
1689     mem_barrier();
1690     write8(0xa15100, 0x80); // FM=1
1691     x32_cmd(CMD_WRITE8,  0x24000000, 0, 0);
1692     x32_cmd(CMD_WRITE8,  0x24020001, 0, 0);
1693     x32_cmd(CMD_WRITE16, 0x24000002, 0, 0);
1694     x32_cmd(CMD_WRITE16, 0x24020000, 0, 0);
1695     x32_cmd(CMD_WRITE32, 0x24020004, 0x5a0000a5, 1);
1696     write8(0xa15100, 0x00); // FM=0
1697     mem_barrier();
1698     expect(ok, fbl[0], 0x12340000);
1699     expect(ok, fbl[1], 0x5aabcda5);
1700     return ok;
1701 }
1702
1703 enum {
1704     T_MD = 0,
1705     T_32 = 1, // 32X
1706 };
1707
1708 static const struct {
1709     u8 type;
1710     int (*test)(void);
1711     const char *name;
1712 } g_tests[] = {
1713     { T_MD, t_dma_zero_wrap,       "dma zero len + wrap" },
1714     { T_MD, t_dma_zero_fill,       "dma zero len + fill" },
1715     { T_MD, t_dma_ram_wrap,        "dma ram wrap" },
1716     { T_MD, t_dma_multi,           "dma multi" },
1717     { T_MD, t_dma_cram_wrap,       "dma cram wrap" },
1718     { T_MD, t_dma_vsram_wrap,      "dma vsram wrap" },
1719     { T_MD, t_dma_and_data,        "dma and data" },
1720     { T_MD, t_dma_short_cmd,       "dma short cmd" },
1721     { T_MD, t_dma_fill3_odd,       "dma fill3 odd" },
1722     { T_MD, t_dma_fill3_even,      "dma fill3 even" },
1723 #ifndef PICO // later
1724     { T_MD, t_dma_fill3_vsram,     "dma fill3 vsram" },
1725 #endif
1726     { T_MD, t_dma_fill_dis,        "dma fill disabled" },
1727     { T_MD, t_dma_fill_src,        "dma fill src incr" },
1728     { T_MD, t_dma_128k,            "dma 128k mode" },
1729     { T_MD, t_vdp_128k_b16,        "vdp 128k addr bit16" },
1730     // { t_vdp_128k_b16_inc,    "vdp 128k bit16 inc" }, // mystery
1731     { T_MD, t_vdp_reg_cmd,         "vdp reg w cmd reset" },
1732     { T_MD, t_vdp_sr_vb,           "vdp status reg vb" },
1733     { T_MD, t_z80mem_long_mirror,  "z80 ram long mirror" },
1734     { T_MD, t_z80mem_noreq_w,      "z80 ram noreq write" },
1735     { T_MD, t_z80mem_vdp_r,        "z80 vdp read" },
1736     // { t_z80mem_vdp_w,        "z80 vdp write" }, // hang
1737     { T_MD, t_tim_loop,            "time loop" },
1738     { T_MD, t_tim_z80_ram,         "time z80 ram" },
1739     { T_MD, t_tim_z80_ym,          "time z80 ym2612" },
1740     { T_MD, t_tim_z80_vdp,         "time z80 vdp" },
1741     { T_MD, t_tim_z80_bank_rom,    "time z80 bank rom" },
1742     { T_MD, t_tim_vcnt,            "time V counter" },
1743     { T_MD, t_tim_hblank_h40,      "time hblank h40" },
1744     { T_MD, t_tim_hblank_h32,      "time hblank h32" },
1745     { T_MD, t_tim_vdp_as_vram_w,   "time vdp vram w" },
1746     { T_MD, t_tim_vdp_as_cram_w,   "time vdp cram w" },
1747     { T_MD, t_irq_hint,            "irq4 / line" },
1748     { T_MD, t_irq_ack_v_h,         "irq ack v-h" },
1749     { T_MD, t_irq_ack_v_h_2,       "irq ack v-h 2" },
1750     { T_MD, t_irq_ack_h_v,         "irq ack h-v" },
1751     { T_MD, t_irq_ack_h_v_2,       "irq ack h-v 2" },
1752     { T_MD, t_irq_f_flag_h40,      "irq f flag h40" },
1753     { T_MD, t_irq_f_flag_h32,      "irq f flag h32" },
1754
1755     // the first one enables 32X, so must be kept
1756     // all tests assume RV=1 FM=0
1757     { T_32, t_32x_init,            "32x init" },
1758     { T_32, t_32x_echo,            "32x echo" },
1759     { T_32, t_32x_md_bios,         "32x md bios" },
1760     { T_32, t_32x_md_rom,          "32x md rom" },
1761     { T_32, t_32x_md_fb,           "32x md fb" },
1762     { T_32, t_32x_sh_fb,           "32x sh fb" },
1763 };
1764
1765 static void setup_z80(void)
1766 {
1767     u8 *zram = (u8 *)0xa00000;
1768     int i, len;
1769
1770     /* z80 */
1771     write16(0xa11100, 0x100);
1772     write16(0xa11200, 0x100);
1773
1774     while (read16(0xa11100) & 0x100)
1775         ;
1776
1777     // load the default test program, clear it's data
1778     len = z80_test_end - z80_test;
1779     for (i = 0; i < len; i++)
1780         write8(&zram[i], z80_test[i]);
1781     for (i = 0x1000; i < 0x1007; i++)
1782         write8(&zram[i], 0);
1783
1784     // reset
1785     write16(0xa11200, 0x000);
1786     write16(0xa11100, 0x000);
1787     burn10(1);
1788     write16(0xa11200, 0x100);
1789     burn10(1);
1790
1791     // take back the bus
1792     write16(0xa11100, 0x100);
1793     while (read16(0xa11100) & 0x100)
1794         ;
1795 }
1796
1797 static void wait_next_vsync(void)
1798 {
1799     while (read16(VDP_CTRL_PORT) & 8)
1800         /* blanking */;
1801     while (!(read16(VDP_CTRL_PORT) & 8))
1802         /* not blanking */;
1803 }
1804
1805 static unused int hexinc(char *c)
1806 {
1807     (*c)++;
1808     if (*c > 'f') {
1809         *c = '0';
1810         return 1;
1811     }
1812     if (*c == '9' + 1)
1813         *c = 'a';
1814     return 0;
1815 }
1816
1817 int main()
1818 {
1819     int passed = 0;
1820     int skipped = 0;
1821     int have_32x;
1822     int ret;
1823     u8 v8;
1824     int i;
1825
1826     setup_z80();
1827
1828     /* io */
1829     write8(0xa10009, 0x40);
1830
1831     /* setup VDP */
1832     while (read16(VDP_CTRL_PORT) & 2)
1833         ;
1834
1835     VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
1836     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA);
1837     VDP_setReg(VDP_MODE3, 0x00);
1838     VDP_setReg(VDP_MODE4, 0x81);
1839     VDP_setReg(VDP_NT_SCROLLA, APLANE >> 10);
1840     VDP_setReg(VDP_NT_SCROLLB, BPLANE >> 13);
1841     VDP_setReg(VDP_SAT_BASE, SLIST >> 9);
1842     VDP_setReg(VDP_HSCROLL, HSCRL >> 10);
1843     VDP_setReg(VDP_AUTOINC, 2);
1844     VDP_setReg(VDP_SCROLLSZ, 0x01);
1845     VDP_setReg(VDP_BACKDROP, 0);
1846
1847     // early tests
1848     t_dma_zero_wrap_early();
1849     t_dma_zero_fill_early();
1850
1851     /* pattern 0 */
1852     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0));
1853     for (i = 0; i < 32 / 4; i++)
1854         write32(VDP_DATA_PORT, 0);
1855
1856     /* clear name tables */
1857     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(APLANE));
1858     for (i = 0; i < PLANE_W * PLANE_H / 2; i++)
1859         write32(VDP_DATA_PORT, 0);
1860
1861     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(BPLANE));
1862     for (i = 0; i < PLANE_W * PLANE_H / 2; i++)
1863         write32(VDP_DATA_PORT, 0);
1864
1865     /* SAT, h. scroll */
1866     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(SLIST));
1867     write32(VDP_DATA_PORT, 0);
1868
1869     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(HSCRL));
1870     write32(VDP_DATA_PORT, 0);
1871
1872     /* scroll plane vscroll */
1873     write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
1874     write32(VDP_DATA_PORT, 0);
1875     printf_ypos = 1;
1876
1877     /* load font */
1878     write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(TILE_FONT_BASE));
1879     for (i = 0; i < FONT_LEN * 32 / 4; i++)
1880         write32(VDP_DATA_PORT, font_base[i]);
1881
1882     /* set colors */
1883     setup_default_palette();
1884
1885     VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
1886
1887     have_32x = read32(0xa130ec) == MKLONG('M','A','R','S');
1888     v8 = read8(0xa10001);
1889     printf("MD version: %02x %s %s %s\n", v8,
1890         (v8 & 0x80) ? "world" : "jap",
1891         (v8 & 0x40) ? "pal" : "ntsc",
1892         have_32x ? "32X" : "");
1893
1894     for (i = 0; i < ARRAY_SIZE(g_tests); i++) {
1895         // print test number if we haven't scrolled away
1896         if (printf_ypos < CSCREEN_H) {
1897             int old_ypos = printf_ypos;
1898             printf_ypos = 0;
1899             printf("%02d/%02d", i, ARRAY_SIZE(g_tests));
1900             printf_ypos = old_ypos;
1901             printf_xpos = 0;
1902         }
1903         if ((g_tests[i].type & T_32) && !have_32x) {
1904             skipped++;
1905             continue;
1906         }
1907         ret = g_tests[i].test();
1908         if (ret != 1) {
1909             text_pal = 2;
1910             printf("failed %d: %s\n", i, g_tests[i].name);
1911             text_pal = 0;
1912         }
1913         else
1914             passed++;
1915     }
1916
1917     text_pal = 0;
1918     printf("%d/%d passed, %d skipped.\n",
1919            passed, ARRAY_SIZE(g_tests), skipped);
1920
1921     printf_ypos = 0;
1922     printf("     ");
1923
1924     while (!(get_input() & BTNM_A))
1925         wait_next_vsync();
1926
1927
1928     {
1929         char c[3] = { '0', '0', '0' };
1930         short hscroll = 0, vscroll = 0;
1931         short hsz = 1, vsz = 0;
1932         short cellmode = 0;
1933
1934         write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(APLANE));
1935
1936 #if 0
1937         for (i = 0, c[0] = 'a'; i < 8 * 1024 / 2; i++) {
1938             write16(VDP_DATA_PORT, (u16)c[0] - 32 + TILE_FONT_BASE / 32);
1939             c[0]++;
1940             if (c[0] == 'z' + 1)
1941                 c[0] = 'a';
1942         }
1943 #else
1944         for (i = 0; i < 8 * 1024 / 2 / 4; i++) {
1945             write16(VDP_DATA_PORT, (u16)'.'  - 32 + TILE_FONT_BASE / 32);
1946             write16(VDP_DATA_PORT, (u16)c[2] - 32 + TILE_FONT_BASE / 32);
1947             write16(VDP_DATA_PORT, (u16)c[1] - 32 + TILE_FONT_BASE / 32);
1948             write16(VDP_DATA_PORT, (u16)c[0] - 32 + TILE_FONT_BASE / 32);
1949             if (hexinc(&c[0]))
1950                 if (hexinc(&c[1]))
1951                     hexinc(&c[2]);
1952         }
1953 #endif
1954         while (get_input() & BTNM_A)
1955             wait_next_vsync();
1956
1957         wait_next_vsync();
1958         for (;;) {
1959             int b = get_input();
1960
1961             if (b & BTNM_C) {
1962                 hscroll = 1, vscroll = -1;
1963                 do {
1964                     wait_next_vsync();
1965                 } while (get_input() & BTNM_C);
1966                 cellmode ^= 1;
1967             }
1968             if (b & (BTNM_L | BTNM_R | BTNM_C)) {
1969                 hscroll += (b & BTNM_L) ? 1 : -1;
1970                 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(HSCRL));
1971                 write16(VDP_DATA_PORT, hscroll);
1972             }
1973             if (b & (BTNM_U | BTNM_D | BTNM_C)) {
1974                 vscroll += (b & BTNM_U) ? -1 : 1;
1975                 write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
1976                 if (cellmode) {
1977                     int end = (int)vscroll + 21;
1978                     for (i = vscroll; i < end; i++)
1979                         write32(VDP_DATA_PORT, i << 17);
1980                     VDP_setReg(VDP_MODE3, 0x04);
1981                 }
1982                 else {
1983                     write16(VDP_DATA_PORT, vscroll);
1984                     VDP_setReg(VDP_MODE3, 0x00);
1985                 }
1986             }
1987             if (b & BTNM_A) {
1988                 hsz = (hsz + 1) & 3;
1989                 do {
1990                     wait_next_vsync();
1991                 } while (get_input() & BTNM_A);
1992             }
1993             if (b & BTNM_B) {
1994                 vsz = (vsz + 1) & 3;
1995                 do {
1996                     wait_next_vsync();
1997                 } while (get_input() & BTNM_B);
1998             }
1999             VDP_setReg(VDP_SCROLLSZ, (vsz << 4) | hsz);
2000
2001             printf_xpos = 1;
2002             printf_ypos = 0;
2003             text_pal = 1;
2004             printf(" %d %d ", hsz, vsz);
2005
2006             wait_next_vsync();
2007         }
2008     }
2009
2010     for (;;)
2011         ;
2012
2013     return 0;
2014 }
2015
2016 // vim:ts=4:sw=4:expandtab