testpico: 32x vint tests
[megadrive.git] / testpico / main.c
CommitLineData
ffd4b35c 1/*
2 * This software is released into the public domain.
3 * See UNLICENSE file in top level directory.
4 */
5#include <stdlib.h>
6#include <stdarg.h>
9d39a80e 7#include "common.h"
ffd4b35c 8#include "asmtools.h"
5073ab5a 9//#pragma GCC diagnostic ignored "-Wunused-function"
ffd4b35c 10
30a57837 11#ifndef VERSION
12#define VERSION "unknown build"
13#endif
14
ffd4b35c 15#define VDP_DATA_PORT 0xC00000
16#define VDP_CTRL_PORT 0xC00004
a385208c 17#define VDP_HV_COUNTER 0xC00008
ffd4b35c 18
19#define TILE_MEM_END 0xB000
20
21#define FONT_LEN 128
a385208c 22#define TILE_FONT_BASE (TILE_MEM_END - FONT_LEN * 32)
ffd4b35c 23
24/* note: using ED menu's layout here.. */
25#define WPLANE (TILE_MEM_END + 0x0000)
26#define HSCRL (TILE_MEM_END + 0x0800)
27#define SLIST (TILE_MEM_END + 0x0C00)
28#define APLANE (TILE_MEM_END + 0x1000)
29#define BPLANE (TILE_MEM_END + 0x3000)
30
ffd4b35c 31#define write16_z80le(a, d) \
32 ((volatile u8 *)(a))[0] = (u8)(d), \
33 ((volatile u8 *)(a))[1] = ((d) >> 8)
34
35static inline u16 read16_z80le(const void *a_)
36{
37 volatile const u8 *a = (volatile const u8 *)a_;
38 return a[0] | ((u16)a[1] << 8);
39}
40
41#define CTL_WRITE_VRAM(adr) \
42 (((0x4000 | ((adr) & 0x3FFF)) << 16) | ((adr) >> 14) | 0x00)
43#define CTL_WRITE_VSRAM(adr) \
44 (((0x4000 | ((adr) & 0x3FFF)) << 16) | ((adr) >> 14) | 0x10)
45#define CTL_WRITE_CRAM(adr) \
46 (((0xC000 | ((adr) & 0x3FFF)) << 16) | ((adr) >> 14) | 0x00)
47#define CTL_READ_VRAM(adr) \
48 (((0x0000 | ((adr) & 0x3FFF)) << 16) | ((adr) >> 14) | 0x00)
49#define CTL_READ_VSRAM(adr) \
50 (((0x0000 | ((adr) & 0x3FFF)) << 16) | ((adr) >> 14) | 0x10)
51#define CTL_READ_CRAM(adr) \
52 (((0x0000 | ((adr) & 0x3FFF)) << 16) | ((adr) >> 14) | 0x20)
53
54#define CTL_WRITE_DMA 0x80
55
56#define VDP_setReg(r, v) \
57 write16(VDP_CTRL_PORT, 0x8000 | ((r) << 8) | ((v) & 0xff))
58
59enum {
60 VDP_MODE1 = 0x00,
61 VDP_MODE2 = 0x01,
62 VDP_NT_SCROLLA = 0x02,
63 VDP_NT_WIN = 0x03,
64 VDP_NT_SCROLLB = 0x04,
65 VDP_SAT_BASE = 0x05,
66 VDP_BACKDROP = 0x07,
67 VDP_MODE3 = 0x0b,
68 VDP_MODE4 = 0x0c,
69 VDP_HSCROLL = 0x0d,
70 VDP_AUTOINC = 0x0f,
71 VDP_SCROLLSZ = 0x10,
72 VDP_DMA_LEN0 = 0x13,
73 VDP_DMA_LEN1 = 0x14,
74 VDP_DMA_SRC0 = 0x15,
75 VDP_DMA_SRC1 = 0x16,
76 VDP_DMA_SRC2 = 0x17,
77};
78
79#define VDP_MODE1_PS 0x04
80#define VDP_MODE1_IE1 0x10 // h int
81#define VDP_MODE2_MD 0x04
82#define VDP_MODE2_PAL 0x08 // 30 col
83#define VDP_MODE2_DMA 0x10
84#define VDP_MODE2_IE0 0x20 // v int
85#define VDP_MODE2_DISP 0x40
a385208c 86#define VDP_MODE2_128K 0x80
87
88#define SR_PAL (1 << 0)
89#define SR_DMA (1 << 1)
90#define SR_HB (1 << 2)
91#define SR_VB (1 << 3)
92#define SR_ODD (1 << 4)
93#define SR_C (1 << 5)
94#define SR_SOVR (1 << 6)
95#define SR_F (1 << 7)
96#define SR_FULL (1 << 8)
97#define SR_EMPT (1 << 9)
ffd4b35c 98
99/* cell counts */
100#define LEFT_BORDER 1 /* lame TV */
101#define PLANE_W 64
102#define PLANE_H 32
103#define CSCREEN_H 28
104
105/* data.s */
106extern const u32 font_base[];
107extern const u8 z80_test[];
108extern const u8 z80_test_end[];
109
110static int text_pal;
111
112static noinline void VDP_drawTextML(const char *str, u16 plane_base,
113 u16 x, u16 y)
114{
115 const u8 *src = (const u8 *)str;
116 u16 basetile = text_pal << 13;
117 int max_len = 40 - LEFT_BORDER;
118 int len;
119 u32 addr;
120
121 x += LEFT_BORDER;
122
123 for (len = 0; str[len] && len < max_len; len++)
124 ;
125 if (len > (PLANE_W - x))
126 len = PLANE_W - x;
127
128 addr = plane_base + ((x + (PLANE_W * y)) << 1);
129 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(addr));
130
131 while (len-- > 0) {
132 write16(VDP_DATA_PORT,
133 basetile | ((*src++) - 32 + TILE_FONT_BASE / 32));
134 }
135}
136
137static int printf_ypos;
138
139static void printf_line(int x, const char *buf)
140{
141 u32 addr;
142 int i;
143
144 VDP_drawTextML(buf, APLANE, x, printf_ypos++ & (PLANE_H - 1));
145
146 if (printf_ypos >= CSCREEN_H) {
147 /* clear next line */
148 addr = APLANE;
149 addr += (PLANE_W * (printf_ypos & (PLANE_H - 1))) << 1;
150 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(addr));
151 for (i = 0; i < 40 / 2; i++)
152 write32(VDP_DATA_PORT, 0);
153
154 /* scroll plane */
155 write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
156 write16(VDP_DATA_PORT, (printf_ypos - CSCREEN_H + 1) * 8);
157 }
158}
159
160#define PRINTF_LEN 40
161
162static int printf_xpos;
163
164static noinline int printf(const char *fmt, ...)
165{
166 static const char hexchars[] = "0123456789abcdef";
167 char c, buf[PRINTF_LEN + 11 + 1];
168 const char *s;
169 va_list ap;
170 int ival;
171 u32 uval;
172 int d = 0;
173 int i, j;
174
175 va_start(ap, fmt);
176 for (d = 0; *fmt; ) {
177 int prefix0 = 0;
178 int fwidth = 0;
179
180 c = *fmt++;
181 if (d < PRINTF_LEN)
182 buf[d] = c;
183
184 if (c != '%') {
185 if (c == '\n') {
186 buf[d] = 0;
187 printf_line(printf_xpos, buf);
188 d = 0;
189 printf_xpos = 0;
190 continue;
191 }
192 d++;
193 continue;
194 }
195 if (d >= PRINTF_LEN)
196 continue;
197
198 if (*fmt == '0') {
199 prefix0 = 1;
200 fmt++;
201 }
202
203 while ('1' <= *fmt && *fmt <= '9') {
204 fwidth = fwidth * 10 + *fmt - '0';
205 fmt++;
206 }
207
208 switch (*fmt++) {
209 case '%':
210 d++;
211 break;
212 case 'd':
213 case 'i':
214 ival = va_arg(ap, int);
215 if (ival < 0) {
216 buf[d++] = '-';
217 ival = -ival;
218 }
219 for (i = 1000000000; i >= 10; i /= 10)
220 if (ival >= i)
221 break;
222 for (; i >= 10; i /= 10) {
223 buf[d++] = '0' + ival / i;
224 ival %= i;
225 }
226 buf[d++] = '0' + ival;
227 break;
228 case 'x':
229 uval = va_arg(ap, int);
230 while (fwidth > 1 && uval < (1 << (fwidth - 1) * 4)) {
231 buf[d++] = prefix0 ? '0' : ' ';
232 fwidth--;
233 }
234 for (j = 1; j < 8 && uval >= (1 << j * 4); j++)
235 ;
236 for (j--; j >= 0; j--)
237 buf[d++] = hexchars[(uval >> j * 4) & 0x0f];
238 break;
5073ab5a 239 case 'c':
240 buf[d++] = va_arg(ap, int);
241 break;
ffd4b35c 242 case 's':
243 s = va_arg(ap, char *);
244 while (*s && d < PRINTF_LEN)
245 buf[d++] = *s++;
246 break;
247 default:
248 // don't handle, for now
249 d++;
250 va_arg(ap, void *);
251 break;
252 }
253 }
254 buf[d] = 0;
255 va_end(ap);
256
257 if (d != 0) {
258 // line without \n
259 VDP_drawTextML(buf, APLANE, printf_xpos,
260 printf_ypos & (PLANE_H - 1));
261 printf_xpos += d;
262 }
263
264 return d; // wrong..
265}
266
267static const char *exc_names[] = {
268 NULL,
269 NULL,
270 "Bus Error",
271 "Address Error",
272 "Illegal Instruction",
273 "Zero Divide",
274 "CHK Instruction",
275 "TRAPV Instruction",
276 "Privilege Violation", /* 8 8 */
277 "Trace",
278 "Line 1010 Emulator",
279 "Line 1111 Emulator",
280 NULL,
281 NULL,
282 NULL,
283 "Uninitialized Interrupt",
284 NULL, /* 10 16 */
285 NULL,
286 NULL,
287 NULL,
288 NULL,
289 NULL,
290 NULL,
291 NULL,
292 "Spurious Interrupt", /* 18 24 */
293 "l1 irq",
294 "l2 irq",
295 "l3 irq",
296 "l4 irq",
297 "l5 irq",
298 "l6 irq",
299 "l7 irq",
300};
301
302struct exc_frame {
303 u32 dr[8];
304 u32 ar[8];
305 u16 ecxnum; // from handler
306 union {
307 struct {
308 u16 sr;
309 u32 pc;
310 } g _packed;
311 struct {
312 u16 fc;
313 u32 addr;
314 u16 ir;
315 u16 sr;
316 u32 pc;
317 } bae _packed; // bus/address error frame
318 };
319} _packed;
320
ffd4b35c 321void exception(const struct exc_frame *f)
322{
234c4556 323 u32 *sp, sp_add;
ffd4b35c 324 int i;
325
326 while (read16(VDP_CTRL_PORT) & 2)
327 ;
328 VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
329 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DISP);
330 /* adjust scroll */
331 write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
332 write16(VDP_DATA_PORT,
333 printf_ypos >= CSCREEN_H ?
334 (printf_ypos - CSCREEN_H + 1) * 8 : 0);
335
336 printf("exception %i ", f->ecxnum);
337 if (f->ecxnum < ARRAY_SIZE(exc_names) && exc_names[f->ecxnum] != NULL)
338 printf("(%s)", exc_names[f->ecxnum]);
339 if (f->ecxnum < 4)
340 printf(" (%s)", (f->bae.fc & 0x10) ? "r" : "w");
341 printf(" \n");
342
343 if (f->ecxnum < 4) {
234c4556 344 printf(" PC: %08x SR: %04x \n", f->bae.pc, f->bae.sr);
ffd4b35c 345 printf("addr: %08x IR: %04x FC: %02x \n",
346 f->bae.addr, f->bae.ir, f->bae.fc);
234c4556 347 sp_add = 14;
ffd4b35c 348 }
349 else {
234c4556 350 printf(" PC: %08x SR: %04x \n", f->g.pc, f->g.sr);
351 sp_add = 6;
ffd4b35c 352 }
7449b889 353 sp = (u32 *)(f->ar[7] + sp_add);
354 for (i = 0; i < 7; i++)
ffd4b35c 355 printf(" D%d: %08x A%d: %08x \n", i, f->dr[i], i, f->ar[i]);
7449b889 356 printf(" D%d: %08x SP: %08x \n", i, f->dr[i], (u32)sp);
234c4556 357 printf(" \n");
234c4556 358 printf(" %08x %08x %08x %08x\n", sp[0], sp[1], sp[2], sp[3]);
359 printf(" %08x %08x %08x %08x\n", sp[4], sp[5], sp[6], sp[7]);
ffd4b35c 360}
361
362// ---
363
364static void setup_default_palette(void)
365{
366 write32(VDP_CTRL_PORT, CTL_WRITE_CRAM(0));
367 write32(VDP_DATA_PORT, 0);
368 write32(VDP_CTRL_PORT, CTL_WRITE_CRAM(15 * 2)); // font normal
369 write16(VDP_DATA_PORT, 0xeee);
370 write32(VDP_CTRL_PORT, CTL_WRITE_CRAM(31 * 2)); // green
371 write16(VDP_DATA_PORT, 0x0e0);
372 write32(VDP_CTRL_PORT, CTL_WRITE_CRAM(47 * 2)); // red
373 write16(VDP_DATA_PORT, 0x00e);
374}
375
376static void do_setup_dma(const void *src_, u16 words)
377{
378 u32 src = (u32)src_;
379 // VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA);
380 VDP_setReg(VDP_DMA_LEN0, words);
381 VDP_setReg(VDP_DMA_LEN1, words >> 8);
382 VDP_setReg(VDP_DMA_SRC0, src >> 1);
383 VDP_setReg(VDP_DMA_SRC1, src >> 9);
384 VDP_setReg(VDP_DMA_SRC2, src >> 17);
385 // write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(addr) | CTL_WRITE_DMA);
386}
387
a385208c 388static void vdp_wait_for_fifo_empty(void)
389{
390 while (!(read16(VDP_CTRL_PORT) & 0x200))
391 /* fifo not empty */;
30a57837 392
393 mem_barrier();
a385208c 394}
395
396static void vdp_wait_for_dma_idle(void)
397{
398 while (read16(VDP_CTRL_PORT) & 2)
399 /* dma busy */;
30a57837 400
401 mem_barrier();
a385208c 402}
403
404static void vdp_wait_for_line_0(void)
405{
406 // in PAL vcounter reports 0 twice in a frame,
407 // so wait for vblank to clear first
408 while (!(read16(VDP_CTRL_PORT) & 8))
409 /* not blanking */;
410 while (read16(VDP_CTRL_PORT) & 8)
411 /* blanking */;
412 while (read8(VDP_HV_COUNTER) != 0)
413 ;
30a57837 414
415 mem_barrier();
a385208c 416}
417
7449b889 418static void wait_next_vsync(void)
419{
420 while (read16(VDP_CTRL_PORT) & SR_VB)
421 /* blanking */;
422 while (!(read16(VDP_CTRL_PORT) & SR_VB))
423 /* not blanking */;
30a57837 424
425 mem_barrier();
7449b889 426}
427
ffd4b35c 428static void t_dma_zero_wrap_early(void)
429{
430 const u32 *src = (const u32 *)0x3c0000;
431 u32 *ram = (u32 *)0xff0000;
432
433 do_setup_dma(src + 4, 2);
434 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0) | CTL_WRITE_DMA);
435 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0) | CTL_WRITE_DMA);
436
437 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0));
438 ram[0] = read32(VDP_DATA_PORT);
439 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0xfffc));
440 ram[1] = read32(VDP_DATA_PORT);
441}
442
443static void t_dma_zero_fill_early(void)
444{
445 u32 *ram = (u32 *)0xff0000;
446
447 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0));
448 write32(VDP_DATA_PORT, 0);
449 write32(VDP_DATA_PORT, 0);
450 write32(VDP_DATA_PORT, 0);
451 write32(VDP_DATA_PORT, 0);
452
453 VDP_setReg(VDP_AUTOINC, 1);
454 VDP_setReg(VDP_DMA_SRC2, 0x80);
455 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(1) | CTL_WRITE_DMA);
456 write16(VDP_DATA_PORT, 0x1122);
457 ram[2] = read16(VDP_CTRL_PORT);
a385208c 458 vdp_wait_for_dma_idle();
ffd4b35c 459
460 VDP_setReg(VDP_AUTOINC, 2);
461 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0));
462 ram[3] = read32(VDP_DATA_PORT);
463}
464
5073ab5a 465#define R_SKIP 0x5a5a
466
ffd4b35c 467#define expect(ok_, v0_, v1_) \
e71680d5 468do { if ((v0_) != (v1_)) { \
30a57837 469 printf("%d %s: %08x %08x\n", __LINE__, #v0_, v0_, v1_); \
ffd4b35c 470 ok_ = 0; \
e71680d5 471}} while (0)
ffd4b35c 472
5073ab5a 473#define expect_sh2(ok_, sh2_, v0_, v1_) \
474do { if ((v0_) != (v1_)) { \
30a57837 475 printf("%d %csh2: %08x %08x\n", __LINE__, sh2_ ? 's' : 'm', v0_, v1_); \
5073ab5a 476 ok_ = 0; \
477}} while (0)
478
a385208c 479#define expect_range(ok_, v0_, vmin_, vmax_) \
e71680d5 480do { if ((v0_) < (vmin_) || (v0_) > (vmax_)) { \
a385208c 481 printf("%s: %02x /%02x-%02x\n", #v0_, v0_, vmin_, vmax_); \
482 ok_ = 0; \
e71680d5 483}} while (0)
a385208c 484
485#define expect_bits(ok_, v0_, val_, mask_) \
e71680d5 486do { if (((v0_) & (mask_)) != (val_)) { \
a385208c 487 printf("%s: %04x & %04x != %04x\n", #v0_, v0_, mask_, val_); \
488 ok_ = 0; \
e71680d5 489}} while (0)
a385208c 490
ffd4b35c 491static int t_dma_zero_wrap(void)
492{
493 const u32 *src = (const u32 *)0x3c0000;
494 const u32 *ram = (const u32 *)0xff0000;
495 int ok = 1;
496
497 expect(ok, ram[0], src[5 + 0x10000/4]);
498 expect(ok, ram[1], src[4]);
499 return ok;
500}
501
502static int t_dma_zero_fill(void)
503{
504 const u32 *ram = (const u32 *)0xff0000;
505 u32 v0 = ram[2] & 2;
506 int ok = 1;
507
508 expect(ok, v0, 2);
509 expect(ok, ram[3], 0x11111111);
510 return ok;
511}
512
513static int t_dma_ram_wrap(void)
514{
515 u32 *ram = (u32 *)0xff0000;
516 u32 saved, v0, v1;
517 int ok = 1;
518
519 saved = read32(&ram[0x10000/4 - 1]);
520 ram[0x10000/4 - 1] = 0x01020304;
521 ram[0] = 0x05060708;
522 do_setup_dma(&ram[0x10000/4 - 1], 4);
523 mem_barrier();
524 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100) | CTL_WRITE_DMA);
525
526 mem_barrier();
527 write32(&ram[0x10000/4 - 1], saved);
528
529 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
530 v0 = read32(VDP_DATA_PORT);
531 v1 = read32(VDP_DATA_PORT);
532
533 expect(ok, v0, 0x01020304);
534 expect(ok, v1, 0x05060708);
535 return ok;
536}
537
538// test no src reprogram, only len0
539static int t_dma_multi(void)
540{
541 const u32 *src = (const u32 *)0x3c0000;
542 u32 v0, v1;
543 int ok = 1;
544
545 do_setup_dma(src, 2);
546 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100) | CTL_WRITE_DMA);
547 VDP_setReg(VDP_DMA_LEN0, 2);
548 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x104) | CTL_WRITE_DMA);
549
550 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
551 v0 = read32(VDP_DATA_PORT);
552 v1 = read32(VDP_DATA_PORT);
553
554 expect(ok, v0, src[0]);
555 expect(ok, v1, src[1]);
556 return ok;
557}
558
559static int t_dma_cram_wrap(void)
560{
561 u32 *ram = (u32 *)0xff0000;
562 u32 v0, v1;
563 int ok = 1;
564
565 write32(VDP_CTRL_PORT, CTL_WRITE_CRAM(0));
566 write32(VDP_DATA_PORT, 0);
567
568 ram[0] = 0x0ec20ec4;
569 ram[1] = 0x0ec60ec8;
570 mem_barrier();
571 do_setup_dma(ram, 4);
572 write32(VDP_CTRL_PORT, CTL_WRITE_CRAM(0x7c | 0xff81) | CTL_WRITE_DMA);
573
574 write32(VDP_CTRL_PORT, CTL_READ_CRAM(0x7c));
575 v0 = read32(VDP_DATA_PORT) & 0x0eee0eee;
576 write32(VDP_CTRL_PORT, CTL_READ_CRAM(0));
577 v1 = read32(VDP_DATA_PORT) & 0x0eee0eee;
578
579 setup_default_palette();
580
581 expect(ok, v0, ram[0]);
582 expect(ok, v1, ram[1]);
583 return ok;
584}
585
586static int t_dma_vsram_wrap(void)
587{
588 u32 *ram32 = (u32 *)0xff0000;
589 u16 *ram16 = (u16 *)0xff0000;
590 u32 v0, v1;
591 int ok = 1;
592 int i;
593
594 write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
595 write32(VDP_DATA_PORT, 0);
596
597 for (i = 0; i < 0x48/2; i++)
598 ram16[i] = i + 1;
599 mem_barrier();
600 do_setup_dma(ram16, 0x48/2);
601 write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0x3c | 0xff81) | CTL_WRITE_DMA);
602
603 write32(VDP_CTRL_PORT, CTL_READ_VSRAM(0x3c));
604 v0 = read32(VDP_DATA_PORT) & 0x03ff03ff;
605 write32(VDP_CTRL_PORT, CTL_READ_VSRAM(0));
606 v1 = read32(VDP_DATA_PORT) & 0x03ff03ff;
607
608 write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
609 write32(VDP_DATA_PORT, 0);
610
611 expect(ok, v0, ram32[0]);
612 expect(ok, v1, ram32[0x48/4 - 1]);
613 return ok;
614}
615
616static int t_dma_and_data(void)
617{
618 const u32 *src = (const u32 *)0x3c0000;
a385208c 619 u32 v0, v1;
ffd4b35c 620 int ok = 1;
621
622 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
623 write32(VDP_DATA_PORT, 0);
624
625 do_setup_dma(src, 2);
626 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0xfc) | CTL_WRITE_DMA);
627 write32(VDP_DATA_PORT, 0x5ec8a248);
628
a385208c 629 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0xfc));
ffd4b35c 630 v0 = read32(VDP_DATA_PORT);
a385208c 631 v1 = read32(VDP_DATA_PORT);
ffd4b35c 632
a385208c 633 expect(ok, v0, src[0]);
634 expect(ok, v1, 0x5ec8a248);
635 return ok;
636}
637
638static int t_dma_short_cmd(void)
639{
640 const u32 *src = (const u32 *)0x3c0000;
641 u32 v0, v1, v2;
642 int ok = 1;
643
644 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x3ff4));
645 write32(VDP_DATA_PORT, 0x10111213);
646 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0xfff0));
647 write32(VDP_DATA_PORT, 0x20212223);
648 write32(VDP_DATA_PORT, 0x30313233);
cc7e5122 649 vdp_wait_for_fifo_empty();
a385208c 650
651 do_setup_dma(src, 2);
652 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0xfff0) | CTL_WRITE_DMA);
653 write16(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x3ff4) >> 16);
654 write32(VDP_DATA_PORT, 0x40414243);
655
656 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x3ff4));
657 v0 = read32(VDP_DATA_PORT);
658 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0xfff0));
659 v1 = read32(VDP_DATA_PORT);
660 v2 = read32(VDP_DATA_PORT);
661
662 expect(ok, v0, 0x10111213);
663 expect(ok, v1, src[0]);
664 expect(ok, v2, 0x40414243);
ffd4b35c 665 return ok;
666}
667
668static int t_dma_fill3_odd(void)
669{
670 u32 v0, v1, v2;
671 int ok = 1;
672
673 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
674 write32(VDP_DATA_PORT, 0);
675 write32(VDP_DATA_PORT, 0);
676 write32(VDP_DATA_PORT, 0);
cc7e5122 677 vdp_wait_for_fifo_empty();
ffd4b35c 678
679 VDP_setReg(VDP_AUTOINC, 3);
680 VDP_setReg(VDP_DMA_LEN0, 3);
681 VDP_setReg(VDP_DMA_SRC2, 0x80);
682 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x101) | CTL_WRITE_DMA);
683 write16(VDP_DATA_PORT, 0x1122);
a385208c 684 vdp_wait_for_dma_idle();
ffd4b35c 685
686 VDP_setReg(VDP_AUTOINC, 2);
687 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
688 v0 = read32(VDP_DATA_PORT);
689 v1 = read32(VDP_DATA_PORT);
690 v2 = read32(VDP_DATA_PORT);
691
692 expect(ok, v0, 0x22110000);
693 expect(ok, v1, 0x00111100);
694 expect(ok, v2, 0x00000011);
695 return ok;
696}
697
698static int t_dma_fill3_even(void)
699{
700 u32 v0, v1, v2;
701 int ok = 1;
702
703 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
704 write32(VDP_DATA_PORT, 0);
705 write32(VDP_DATA_PORT, 0);
706 write32(VDP_DATA_PORT, 0);
cc7e5122 707 vdp_wait_for_fifo_empty();
ffd4b35c 708
709 VDP_setReg(VDP_AUTOINC, 3);
710 VDP_setReg(VDP_DMA_LEN0, 3);
711 VDP_setReg(VDP_DMA_SRC2, 0x80);
712 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100) | CTL_WRITE_DMA);
713 write16(VDP_DATA_PORT, 0x1122);
a385208c 714 vdp_wait_for_dma_idle();
ffd4b35c 715
716 VDP_setReg(VDP_AUTOINC, 2);
717 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
718 v0 = read32(VDP_DATA_PORT);
719 v1 = read32(VDP_DATA_PORT);
720 v2 = read32(VDP_DATA_PORT);
721
722 expect(ok, v0, 0x11221100);
723 expect(ok, v1, 0x00000011);
724 expect(ok, v2, 0x11000000);
725 return ok;
726}
727
728static unused int t_dma_fill3_vsram(void)
729{
730 u32 v0, v1, v2;
731 int ok = 1;
732
733 write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
734 write32(VDP_DATA_PORT, 0);
735 write32(VDP_DATA_PORT, 0);
736 write32(VDP_DATA_PORT, 0);
737
738 write16(VDP_DATA_PORT, 0x0111);
739 write16(VDP_DATA_PORT, 0x0222);
740 write16(VDP_DATA_PORT, 0x0333);
a385208c 741 vdp_wait_for_fifo_empty();
ffd4b35c 742
743 VDP_setReg(VDP_AUTOINC, 3);
744 VDP_setReg(VDP_DMA_LEN0, 3);
745 VDP_setReg(VDP_DMA_SRC2, 0x80);
746 write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(1) | CTL_WRITE_DMA);
747 write16(VDP_DATA_PORT, 0x0102);
a385208c 748 vdp_wait_for_dma_idle();
ffd4b35c 749
750 VDP_setReg(VDP_AUTOINC, 2);
751 write32(VDP_CTRL_PORT, CTL_READ_VSRAM(0));
752 v0 = read32(VDP_DATA_PORT);
753 v1 = read32(VDP_DATA_PORT);
754 v2 = read32(VDP_DATA_PORT);
755
756 write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
757 write32(VDP_DATA_PORT, 0);
758
759 expect(ok, v0, 0x01020000);
760 expect(ok, v1, 0x01110111);
761 expect(ok, v2, 0x00000111);
762 return ok;
763}
764
765static int t_dma_fill_dis(void)
766{
767 u32 v0, v1;
768 int ok = 1;
769
770 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
771 write32(VDP_DATA_PORT, 0);
772 write32(VDP_DATA_PORT, 0);
773
774 VDP_setReg(VDP_DMA_LEN0, 1);
775 VDP_setReg(VDP_DMA_SRC2, 0x80);
776 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100) | CTL_WRITE_DMA);
777 VDP_setReg(VDP_MODE2, VDP_MODE2_MD);
778 write16(VDP_DATA_PORT, 0x1122);
a385208c 779 vdp_wait_for_dma_idle();
ffd4b35c 780
781 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
782 write16(VDP_DATA_PORT, 0x3344);
a385208c 783 vdp_wait_for_dma_idle();
ffd4b35c 784
785 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
786 v0 = read32(VDP_DATA_PORT);
787 v1 = read32(VDP_DATA_PORT);
788
789 expect(ok, v0, 0);
790 expect(ok, v1, 0);
791 return ok;
792}
793
794static int t_dma_fill_src(void)
795{
796 const u32 *src = (const u32 *)0x3c0000;
797 u32 v0, v1;
798 int ok = 1;
799
800 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
801 write32(VDP_DATA_PORT, 0);
802
803 // do_setup_dma(src, 2); // hang, can't write src2 twice
804 VDP_setReg(VDP_DMA_LEN0, 2);
805 VDP_setReg(VDP_DMA_SRC0, (u32)src >> 1);
806 VDP_setReg(VDP_DMA_SRC1, (u32)src >> 9);
807 VDP_setReg(VDP_DMA_SRC2, 0x80);
808 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100) | CTL_WRITE_DMA);
809 write16(VDP_DATA_PORT, 0x1122);
a385208c 810 vdp_wait_for_dma_idle();
ffd4b35c 811
812 VDP_setReg(VDP_DMA_LEN0, 2);
813 VDP_setReg(VDP_DMA_SRC2, (u32)src >> 17);
814 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x104) | CTL_WRITE_DMA);
815
816 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
817 v0 = read32(VDP_DATA_PORT);
818 v1 = read32(VDP_DATA_PORT);
819
820 expect(ok, v0, 0x11220011);
821 expect(ok, v1, src[1]);
822 return ok;
823}
824
7c817df6 825// should not see the busy flag
826static int t_dma_busy_vram(void)
827{
828 const u32 *src = (const u32 *)0x3c0000;
829 u16 sr[3];
830 int ok = 1;
831
832 vdp_wait_for_line_0();
833
834 do_setup_dma(src, 1);
835 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100) | CTL_WRITE_DMA);
836 sr[0] = read16(VDP_CTRL_PORT);
837
838 do_setup_dma(src, 4);
839 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100) | CTL_WRITE_DMA);
840 sr[1] = read16(VDP_CTRL_PORT);
841
842 VDP_setReg(VDP_DMA_LEN0, 8);
843 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100) | CTL_WRITE_DMA);
844 sr[2] = read16(VDP_CTRL_PORT);
845
846 expect_bits(ok, sr[0], 0, SR_DMA);
847 expect_bits(ok, sr[1], 0, SR_DMA);
848 expect_bits(ok, sr[2], 0, SR_DMA);
849 return ok;
850}
851
a385208c 852// (((a & 2) >> 1) ^ 1) | ((a & $400) >> 9) | (a & $3FC) | ((a & $1F800) >> 1)
853static int t_dma_128k(void)
854{
855 u16 *ram = (u16 *)0xff0000;
856 u32 v0, v1;
857 int ok = 1;
858
859 ram[0] = 0x5a11;
860 ram[1] = 0x5a22;
861 ram[2] = 0x5a33;
862
863 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
864 write32(VDP_DATA_PORT, 0x01020304);
865 write32(VDP_DATA_PORT, 0x05060708);
866 vdp_wait_for_fifo_empty();
867
868 mem_barrier();
869 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_128K);
870 do_setup_dma(ram, 3);
871 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100) | CTL_WRITE_DMA);
872 vdp_wait_for_fifo_empty();
873
874 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
875 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
876 v0 = read32(VDP_DATA_PORT);
877 v1 = read32(VDP_DATA_PORT);
878
879 expect(ok, v0, 0x22110304);
880 expect(ok, v1, 0x05330708);
881 return ok;
882}
883
884static int t_vdp_128k_b16(void)
885{
886 u32 v0, v1;
887 int ok = 1;
888
889 VDP_setReg(VDP_AUTOINC, 0);
890 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x8100));
891 write32(VDP_DATA_PORT, 0x01020304);
892 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x10100));
893 write32(VDP_DATA_PORT, 0x05060708);
894 vdp_wait_for_fifo_empty();
895
896 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_128K);
897 write16(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100) >> 16); // note: upper cmd
898 write32(VDP_DATA_PORT, 0x11223344);
899 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x10102));
900 write32(VDP_DATA_PORT, 0x55667788);
901 vdp_wait_for_fifo_empty();
902
903 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
904 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x8100));
905 v0 = read16(VDP_DATA_PORT);
906 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x0100));
907 v1 = read16(VDP_DATA_PORT);
908
909 VDP_setReg(VDP_AUTOINC, 2);
910
911 expect(ok, v0, 0x8844);
912 expect(ok, v1, 0x0708);
913 return ok;
914}
915
916static unused int t_vdp_128k_b16_inc(void)
917{
918 u32 v0, v1;
919 int ok = 1;
920
921 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0));
922 write32(VDP_DATA_PORT, 0x01020304);
923 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x8000));
924 write32(VDP_DATA_PORT, 0x05060708);
925 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0xfffe));
926 write32(VDP_DATA_PORT, 0x090a0b0c);
927 vdp_wait_for_fifo_empty();
928
929 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_128K);
930 write16(VDP_CTRL_PORT, CTL_WRITE_VRAM(0) >> 16); // note: upper cmd
931 write16(VDP_DATA_PORT, 0x1122);
932 vdp_wait_for_fifo_empty();
933
934 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
935 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0));
936 v0 = read32(VDP_DATA_PORT);
937 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x8000));
938 v1 = read32(VDP_DATA_PORT);
939 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0));
940 write32(VDP_DATA_PORT, 0);
941 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x8000));
942 write32(VDP_DATA_PORT, 0);
943
944 expect(ok, v0, 0x0b0c0304); // XXX: no 22 anywhere?
945 expect(ok, v1, 0x05060708);
946 return ok;
947}
948
949static int t_vdp_reg_cmd(void)
950{
951 u32 v0;
952 int ok = 1;
953
954 VDP_setReg(VDP_AUTOINC, 0);
955 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
956 write32(VDP_DATA_PORT, 0x01020304);
957 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
958 write32(VDP_DATA_PORT, 0x05060708);
959
960 VDP_setReg(VDP_AUTOINC, 2);
961 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x0100));
962 v0 = read16(VDP_DATA_PORT);
963
964 expect(ok, v0, 0x0304);
965 return ok;
966}
967
cc7e5122 968static int t_vdp_sr_vb(void)
969{
970 u16 sr[4];
971 int ok = 1;
972
973 while (read8(VDP_HV_COUNTER) != 242)
974 ;
975 sr[0] = read16(VDP_CTRL_PORT);
976 VDP_setReg(VDP_MODE2, VDP_MODE2_MD);
977 sr[1] = read16(VDP_CTRL_PORT);
978 while (read8(VDP_HV_COUNTER) != 4)
979 ;
980 sr[2] = read16(VDP_CTRL_PORT);
981 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
982 sr[3] = read16(VDP_CTRL_PORT);
983
984 expect_bits(ok, sr[0], SR_VB, SR_VB);
985 expect_bits(ok, sr[1], SR_VB, SR_VB);
986 expect_bits(ok, sr[2], SR_VB, SR_VB);
987 expect_bits(ok, sr[3], 0, SR_VB);
988 return ok;
989}
990
ffd4b35c 991/* z80 tests assume busreq state */
992static int t_z80mem_long_mirror(void)
993{
994 u8 *zram = (u8 *)0xa00000;
995 int ok = 1;
996
997 write8(&zram[0x1100], 0x11);
998 write8(&zram[0x1101], 0x22);
999 write8(&zram[0x1102], 0x33);
1000 write8(&zram[0x1103], 0x44);
1001 mem_barrier();
1002 write32(&zram[0x3100], 0x55667788);
1003 mem_barrier();
1004
1005 expect(ok, zram[0x1100], 0x55);
1006 expect(ok, zram[0x1101], 0x22);
1007 expect(ok, zram[0x1102], 0x77);
1008 expect(ok, zram[0x1103], 0x44);
1009 return ok;
1010}
1011
a385208c 1012static int t_z80mem_noreq_w(void)
1013{
1014 u8 *zram = (u8 *)0xa00000;
1015 int ok = 1;
1016
1017 write8(&zram[0x1100], 0x11);
1018 mem_barrier();
1019 write16(0xa11100, 0x000);
1020 write8(&zram[0x1100], 0x22);
1021 mem_barrier();
1022
1023 write16(0xa11100, 0x100);
1024 while (read16(0xa11100) & 0x100)
1025 ;
1026
1027 expect(ok, zram[0x1100], 0x11);
1028 return ok;
1029}
1030
e71680d5 1031#define Z80_C_DISPATCH 113 // see z80_test.s80
1032#define Z80_C_END 17
1033#define Z80_C_END_VCNT 67
1034
1035#define Z80_CYLES_TEST1(b) (Z80_C_DISPATCH + ((b) - 1) * 21 + 26 + Z80_C_END)
a385208c 1036
ffd4b35c 1037static int t_z80mem_vdp_r(void)
1038{
1039 u8 *zram = (u8 *)0xa00000;
1040 int ok = 1;
1041
1042 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
1043 write32(VDP_DATA_PORT, 0x11223344);
1044 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
1045
1046 zram[0x1000] = 1; // cp
ffd4b35c 1047 write16_z80le(&zram[0x1002], 0x7f00); // src
a385208c 1048 write16_z80le(&zram[0x1004], 0x1100); // dst
1049 write16_z80le(&zram[0x1006], 2); // len
1050 zram[0x1100] = zram[0x1101] = zram[0x1102] = 0x5a;
ffd4b35c 1051 mem_barrier();
1052 write16(0xa11100, 0x000);
e71680d5 1053 burn10(Z80_CYLES_TEST1(2) * 15 / 7 / 10);
ffd4b35c 1054
1055 write16(0xa11100, 0x100);
1056 while (read16(0xa11100) & 0x100)
1057 ;
1058
1059 expect(ok, zram[0x1000], 0);
a385208c 1060 expect(ok, zram[0x1100], 0x11);
1061 expect(ok, zram[0x1101], 0x44);
1062 expect(ok, zram[0x1102], 0x5a);
ffd4b35c 1063 return ok;
1064}
1065
1066static unused int t_z80mem_vdp_w(void)
1067{
1068 u8 *zram = (u8 *)0xa00000;
1069 u32 v0;
1070 int ok = 1;
1071
1072 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
1073 write32(VDP_DATA_PORT, 0x11223344);
1074 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
a385208c 1075 vdp_wait_for_fifo_empty();
ffd4b35c 1076
1077 zram[0x1000] = 1; // cp
a385208c 1078 write16_z80le(&zram[0x1002], 0x1100); // src
ffd4b35c 1079 write16_z80le(&zram[0x1004], 0x7f00); // dst
a385208c 1080 write16_z80le(&zram[0x1006], 2); // len
1081 zram[0x1100] = 0x55;
1082 zram[0x1101] = 0x66;
ffd4b35c 1083 mem_barrier();
1084 write16(0xa11100, 0x000);
e71680d5 1085 burn10(Z80_CYLES_TEST1(2) * 15 / 7 / 10);
ffd4b35c 1086
1087 write16(0xa11100, 0x100);
1088 while (read16(0xa11100) & 0x100)
1089 ;
1090
1091 write32(VDP_CTRL_PORT, CTL_READ_VRAM(0x100));
1092 v0 = read32(VDP_DATA_PORT);
1093
1094 expect(ok, zram[0x1000], 0);
1095 expect(ok, v0, 0x55556666);
1096 return ok;
1097}
1098
a385208c 1099static int t_tim_loop(void)
1100{
1101 u8 vcnt;
1102 int ok = 1;
1103
1104 vdp_wait_for_line_0();
1105 burn10(488*220/10);
1106 vcnt = read8(VDP_HV_COUNTER);
1107 mem_barrier();
1108
1109 //expect_range(ok, vcnt, 0x80, 0x80);
1110 expect(ok, vcnt, 223);
1111 return ok;
1112}
1113
e71680d5 1114static int t_tim_z80_loop(void)
1115{
1116 u8 pal = read8(0xa10001) & 0x40;
1117 u8 *zram = (u8 *)0xa00000;
1118 u16 z80_loops = pal ? 3420*(313*2+1)/15/100 : 3420*(262*2+1)/15/100; // 2fr + 1ln
1119 u16 _68k_loops = pal ? 3420*(313*2+1)/7/10 : 3420*(262*2+1)/7/10;
1120 int ok = 1;
1121
1122 zram[0x1000] = 3; // idle loop, save vcnt
1123 write16_z80le(&zram[0x1002], 0); // src (unused)
1124 write16_z80le(&zram[0x1004], 0x1100); // vcnt dst
1125 write16_z80le(&zram[0x1006], z80_loops); // x100 cycles
1126 zram[0x1100] = 0;
1127 mem_barrier();
1128
1129 vdp_wait_for_line_0();
1130 write16(0xa11100, 0x000);
1131 burn10(_68k_loops + (Z80_C_DISPATCH + Z80_C_END_VCNT) * 15 / 7 / 10);
1132
1133 write16(0xa11100, 0x100);
1134 while (read16(0xa11100) & 0x100)
1135 ;
1136 expect(ok, zram[0x1000], 0);
1137 expect(ok, zram[0x1100], 1);
1138 return ok;
1139}
1140
1141#define Z80_CYCLES_TEST2(b) (Z80_C_DISPATCH + (b) * 38 + Z80_C_END_VCNT)
a385208c 1142
1143// 80 80 91 95-96
1144static void z80_read_loop(u8 *zram, u16 src)
1145{
1146 const int pairs = 512 + 256;
1147
1148 zram[0x1000] = 2; // read loop, save vcnt
1149 write16_z80le(&zram[0x1002], src); // src
1150 write16_z80le(&zram[0x1004], 0x1100); // vcnt dst
1151 write16_z80le(&zram[0x1006], pairs); // reads/2
1152 zram[0x1100] = 0;
1153 mem_barrier();
1154
1155 vdp_wait_for_line_0();
1156 write16(0xa11100, 0x000);
e71680d5 1157 burn10(Z80_CYCLES_TEST2(pairs) * 15 / 7 * 2 / 10);
a385208c 1158
1159 write16(0xa11100, 0x100);
1160 while (read16(0xa11100) & 0x100)
1161 ;
1162}
1163
1164static int t_tim_z80_ram(void)
1165{
1166 u8 *zram = (u8 *)0xa00000;
1167 int ok = 1;
1168
1169 z80_read_loop(zram, 0);
1170
1171 expect(ok, zram[0x1000], 0);
1172 expect_range(ok, zram[0x1100], 0x80, 0x80);
1173 return ok;
1174}
1175
1176static int t_tim_z80_ym(void)
1177{
1178 u8 *zram = (u8 *)0xa00000;
1179 int ok = 1;
1180
1181 z80_read_loop(zram, 0x4000);
1182
1183 expect(ok, zram[0x1000], 0);
1184 expect_range(ok, zram[0x1100], 0x80, 0x80);
1185 return ok;
1186}
1187
1188static int t_tim_z80_vdp(void)
1189{
1190 u8 *zram = (u8 *)0xa00000;
1191 int ok = 1;
1192
1193 z80_read_loop(zram, 0x7f08);
1194
1195 expect(ok, zram[0x1000], 0);
a385208c 1196 expect_range(ok, zram[0x1100], 0x91, 0x91);
a385208c 1197 return ok;
1198}
1199
1200static int t_tim_z80_bank_rom(void)
1201{
1202 u8 *zram = (u8 *)0xa00000;
1203 int i, ok = 1;
1204
1205 for (i = 0; i < 17; i++)
1206 write8(0xa06000, 0); // bank 0
1207
1208 z80_read_loop(zram, 0x8000);
1209
1210 expect(ok, zram[0x1000], 0);
a385208c 1211 expect_range(ok, zram[0x1100], 0x95, 0x96);
a385208c 1212 return ok;
1213}
1214
1215/* borderline too slow */
1216#if 0
cc7e5122 1217static void test_vcnt_vb(void)
a385208c 1218{
1219 const u32 *srhv = (u32 *)0xc00006; // to read SR and HV counter
1220 u32 *ram = (u32 *)0xff0000;
1221 u16 vcnt, vcnt_expect = 0;
1222 u16 sr, count = 0;
1223 u32 val, old;
1224
1225 vdp_wait_for_line_0();
1226 old = read32(srhv);
1227 *ram++ = old;
1228 for (;;) {
1229 val = read32(srhv);
1230 vcnt = val & 0xff00;
1231 if (vcnt == vcnt_expect)
1232 continue;
1233 sr = val >> 16;
1234 if (vcnt == 0 && !(sr & SR_VB)) // not VB
1235 break; // wrapped to start of frame
1236// count++;
1237 vcnt_expect += 0x100;
1238 if (vcnt == vcnt_expect && !((sr ^ (old >> 16)) & SR_VB)) {
1239 old = val;
1240 continue;
1241 }
1242 // should have a vcnt jump here
1243 *ram++ = old;
1244 *ram++ = val;
1245 vcnt_expect = vcnt;
1246 old = val;
1247 }
1248 *ram++ = val;
1249 *ram = count;
1250 mem_barrier();
1251}
1252#endif
1253
1254static int t_tim_vcnt(void)
1255{
1256 const u32 *ram32 = (u32 *)0xff0000;
1257 const u8 *ram = (u8 *)0xff0000;
1258 u8 pal = read8(0xa10001) & 0x40;
1259 u8 vc_jmp_b = pal ? 0x02 : 0xea;
1260 u8 vc_jmp_a = pal ? 0xca : 0xe5;
1261 u16 lines = pal ? 313 : 262;
1262 int ok = 1;
1263
cc7e5122 1264 test_vcnt_vb();
a385208c 1265 expect(ok, ram[0*4+2], 0); // line 0
1266 expect_bits(ok, ram[0*4+1], 0, SR_VB);
1267 expect(ok, ram[1*4+2], 223); // last no blank
1268 expect_bits(ok, ram[1*4+1], 0, SR_VB);
1269 expect(ok, ram[2*4+2], 224); // 1st blank
1270 expect_bits(ok, ram[2*4+1], SR_VB, SR_VB);
1271 expect(ok, ram[3*4+2], vc_jmp_b); // before jump
1272 expect_bits(ok, ram[3*4+1], SR_VB, SR_VB);
1273 expect(ok, ram[4*4+2], vc_jmp_a); // after jump
1274 expect_bits(ok, ram[4*4+1], SR_VB, SR_VB);
1275 expect(ok, ram[5*4+2], 0xfe); // before vb clear
1276 expect_bits(ok, ram[5*4+1], SR_VB, SR_VB);
1277 expect(ok, ram[6*4+2], 0xff); // after vb clear
1278 expect_bits(ok, ram[6*4+1], 0, SR_VB);
1279 expect(ok, ram[7*4+2], 0); // next line 0
1280 expect_bits(ok, ram[7*4+1], 0, SR_VB);
1281 expect(ok, ram32[8], lines - 1);
1282 return ok;
1283}
1284
e71680d5 1285static int t_tim_vcnt_loops(void)
1286{
1287 const u16 *ram16 = (u16 *)0xfff004;
1288 u8 pal = read8(0xa10001) & 0x40;
1289 u16 i, lines = pal ? 313 : 262;
1290 int ok = 1;
1291
1292 test_vcnt_loops();
1293 expect(ok, ram16[-1*2+0], 0xff);
1294 expect_range(ok, ram16[-1*2+1], 21, 22);
1295 for (i = 0; i < lines; i++)
1296 expect_range(ok, ram16[i*2+1], 19, 21);
1297 expect(ok, ram16[lines*2+0], 0);
635f2450 1298 expect_range(ok, ram16[lines*2+1], 19, 21);
e71680d5 1299 return ok;
1300}
1301
cc7e5122 1302static int t_tim_hblank_h40(void)
1303{
1304 const u8 *r = (u8 *)0xff0000;
1305 int ok = 1;
1306
1307 test_hb();
1308
1309 // set: 0-2
1310 expect_bits(ok, r[2], SR_HB, SR_HB);
1311 expect_bits(ok, r[5], SR_HB, SR_HB);
1312 // <wait>
1313 expect_bits(ok, r[7], SR_HB, SR_HB);
1314 // clear: 8-11
1315 expect_bits(ok, r[12], 0, SR_HB);
1316 return ok;
1317}
1318
1319static int t_tim_hblank_h32(void)
1320{
1321 const u8 *r = (u8 *)0xff0000;
1322 int ok = 1;
1323
1324 VDP_setReg(VDP_MODE4, 0x00);
1325 test_hb();
1326 VDP_setReg(VDP_MODE4, 0x81);
1327
cc7e5122 1328 expect_bits(ok, r[0], 0, SR_HB);
cc7e5122 1329 // set: 1-4
1330 expect_bits(ok, r[4], SR_HB, SR_HB);
1331 expect_bits(ok, r[5], SR_HB, SR_HB);
1332 // <wait>
1333 expect_bits(ok, r[8], SR_HB, SR_HB);
1334 // clear: 9-11
1335 expect_bits(ok, r[12], 0, SR_HB);
1336 return ok;
1337}
1338
a385208c 1339static int t_tim_vdp_as_vram_w(void)
1340{
1341 int ok = 1;
1342 u8 vcnt;
1343
1344 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0x100));
1345 vdp_wait_for_line_0();
1346 write16_x16(VDP_DATA_PORT, 112*18 / 16, 0);
1347 vcnt = read8(VDP_HV_COUNTER);
1348 mem_barrier();
1349
1350 expect(ok, vcnt, 112*2-1);
1351 return ok;
1352}
1353
1354static int t_tim_vdp_as_cram_w(void)
1355{
1356 int ok = 1;
1357 u8 vcnt;
1358
1359 write32(VDP_CTRL_PORT, CTL_WRITE_CRAM(0));
1360 vdp_wait_for_line_0();
1361 write16_x16(VDP_DATA_PORT, 112*18 / 16, 0);
1362 vcnt = read8(VDP_HV_COUNTER);
1363 mem_barrier();
1364
1365 setup_default_palette();
1366
a385208c 1367 expect(ok, vcnt, 112);
a385208c 1368 return ok;
1369}
1370
e71680d5 1371static const u8 hcnt2tm[] =
1372{
1373 0x0a, 0x1d, 0x31, 0x44, 0x58, 0x6b, 0x7f, 0x92,
1374 0xa6, 0xb9, 0xcc, 0x00, 0x00, 0x00, 0xe2, 0xf6
1375};
1376
1377static int t_tim_ym_timer_z80(int is_b)
1378{
1379 u8 pal = read8(0xa10001) & 0x40;
1380 u8 *zram = (u8 *)0xa00000;
1381 u8 *z80 = zram;
1382 u16 _68k_loops = 3420*(302+5+1)/7/10; // ~ (72*1024*2)/(3420./7)
1383 u16 start, end, diff;
1384 int ok = 1;
1385
1386 zram[0x1000] = 4 + is_b; // ym2612 timer a/b test
1387 zram[0x1100] = zram[0x1101] = zram[0x1102] = zram[0x1103] = 0;
1388 mem_barrier();
1389
1390 vdp_wait_for_line_0();
1391 write16(0xa11100, 0x000);
1392
1393 burn10(_68k_loops + (Z80_C_DISPATCH + Z80_C_END_VCNT) * 15 / 7 / 10);
1394
1395 write16(0xa11100, 0x100);
1396 while (read16(0xa11100) & 0x100)
1397 ;
1398 mem_barrier();
1399 expect(ok, zram[0x1000], 0);
1400 (void)hcnt2tm;
1401 //start = ((u16)zram[0x1102] << 8) | hcnt2tm[zram[0x1103] >> 4];
1402 //end = ((u16)zram[0x1100] << 8) | hcnt2tm[zram[0x1101] >> 4];
1403 start = zram[0x1102];
1404 end = zram[0x1100];
1405 diff = end - start;
1406 if (pal)
1407 expect_range(ok, diff, 0xf4, 0xf6);
1408 else
1409 expect_range(ok, diff, 0x27, 0x29);
1410 write8(&z80[0x4001], 0); // stop, but should keep the flag
1411 mem_barrier();
1412 burn10(32*6/10); // busy bit, 32 FM ticks (M/7/6)
1413 if (is_b) {
1414 expect(ok, z80[0x4000], 2);
1415 write8(&z80[0x4001], 0x20); // reset flag (reg 0x27, set up by z80)
1416 }
1417 else {
1418 expect(ok, z80[0x4000], 1);
1419 write8(&z80[0x4001], 0x10);
1420 }
1421 mem_barrier();
1422 burn10(32*6/10);
1423 expect(ok, z80[0x4000], 0);
1424 return ok;
1425}
1426
1427static int t_tim_ym_timera_z80(void)
1428{
1429 return t_tim_ym_timer_z80(0);
1430}
1431
1432static int t_tim_ym_timerb_z80(void)
1433{
1434 return t_tim_ym_timer_z80(1);
1435}
1436
1437static int t_tim_ym_timerb_stop(void)
1438{
1439 const struct {
1440 //u8 vcnt_start;
1441 //u8 hcnt_start;
1442 u16 vcnt_start;
1443 u16 stat0;
1444 //u8 vcnt_end;
1445 //u8 hcnt_end;
1446 u16 vcnt_end;
1447 u16 stat1;
1448 } *t = (void *)0xfff000;
1449 u8 *z80 = (u8 *)0xa00000;
1450 u16 diff;
1451 int ok = 1;
1452 write16(0xa11100, 0x100);
1453 while (read16(0xa11100) & 0x100)
1454 ;
1455 test_ym_stopped_tick();
1456 mem_barrier();
1457 //start = ((u16)t->vcnt_start << 8) | hcnt2tm[t->hcnt_start >> 4];
1458 //end = ((u16)t->vcnt_end << 8) | hcnt2tm[t->hcnt_end >> 4];
1459 //diff = end - start;
1460 diff = t->vcnt_end - t->vcnt_start;
1461 //expect_range(ok, diff, 0x492, 0x5c2); // why so much variation?
1462 expect_range(ok, diff, 4, 5);
1463 expect(ok, t->stat0, 0);
1464 expect(ok, t->stat1, 2);
1465 expect(ok, z80[0x4000], 2);
1466 write8(&z80[0x4001], 0x30);
1467 return ok;
1468}
1469
1470static int t_tim_ym_timer_ab_sync(void)
1471{
3d80f940 1472 u16 v1, v2, v3, v4, v5, ln0, ln1, ln2;
e71680d5 1473 int ok = 1;
3d80f940 1474
1475 vdp_wait_for_line_0();
635f2450 1476 v1 = test_ym_ab_sync();
3d80f940 1477
1478 ln0 = get_line();
1479 burn10(3420*15/7/10); // ~15 scanlines
1480 write8(0xa04001, 0x3f); // clear, no reload
1481 burn10(12); // wait for busy to clear
635f2450 1482 v2 = read8(0xa04000);
1483 v3 = test_ym_ab_sync2();
3d80f940 1484
1485 ln1 = get_line();
1486 burn10(3420*15/7/10); // ~15 scanlines
1487 v4 = test_ym_ab_sync2();
1488
1489 ln2 = get_line();
1490 burn10(3420*30/7/10); // ~35 scanlines
1491 v5 = read8(0xa04000);
1492
635f2450 1493 expect(ok, v1, 3);
1494 expect(ok, v2, 0);
1495 expect(ok, v3, 3);
3d80f940 1496 expect(ok, v4, 2);
1497 expect(ok, v5, 0);
1498 expect_range(ok, ln1-ln0, 18, 19);
1499 expect_range(ok, ln2-ln1, 32, 34); // almost always 33
e71680d5 1500 return ok;
1501}
1502
4f936a9c 1503struct irq_test {
1504 u16 cnt;
1505 union {
1506 u16 hv;
1507 u8 v;
1508 } first, last;
8517a6df 1509 u16 pad;
4f936a9c 1510};
1511
e71680d5 1512// broken on fresh boot due to uknown reasons
6c839579 1513static int t_irq_hint(void)
1514{
4f936a9c 1515 struct irq_test *it = (void *)0xfff000;
e71680d5 1516 struct irq_test *itv = it + 1;
6c839579 1517 int ok = 1;
1518
e71680d5 1519 memset_(it, 0, sizeof(*it) * 2);
1520 memcpy_((void *)0xff0100, test_hint, test_hint_end - test_hint);
1521 memcpy_((void *)0xff0140, test_vint, test_vint_end - test_vint);
1522
1523 // without this, tests fail after cold boot
1524 while (!(read16(VDP_CTRL_PORT) & 8))
1525 /* not blanking */;
1526
6c839579 1527 // for more fun, disable the display
1528 VDP_setReg(VDP_MODE2, VDP_MODE2_MD);
1529
6c839579 1530 VDP_setReg(10, 0);
1531 while (read8(VDP_HV_COUNTER) != 100)
1532 ;
1533 while (read8(VDP_HV_COUNTER) != 229)
1534 ;
1535 // take the pending irq
1536 VDP_setReg(VDP_MODE1, VDP_MODE1_PS | VDP_MODE1_IE1);
1537 move_sr(0x2000);
1538 burn10(488 * 2 / 10);
1539 move_sr(0x2700);
4f936a9c 1540 expect(ok, it->first.v, 229); // pending irq trigger
1541 expect(ok, it->cnt, 1);
e71680d5 1542 expect(ok, itv->cnt, 0);
4f936a9c 1543
6c839579 1544 // count irqs
4f936a9c 1545 it->cnt = it->first.hv = it->last.hv = 0;
6c839579 1546 move_sr(0x2000);
cc7e5122 1547 while (read8(VDP_HV_COUNTER) != 4)
6c839579 1548 ;
1549 while (read8(VDP_HV_COUNTER) != 228)
1550 ;
1551 move_sr(0x2700);
4f936a9c 1552 expect(ok, it->cnt, 225);
1553 expect(ok, it->first.v, 0);
1554 expect(ok, it->last.v, 224);
1555
6c839579 1556 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
1557
4f936a9c 1558 // detect reload line
1559 it->cnt = it->first.hv = it->last.hv = 0;
1560 VDP_setReg(10, 17);
1561 move_sr(0x2000);
1562 while (read16(VDP_CTRL_PORT) & 8)
1563 /* blanking */;
1564 VDP_setReg(10, 255);
1565 while (read8(VDP_HV_COUNTER) != 228)
1566 ;
1567 move_sr(0x2700);
1568 expect(ok, it->cnt, 1);
1569 expect(ok, it->first.v, 17);
1570 expect(ok, it->last.v, 17);
1571
1572 VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
1573
6c839579 1574 return ok;
1575}
1576
8517a6df 1577static int t_irq_both_cpu_unmask(void)
1578{
1579 struct irq_test *ith = (void *)0xfff000;
1580 struct irq_test *itv = ith + 1;
1581 u16 s0, s1;
1582 int ok = 1;
1583
1584 memset_(ith, 0, sizeof(*ith) * 2);
1585 memcpy_((void *)0xff0100, test_hint, test_hint_end - test_hint);
1586 memcpy_((void *)0xff0140, test_vint, test_vint_end - test_vint);
1587 VDP_setReg(10, 0);
1588 while (read8(VDP_HV_COUNTER) != 100)
1589 ;
1590 while (read8(VDP_HV_COUNTER) != 226)
1591 ;
1592 VDP_setReg(10, 99);
1593 VDP_setReg(VDP_MODE1, VDP_MODE1_PS | VDP_MODE1_IE1);
1594 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_IE0 | VDP_MODE2_DISP);
1595 /* go to active display line 100 */
1596 while (read8(VDP_HV_COUNTER) != 100)
1597 ;
1598 s0 = read16(VDP_CTRL_PORT);
1599 s1 = move_sr_and_read(0x2000, VDP_CTRL_PORT);
1600 move_sr(0x2700);
1601 VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
1602 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
1603
1604 expect(ok, itv->cnt, 1); // vint count
1605 expect(ok, itv->first.v, 100); // vint line
1606 expect(ok, ith->cnt, 1); // hint count
1607 expect(ok, ith->first.v, 100); // hint line
1608 expect_bits(ok, s0, SR_F, SR_F);
1609 expect_bits(ok, s1, 0, SR_F);
1610 return ok;
1611}
1612
6c839579 1613static int t_irq_ack_v_h(void)
1614{
8517a6df 1615 struct irq_test *ith = (void *)0xfff000;
1616 struct irq_test *itv = ith + 1;
6c839579 1617 u16 s0, s1, s2;
1618 int ok = 1;
1619
8517a6df 1620 memset_(ith, 0, sizeof(*ith) * 2);
6c839579 1621 memcpy_((void *)0xff0100, test_hint, test_hint_end - test_hint);
1622 memcpy_((void *)0xff0140, test_vint, test_vint_end - test_vint);
1623 VDP_setReg(10, 0);
4f936a9c 1624 /* ensure hcnt reload */
1625 while (!(read16(VDP_CTRL_PORT) & 8))
1626 /* not blanking */;
1627 while (read16(VDP_CTRL_PORT) & 8)
1628 /* blanking */;
6c839579 1629 VDP_setReg(VDP_MODE1, VDP_MODE1_PS | VDP_MODE1_IE1);
1630 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_IE0);
1631 while (read8(VDP_HV_COUNTER) != 100)
1632 ;
1633 while (read8(VDP_HV_COUNTER) != 226)
1634 ;
1635 s0 = read16(VDP_CTRL_PORT);
1636 s1 = move_sr_and_read(0x2500, VDP_CTRL_PORT);
1637 burn10(666 / 10);
1638 s2 = move_sr_and_read(0x2000, VDP_CTRL_PORT);
1639 burn10(488 / 10);
1640 move_sr(0x2700);
1641 VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
1642 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
1643
8517a6df 1644 expect(ok, itv->cnt, 1); // vint count
1645 expect(ok, itv->first.v, 226); // vint line
1646 expect(ok, ith->cnt, 1); // hint count
1647 expect(ok, ith->first.v, 228); // hint line
6c839579 1648 expect_bits(ok, s0, SR_F, SR_F);
1649 expect_bits(ok, s1, 0, SR_F);
1650 expect_bits(ok, s2, 0, SR_F);
1651 return ok;
1652}
1653
cc7e5122 1654static int t_irq_ack_v_h_2(void)
1655{
8517a6df 1656 struct irq_test *ith = (void *)0xfff000;
1657 struct irq_test *itv = ith + 1;
cc7e5122 1658 u16 s0, s1;
1659 int ok = 1;
1660
8517a6df 1661 memset_(ith, 0, sizeof(*ith) * 2);
cc7e5122 1662 memcpy_((void *)0xff0100, test_hint, test_hint_end - test_hint);
1663 memcpy_((void *)0xff0140, test_vint, test_vint_end - test_vint);
1664 VDP_setReg(10, 0);
1665 while (read8(VDP_HV_COUNTER) != 100)
1666 ;
1667 while (read8(VDP_HV_COUNTER) != 226)
1668 ;
1669 s0 = read16(VDP_CTRL_PORT);
1670 test_v_h_2();
1671 s1 = read16(VDP_CTRL_PORT);
1672 VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
1673 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
1674
8517a6df 1675 expect(ok, itv->cnt, 2); // vint count
1676 expect(ok, itv->first.v, 226); // vint line
1677 expect(ok, ith->cnt, 1); // hint count
1678 expect(ok, ith->first.v, 227); // hint line
cc7e5122 1679 expect_bits(ok, s0, SR_F, SR_F);
1680 expect_bits(ok, s1, 0, SR_F);
1681 return ok;
1682}
1683
6c839579 1684static int t_irq_ack_h_v(void)
1685{
1686 u16 *ram = (u16 *)0xfff000;
1687 u8 *ram8 = (u8 *)0xfff000;
1688 u16 s0, s1, s[4];
1689 int ok = 1;
1690
1691 ram[0] = ram[1] = ram[2] =
1692 ram[4] = ram[5] = ram[6] = 0;
1693 memcpy_((void *)0xff0100, test_hint, test_hint_end - test_hint);
1694 memcpy_((void *)0xff0140, test_vint, test_vint_end - test_vint);
1695 VDP_setReg(10, 0);
1696 while (read8(VDP_HV_COUNTER) != 100)
1697 ;
1698 while (read8(VDP_HV_COUNTER) != 226)
1699 ;
1700 s0 = read16(VDP_CTRL_PORT);
1701 VDP_setReg(VDP_MODE1, VDP_MODE1_PS | VDP_MODE1_IE1);
1702 move_sr(0x2000);
1703 burn10(666 / 10);
1704 s1 = read16(VDP_CTRL_PORT);
1705 write_and_read1(VDP_CTRL_PORT, 0x8000 | (VDP_MODE2 << 8)
1706 | VDP_MODE2_MD | VDP_MODE2_IE0, s);
6c839579 1707 move_sr(0x2700);
1708 VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
1709 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
1710
1711 expect(ok, ram[0], 1); // hint count
1712 expect(ok, ram8[2], 226); // hint line
1713 expect(ok, ram[4], 1); // vint count
1714 expect(ok, ram8[10], 228); // vint line
1715 expect_bits(ok, s0, SR_F, SR_F);
1716 expect_bits(ok, s1, SR_F, SR_F);
1717 expect_bits(ok, s[0], SR_F, SR_F);
1718 expect_bits(ok, s[1], SR_F, SR_F);
1719 expect_bits(ok, s[2], 0, SR_F);
1720 expect_bits(ok, s[3], 0, SR_F);
1721 return ok;
1722}
1723
cc7e5122 1724static int t_irq_ack_h_v_2(void)
1725{
1726 u16 *ram = (u16 *)0xfff000;
1727 u8 *ram8 = (u8 *)0xfff000;
1728 u16 s0, s1;
1729 int ok = 1;
1730
1731 ram[0] = ram[1] = ram[2] =
1732 ram[4] = ram[5] = ram[6] = 0;
1733 memcpy_((void *)0xff0100, test_hint, test_hint_end - test_hint);
1734 memcpy_((void *)0xff0140, test_vint, test_vint_end - test_vint);
1735 VDP_setReg(10, 0);
1736 while (read8(VDP_HV_COUNTER) != 100)
1737 ;
1738 while (read8(VDP_HV_COUNTER) != 226)
1739 ;
1740 s0 = read16(VDP_CTRL_PORT);
1741 test_h_v_2();
1742 s1 = read16(VDP_CTRL_PORT);
1743 VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
1744 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
1745
1746 expect(ok, ram[0], 2); // hint count
1747 expect(ok, ram8[2], 226); // hint first line
1748 expect(ok, ram8[4], 226); // hint last line
1749 expect(ok, ram[4], 0); // vint count
1750 expect(ok, ram8[10], 0); // vint line
1751 expect_bits(ok, s0, SR_F, SR_F);
1752 expect_bits(ok, s1, 0, SR_F);
1753 return ok;
1754}
1755
1756static void t_irq_f_flag(void)
1757{
1758 memcpy_((void *)0xff0140, test_f_vint, test_f_vint_end - test_f_vint);
1759 memset_((void *)0xff0000, 0, 10);
1760 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_IE0 | VDP_MODE2_DISP);
1761 test_f();
1762 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
1763}
1764
1765static int t_irq_f_flag_h40(void)
1766{
1767 u8 f, *r = (u8 *)0xff0000;
1768 int ok = 1;
1769
1770 t_irq_f_flag();
1771
1772 expect_bits(ok, r[0], 0, SR_F);
1773 expect_bits(ok, r[1], 0, SR_F);
1774 expect_bits(ok, r[2], 0, SR_F);
1775 // hits 1-3 times in range 3-9, usually ~5
1776 f = r[3] | r[4] | r[5] | r[6] | r[7];
1777
1778 expect_bits(ok, r[10], 0, SR_F);
1779 expect_bits(ok, r[11], 0, SR_F);
1780 expect_bits(ok, f, SR_F, SR_F);
1781 return ok;
1782}
1783
1784static int t_irq_f_flag_h32(void)
1785{
1786 u8 f, *r = (u8 *)0xff0000;
1787 int ok = 1;
1788
1789 VDP_setReg(VDP_MODE4, 0x00);
1790 t_irq_f_flag();
1791 VDP_setReg(VDP_MODE4, 0x81);
1792
1793 expect_bits(ok, r[0], 0, SR_F);
1794 expect_bits(ok, r[1], 0, SR_F);
1795 // hits 1-3 times in range 2-7, usually 3
1796 f = r[2] | r[3] | r[4] | r[5] | r[6] | r[7];
1797
1798 expect_bits(ok, r[8], 0, SR_F);
1799 expect_bits(ok, r[9], 0, SR_F);
1800 expect_bits(ok, r[10], 0, SR_F);
1801 expect_bits(ok, r[11], 0, SR_F);
1802 expect_bits(ok, f, SR_F, SR_F);
1803 return ok;
1804}
1805
9d39a80e 1806// 32X
1807
5073ab5a 1808#define IRQ_CNT_FB_BASE 0x1ff00
1809
6474d733 1810// see do_cmd()
5073ab5a 1811static void x32_cmd(enum x32x_cmd cmd, u32 a0, u32 a1, u16 is_slave)
1812{
1813 u16 v, *r = (u16 *)0xa15120;
6474d733 1814 u8 *r8 = (u8 *)r;
5073ab5a 1815 u16 cmd_s = cmd | (is_slave << 15);
1816 int i;
1817
1818 write32(&r[4/2], a0);
1819 write32(&r[8/2], a1);
1820 mem_barrier();
1821 write16(r, cmd_s);
1822 mem_barrier();
1823 for (i = 0; i < 10000 && (v = read16(r)) == cmd_s; i++)
1824 burn10(1);
1825 if (v != 0) {
1826 printf("cmd clr: %x\n", v);
1827 mem_barrier();
6474d733 1828 printf("exc m s: %02x %02x\n", r8[0x0e], r8[0x0f]);
5073ab5a 1829 write16(r, 0);
1830 }
30a57837 1831 v = read8(&r8[2]);
5073ab5a 1832 if (v != 0) {
1833 printf("cmd err: %x\n", v);
1834 write16(&r[1], 0);
1835 }
30a57837 1836 mem_barrier();
5073ab5a 1837}
1838
1839static int t_32x_reset_btn(void)
1840{
1841 void (*do_32x_disable)(void) = (void *)0xff0040;
1842 u32 *fbl_icnt = (u32 *)(0x840000 + IRQ_CNT_FB_BASE);
1843 u16 *m_icnt = (u16 *)fbl_icnt;
1844 u16 *s_icnt = m_icnt + 8;
1845 u32 *r32 = (u32 *)0xa15100;
1846 u16 *r16 = (u16 *)r32, i, s;
1847 u8 *r8 = (u8 *)r32;
1848 u32 *rl = (u32 *)0;
1849 int ok = 1;
1850
1851 if (!(read16(r16) & 1))
1852 return R_SKIP;
1853
1854 expect(ok, r16[0x00/2], 0x8083);
1855
1856 write8(r8, 0x00); // FM=0
1857 mem_barrier();
1858 expect(ok, r16[0x00/2], 0x83);
1859 expect(ok, r16[0x02/2], 0);
1860 expect(ok, r16[0x04/2], 3);
1861 expect(ok, r16[0x06/2], 1); // RV (set in sega_gcc.s reset handler)
1862 expect(ok, r32[0x08/4], 0x5a5a08);
1863 expect(ok, r32[0x0c/4], 0x5a5a0c);
1864 expect(ok, r16[0x10/2], 0x5a10);
1865 expect(ok, r32[0x14/4], 0);
1866 expect(ok, r32[0x18/4], 0);
1867 expect(ok, r32[0x1c/4], 0);
1868 expect(ok, r32[0x20/4], 0x00005a20);
1869 expect(ok, r32[0x24/4], 0x5a5a5a24);
1870 expect(ok, r32[0x28/4], 0x5a5a5a28);
ec8170d9 1871 expect(ok, r32[0x2c/4], 0x075a5a2c); // 7 - last_irq_vec
5073ab5a 1872 if (!(r16[0x00/2] & 0x8000)) {
7449b889 1873 expect(ok, r8 [0x81], 1);
1874 expect(ok, r16[0x82/2], 1);
1875 expect(ok, r16[0x84/2], 0xff);
1876 expect(ok, r16[0x86/2], 0xffff);
1877 expect(ok, r16[0x88/2], 0);
5073ab5a 1878 expect(ok, r8 [0x8b] & ~2, 0); // FEN toggles periodically?
1879 expect(ok, r16[0x8c/2], 0);
1880 expect(ok, r16[0x8e/2], 0);
7449b889 1881 // setup vdp for t_32x_init
1882 r8 [0x81] = 0;
1883 r16[0x82/2] = r16[0x84/2] = r16[0x86/2] = 0;
5073ab5a 1884 }
1885 r32[0x20/4] = r32[0x24/4] = r32[0x28/4] = r32[0x2c/4] = 0;
1886 for (s = 0; s < 2; s++)
1887 {
1888 x32_cmd(CMD_READ32, 0x20004000, 0, s); // not cleared by hw
1889 expect_sh2(ok, s, r32[0x24/4], 0x02020000); // ADEN | cmd
1890 // t_32x_sh_defaults will test the other bits
1891 }
1892 // setup for t_32x_sh_defaults
1893 x32_cmd(CMD_WRITE8, 0x20004001, 0, 0);
1894 x32_cmd(CMD_WRITE8, 0x20004001, 0, 1);
1895
1896 for (i = 0; i < 7; i++) {
1897 expect(ok, m_icnt[i], 0x100);
1898 expect(ok, s_icnt[i], 0x100);
1899 }
1900 expect(ok, m_icnt[7], 0x101); // VRES happened
ec8170d9 1901 expect(ok, s_icnt[7], 0x100); // masked on slave
1902
1903 x32_cmd(CMD_GETSR, 0, 0, 1);
1904 expect_sh2(ok, 1, r32[0x24/4] & ~1, 0xf0); // still masked
1905 x32_cmd(CMD_SETSR, 0x10, 0, 1);
1906 expect(ok, r16[0x00/2], 0x8083);
1907 write8(r8, 0x00); // FM=0
1908 mem_barrier();
1909 expect(ok, m_icnt[7], 0x101);
5073ab5a 1910 expect(ok, s_icnt[7], 0x101);
ec8170d9 1911 expect(ok, r32[0x2c/4], 0x00070000); // 7 - last_irq_vec
1912 r32[0x2c/4] = 0;
5073ab5a 1913
1914 memcpy_(do_32x_disable, x32x_disable,
1915 x32x_disable_end - x32x_disable);
1916 do_32x_disable();
1917
1918 expect(ok, r16[0x00/2], 0x82);
1919 expect(ok, r16[0x02/2], 0);
1920 expect(ok, r16[0x04/2], 3);
c8abdf56 1921 expect(ok, r16[0x06/2], 0); // RV cleared by x32x_disable
5073ab5a 1922 expect(ok, r32[0x08/4], 0x5a5a08);
1923 expect(ok, r32[0x0c/4], 0x5a5a0c);
1924 expect(ok, r16[0x10/2], 0x5a10);
1925 expect(ok, rl[0x04/4], 0x000800);
1926
1927 // setup for t_32x_init, t_32x_sh_defaults
1928 r16[0x04/2] = 0;
5073ab5a 1929 r16[0x10/2] = 0x1234; // warm reset indicator
1930 mem_barrier();
1931 expect(ok, r16[0x06/2], 0); // RV
1932 return ok;
1933}
1934
9d39a80e 1935static int t_32x_init(void)
1936{
1937 void (*do_32x_enable)(void) = (void *)0xff0040;
1938 u32 M_OK = MKLONG('M','_','O','K');
1939 u32 S_OK = MKLONG('S','_','O','K');
5073ab5a 1940 u32 *r32 = (u32 *)0xa15100;
1941 u16 *r16 = (u16 *)r32;
1942 u8 *r8 = (u8 *)r32;
71b41fdd 1943 int i, ok = 1;
9d39a80e 1944
71b41fdd 1945 //v1070 = read32(0x1070);
1946
1947 /* what does REN mean exactly?
1948 * Seems to be sometimes clear after reset */
1949 for (i = 0; i < 1000000; i++)
1950 if (read16(r16) & 0x80)
1951 break;
9d39a80e 1952 expect(ok, r16[0x00/2], 0x82);
1953 expect(ok, r16[0x02/2], 0);
1954 expect(ok, r16[0x04/2], 0);
1955 expect(ok, r16[0x06/2], 0);
5073ab5a 1956 expect(ok, r8 [0x08], 0);
1957 //expect(ok, r32[0x08/4], 0); // garbage 24bit
1958 expect(ok, r8 [0x0c], 0);
1959 //expect(ok, r32[0x0c/4], 0); // garbage 24bit
1960 if (r16[0x10/2] != 0x1234) // warm reset
1961 expect(ok, r16[0x10/2], 0xffff);
1962 expect(ok, r16[0x12/2], 0);
1963 expect(ok, r32[0x14/4], 0);
1964 expect(ok, r32[0x18/4], 0);
1965 expect(ok, r32[0x1c/4], 0);
1966 //expect(ok, r8 [0x81], 0); // VDP; hangs without ADEN
1967 r32[0x20/4] = 0; // master resp
1968 r32[0x24/4] = 0; // slave resp
1969 r32[0x28/4] = 0;
1970 r32[0x2c/4] = 0;
1971
c8abdf56 1972 // check writable bits without ADEN
1973 // 08,0c have garbage or old values (survive MD's power cycle)
1974 write16(&r16[0x00/2], 0);
1975 mem_barrier();
1976 expect(ok, r16[0x00/2], 0x80);
1977 write16(&r16[0x00/2], 0xfffe);
1978 mem_barrier();
1979 expect(ok, r16[0x00/2], 0x8082);
1980 r16[0x00/2] = 0x82;
1981 r16[0x02/2] = 0xffff;
1982 r32[0x04/4] = 0xffffffff;
1983 r32[0x08/4] = 0xffffffff;
1984 r32[0x0c/4] = 0xffffffff;
1985 r16[0x10/2] = 0xffff;
1986 r32[0x14/4] = 0xffffffff;
1987 r32[0x18/4] = 0xffffffff;
1988 r32[0x1c/4] = 0xffffffff;
1989 mem_barrier();
1990 expect(ok, r16[0x00/2], 0x82);
1991 expect(ok, r16[0x02/2], 0x03);
1992 expect(ok, r16[0x04/2], 0x03);
1993 expect(ok, r16[0x06/2], 0x07);
1994 expect(ok, r32[0x08/4], 0x00fffffe);
1995 expect(ok, r32[0x0c/4], 0x00ffffff);
1996 expect(ok, r16[0x10/2], 0xfffc);
1997 expect(ok, r32[0x14/4], 0);
1998 expect(ok, r16[0x18/2], 0);
1999 expect(ok, r16[0x1a/2], 0x0101);
2000 expect(ok, r32[0x1c/4], 0);
2001 r16[0x02/2] = 0;
2002 r32[0x04/4] = 0;
5073ab5a 2003 r32[0x08/4] = 0;
2004 r32[0x0c/4] = 0;
c8abdf56 2005 r16[0x1a/2] = 0;
9d39a80e 2006
2007 // could just set RV, but BIOS reads ROM, so can't
2008 memcpy_(do_32x_enable, x32x_enable,
2009 x32x_enable_end - x32x_enable);
2010 do_32x_enable();
2011
2012 expect(ok, r16[0x00/2], 0x83);
2013 expect(ok, r16[0x02/2], 0);
2014 expect(ok, r16[0x04/2], 0);
2015 expect(ok, r16[0x06/2], 1); // RV
5073ab5a 2016 expect(ok, r32[0x14/4], 0);
2017 expect(ok, r32[0x18/4], 0);
2018 expect(ok, r32[0x1c/4], 0);
2019 expect(ok, r32[0x20/4], M_OK);
9d39a80e 2020 while (!read16(&r16[0x24/2]))
2021 ;
5073ab5a 2022 expect(ok, r32[0x24/4], S_OK);
2023 write32(&r32[0x20/4], 0);
2024 if (!(r16[0x00/2] & 0x8000)) {
2025 expect(ok, r8 [0x81], 0);
2026 expect(ok, r16[0x82/2], 0);
2027 expect(ok, r16[0x84/2], 0);
2028 expect(ok, r16[0x86/2], 0);
2029 //expect(ok, r16[0x88/2], 0); // triggers fill?
2030 expect(ok, r8 [0x8b] & ~2, 0);
2031 expect(ok, r16[0x8c/2], 0);
2032 expect(ok, r16[0x8e/2], 0);
06d7984c 2033 }
5073ab5a 2034 return ok;
9d39a80e 2035}
2036
2037static int t_32x_echo(void)
2038{
6474d733 2039 u16 *r16 = (u16 *)0xa15100;
9d39a80e 2040 int ok = 1;
2041
6474d733 2042 r16[0x2c/2] = r16[0x2e/2] = 0;
06d7984c 2043 x32_cmd(CMD_ECHO, 0x12340000, 0, 0);
6474d733 2044 expect_sh2(ok, 0, r16[0x26/2], 0x1234);
06d7984c 2045 x32_cmd(CMD_ECHO, 0x23450000, 0, 1);
6474d733 2046 expect_sh2(ok, 1, r16[0x26/2], 0xa345);
2047 expect(ok, r16[0x2c/2], 0); // no last_irq_vec
2048 expect(ok, r16[0x2e/2], 0); // no exception_index
5073ab5a 2049 return ok;
2050}
2051
2052static int t_32x_sh_defaults(void)
2053{
2054 u32 *r32 = (u32 *)0xa15120;
2055 int ok = 1, s;
2056
2057 for (s = 0; s < 2; s++)
2058 {
2059 x32_cmd(CMD_READ32, 0x20004000, 0, s);
2060 expect_sh2(ok, s, r32[0x04/4], 0x02000000); // ADEN
2061 x32_cmd(CMD_READ32, 0x20004004, 0, s);
2062 expect_sh2(ok, s, r32[0x04/4], 0x00004001); // Empty Rv
2063 x32_cmd(CMD_READ32, 0x20004008, 0, s);
2064 expect_sh2(ok, s, r32[0x04/4], 0);
2065 x32_cmd(CMD_READ32, 0x2000400c, 0, s);
2066 expect_sh2(ok, s, r32[0x04/4], 0);
2067 x32_cmd(CMD_GETGBR, 0, 0, s);
2068 expect_sh2(ok, s, r32[0x04/4], 0x20004000);
2069 }
06d7984c 2070 return ok;
2071}
2072
2073static int t_32x_md_bios(void)
2074{
2075 void (*do_call_c0)(int a, int d) = (void *)0xff0040;
2076 u8 *rmb = (u8 *)0xff0000;
2077 u32 *rl = (u32 *)0;
2078 int ok = 1;
2079
2080 memcpy_(do_call_c0, test_32x_b_c0,
2081 test_32x_b_c0_end - test_32x_b_c0);
2082 write8(rmb, 0);
2083 do_call_c0(0xff0000, 0x5a);
2084
2085 expect(ok, rmb[0], 0x5a);
2086 expect(ok, rl[0x04/4], 0x880200);
234c4556 2087 expect(ok, rl[0x10/4], 0x880212);
2088 expect(ok, rl[0x94/4], 0x8802d8);
9d39a80e 2089 return ok;
2090}
2091
2092static int t_32x_md_rom(void)
2093{
2094 u32 *rl = (u32 *)0;
2095 int ok = 1;
2096
2097 expect(ok, rl[0x004/4], 0x880200);
2098 expect(ok, rl[0x100/4], 0x53454741);
2099 expect(ok, rl[0x70/4], 0);
71b41fdd 2100 write32(&rl[0x70/4], 0xa5123456);
9d39a80e 2101 write32(&rl[0x78/4], ~0);
2102 mem_barrier();
9d39a80e 2103 expect(ok, rl[0x78/4], 0x8802ae);
71b41fdd 2104 expect(ok, rl[0x70/4], 0xa5123456);
2105 //expect(ok, rl[0x1070/4], v1070);
2106 write32(&rl[0x70/4], 0);
2107 // with RV 0x880000/0x900000 hangs, can't test
9d39a80e 2108 return ok;
2109}
2110
06d7984c 2111static int t_32x_md_fb(void)
2112{
2113 u8 *fbb = (u8 *)0x840000;
2114 u16 *fbw = (u16 *)fbb;
2115 u32 *fbl = (u32 *)fbb;
2116 u8 *fob = (u8 *)0x860000;
2117 u16 *fow = (u16 *)fob;
2118 u32 *fol = (u32 *)fob;
2119 int ok = 1;
2120
2121 fbl[0] = 0x12345678;
2122 fol[1] = 0x89abcdef;
2123 mem_barrier();
2124 expect(ok, fbw[1], 0x5678);
2125 expect(ok, fow[2], 0x89ab);
2126 fbb[0] = 0;
2127 fob[1] = 0;
2128 fbw[1] = 0;
2129 fow[2] = 0;
2130 fow[3] = 1;
2131 mem_barrier();
2132 fow[3] = 0x200;
2133 mem_barrier();
2134 expect(ok, fol[0], 0x12340000);
2135 expect(ok, fbl[1], 0x89ab0201);
2136 return ok;
2137}
2138
2139static int t_32x_sh_fb(void)
2140{
2141 u32 *fbl = (u32 *)0x840000;
5073ab5a 2142 u8 *r8 = (u8 *)0xa15100;
06d7984c 2143 int ok = 1;
2144
5073ab5a 2145 if (read8(r8) & 0x80)
2146 write8(r8, 0x00); // FM=0
06d7984c 2147 fbl[0] = 0x12345678;
2148 fbl[1] = 0x89abcdef;
2149 mem_barrier();
5073ab5a 2150 write8(r8, 0x80); // FM=1
2151 x32_cmd(CMD_WRITE8, 0x24000000, 0, 0); // should ignore
2152 x32_cmd(CMD_WRITE8, 0x24020001, 0, 0); // ignore
2153 x32_cmd(CMD_WRITE16, 0x24000002, 0, 0); // ok
2154 x32_cmd(CMD_WRITE16, 0x24020000, 0, 0); // ignore
06d7984c 2155 x32_cmd(CMD_WRITE32, 0x24020004, 0x5a0000a5, 1);
5073ab5a 2156 write8(r8, 0x00); // FM=0
06d7984c 2157 mem_barrier();
2158 expect(ok, fbl[0], 0x12340000);
2159 expect(ok, fbl[1], 0x5aabcda5);
2160 return ok;
2161}
2162
30a57837 2163static int t_32x_irq_cmd(void)
234c4556 2164{
5073ab5a 2165 u32 *fbl_icnt = (u32 *)(0x840000 + IRQ_CNT_FB_BASE);
2166 u16 *m_icnt = (u16 *)fbl_icnt;
2167 u16 *s_icnt = m_icnt + 8;
234c4556 2168 u32 *r = (u32 *)0xa15100;
2169 u16 *r16 = (u16 *)r;
6474d733 2170 u8 *r8 = (u8 *)r;
5073ab5a 2171 int ok = 1, i;
234c4556 2172
5073ab5a 2173 write8(r, 0x00); // FM=0
6474d733 2174 r[0x2c/4] = 0;
5073ab5a 2175 mem_barrier();
2176 for (i = 0; i < 8; i++)
2177 write32(&fbl_icnt[i], 0);
2178 mem_barrier();
2179 write16(&r16[0x02/2], 0xfffd); // INTM+unused_bits
2180 mem_barrier();
2181 expect(ok, r16[0x02/2], 1);
2182 x32_cmd(CMD_WRITE8, 0x20004001, 2, 0); // unmask cmd
2183 x32_cmd(CMD_WRITE8, 0x20004001, 2, 1); // unmask cmd slave
2184 burn10(10);
2185 write8(r, 0x00); // FM=0 (hangs without)
2186 mem_barrier();
2187 expect(ok, r16[0x02/2], 0);
6474d733 2188 expect(ok, r8 [0x2c], 4);
2189 expect(ok, r8 [0x2d], 0);
2190 expect(ok, r16[0x2e/2], 0); // no exception_index
5073ab5a 2191 expect(ok, m_icnt[4], 1);
2192 expect(ok, s_icnt[4], 0);
2193 write16(&r16[0x02/2], 0xaaaa); // INTS+unused_bits
2194 mem_barrier();
2195 expect(ok, r16[0x02/2], 2);
30a57837 2196 //burn10(10);
2197 x32_cmd(CMD_WRITE8, 0x20004001, 0, 0); // mask again
2198 x32_cmd(CMD_WRITE8, 0x20004001, 0, 1);
5073ab5a 2199 mem_barrier();
2200 expect(ok, r16[0x02/2], 0);
6474d733 2201 expect(ok, r8 [0x2c], 4);
2202 expect(ok, r8 [0x2d], 4);
2203 expect(ok, r16[0x2e/2], 0); // no exception_index
5073ab5a 2204 write8(r, 0x00); // FM=0
2205 mem_barrier();
2206 expect(ok, m_icnt[4], 1);
2207 expect(ok, s_icnt[4], 1);
2208 for (i = 0; i < 8; i++) {
2209 if (i == 4)
2210 continue;
2211 expect(ok, m_icnt[i], 0);
2212 expect(ok, s_icnt[i], 0);
2213 }
2214 return ok;
2215}
234c4556 2216
30a57837 2217static int t_32x_irq_vint(void)
2218{
2219 u32 *fbl_icnt = (u32 *)(0x840000 + IRQ_CNT_FB_BASE);
2220 u16 *m_icnt = (u16 *)fbl_icnt;
2221 u16 *s_icnt = m_icnt + 8;
2222 u32 *r = (u32 *)0xa15100;
2223 u16 *r16 = (u16 *)r;
2224 u8 *r8 = (u8 *)r;
2225 int ok = 1, i;
2226
2227 vdp_wait_for_line_0();
2228 write8(r, 0x00); // FM=0
2229 r[0x2c/4] = 0;
2230 mem_barrier();
2231 for (i = 0; i < 8; i++)
2232 write32(&fbl_icnt[i], 0);
2233 mem_barrier();
2234 x32_cmd(CMD_SETSR, 0xf0, 0, 0); // master mask at sr
2235 x32_cmd(CMD_WRITE8, 0x20004001, 8, 0); // unmask both 32x vint
2236 x32_cmd(CMD_WRITE8, 0x20004001, 8, 1);
2237 burn10(10);
2238 mem_barrier();
2239 expect(ok, r16[0x2c/2], 0); // no pending vints
2240 expect(ok, r16[0x2e/2], 0); // no exception_index
2241
2242 write8(&r8[0x23], 0x5a); // no-32x-source-autoclear flag
2243 wait_next_vsync();
2244 burn10(10);
2245 expect(ok, r8 [0x2c], 0);
2246 expect(ok, r8 [0x2d], 12/2);
2247 write8(&r8[0x2d], 0);
2248 burn10(10);
2249 expect(ok, r8 [0x2c], 0);
2250 expect(ok, r8 [0x2d], 12/2);
2251
2252 x32_cmd(CMD_WRITE16, 0x20004016, 0, 0); // clear on 32x (from master)
2253 burn10(10);
2254 write16(&r[0x2c/4], 0);
2255 burn10(10);
2256 expect(ok, r8 [0x2c], 0);
2257 expect(ok, r8 [0x2d], 12/2);
2258 // (here the slave can't accept commands as it keeps retaking the irq)
2259 write8(&r8[0x23], 0); // handler 32x clear on
2260 burn10(10);
2261 write16(&r[0x2c/4], 0);
2262 burn10(10);
2263 expect(ok, r16[0x2c/2], 0); // no pending vints
2264 expect(ok, r16[0x2e/2], 0); // no exception_index
2265 write8(r, 0x00); // FM=0
2266 mem_barrier();
2267 expect(ok, m_icnt[12/2], 0);
2268 expect_range(ok, s_icnt[12/2], 0x10, 0x1000);
2269
2270 x32_cmd(CMD_SETSR, 0x10, 0, 0); // master unmask at sr
2271 wait_next_vsync();
2272 burn10(10);
2273 expect(ok, r8 [0x2c], 12/2);
2274 expect(ok, r8 [0x2d], 12/2);
2275
2276 x32_cmd(CMD_WRITE8, 0x20004001, 0, 0); // mask
2277 x32_cmd(CMD_WRITE8, 0x20004001, 0, 1);
2278 write16(&r[0x2c/4], 0);
2279 wait_next_vsync();
2280 burn10(10);
2281 expect(ok, r16[0x2c/2], 0); // no pending vints
2282 expect(ok, r16[0x2e/2], 0); // no exception_index
2283
2284 x32_cmd(CMD_WRITE8, 0x20004001, 8, 1); // slave unmask
2285 burn10(10);
2286 x32_cmd(CMD_WRITE8, 0x20004001, 0, 1); // mask
2287 burn10(10);
2288 expect(ok, r8 [0x2c], 0);
2289 expect(ok, r8 [0x2d], 12/2);
2290 write16(&r[0x2c/4], 0);
2291
2292 vdp_wait_for_line_0();
2293 x32_cmd(CMD_WRITE8, 0x20004001, 8, 0); // master unmask
2294 burn10(10);
2295 x32_cmd(CMD_WRITE8, 0x20004001, 0, 0); // mask
2296 burn10(10);
2297 expect(ok, r8 [0x2c], 0);
2298 expect(ok, r8 [0x2d], 0);
2299
2300 write8(&r8[0x23], 0); // handler 32x clear on
2301 write8(r, 0x00); // FM=0
2302 mem_barrier();
2303 expect(ok, m_icnt[12/2], 1);
2304 for (i = 0; i < 8; i++) {
2305 if (i == 12/2)
2306 continue;
2307 expect(ok, m_icnt[i], 0);
2308 expect(ok, s_icnt[i], 0);
2309 }
2310 return ok;
2311}
2312
5073ab5a 2313static int t_32x_reg_w(void)
2314{
2315 u32 *r32 = (u32 *)0xa15100;
2316 u16 *r16 = (u16 *)r32, old;
2317 int ok = 1;
234c4556 2318
5073ab5a 2319 r32[0x08/4] = ~0;
2320 r32[0x0c/4] = ~0;
2321 r16[0x10/2] = ~0;
2322 mem_barrier();
2323 expect(ok, r32[0x08/4], 0xfffffe);
2324 expect(ok, r32[0x0c/4], 0xffffff);
2325 expect(ok, r16[0x10/2], 0xfffc);
2326 mem_barrier();
2327 r32[0x08/4] = r32[0x0c/4] = 0;
2328 r16[0x10/2] = 0;
2329 old = r16[0x06/2];
2330 x32_cmd(CMD_WRITE16, 0x20004006, ~old, 0);
2331 expect(ok, r16[0x06/2], old);
2332 return ok;
2333}
234c4556 2334
5073ab5a 2335// prepare for reset btn press tests
2336static int t_32x_reset_prep(void)
2337{
7449b889 2338 u32 *fbl = (u32 *)0x840000;
2339 u32 *fbl_icnt = fbl + IRQ_CNT_FB_BASE / 4;
5073ab5a 2340 u32 *r32 = (u32 *)0xa15100;
2341 u16 *r16 = (u16 *)r32;
2342 u8 *r8 = (u8 *)r32;
2343 int ok = 1, i;
2344
2345 expect(ok, r16[0x00/2], 0x83);
2346 write8(r8, 0x00); // FM=0
6474d733 2347 r32[0x2c/4] = 0;
234c4556 2348 mem_barrier();
5073ab5a 2349 expect(ok, r8[0x8b] & ~2, 0);
2350 for (i = 0; i < 8; i++)
2351 write32(&fbl_icnt[i], 0x01000100);
2352 x32_cmd(CMD_WRITE8, 0x20004001, 0x02, 0); // unmask cmd
2353 x32_cmd(CMD_WRITE8, 0x20004001, 0x02, 1); // unmask slave
ec8170d9 2354 x32_cmd(CMD_SETSR, 0xf0, 0, 1); // mask slave irqs (on the cpu)
5073ab5a 2355 burn10(10);
2356 write8(r8, 0x00); // FM=0
6474d733 2357 expect(ok, r32[0x2c/4], 0);
5073ab5a 2358 mem_barrier();
2359 for (i = 0; i < 8; i++)
2360 expect(ok, fbl_icnt[i], 0x01000100);
2361
2362 r16[0x04/2] = 0xffff;
2363 r32[0x08/4] = 0x5a5a5a08;
2364 r32[0x0c/4] = 0x5a5a5a0c;
2365 r16[0x10/2] = 0x5a10;
2366 r32[0x20/4] = 0x00005a20; // no x32_cmd
2367 r32[0x24/4] = 0x5a5a5a24;
2368 r32[0x28/4] = 0x5a5a5a28;
2369 r32[0x2c/4] = 0x5a5a5a2c;
7449b889 2370 if (!(r16[0x00/2] & 0x8000)) {
2371 wait_next_vsync();
2372 r16[0x8a/2] = 0x0001;
2373 mem_barrier();
2374 for (i = 0; i < 220/2; i++)
31bdf771 2375 write32(&fbl[i], 0);
7449b889 2376 r8 [0x81] = 1;
2377 r16[0x82/2] = 0xffff;
2378 r16[0x84/2] = 0xffff;
2379 r16[0x86/2] = 0xffff;
2380 r16[0x8a/2] = 0x0000;
2381 r16[0x8c/2] = 0xffff;
2382 r16[0x8e/2] = 0xffff;
2383 r16[0x100/2] = 0;
2384 }
234c4556 2385 return ok;
2386}
2387
9d39a80e 2388enum {
2389 T_MD = 0,
2390 T_32 = 1, // 32X
2391};
2392
ffd4b35c 2393static const struct {
9d39a80e 2394 u8 type;
ffd4b35c 2395 int (*test)(void);
2396 const char *name;
2397} g_tests[] = {
5073ab5a 2398 // this must be first to disable the 32x and restore the 68k vector table
2399 { T_32, t_32x_reset_btn, "32x resetbtn" },
2400
9d39a80e 2401 { T_MD, t_dma_zero_wrap, "dma zero len + wrap" },
2402 { T_MD, t_dma_zero_fill, "dma zero len + fill" },
2403 { T_MD, t_dma_ram_wrap, "dma ram wrap" },
2404 { T_MD, t_dma_multi, "dma multi" },
2405 { T_MD, t_dma_cram_wrap, "dma cram wrap" },
2406 { T_MD, t_dma_vsram_wrap, "dma vsram wrap" },
2407 { T_MD, t_dma_and_data, "dma and data" },
2408 { T_MD, t_dma_short_cmd, "dma short cmd" },
2409 { T_MD, t_dma_fill3_odd, "dma fill3 odd" },
2410 { T_MD, t_dma_fill3_even, "dma fill3 even" },
9d39a80e 2411 { T_MD, t_dma_fill3_vsram, "dma fill3 vsram" },
9d39a80e 2412 { T_MD, t_dma_fill_dis, "dma fill disabled" },
2413 { T_MD, t_dma_fill_src, "dma fill src incr" },
7c817df6 2414 { T_MD, t_dma_busy_vram, "dma no busy" },
9d39a80e 2415 { T_MD, t_dma_128k, "dma 128k mode" },
2416 { T_MD, t_vdp_128k_b16, "vdp 128k addr bit16" },
a385208c 2417 // { t_vdp_128k_b16_inc, "vdp 128k bit16 inc" }, // mystery
9d39a80e 2418 { T_MD, t_vdp_reg_cmd, "vdp reg w cmd reset" },
2419 { T_MD, t_vdp_sr_vb, "vdp status reg vb" },
2420 { T_MD, t_z80mem_long_mirror, "z80 ram long mirror" },
2421 { T_MD, t_z80mem_noreq_w, "z80 ram noreq write" },
2422 { T_MD, t_z80mem_vdp_r, "z80 vdp read" },
ffd4b35c 2423 // { t_z80mem_vdp_w, "z80 vdp write" }, // hang
9d39a80e 2424 { T_MD, t_tim_loop, "time loop" },
e71680d5 2425 { T_MD, t_tim_z80_loop, "time z80 loop" },
9d39a80e 2426 { T_MD, t_tim_z80_ram, "time z80 ram" },
2427 { T_MD, t_tim_z80_ym, "time z80 ym2612" },
2428 { T_MD, t_tim_z80_vdp, "time z80 vdp" },
2429 { T_MD, t_tim_z80_bank_rom, "time z80 bank rom" },
2430 { T_MD, t_tim_vcnt, "time V counter" },
e71680d5 2431 { T_MD, t_tim_vcnt_loops, "time vcnt loops" },
9d39a80e 2432 { T_MD, t_tim_hblank_h40, "time hblank h40" },
2433 { T_MD, t_tim_hblank_h32, "time hblank h32" },
2434 { T_MD, t_tim_vdp_as_vram_w, "time vdp vram w" },
2435 { T_MD, t_tim_vdp_as_cram_w, "time vdp cram w" },
e71680d5 2436 { T_MD, t_tim_ym_timera_z80, "time timer a z80" },
2437 { T_MD, t_tim_ym_timerb_z80, "time timer b z80" },
2438 { T_MD, t_tim_ym_timerb_stop, "timer b stop" },
2439 { T_MD, t_tim_ym_timer_ab_sync,"timer ab sync" },
9d39a80e 2440 { T_MD, t_irq_hint, "irq4 / line" },
8517a6df 2441 { T_MD, t_irq_both_cpu_unmask, "irq both umask" },
9d39a80e 2442 { T_MD, t_irq_ack_v_h, "irq ack v-h" },
2443 { T_MD, t_irq_ack_v_h_2, "irq ack v-h 2" },
2444 { T_MD, t_irq_ack_h_v, "irq ack h-v" },
2445 { T_MD, t_irq_ack_h_v_2, "irq ack h-v 2" },
2446 { T_MD, t_irq_f_flag_h40, "irq f flag h40" },
9d39a80e 2447 { T_MD, t_irq_f_flag_h32, "irq f flag h32" },
2448
06d7984c 2449 // the first one enables 32X, so must be kept
2450 // all tests assume RV=1 FM=0
9d39a80e 2451 { T_32, t_32x_init, "32x init" },
2452 { T_32, t_32x_echo, "32x echo" },
5073ab5a 2453 { T_32, t_32x_sh_defaults, "32x sh def" },
06d7984c 2454 { T_32, t_32x_md_bios, "32x md bios" },
2455 { T_32, t_32x_md_rom, "32x md rom" },
2456 { T_32, t_32x_md_fb, "32x md fb" },
2457 { T_32, t_32x_sh_fb, "32x sh fb" },
30a57837 2458 { T_32, t_32x_irq_cmd, "32x irq cmd" },
2459 { T_32, t_32x_irq_vint, "32x irq vint" },
5073ab5a 2460 { T_32, t_32x_reg_w, "32x reg w" },
2461 { T_32, t_32x_reset_prep, "32x rstprep" }, // must be last 32x
ffd4b35c 2462};
2463
2464static void setup_z80(void)
2465{
2466 u8 *zram = (u8 *)0xa00000;
2467 int i, len;
2468
2469 /* z80 */
2470 write16(0xa11100, 0x100);
2471 write16(0xa11200, 0x100);
2472
2473 while (read16(0xa11100) & 0x100)
2474 ;
2475
2476 // load the default test program, clear it's data
2477 len = z80_test_end - z80_test;
2478 for (i = 0; i < len; i++)
2479 write8(&zram[i], z80_test[i]);
2480 for (i = 0x1000; i < 0x1007; i++)
2481 write8(&zram[i], 0);
a385208c 2482
2483 // reset
2484 write16(0xa11200, 0x000);
2485 write16(0xa11100, 0x000);
2486 burn10(1);
2487 write16(0xa11200, 0x100);
e71680d5 2488
2489 burn10(50 * 15 / 7 / 10); // see z80_test.s80
a385208c 2490
2491 // take back the bus
2492 write16(0xa11100, 0x100);
2493 while (read16(0xa11100) & 0x100)
2494 ;
2495}
2496
cc7e5122 2497static unused int hexinc(char *c)
a385208c 2498{
2499 (*c)++;
2500 if (*c > 'f') {
2501 *c = '0';
2502 return 1;
2503 }
2504 if (*c == '9' + 1)
2505 *c = 'a';
2506 return 0;
ffd4b35c 2507}
2508
2509int main()
2510{
5073ab5a 2511 void (*px32x_switch_rv)(short rv);
2512 short (*pget_input)(void) = get_input;
ffd4b35c 2513 int passed = 0;
9d39a80e 2514 int skipped = 0;
2515 int have_32x;
234c4556 2516 int en_32x;
ffd4b35c 2517 int ret;
a385208c 2518 u8 v8;
ffd4b35c 2519 int i;
2520
2521 setup_z80();
2522
a385208c 2523 /* io */
2524 write8(0xa10009, 0x40);
2525
ffd4b35c 2526 /* setup VDP */
2527 while (read16(VDP_CTRL_PORT) & 2)
2528 ;
2529
2530 VDP_setReg(VDP_MODE1, VDP_MODE1_PS);
2531 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA);
2532 VDP_setReg(VDP_MODE3, 0x00);
2533 VDP_setReg(VDP_MODE4, 0x81);
2534 VDP_setReg(VDP_NT_SCROLLA, APLANE >> 10);
2535 VDP_setReg(VDP_NT_SCROLLB, BPLANE >> 13);
2536 VDP_setReg(VDP_SAT_BASE, SLIST >> 9);
2537 VDP_setReg(VDP_HSCROLL, HSCRL >> 10);
2538 VDP_setReg(VDP_AUTOINC, 2);
2539 VDP_setReg(VDP_SCROLLSZ, 0x01);
2540 VDP_setReg(VDP_BACKDROP, 0);
2541
2542 // early tests
2543 t_dma_zero_wrap_early();
2544 t_dma_zero_fill_early();
2545
2546 /* pattern 0 */
2547 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(0));
2548 for (i = 0; i < 32 / 4; i++)
2549 write32(VDP_DATA_PORT, 0);
2550
2551 /* clear name tables */
2552 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(APLANE));
2553 for (i = 0; i < PLANE_W * PLANE_H / 2; i++)
2554 write32(VDP_DATA_PORT, 0);
2555
2556 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(BPLANE));
2557 for (i = 0; i < PLANE_W * PLANE_H / 2; i++)
2558 write32(VDP_DATA_PORT, 0);
2559
2560 /* SAT, h. scroll */
2561 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(SLIST));
2562 write32(VDP_DATA_PORT, 0);
2563
2564 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(HSCRL));
2565 write32(VDP_DATA_PORT, 0);
2566
2567 /* scroll plane vscroll */
2568 write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
2569 write32(VDP_DATA_PORT, 0);
2570 printf_ypos = 1;
2571
2572 /* load font */
2573 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(TILE_FONT_BASE));
2574 for (i = 0; i < FONT_LEN * 32 / 4; i++)
2575 write32(VDP_DATA_PORT, font_base[i]);
2576
2577 /* set colors */
2578 setup_default_palette();
2579
2580 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
2581
30a57837 2582 printf("%s\n", VERSION);
9d39a80e 2583 have_32x = read32(0xa130ec) == MKLONG('M','A','R','S');
5073ab5a 2584 en_32x = have_32x && (read16(0xa15100) & 1);
a385208c 2585 v8 = read8(0xa10001);
234c4556 2586 printf("MD version: %02x %s %s %s%s\n", v8,
a385208c 2587 (v8 & 0x80) ? "world" : "jap",
9d39a80e 2588 (v8 & 0x40) ? "pal" : "ntsc",
234c4556 2589 have_32x ? "32X" : "",
2590 en_32x ? "+" : "");
7449b889 2591 printf("reset hvc %04x->%04x\n", read16(-4), read16(-2));
2592
2593 // sanity check
2594 extern u32 sh2_test[];
2595 if (sh2_test[0] != read32(0x3e0) || sh2_test[0x200/4] != read32(0x3e4))
2596 printf("bad 0x3c0 tab\n");
ffd4b35c 2597
2598 for (i = 0; i < ARRAY_SIZE(g_tests); i++) {
2599 // print test number if we haven't scrolled away
2600 if (printf_ypos < CSCREEN_H) {
2601 int old_ypos = printf_ypos;
2602 printf_ypos = 0;
ffd4b35c 2603 printf("%02d/%02d", i, ARRAY_SIZE(g_tests));
2604 printf_ypos = old_ypos;
2605 printf_xpos = 0;
2606 }
9d39a80e 2607 if ((g_tests[i].type & T_32) && !have_32x) {
2608 skipped++;
2609 continue;
2610 }
ffd4b35c 2611 ret = g_tests[i].test();
5073ab5a 2612 if (ret == R_SKIP) {
2613 skipped++;
2614 continue;
2615 }
a385208c 2616 if (ret != 1) {
2617 text_pal = 2;
ffd4b35c 2618 printf("failed %d: %s\n", i, g_tests[i].name);
a385208c 2619 text_pal = 0;
2620 }
ffd4b35c 2621 else
2622 passed++;
2623 }
2624
2625 text_pal = 0;
9d39a80e 2626 printf("%d/%d passed, %d skipped.\n",
2627 passed, ARRAY_SIZE(g_tests), skipped);
ffd4b35c 2628
2629 printf_ypos = 0;
2630 printf(" ");
2631
7449b889 2632 if (have_32x && (read16(0xa15100) & 1)) {
5073ab5a 2633 u8 *p = (u8 *)0xff0040;
2634 u32 len = x32x_switch_rv_end - x32x_switch_rv;
2635 px32x_switch_rv = (void *)p; p += len;
2636 memcpy_(px32x_switch_rv, x32x_switch_rv, len);
2637
2638 len = get_input_end - get_input_s;
2639 pget_input = (void *)p; p += len;
2640 memcpy_(pget_input, get_input_s, len);
2641
2642 // prepare for reset - run from 880xxx as the reset vector points there
2643 // todo: broken printf
2644 px32x_switch_rv(0);
2645 }
7449b889 2646 for (i = 0; i < 60*60 && !(pget_input() & BTNM_A); i++) {
2647 while (read16(VDP_CTRL_PORT) & SR_VB)
2648 write16(-4, read16(VDP_HV_COUNTER)); /* blanking */
2649 while (!(read16(VDP_CTRL_PORT) & SR_VB))
2650 write16(-4, read16(VDP_HV_COUNTER)); /* not blanking */;
2651 }
30a57837 2652#if 0 //ndef PICO
e71680d5 2653 // blank due to my lame tv being burn-in prone
2654 VDP_setReg(VDP_MODE2, VDP_MODE2_MD);
2655#endif
5073ab5a 2656 while (!(pget_input() & BTNM_A))
7449b889 2657 write16(-4, read16(VDP_HV_COUNTER));
e71680d5 2658 VDP_setReg(VDP_MODE2, VDP_MODE2_MD | VDP_MODE2_DMA | VDP_MODE2_DISP);
a385208c 2659
2660
2661 {
2662 char c[3] = { '0', '0', '0' };
2663 short hscroll = 0, vscroll = 0;
2664 short hsz = 1, vsz = 0;
2665 short cellmode = 0;
2666
2667 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(APLANE));
2668
cc7e5122 2669#if 0
2670 for (i = 0, c[0] = 'a'; i < 8 * 1024 / 2; i++) {
2671 write16(VDP_DATA_PORT, (u16)c[0] - 32 + TILE_FONT_BASE / 32);
2672 c[0]++;
2673 if (c[0] == 'z' + 1)
2674 c[0] = 'a';
2675 }
2676#else
a385208c 2677 for (i = 0; i < 8 * 1024 / 2 / 4; i++) {
2678 write16(VDP_DATA_PORT, (u16)'.' - 32 + TILE_FONT_BASE / 32);
2679 write16(VDP_DATA_PORT, (u16)c[2] - 32 + TILE_FONT_BASE / 32);
2680 write16(VDP_DATA_PORT, (u16)c[1] - 32 + TILE_FONT_BASE / 32);
2681 write16(VDP_DATA_PORT, (u16)c[0] - 32 + TILE_FONT_BASE / 32);
2682 if (hexinc(&c[0]))
2683 if (hexinc(&c[1]))
2684 hexinc(&c[2]);
2685 }
cc7e5122 2686#endif
5073ab5a 2687 while (pget_input() & BTNM_A)
a385208c 2688 wait_next_vsync();
2689
2690 wait_next_vsync();
2691 for (;;) {
5073ab5a 2692 int b = pget_input();
a385208c 2693
2694 if (b & BTNM_C) {
2695 hscroll = 1, vscroll = -1;
2696 do {
2697 wait_next_vsync();
5073ab5a 2698 } while (pget_input() & BTNM_C);
a385208c 2699 cellmode ^= 1;
2700 }
2701 if (b & (BTNM_L | BTNM_R | BTNM_C)) {
2702 hscroll += (b & BTNM_L) ? 1 : -1;
2703 write32(VDP_CTRL_PORT, CTL_WRITE_VRAM(HSCRL));
2704 write16(VDP_DATA_PORT, hscroll);
2705 }
2706 if (b & (BTNM_U | BTNM_D | BTNM_C)) {
2707 vscroll += (b & BTNM_U) ? -1 : 1;
2708 write32(VDP_CTRL_PORT, CTL_WRITE_VSRAM(0));
2709 if (cellmode) {
2710 int end = (int)vscroll + 21;
2711 for (i = vscroll; i < end; i++)
2712 write32(VDP_DATA_PORT, i << 17);
2713 VDP_setReg(VDP_MODE3, 0x04);
2714 }
2715 else {
2716 write16(VDP_DATA_PORT, vscroll);
2717 VDP_setReg(VDP_MODE3, 0x00);
2718 }
2719 }
2720 if (b & BTNM_A) {
2721 hsz = (hsz + 1) & 3;
2722 do {
2723 wait_next_vsync();
5073ab5a 2724 } while (pget_input() & BTNM_A);
a385208c 2725 }
2726 if (b & BTNM_B) {
2727 vsz = (vsz + 1) & 3;
2728 do {
2729 wait_next_vsync();
5073ab5a 2730 } while (pget_input() & BTNM_B);
a385208c 2731 }
2732 VDP_setReg(VDP_SCROLLSZ, (vsz << 4) | hsz);
2733
2734 printf_xpos = 1;
2735 printf_ypos = 0;
2736 text_pal = 1;
2737 printf(" %d %d ", hsz, vsz);
2738
2739 wait_next_vsync();
2740 }
2741 }
2742
ffd4b35c 2743 for (;;)
2744 ;
2745
2746 return 0;
2747}
2748
2749// vim:ts=4:sw=4:expandtab