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