testpico: show that vres clear is separate
[megadrive.git] / testpico / sh2_main.c
1 #include "common.h"
2
3 void spin(int loops);
4 u16  read_frt(void);
5
6 // comm area map:
7 // 00-01: cmd
8 // 02-03: error
9 // 04-07: arg0/response
10 // 08-0b: arg1
11 // 0c: last_irq_vec_master
12 // 0d: last_irq_vec_slave
13 // 0e: exception_index_master
14 // 0f: exception_index_slave
15 static void do_cmd(u16 cmd, u16 r[6], u32 is_slave)
16 {
17     u32 *rl = (u32 *)r;
18     u32 a, d;
19     u16 v;
20
21     switch (cmd)
22     {
23     case CMD_ECHO:
24         v = read16(&r[4/2]) ^ (is_slave << 15);
25         write16(&r[6/2], v);
26         break;
27     case CMD_READ_FRT:
28         v = read_frt();
29         write16(&r[4/2], v);
30         break;
31     case CMD_READ8:
32         a = read32(&rl[4/4]);
33         d = read8(a);
34         write32(&rl[4/4], d);
35         break;
36     case CMD_READ16:
37         a = read32(&rl[4/4]);
38         d = read16(a);
39         write32(&rl[4/4], d);
40         break;
41     case CMD_READ32:
42         a = read32(&rl[4/4]);
43         d = read32(a);
44         write32(&rl[4/4], d);
45         break;
46     case CMD_WRITE8:
47         a = read32(&rl[4/4]);
48         d = read32(&rl[8/4]);
49         write8(a, d);
50         break;
51     case CMD_WRITE16:
52         a = read32(&rl[4/4]);
53         d = read32(&rl[8/4]);
54         write16(a, d);
55         break;
56     case CMD_WRITE32:
57         a = read32(&rl[4/4]);
58         d = read32(&rl[8/4]);
59         write32(a, d);
60         break;
61     case CMD_GETGBR:
62         asm volatile("stc gbr, %0" : "=r"(d));
63         write32(&rl[4/4], d);
64         break;
65     case CMD_GETVBR:
66         asm volatile("stc vbr, %0" : "=r"(d));
67         write32(&rl[4/4], d);
68         break;
69     case CMD_GETSR:
70         asm volatile("stc sr, %0" : "=r"(d));
71         write32(&rl[4/4], d);
72         break;
73     case CMD_SETSR:
74         d = read32(&rl[4/4]);
75         asm volatile("ldc %0, sr" :: "r"(d));
76         break;
77     default:
78         r[2/2]++; // error
79         mem_barrier();
80         break;
81     }
82 }
83
84 void main_c(u32 is_slave)
85 {
86     u16 *r = (u16 *)0x20004000;
87
88     for (;;)
89     {
90         u16 cmd, cmdr;
91
92         mem_barrier();
93         cmd = read16(&r[0x20/2]);
94         mem_barrier();
95         cmdr = read16(&r[0x20/2]);
96         if (cmd == 0
97             || cmd != cmdr  // documented as "normal" case
98             || ((cmd & 0x8000) ^ (is_slave << 15))
99             || cmd == 0x4d5f) { // 'M_' from BIOS
100             spin(64);
101             continue;
102         }
103         cmd &= 0x7fff;
104         do_cmd(cmd, &r[0x20/2], is_slave);
105         write16(&r[0x20/2], 0);
106     }
107 }
108
109 // vim:ts=4:sw=4:expandtab