Mercurial > repos > blastem
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 } |