filename getter
[megadrive.git] / mx / linux / main.c
CommitLineData
8c8e818c 1#include <stdio.h>
726b85c8 2#include <string.h>
8c8e818c 3#include <usb.h>
4
5
6typedef unsigned char u8;
7typedef unsigned short u16;
8typedef unsigned int u32;
9#define array_size(x) (sizeof(x) / sizeof(x[0]))
10
11static const struct {
12 unsigned short vendor;
13 unsigned short product;
14 const char *name;
15} g_devices[] = {
16 { 0x03eb, 0x202a, "16MX+U Game Device" },
17 { 0x03eb, 0x202b, "32MX+U Game Device" },
18 { 0x03eb, 0x202c, "16MX+US Game Device" },
19 { 0x03eb, 0x202d, "32MX+UF Game Device" },
20};
21
22/*****************************************************************************/
23
fb4ee110 24#define CMD_ATM_READY 0x22
25#define CMD_SEC_GET_NAME 'G' /* read filename */
726b85c8 26
fb4ee110 27/* bus controllers */
28#define CTL_DATA_BUS 0x55
29#define CTL_ADDR_BUS 0xAA
30
31#define FILENAME_ROM0 0
32#define FILENAME_ROM1 1
33#define FILENAME_RAM 2
726b85c8 34
35typedef struct {
8c8e818c 36 u8 magic[4];
37 u8 reserved[11];
38 u8 magic2;
39 u8 mx_cmd;
40 union {
41 struct {
42 u8 which_device;
8c8e818c 43 } dev_info;
44 struct {
45 u8 addrb2; /* most significant */
46 u8 addrb1;
47 u8 addrb0;
48 u8 num_pages;
49 } rom_rw;
50 struct {
fb4ee110 51 u8 which;
8c8e818c 52 } filename;
53 struct {
54 u8 times_cmd;
55 u8 action;
56 u8 cntb3;
57 u8 cntb2;
58 u8 cntb1;
59 u8 cntb0;
60 } times_write;
61 };
62 u8 pad[8];
726b85c8 63} dev_cmd_t;
64
65typedef struct {
66 u8 firmware_ver[4];
67 u8 bootloader_ver[4];
68 char names[56];
69} dev_info_t;
70
71static void prepare_cmd(dev_cmd_t *dev_cmd, u8 cmd)
72{
73 memset(dev_cmd, 0, sizeof(*dev_cmd));
74
75 memcpy(dev_cmd->magic, "USBC", 4);
fb4ee110 76 dev_cmd->magic2 = 0x67; /* MySCSICommand, EXCOMMAND */
726b85c8 77 dev_cmd->mx_cmd = cmd;
78}
79
80static int write_cmd(struct usb_dev_handle *dev, dev_cmd_t *cmd)
81{
82 int ret = usb_bulk_write(dev, 0x03, (char *)cmd, sizeof(*cmd), 2000);
83 if (ret < 0) {
84 fprintf(stderr, "failed to write:\n");
85 fprintf(stderr, "%s (%d)\n", usb_strerror(), ret);
86 } else if (ret != sizeof(*cmd))
87 printf("write_cmd: wrote only %d of %d bytes\n", ret, sizeof(*cmd));
88
89 return ret;
90}
91
92static int read_response(struct usb_dev_handle *dev, void *buff, int size)
93{
94 int ret = usb_bulk_read(dev, 0x82, buff, size, 2000);
95 if (ret < 0) {
96 fprintf(stderr, "failed to read:\n");
97 fprintf(stderr, "%s (%d)\n", usb_strerror(), ret);
98 } else if (ret != size)
99 printf("read_response: read only %d of %d bytes\n", ret, size);
8c8e818c 100
726b85c8 101 return ret;
102}
8c8e818c 103
fb4ee110 104static int read_info(struct usb_dev_handle *device, u8 ctl_id)
105{
106 dev_cmd_t cmd;
107 dev_info_t info;
108 int ret;
109
110 prepare_cmd(&cmd, CMD_ATM_READY);
111 cmd.dev_info.which_device = ctl_id;
112 memset(&info, 0, sizeof(info));
113
114 ret = write_cmd(device, &cmd);
115 if (ret < 0)
116 return ret;
117
118 ret = read_response(device, &info, sizeof(info));
119 if (ret < 0)
120 return ret;
121
122 printf(" firmware version: %X.%X.%X%c\n", info.firmware_ver[0],
123 info.firmware_ver[1], info.firmware_ver[2], info.firmware_ver[3]);
124 printf(" bootloader version: %X.%X.%X%c\n", info.bootloader_ver[0],
125 info.bootloader_ver[1], info.bootloader_ver[2], info.bootloader_ver[3]);
126 info.names[sizeof(info.names) - 1] = 0;
127 printf(" device name: %s\n", info.names);
128
129 return 0;
130}
131
132static int get_filename(struct usb_dev_handle *dev, char *dst, int len, u8 which)
133{
134 char buff[65];
135 dev_cmd_t cmd;
136 int ret;
137
138 prepare_cmd(&cmd, CMD_SEC_GET_NAME);
139 cmd.filename.which = which;
140 memset(buff, 0, sizeof(buff));
141
142 ret = write_cmd(dev, &cmd);
143 if (ret < 0)
144 return ret;
145
146 ret = read_response(dev, buff, 64);
147 if (ret < 0)
148 return ret;
149
150 strncpy(dst, buff, len);
151 dst[len - 1] = 0;
152
153 return 0;
154}
155
8c8e818c 156static usb_dev_handle *get_device(void)
157{
158 struct usb_dev_handle *handle;
159 struct usb_device *dev;
160 struct usb_bus *bus;
161 int i, ret;
162
163 ret = usb_find_busses();
164 if (ret <= 0) {
165 fprintf(stderr, "Can't find USB busses\n");
166 return NULL;
167 }
168
169 ret = usb_find_devices();
170 if (ret <= 0) {
171 fprintf(stderr, "Can't find USB devices\n");
172 return NULL;
173 }
174
175 bus = usb_get_busses();
176 for (; bus; bus = bus->next)
177 {
178 for (dev = bus->devices; dev; dev = dev->next)
179 {
180 for (i = 0; i < array_size(g_devices); i++)
181 {
182 if (dev->descriptor.idVendor == g_devices[i].vendor &&
183 dev->descriptor.idProduct == g_devices[i].product)
184 goto found;
185 }
186 }
187 }
188
189 fprintf(stderr, "device not found.\n");
190 return NULL;
191
192found:
193 printf("found %s.\n", g_devices[i].name);
194
195 handle = usb_open(dev);
196 if (handle == NULL) {
197 fprintf(stderr, "failed to open device:\n");
198 fprintf(stderr, "%s\n", usb_strerror());
199 return NULL;
200 }
201
202 ret = usb_set_configuration(handle, 1);
203 if (ret != 0) {
204 fprintf(stderr, "couldn't set configuration for /*/bus/usb/%s/%s:\n",
205 bus->dirname, dev->filename);
726b85c8 206 fprintf(stderr, "%s (%d)\n", usb_strerror(), ret);
8c8e818c 207 return NULL;
208 }
209
210 ret = usb_claim_interface(handle, 0);
211 if (ret != 0) {
212 fprintf(stderr, "couldn't claim /*/bus/usb/%s/%s:\n",
213 bus->dirname, dev->filename);
214 fprintf(stderr, "%s (%d)\n", usb_strerror(), ret);
215 return NULL;
216 }
217
218 return handle;
219}
220
221static void release_device(struct usb_dev_handle *device)
222{
223 usb_release_interface(device, 0);
224 usb_close(device);
225}
226
227int main(int argc, char *argv[])
228{
229 struct usb_dev_handle *device;
fb4ee110 230 char fname[65];
726b85c8 231 int ret;
8c8e818c 232
233 usb_init();
234
235 device = get_device();
236 if (device == NULL)
237 return 1;
238
726b85c8 239 printf("data bus controller:\n");
240 ret = read_info(device, CTL_DATA_BUS);
241 if (ret < 0)
242 goto end;
243
244 printf("address bus controller:\n");
245 ret = read_info(device, CTL_ADDR_BUS);
246 if (ret < 0)
247 goto end;
8c8e818c 248
fb4ee110 249 ret = get_filename(device, fname, sizeof(fname), FILENAME_ROM0);
250 if (ret < 0)
251 goto end;
252 printf("ROM filename: %s\n", fname);
253
254 ret = get_filename(device, fname, sizeof(fname), FILENAME_RAM);
255 if (ret < 0)
256 goto end;
257 printf("SRAM filename: %s\n", fname);
258
259
8c8e818c 260
726b85c8 261end:
8c8e818c 262 release_device(device);
263
726b85c8 264 return ret;
8c8e818c 265}
266