108156b4e8b7f2b962192d94b6e1e029c162458a
[picodrive.git] / test_misc2_gen.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <time.h>
4
5
6 static FILE *f;
7
8 #define bswap16(x) (x=(unsigned short)((x<<8)|(x>>8)))
9 #define bswap32(x) (x=((x<<24)|((x<<8)&0xff0000)|((x>>8)&0x00ff00)|((unsigned)x>>24)))
10
11 static void write_op(unsigned short op, unsigned short word0, unsigned short word1, unsigned short word2)
12 {
13         bswap16(op);
14         bswap16(word0);
15         bswap16(word1);
16         bswap16(word2);
17
18         fwrite(&op,    1, sizeof(op), f);
19         fwrite(&word0, 1, sizeof(word0), f);
20         fwrite(&word1, 1, sizeof(word1), f);
21         fwrite(&word2, 1, sizeof(word2), f);
22 }
23
24 static void write32(unsigned int a)
25 {
26         bswap32(a);
27         fwrite(&a,     1, sizeof(a),  f);
28 }
29
30 static int op_check(unsigned short op)
31 {
32         if ((op&0xf000) == 0x6000) return 0; // Bxx
33         if ((op&0xf0f8) == 0x50c8) return 0; // DBxx
34         if ((op&0xff80) == 0x4e80) return 0; // Jsr
35         if ((op&0xf000) == 0xa000) return 0; // a-line
36         if ((op&0xf000) == 0xf000) return 0; // f-line
37         if ((op&0xfff8)==0x4e70&&op!=0x4e71&&op!=0x4e76) return 0; // reset, rte, rts
38
39         if ((op&0x3f) >= 0x28) op = (op&~0x3f) | (rand() % 0x28);
40         return 1;
41 }
42
43 static unsigned short safe_rand(void)
44 {
45         unsigned short op;
46
47         /* avoid branch opcodes */
48         do
49         {
50                 op = rand();
51         }
52         while (!op_check(op));
53
54         return op;
55 }
56
57 int main()
58 {
59         int i, op;
60
61         srand(time(0));
62
63         f = fopen("test_misc2.bin", "wb");
64         if (!f) return 1;
65
66         write32(0x00ff8000); // stack
67         write32(0x300); // IP
68
69         for (i=0x100/4-2; i; i--)
70         {
71                 write32(0x200+i*4); // exception vectors
72         }
73
74         for (i=0x100/4; i; i--)
75         {
76                 write32(0); // pad
77         }
78
79         for (i=0x100/4; i; i--)
80         {
81                 write32(0x4e734e73); // fill with rte instructions
82         }
83
84         for (op = 0; op < 0x10000; op++)
85         {
86                 if ((op&0xf000) == 0x6000) // Bxx
87                 {
88                         if ((op&0x00ff) == 0)
89                                 write_op(op, 6, 0, 0);
90                 }
91                 else if ((op&0xf0f8)==0x50c8) // DBxx
92                 {
93                         write_op(op, 6, 0, 0);
94                 }
95                 else if ((op&0xff80)==0x4e80) // Jsr
96                 {
97                         int addr = 0x300 + op*8 + 8;
98                         if ((op&0x3f) == 0x39)
99                                 write_op(op, addr >> 16, addr & 0xffff, 0);
100                 }
101                 else if ((op&0xf000)==0xa000 || (op&0xf000)==0xf000) // a-line, f-line
102                 {
103                         if (op != 0xa000 && op != 0xf000) continue;
104                 }
105                 else if ((op&0xfff8)==0x4e70&&op!=0x4e71&&op!=0x4e76); // rte, rts, stop, reset
106                 else
107                 {
108                         write_op(op, safe_rand(), safe_rand(), safe_rand());
109                 }
110         }
111
112         // jump to the beginning
113         write_op(0x4ef8, 0x300, 0x4ef8, 0x300);
114         write_op(0x4ef8, 0x300, 0x4ef8, 0x300);
115
116         fclose(f);
117         return 0;
118 }
119