romdump.c
3.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define B2S(b) ( (((b)[0^(swapped)] & 0xffL) << 8) | \
(((b)[1^(swapped)] & 0xffL) << 0) )
#define B2L(b) ( (((b)[0^(swapped)] & 0xffL) << 24) | \
(((b)[1^(swapped)] & 0xffL) << 16) | \
(((b)[2^(swapped)] & 0xffL) << 8) | \
(((b)[3^(swapped)] & 0xffL)) )
#define HEADER_MAGIC 0x80371240
extern void swab(const void *from, void *to, ssize_t n);
int swapped;
struct ccode {
int code;
char* name;
} ccode[] = {
{ 0x00 , " (NONE)"},
{ 0x4A , "J (JAPAN)"},
{ 0x37 , "7 (BETA)"},
{ 0x41 , "A (NTSC)"},
{ 0x44 , "D (GERMANY)"},
{ 0x45 , "E (USA)"},
{ 0x46 , "F (FRANCE)"},
{ 0x49 , "I (ITALY)"},
{ 0x50 , "P (EUROPE)"},
{ 0x53 , "S (SPAIN)"},
{ 0x55 , "U (AUSTRALIA)"},
{ 0x58 , "X (PAL)"},
{ 0x59 , "Y (PAL)"},
{ 0, 0},
};
char* find_ccode(long code) {
int i;
for (i = 0; ccode[i].name; i++)
if (code == ccode[i].code) return ccode[i].name;
return "";
}
int
main(int argc, char **argv)
{
FILE *f;
int i;
unsigned int a, b = 0xffffffff, entry, e = 0xffffffff;
unsigned char buf[20];
if (argc != 2) {
fprintf(stderr, "Usage: romdump <rom name>\n");
return 1;
}
f = fopen(argv[1], "rb");
if (f == NULL) {
char err[21 + strlen(argv[1])];
sprintf(err, "Couldn't open file %s", argv[1]);
perror(err);
return 1;
}
if( fread(buf, 1, 12, f) != 12 ) {
exit(1);
}
if ( B2L(buf) == HEADER_MAGIC ) {
swapped = 0;
} else if ( (swapped=1) && B2L(buf) == HEADER_MAGIC ) {
swapped = 1;
} else {
fprintf(stderr, "%s: not a rom file\n", argv[1]);
exit(1);
}
fseek(f, 0, SEEK_SET);
fread(buf, 1, 4, f);
printf("header = 0x%lx\n", B2L(buf));
fread(buf, 1, 4, f);
printf("clock rate = 0x%lx\n", B2L(buf));
fread(buf, 1, 4, f);
printf("boot addr = 0x%x\n", entry = B2L(buf));
fread(buf, 1, 4, f);
printf("release = OS %ld%c\n", B2L(buf)>>8, (int)B2L(buf)&0xff);
fread(buf, 1, 4, f);
printf("crc1 = 0x%lx\n", B2L(buf));
fread(buf, 1, 4, f);
printf("crc2 = 0x%lx\n", B2L(buf));
fread(buf, 1, 4, f);
//printf("u0 = 0x%lx\n", B2L(buf));
fread(buf, 1, 4, f);
//printf("u1 = 0x%lx\n", B2L(buf));
fread(buf, 1, 20, f);
if (swapped) swab(buf, buf, 20);
printf("name = %.20s\n", buf);
fread(buf, 1, 4, f);
//printf("u3 = 0x%lx\n", B2L(buf));
fread(buf, 1, 4, f);
printf("manuf id = 0x%lx (%d)\n", B2L(buf), (int)B2L(buf));
buf[2] = 0; buf[3] = 0;
fread(buf, 1, 2, f);
printf("cart id = 0x%lx\n", B2S(buf));
fread(buf, 1, 2, f);
printf("country code = 0x%lx/%s\nrevision = 0x%lx\n", B2S(buf)>>8,
find_ccode(B2S(buf)>>8), B2S(buf)&0xff);
fseek(f, 4096, SEEK_SET);
for(i = 0; i < 16; i++) {
fread(buf, 1, 4, f); a = B2L(buf);
/* lui t0 */
if ((a >> 16) == 0x3c08) b = a << 16;
/* addui t0 ori t0 */
else if ((a>>16) == 0x2508 || (a>>16) == 0x3508) b|=(a&0xffff);
/* lui t2 */
else if ((a>>16) == 0x3c0a) e = a << 16;
/* addui t2 ori t2 */
else if ((a>>16) == 0x254a || (a>>16) == 0x354a) e|=(a&0xffff);
}
printf("boot: bss start 0x%x\n", b);
printf("boot: text/data size 0x%x (%d)\n", b-entry, b-entry);
printf("boot: entry 2 0x%x\n", e);
fseek(f, 0, SEEK_END);
printf("rom size 0x%lx %.1fM\n", ftell(f), ftell(f)/(1024.*1024));
fclose(f);
return 0;
}