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