+static int usb_read_while_ready(OsRoutine *ed,
+ void *buf_, int maxlen)
+{
+ u8 *buf = buf_;
+ int r = 0;
+
+ while (ed->usbRdReady() && r < maxlen)
+ buf[r++] = ed->usbReadByte();
+
+ return r;
+}
+
+/*
+ * TH = 1 : ?1CBRLDU 3-button pad return value (not read)
+ * TH = 0 : ?0SA00DU 3-button pad return value
+ * TH = 1 : ?1CBRLDU 3-button pad return value
+ * TH = 0 : ?0SA0000 D3-0 are forced to '0'
+ * TH = 1 : ?1CBMXYZ Extra buttons returned in D3-0
+ * TH = 0 : ?0SA1111 D3-0 are forced to '1'
+ */
+static void test_joy_latency(int *min_out, int *max_out)
+{
+ u8 rbuf[8 * 6];
+ int min = 8;
+ int max = 0;
+ int i, v, b, e;
+
+ for (i = 0; i < 64; i++) {
+ read_joy_responses(rbuf);
+
+ for (b = 0; b < 8 * 4; b++) {
+ v = b & 7;
+ e = (b & 0x08) ? 0x0c : 0;
+ if ((rbuf[b] & 0x0c) == e) {
+ if (v < min)
+ min = v;
+ }
+ else if (v > max)
+ max = v;
+ }
+ }
+
+ /* print out the last test */
+ for (b = 0; b < 8 * 5; b++) {
+ printf(" %02x", rbuf[b]);
+ if ((b & 7) == 7)
+ printf("\n");
+ }
+ printf("\n");
+
+ *min_out = min;
+ *max_out = max;
+}
+
+static int do_test(OsRoutine *ed, u8 b3)
+{
+ int min = 0, max = 0;
+
+ switch (b3)
+ {
+ case 'j':
+ test_joy_latency(&min, &max);
+ printf("latency: %d - %d\n\n", min, max);
+ return 0;
+ default:
+ break;
+ }
+
+ return -1;
+}
+