comparison io.c @ 1348:040c5600e2d9

Implemented slow rise time of IO pins set as inputs, but not driven by device. Fixes input in Decap Attack and possibly other games with buggy controller code
author Michael Pavone <pavone@retrodev.com>
date Mon, 08 May 2017 22:31:28 -0700
parents 071e761bcdcf
children e587f16e7d3d
comparison
equal deleted inserted replaced
1347:4c4beb22b042 1348:040c5600e2d9
1504 mouse_check_ready(port, current_cycle); 1504 mouse_check_ready(port, current_cycle);
1505 if (port->device.mouse.ready_cycle != CYCLE_NEVER) { 1505 if (port->device.mouse.ready_cycle != CYCLE_NEVER) {
1506 port->device.mouse.ready_cycle -= deduction; 1506 port->device.mouse.ready_cycle -= deduction;
1507 } 1507 }
1508 } 1508 }
1509 for (int i = 0; i < 8; i++)
1510 {
1511 if (port->slow_rise_start[i] != CYCLE_NEVER) {
1512 if (port->slow_rise_start[i] >= deduction) {
1513 port->slow_rise_start[i] -= deduction;
1514 } else {
1515 port->slow_rise_start[i] = CYCLE_NEVER;
1516 }
1517 }
1518 }
1509 if (last_poll_cycle >= deduction) { 1519 if (last_poll_cycle >= deduction) {
1510 last_poll_cycle -= deduction; 1520 last_poll_cycle -= deduction;
1511 } else { 1521 } else {
1512 last_poll_cycle = 0; 1522 last_poll_cycle = 0;
1513 } 1523 }
1620 enum { 1630 enum {
1621 KB_SETUP, 1631 KB_SETUP,
1622 KB_READ, 1632 KB_READ,
1623 KB_WRITE 1633 KB_WRITE
1624 }; 1634 };
1635
1636 void io_control_write(io_port *port, uint8_t value, uint32_t current_cycle)
1637 {
1638 uint8_t changes = value ^ port->control;
1639 if (changes) {
1640 for (int i = 0; i < 8; i++)
1641 {
1642 if (!(value & 1 << i) && !(port->output & 1 << i)) {
1643 //port switched from output to input and the output value was 0
1644 //since there is a weak pull-up on input pins, this will lead
1645 //to a slow rise from 0 to 1 if the pin isn't being externally driven
1646 port->slow_rise_start[i] = current_cycle;
1647 } else {
1648 port->slow_rise_start[i] = CYCLE_NEVER;
1649 }
1650 }
1651 port->control = value;
1652 }
1653 }
1625 1654
1626 void io_data_write(io_port * port, uint8_t value, uint32_t current_cycle) 1655 void io_data_write(io_port * port, uint8_t value, uint32_t current_cycle)
1627 { 1656 {
1628 uint8_t old_output = (port->control & port->output) | (~port->control & 0xFF); 1657 uint8_t old_output = (port->control & port->output) | (~port->control & 0xFF);
1629 uint8_t output = (port->control & value) | (~port->control & 0xFF); 1658 uint8_t output = (port->control & value) | (~port->control & 0xFF);
1764 } while (read_pos != port->device.keyboard.write_pos); 1793 } while (read_pos != port->device.keyboard.write_pos);
1765 1794
1766 return bytes; 1795 return bytes;
1767 } 1796 }
1768 1797
1798 #define SLOW_RISE_DEVICE (30*7)
1799 #define SLOW_RISE_INPUT (12*7)
1800
1801 static uint8_t get_output_value(io_port *port, uint32_t current_cycle, uint32_t slow_rise_delay)
1802 {
1803 uint8_t output = (port->control | 0x80) & port->output;
1804 for (int i = 0; i < 8; i++)
1805 {
1806 if (!(port->control & 1 << i)) {
1807 if (port->slow_rise_start[i] != CYCLE_NEVER) {
1808 if (current_cycle - port->slow_rise_start[i] >= slow_rise_delay) {
1809 output |= 1 << i;
1810 }
1811 } else {
1812 output |= 1 << i;
1813 }
1814 }
1815 }
1816 return output;
1817 }
1818
1769 uint8_t io_data_read(io_port * port, uint32_t current_cycle) 1819 uint8_t io_data_read(io_port * port, uint32_t current_cycle)
1770 { 1820 {
1821 uint8_t output = get_output_value(port, current_cycle, SLOW_RISE_DEVICE);
1771 uint8_t control = port->control | 0x80; 1822 uint8_t control = port->control | 0x80;
1772 uint8_t output = (control & port->output) | (~control & 0xFF);
1773 uint8_t th = output & 0x40; 1823 uint8_t th = output & 0x40;
1774 uint8_t input; 1824 uint8_t input;
1825 uint8_t device_driven;
1775 if (current_cycle - last_poll_cycle > MIN_POLL_INTERVAL) { 1826 if (current_cycle - last_poll_cycle > MIN_POLL_INTERVAL) {
1776 process_events(); 1827 process_events();
1777 last_poll_cycle = current_cycle; 1828 last_poll_cycle = current_cycle;
1778 } 1829 }
1779 switch (port->device_type) 1830 switch (port->device_type)
1787 if (!th) { 1838 if (!th) {
1788 input |= 0xC; 1839 input |= 0xC;
1789 } 1840 }
1790 //controller output is logically inverted 1841 //controller output is logically inverted
1791 input = ~input; 1842 input = ~input;
1843 device_driven = 0x3F;
1792 break; 1844 break;
1793 } 1845 }
1794 case IO_GAMEPAD6: 1846 case IO_GAMEPAD6:
1795 { 1847 {
1796 if (current_cycle >= port->device.pad.timeout_cycle) { 1848 if (current_cycle >= port->device.pad.timeout_cycle) {
1814 input = port->input[GAMEPAD_TH0] | 0xC; 1866 input = port->input[GAMEPAD_TH0] | 0xC;
1815 } 1867 }
1816 } 1868 }
1817 //controller output is logically inverted 1869 //controller output is logically inverted
1818 input = ~input; 1870 input = ~input;
1871 device_driven = 0x3F;
1819 break; 1872 break;
1820 } 1873 }
1821 case IO_MOUSE: 1874 case IO_MOUSE:
1822 { 1875 {
1823 mouse_check_ready(port, current_cycle); 1876 mouse_check_ready(port, current_cycle);
1873 input = delta_y & 0xF; 1926 input = delta_y & 0xF;
1874 break; 1927 break;
1875 } 1928 }
1876 input |= ((port->device.mouse.tr_counter & 1) == 0) << 4; 1929 input |= ((port->device.mouse.tr_counter & 1) == 0) << 4;
1877 } 1930 }
1931 device_driven = 0x1F;
1878 break; 1932 break;
1879 } 1933 }
1880 case IO_SATURN_KEYBOARD: 1934 case IO_SATURN_KEYBOARD:
1881 { 1935 {
1882 if (th) { 1936 if (th) {
1945 input = 1; 1999 input = 1;
1946 break; 2000 break;
1947 } 2001 }
1948 input |= ((port->device.keyboard.tr_counter & 1) == 0) << 4; 2002 input |= ((port->device.keyboard.tr_counter & 1) == 0) << 4;
1949 } 2003 }
2004 device_driven = 0x1F;
1950 break; 2005 break;
1951 } 2006 }
1952 case IO_XBAND_KEYBOARD: 2007 case IO_XBAND_KEYBOARD:
1953 { 2008 {
1954 if (th) { 2009 if (th) {
2006 } 2061 }
2007 } else { 2062 } else {
2008 input = 0xF; 2063 input = 0xF;
2009 } 2064 }
2010 input |= ((port->device.keyboard.tr_counter & 1) == 0) << 4; 2065 input |= ((port->device.keyboard.tr_counter & 1) == 0) << 4;
2066 //this is not strictly correct at all times, but good enough for now
2067 device_driven = 0x1F;
2011 } 2068 }
2012 break; 2069 break;
2013 } 2070 }
2014 #ifndef _WIN32 2071 #ifndef _WIN32
2015 case IO_SEGA_PARALLEL: 2072 case IO_SEGA_PARALLEL:
2016 if (!th) 2073 if (!th)
2017 { 2074 {
2018 service_pipe(port); 2075 service_pipe(port);
2019 } 2076 }
2020 input = port->input[th ? IO_TH1 : IO_TH0]; 2077 input = port->input[th ? IO_TH1 : IO_TH0];
2078 device_driven = 0x3F;
2021 break; 2079 break;
2022 case IO_GENERIC: 2080 case IO_GENERIC:
2023 if (port->input[IO_TH0] & 0x80 && port->input[IO_STATE] == IO_WRITTEN) 2081 if (port->input[IO_TH0] & 0x80 && port->input[IO_STATE] == IO_WRITTEN)
2024 { 2082 {
2025 //device requested a blocking read after writes 2083 //device requested a blocking read after writes
2026 port->input[IO_STATE] = IO_READ_PENDING; 2084 port->input[IO_STATE] = IO_READ_PENDING;
2027 } 2085 }
2028 service_socket(port); 2086 service_socket(port);
2029 input = port->input[IO_TH0]; 2087 input = port->input[IO_TH0];
2088 device_driven = 0x7F;
2030 break; 2089 break;
2031 #endif 2090 #endif
2032 default: 2091 default:
2033 input = 0xFF; 2092 input = 0;
2034 break; 2093 device_driven = 0;
2035 } 2094 break;
2036 uint8_t value = (input & (~control)) | (port->output & control); 2095 }
2096 uint8_t value = (input & (~control) & device_driven) | (port->output & control);
2097 //deal with pins that are configured as inputs, but not being actively driven by the device
2098 uint8_t floating = (~device_driven) & (~control);
2099 if (floating) {
2100 value |= get_output_value(port, current_cycle, SLOW_RISE_INPUT) & floating;
2101 }
2037 /*if (port->input[GAMEPAD_TH0] || port->input[GAMEPAD_TH1]) { 2102 /*if (port->input[GAMEPAD_TH0] || port->input[GAMEPAD_TH1]) {
2038 printf ("value: %X\n", value); 2103 printf ("value: %X\n", value);
2039 }*/ 2104 }*/
2040 return value; 2105 return value;
2041 } 2106 }