comparison io.c @ 1232:c0120977eeea

Initial implementation of the XBAND "Eric Smith" keyboard
author Michael Pavone <pavone@retrodev.com>
date Sat, 25 Feb 2017 02:31:07 -0800
parents 95f5253e75c7
children d966298442d4
comparison
equal deleted inserted replaced
1231:d9d775d61fcf 1232:c0120977eeea
28 "SMS gamepad", 28 "SMS gamepad",
29 "3-button gamepad", 29 "3-button gamepad",
30 "6-button gamepad", 30 "6-button gamepad",
31 "Mega Mouse", 31 "Mega Mouse",
32 "Saturn Keyboard", 32 "Saturn Keyboard",
33 "XBAND Keyboard",
33 "Menacer", 34 "Menacer",
34 "Justifier", 35 "Justifier",
35 "Sega multi-tap", 36 "Sega multi-tap",
36 "EA 4-way Play cable A", 37 "EA 4-way Play cable A",
37 "EA 4-way Play cable B", 38 "EA 4-way Play cable B",
486 return; 487 return;
487 } 488 }
488 int idx = keycode & 0x7FFF; 489 int idx = keycode & 0x7FFF;
489 keybinding * binding = bindings[bucket] + idx; 490 keybinding * binding = bindings[bucket] + idx;
490 handle_binding_up(binding); 491 handle_binding_up(binding);
491 store_key_event(0x100 | scancode); 492 store_key_event(0xF000 | scancode);
492 } 493 }
493 494
494 void handle_joyup(int joystick, int button) 495 void handle_joyup(int joystick, int button)
495 { 496 {
496 if (joystick >= MAX_JOYSTICKS || button >= joysticks[joystick].num_buttons) { 497 if (joystick >= MAX_JOYSTICKS || button >= joysticks[joystick].num_buttons) {
783 port->device.mouse.latched_y = 0; 784 port->device.mouse.latched_y = 0;
784 port->device.mouse.ready_cycle = CYCLE_NEVER; 785 port->device.mouse.ready_cycle = CYCLE_NEVER;
785 port->device.mouse.tr_counter = 0; 786 port->device.mouse.tr_counter = 0;
786 } else if(!strcmp(device_type, "saturn keyboard")) { 787 } else if(!strcmp(device_type, "saturn keyboard")) {
787 port->device_type = IO_SATURN_KEYBOARD; 788 port->device_type = IO_SATURN_KEYBOARD;
789 port->device.keyboard.read_pos = 0xFF;
790 port->device.keyboard.write_pos = 0;
791 } else if(!strcmp(device_type, "xband keyboard")) {
792 port->device_type = IO_XBAND_KEYBOARD;
788 port->device.keyboard.read_pos = 0xFF; 793 port->device.keyboard.read_pos = 0xFF;
789 port->device.keyboard.write_pos = 0; 794 port->device.keyboard.write_pos = 0;
790 } else if(!strcmp(device_type, "sega_parallel")) { 795 } else if(!strcmp(device_type, "sega_parallel")) {
791 port->device_type = IO_SEGA_PARALLEL; 796 port->device_type = IO_SEGA_PARALLEL;
792 port->device.stream.data_fd = -1; 797 port->device.stream.data_fd = -1;
1379 map_bindings(ports, mice[mouse].buttons, MAX_MOUSE_BUTTONS); 1384 map_bindings(ports, mice[mouse].buttons, MAX_MOUSE_BUTTONS);
1380 } 1385 }
1381 keyboard_port = NULL; 1386 keyboard_port = NULL;
1382 for (int i = 0; i < 3; i++) 1387 for (int i = 0; i < 3; i++)
1383 { 1388 {
1384 if (ports[i].device_type == IO_SATURN_KEYBOARD) { 1389 if (ports[i].device_type == IO_SATURN_KEYBOARD || ports[i].device_type == IO_XBAND_KEYBOARD) {
1385 keyboard_port = ports + i; 1390 keyboard_port = ports + i;
1386 break; 1391 break;
1387 } 1392 }
1388 } 1393 }
1389 //not really related to the intention of this function, but the best place to do this currently 1394 //not really related to the intention of this function, but the best place to do this currently
1550 } 1555 }
1551 #endif 1556 #endif
1552 1557
1553 const int mouse_delays[] = {112*7, 120*7, 96*7, 132*7, 104*7, 96*7, 112*7, 96*7}; 1558 const int mouse_delays[] = {112*7, 120*7, 96*7, 132*7, 104*7, 96*7, 112*7, 96*7};
1554 1559
1560 enum {
1561 KB_SETUP,
1562 KB_READ,
1563 KB_WRITE
1564 };
1565
1555 void io_data_write(io_port * port, uint8_t value, uint32_t current_cycle) 1566 void io_data_write(io_port * port, uint8_t value, uint32_t current_cycle)
1556 { 1567 {
1557 uint8_t old_output = (port->control & port->output) | (~port->control & 0xFF); 1568 uint8_t old_output = (port->control & port->output) | (~port->control & 0xFF);
1558 uint8_t output = (port->control & value) | (~port->control & 0xFF); 1569 uint8_t output = (port->control & value) | (~port->control & 0xFF);
1559 switch (port->device_type) 1570 switch (port->device_type)
1604 if ((output & TR) != (old_output & TR)) { 1615 if ((output & TR) != (old_output & TR)) {
1605 port->device.keyboard.tr_counter++; 1616 port->device.keyboard.tr_counter++;
1606 } 1617 }
1607 } 1618 }
1608 break; 1619 break;
1620 case IO_XBAND_KEYBOARD:
1621 if (output & TH) {
1622 //request is over
1623 if (
1624 port->device.keyboard.mode == KB_READ && port->device.keyboard.tr_counter > 7
1625 && (port->device.keyboard.tr_counter & 1)
1626 ) {
1627 if (port->device.keyboard.events[port->device.keyboard.read_pos] & 0xFF00) {
1628 port->device.keyboard.events[port->device.keyboard.read_pos] &= 0xFF;
1629 } else {
1630 port->device.keyboard.read_pos++;
1631 port->device.keyboard.read_pos &= 7;
1632 if (port->device.keyboard.read_pos == port->device.keyboard.write_pos) {
1633 port->device.keyboard.read_pos = 0xFF;
1634 }
1635 }
1636 }
1637 port->device.keyboard.tr_counter = 0;
1638 port->device.keyboard.mode = KB_SETUP;
1639 } else {
1640 if ((output & TR) != (old_output & TR)) {
1641 port->device.keyboard.tr_counter++;
1642 if (port->device.keyboard.tr_counter == 2) {
1643 port->device.keyboard.mode = (output & 0xF) ? KB_READ : KB_WRITE;
1644 } else if (port->device.keyboard.mode == KB_WRITE) {
1645 switch (port->device.keyboard.tr_counter)
1646 {
1647 case 3:
1648 //host writes 0b0001
1649 break;
1650 case 4:
1651 //host writes 0b0000
1652 break;
1653 case 5:
1654 //host writes 0b0000
1655 break;
1656 case 6:
1657 port->device.keyboard.cmd = output << 4;
1658 break;
1659 case 7:
1660 port->device.keyboard.cmd |= output & 0xF;
1661 //TODO: actually do something with the command
1662 break;
1663 }
1664 } else if (
1665 port->device.keyboard.mode == KB_READ && port->device.keyboard.tr_counter > 7
1666 && !(port->device.keyboard.tr_counter & 1)
1667 ) {
1668
1669 if (port->device.keyboard.events[port->device.keyboard.read_pos] & 0xFF00) {
1670 port->device.keyboard.events[port->device.keyboard.read_pos] &= 0xFF;
1671 } else {
1672 port->device.keyboard.read_pos++;
1673 port->device.keyboard.read_pos &= 7;
1674 if (port->device.keyboard.read_pos == port->device.keyboard.write_pos) {
1675 port->device.keyboard.read_pos = 0xFF;
1676 }
1677 }
1678 }
1679 }
1680 }
1681 break;
1609 #ifndef _WIN32 1682 #ifndef _WIN32
1610 case IO_GENERIC: 1683 case IO_GENERIC:
1611 wait_for_connection(port); 1684 wait_for_connection(port);
1612 port->input[IO_STATE] = IO_WRITE_PENDING; 1685 port->input[IO_STATE] = IO_WRITE_PENDING;
1613 service_socket(port); 1686 service_socket(port);
1614 break; 1687 break;
1615 #endif 1688 #endif
1616 } 1689 }
1617 port->output = value; 1690 port->output = value;
1618 1691
1692 }
1693
1694 uint8_t get_scancode_bytes(io_port *port)
1695 {
1696 if (port->device.keyboard.read_pos == 0xFF) {
1697 return 0;
1698 }
1699 uint8_t bytes = 0, read_pos = port->device.keyboard.read_pos;
1700 do {
1701 bytes += port->device.keyboard.events[read_pos] & 0xFF00 ? 2 : 1;
1702 read_pos++;
1703 read_pos &= 7;
1704 } while (read_pos != port->device.keyboard.write_pos);
1705
1706 return bytes;
1619 } 1707 }
1620 1708
1621 uint8_t io_data_read(io_port * port, uint32_t current_cycle) 1709 uint8_t io_data_read(io_port * port, uint32_t current_cycle)
1622 { 1710 {
1623 uint8_t control = port->control | 0x80; 1711 uint8_t control = port->control | 0x80;
1775 //TODO: set these based on keyboard state 1863 //TODO: set these based on keyboard state
1776 input = 0; 1864 input = 0;
1777 break; 1865 break;
1778 case 8: 1866 case 8:
1779 input = 6; 1867 input = 6;
1780 if (code & 0x100) { 1868 if (code & 0xFF00) {
1781 //break 1869 //break
1782 input |= 1; 1870 input |= 1;
1783 } else if (code) { 1871 } else if (code) {
1784 input |= 8; 1872 input |= 8;
1785 } 1873 }
1794 input = 0; 1882 input = 0;
1795 break; 1883 break;
1796 default: 1884 default:
1797 input = 1; 1885 input = 1;
1798 break; 1886 break;
1887 }
1888 input |= ((port->device.keyboard.tr_counter & 1) == 0) << 4;
1889 }
1890 break;
1891 }
1892 case IO_XBAND_KEYBOARD:
1893 {
1894 if (th) {
1895 input = 0x1C;
1896 } else {
1897 uint8_t size;
1898 if (port->device.keyboard.mode == KB_SETUP || port->device.keyboard.mode == KB_READ) {
1899 switch (port->device.keyboard.tr_counter)
1900 {
1901 case 0:
1902 input = 0x3;
1903 break;
1904 case 1:
1905 input = 0x6;
1906 break;
1907 case 2:
1908 //This is where thoe host indicates a read or write
1909 //presumably, the keyboard only outputs this if the host
1910 //is not already driving the data bus low
1911 input = 0x9;
1912 break;
1913 case 3:
1914 size = get_scancode_bytes(port);
1915 if (size) {
1916 ++size;
1917 }
1918 if (size > 15) {
1919 size = 15;
1920 }
1921 input = size;
1922 break;
1923 case 4:
1924 case 5:
1925 //always send packet type 0 for now
1926 input = 0;
1927 break;
1928 default:
1929 if (port->device.keyboard.read_pos == 0xFF) {
1930 //we've run out of bytes
1931 input = 0;
1932 } else if (port->device.keyboard.events[port->device.keyboard.read_pos] & 0xFF00) {
1933 if (port->device.keyboard.tr_counter & 1) {
1934 input = port->device.keyboard.events[port->device.keyboard.read_pos] >> 8 & 0xF;
1935 } else {
1936 input = port->device.keyboard.events[port->device.keyboard.read_pos] >> 12;
1937 }
1938 } else {
1939 if (port->device.keyboard.tr_counter & 1) {
1940 input = port->device.keyboard.events[port->device.keyboard.read_pos] & 0xF;
1941 } else {
1942 input = port->device.keyboard.events[port->device.keyboard.read_pos] >> 4;
1943 }
1944 }
1945 break;
1946 }
1947 } else {
1948 input = 0xF;
1799 } 1949 }
1800 input |= ((port->device.keyboard.tr_counter & 1) == 0) << 4; 1950 input |= ((port->device.keyboard.tr_counter & 1) == 0) << 4;
1801 } 1951 }
1802 break; 1952 break;
1803 } 1953 }