8 #include <sys/select.h>
14 #include <linux/usbdevice_fs.h>
15 #include <linux/usb/ch9.h>
16 #include <linux/input.h>
19 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
29 /* return 1 if founf, 0 if not, < 0 on error */
30 static int find_device(struct teensy_dev *dev,
31 uint16_t vendor, uint16_t product)
33 const char path_root[] = "/dev/bus/usb";
35 struct usb_descriptor_header hdr;
36 struct usb_device_descriptor d;
37 struct usb_config_descriptor c;
38 struct usb_interface_descriptor i;
39 struct usb_endpoint_descriptor e;
40 char space[0x100]; /* enough? */
42 char path_bus[256], path_dev[256];
43 struct dirent *ent, *ent_bus;
44 DIR *dir = NULL, *dir_bus = NULL;
50 memset(dev, 0xff, sizeof(*dev));
52 dir = opendir(path_root);
58 for (ent = readdir(dir); ent != NULL; ent = readdir(dir)) {
59 /* should be a number like 000 */
60 if (sscanf(ent->d_name, "%03d", &num) != 1)
63 snprintf(path_bus, sizeof(path_bus), "%s/%s",
64 path_root, ent->d_name);
66 dir_bus = opendir(path_bus);
70 ent_bus = readdir(dir_bus);
71 for (; ent_bus != NULL; ent_bus = readdir(dir_bus)) {
72 if (sscanf(ent->d_name, "%03d", &num) != 1)
75 snprintf(path_dev, sizeof(path_dev), "%s/%s/%s",
76 path_root, ent->d_name, ent_bus->d_name);
78 fd = open(path_dev, O_RDWR);
82 ret = read(fd, &desc.d, sizeof(desc.d));
83 if (ret != sizeof(desc.d)) {
84 fprintf(stderr, "desc read: %d/%zd: ", ret, sizeof(desc.d));
89 if (desc.d.bDescriptorType != USB_DT_DEVICE) {
90 fprintf(stderr, "%s: bad DT: 0x%02x\n",
91 path_dev, desc.d.bDescriptorType);
95 if (desc.d.idVendor == vendor && desc.d.idProduct == product)
112 if (desc.d.bNumConfigurations != 1) {
113 fprintf(stderr, "unexpected bNumConfigurations: %u\n",
114 desc.d.bNumConfigurations);
118 /* walk through all descriptors */
121 ret = read(fd, &desc.hdr, sizeof(desc.hdr));
124 if (ret != sizeof(desc.hdr)) {
125 fprintf(stderr, "desc.hdr read: %d/%zd: ", ret, sizeof(desc.hdr));
130 ret = (int)lseek(fd, -sizeof(desc.hdr), SEEK_CUR);
136 ret = read(fd, &desc, desc.hdr.bLength);
137 if (ret != desc.hdr.bLength) {
138 fprintf(stderr, "desc read: %d/%u: ", ret, desc.hdr.bLength);
143 switch (desc.hdr.bDescriptorType) {
145 if (desc.c.bNumInterfaces != 2) {
146 fprintf(stderr, "unexpected bNumInterfaces: %u\n",
147 desc.c.bNumInterfaces);
152 case USB_DT_INTERFACE:
153 if (desc.i.bInterfaceClass != USB_CLASS_HID
154 || desc.i.bInterfaceSubClass != 0
155 || desc.i.bInterfaceProtocol != 0) {
156 fprintf(stderr, "unexpected interface %x:%x:%x\n",
157 desc.i.bInterfaceClass, desc.i.bInterfaceSubClass,
158 desc.i.bInterfaceProtocol);
161 if (desc.i.bNumEndpoints != 2) {
162 fprintf(stderr, "unexpected bNumEndpoints: %u\n",
163 desc.i.bNumEndpoints);
169 case USB_DT_ENDPOINT:
170 if (iface < 0 || iface >= ARRAY_SIZE(dev->ifaces)) {
171 fprintf(stderr, "bad iface: %d\n", iface);
174 if (desc.e.wMaxPacketSize != 64 && desc.e.wMaxPacketSize != 32) {
175 fprintf(stderr, "iface %d, EP %02x: "
176 "unexpected wMaxPacketSize: %u\n",
177 iface, desc.e.bEndpointAddress, desc.e.wMaxPacketSize);
180 if (desc.e.bEndpointAddress & 0x80)
181 dev->ifaces[iface].ep_in = desc.e.bEndpointAddress; // & 0x7F;
183 dev->ifaces[iface].ep_out = desc.e.bEndpointAddress;
191 fprintf(stderr, "skipping desc 0x%02x\n",
192 desc.hdr.bDescriptorType);
197 /* claim interfaces */
198 for (iface = 0; iface < ARRAY_SIZE(dev->ifaces); iface++) {
199 struct usbdevfs_ioctl usbio;
201 if (dev->ifaces[iface].ep_in == -1) {
202 fprintf(stderr, "missing ep_in, iface: %d\n", iface);
205 if (dev->ifaces[iface].ep_out == -1) {
206 fprintf(stderr, "missing ep_out, iface: %d\n", iface);
210 /* disconnect default driver */
211 memset(&usbio, 0, sizeof(usbio));
213 usbio.ioctl_code = USBDEVFS_DISCONNECT;
214 ret = ioctl(fd, USBDEVFS_IOCTL, &usbio);
215 if (ret != 0 && errno != ENODATA)
216 perror("USBDEVFS_DISCONNECT");
218 ret = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &iface);
220 perror("USBDEVFS_CLAIMINTERFACE");
238 static int enable_echo(int enable)
240 const char *portname = "/dev/tty";
246 memset(&tty, 0, sizeof(tty));
248 fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);
250 fprintf(stderr, "open %s: ", portname);
255 ret = tcgetattr(fd, &tty);
261 // printf("lflag: 0%o\n", tty.c_lflag);
265 tty.c_lflag &= ~ECHO;
267 ret = tcsetattr(fd, TCSANOW, &tty);
280 static void signal_handler(int sig)
283 signal(sig, SIG_DFL);
287 /* ?0SA 00DU, ?1CB RLDU */
288 #define STATE_BYTES 2
290 static uint8_t fixed_input_state[STATE_BYTES] = { 0x33, 0x3f };
303 static const enum mdbtn evdev_md_map[KEY_CNT] = {
305 [KEY_DOWN] = MDBTN_DOWN,
306 [KEY_LEFT] = MDBTN_LEFT,
307 [KEY_RIGHT] = MDBTN_RIGHT,
308 [KEY_HOME] = MDBTN_A,
309 [KEY_PAGEDOWN] = MDBTN_B,
311 [KEY_LEFTALT] = MDBTN_START,
314 int do_evdev_input(int fd)
316 uint8_t old_state[STATE_BYTES];
317 uint8_t changed_bits[STATE_BYTES] = { 0, };
318 struct input_event ev;
322 ret = read(fd, &ev, sizeof(ev));
323 if (ret != sizeof(ev)) {
324 fprintf(stderr, "evdev read %d/%zd: ", ret, sizeof(ev));
329 if (ev.type != EV_KEY)
332 if (ev.value != 0 && ev.value != 1)
335 if ((uint32_t)ev.code >= ARRAY_SIZE(evdev_md_map)) {
336 fprintf(stderr, "evdev read bad key: %u\n", ev.code);
340 mdbtn = evdev_md_map[ev.code];
344 memcpy(old_state, fixed_input_state, STATE_BYTES);
346 /* ?0SA 00DU, ?1CB RLDU */
349 changed_bits[0] = 0x01;
350 changed_bits[1] = 0x01;
353 changed_bits[0] = 0x02;
354 changed_bits[1] = 0x02;
357 changed_bits[0] = 0x00;
358 changed_bits[1] = 0x04;
361 changed_bits[0] = 0x00;
362 changed_bits[1] = 0x08;
365 changed_bits[0] = 0x10;
366 changed_bits[1] = 0x00;
369 changed_bits[0] = 0x00;
370 changed_bits[1] = 0x10;
373 changed_bits[0] = 0x00;
374 changed_bits[1] = 0x20;
377 changed_bits[0] = 0x20;
378 changed_bits[1] = 0x00;
384 for (i = 0; i < STATE_BYTES; i++)
385 fixed_input_state[i] &= ~changed_bits[i];
389 for (i = 0; i < STATE_BYTES; i++)
390 fixed_input_state[i] |= changed_bits[i];
393 return memcmp(old_state, fixed_input_state, STATE_BYTES) ? 1 : 0;
399 uint32_t rerecord_count;
407 static int submit_urb(int fd, struct usbdevfs_urb *urb, int ep,
408 void *buf, size_t buf_size)
410 memset(urb, 0, sizeof(*urb));
411 urb->type = USBDEVFS_URB_TYPE_INTERRUPT;
414 urb->buffer_length = buf_size;
416 return ioctl(fd, USBDEVFS_SUBMITURB, urb);
426 int main(int argc, char *argv[])
428 const char *tasfn = NULL;
429 struct teensy_dev dev;
430 struct usbdevfs_urb urb[URB_CNT];
431 struct usbdevfs_urb *reaped_urb;
432 int fixed_input_changed;
434 int evdev_fd_cnt = 0;
438 int data_in_sent = 0;
440 struct gmv_tas *gmv = NULL;
444 char buf_dbg[64 + 1];
445 struct tas_pkt pkt_in;
446 struct tas_pkt pkt_out;
447 struct timeval *timeout = NULL;
452 for (i = 1; i < argc; i++) {
453 if (argv[i][0] == '-') {
454 if (strcmp(argv[i], "-m") != 0) {
455 fprintf(stderr, "bad arg: %s\n", argv[i]);
459 if (argv[i] == NULL) {
460 fprintf(stderr, "missing arg\n");
466 if (evdev_fd_cnt >= ARRAY_SIZE(evdev_fds)) {
467 fprintf(stderr, "too many evdevs\n");
470 fd = open(argv[i], O_RDONLY);
472 fprintf(stderr, "open %s: ", argv[i]);
477 ret = ioctl(fd, EVIOCGBIT(0, sizeof(evdev_support)),
481 if (!(evdev_support & (1 << EV_KEY))) {
482 fprintf(stderr, "%s doesn't have keys\n", argv[i]);
486 evdev_fds[evdev_fd_cnt++] = fd;
493 f = fopen(tasfn, "rb");
495 fprintf(stderr, "fopen %s: ", tasfn);
500 fseek(f, 0, SEEK_END);
502 fseek(f, 0, SEEK_SET);
503 if (size < (long)sizeof(*gmv)) {
504 fprintf(stderr, "bad gmv size: %ld\n", size);
509 fprintf(stderr, "OOM?\n");
512 ret = fread(gmv, 1, size, f);
514 fprintf(stderr, "fread %d/%ld: ", ret, size);
519 frame_count = (size - sizeof(*gmv)) / 3;
521 /* check the GMV.. */
522 if (frame_count <= 0 || size != sizeof(*gmv) + frame_count * 3) {
523 fprintf(stderr, "broken gmv? frames=%d\n", frame_count);
527 if (strncmp(gmv->sig, "Gens Movie TEST", 15) != 0) {
528 fprintf(stderr, "bad GMV sig\n");
531 if (gmv->ctrl1 != '3') {
532 fprintf(stderr, "unhandled controlled config: '%c'\n", gmv->ctrl1);
535 if (gmv->ver >= 'A') {
536 if (gmv->flags & 0x40) {
537 fprintf(stderr, "unhandled flag: movie requires a savestate\n");
540 if (gmv->flags & 0x20) {
541 fprintf(stderr, "unhandled flag: 3-player movie\n");
544 if (gmv->flags & ~0x80) {
545 fprintf(stderr, "unhandled flag(s): %04x\n", gmv->flags);
550 printf("loaded GMV: %s\n", gmv->name);
551 printf("%d frames, %u rerecords\n",
552 frame_count, gmv->rerecord_count);
556 signal(SIGINT, signal_handler);
563 ret = find_device(&dev, 0x16C0, 0x0486);
569 printf("waiting for device..\n");
582 /* we wait first, then send commands, but if teensy
583 * is started already, it won't send anything */
590 memset(&pkt_in, 0, sizeof(pkt_in));
591 ret = submit_urb(dev.fd, &urb[URB_DATA_IN], dev.ifaces[0].ep_in,
592 &pkt_in, sizeof(pkt_in));
594 perror("USBDEVFS_SUBMITURB URB_DATA_IN");
601 ret = submit_urb(dev.fd, &urb[URB_DBG_IN], dev.ifaces[1].ep_in,
602 buf_dbg, sizeof(buf_dbg) - 1);
604 perror("USBDEVFS_SUBMITURB URB_DBG_IN");
612 for (i = 0; i < evdev_fd_cnt; i++)
613 FD_SET(evdev_fds[i], &rfds);
616 FD_SET(dev.fd, &wfds);
618 ret = select(dev.fd + 1, &rfds, &wfds, NULL, timeout);
625 /* something from input devices? */
626 fixed_input_changed = 0;
627 for (i = 0; i < evdev_fd_cnt; i++) {
628 if (FD_ISSET(evdev_fds[i], &rfds)) {
629 fixed_input_changed |=
630 do_evdev_input(evdev_fds[i]);
634 /* something from USB? */
635 if (FD_ISSET(dev.fd, &wfds))
638 ret = ioctl(dev.fd, USBDEVFS_REAPURB, &reaped_urb);
642 perror("USBDEVFS_REAPURB");
646 if (reaped_urb != NULL && reaped_urb->status != 0) {
647 errno = -reaped_urb->status;
648 if ((unsigned long)(reaped_urb - urb) < ARRAY_SIZE(urb))
649 fprintf(stderr, "urb #%zu: ", reaped_urb - urb);
651 fprintf(stderr, "unknown urb: ");
653 if (reaped_urb->status == -EILSEQ) {
654 /* this is usually a sign of disconnect.. */
660 if (reaped_urb == &urb[URB_DATA_IN]) {
661 /* some request from teensy */
665 switch (pkt_in.type) {
667 printf("%d/%d\n", frames_sent, frame_count);
669 for (i = 0; i < sizeof(pkt_out.data); i++) {
670 pkt_out.data[i * 2 + 0] = 0x33;
671 pkt_out.data[i * 2 + 1] = 0x3f;
673 if (frames_sent < frame_count) {
674 pkt_out.type = PKT_STREAM_DATA;
676 count = frame_count - frames_sent;
677 if (count > sizeof(pkt_out.data) / 2)
678 count = sizeof(pkt_out.data) / 2;
679 for (i = 0; i < count; i++) {
681 b = gmv->data[frames_sent][0];
683 /* ?0SA 00DU, ?1CB RLDU */
684 pkt_out.data[i * 2 + 0] = (b & 0x13) | ((b >> 2) & 0x20);
685 pkt_out.data[i * 2 + 1] = (b & 0x0f) | ((b >> 1) & 0x30);
687 if (gmv->data[frames_sent][1] != 0xff
688 || gmv->data[frames_sent][2] != 0xff)
690 fprintf(stderr, "f %d: unhandled byte(s) %02x %02x\n",
691 frames_sent, gmv->data[frames_sent][1],
692 gmv->data[frames_sent][2]);
699 pkt_out.type = PKT_STREAM_END;
701 ret = submit_urb(dev.fd, &urb[URB_DATA_OUT],
702 dev.ifaces[0].ep_out, &pkt_out, sizeof(pkt_out));
704 perror("USBDEVFS_SUBMITURB URB_DATA_OUT PKT_STREAM_DATA");
708 printf("host: got unknown pkt type: %04x\n", pkt_in.type);
714 else if (reaped_urb == &urb[URB_DATA_OUT]) {
716 else if (reaped_urb == &urb[URB_DBG_IN]) {
718 buf_dbg[reaped_urb->actual_length] = 0;
719 printf("%s", buf_dbg);
723 fprintf(stderr, "reaped unknown urb? %p #%zu\n",
724 reaped_urb, reaped_urb - urb);
728 /* something to send? */
729 if (gmv != NULL && !enable_sent) {
730 memset(&pkt_out, 0, sizeof(pkt_out));
731 pkt_out.type = PKT_STREAM_ENABLE;
732 ret = submit_urb(dev.fd, &urb[URB_DATA_OUT], dev.ifaces[0].ep_out,
733 &pkt_out, sizeof(pkt_out));
735 perror("USBDEVFS_SUBMITURB PKT_STREAM_ENABLE");
740 if (gmv == NULL && fixed_input_changed) {
741 memset(&pkt_out, 0, sizeof(pkt_out));
742 pkt_out.type = PKT_FIXED_STATE;
743 memcpy(pkt_out.data, fixed_input_state, sizeof(fixed_input_state));
745 ret = submit_urb(dev.fd, &urb[URB_DATA_OUT], dev.ifaces[0].ep_out,
746 &pkt_out, sizeof(pkt_out));
748 perror("USBDEVFS_SUBMITURB URB_DATA_OUT");
765 // vim: ts=2:sw=2:expandtab