src/emu/memory.c
| r6450 | r6451 | |
| 368 | 368 | static UINT32 input_port_read32(const input_port_config *port, offs_t offset, UINT32 mem_mask); |
| 369 | 369 | static UINT64 input_port_read64(const input_port_config *port, offs_t offset, UINT64 mem_mask); |
| 370 | 370 | |
| 371 | /* output port handlers */ |
| 372 | static void input_port_write8(const input_port_config *port, offs_t offset, UINT8 data); |
| 373 | static void input_port_write16(const input_port_config *port, offs_t offset, UINT16 data, UINT16 mem_mask); |
| 374 | static void input_port_write32(const input_port_config *port, offs_t offset, UINT32 data, UINT32 mem_mask); |
| 375 | static void input_port_write64(const input_port_config *port, offs_t offset, UINT64 data, UINT64 mem_mask); |
| 371 | 376 | |
| 372 | 377 | |
| 378 | |
| 373 | 379 | /*************************************************************************** |
| 374 | 380 | INLINE FUNCTIONS |
| 375 | 381 | ***************************************************************************/ |
| r6450 | r6451 | |
| 1372 | 1378 | |
| 1373 | 1379 | |
| 1374 | 1380 | |
| 1381 | /*------------------------------------------------- |
| 1382 | memory_install_write_port_handler - install a |
| 1383 | new 8-bit input port handler into the given |
| 1384 | address space |
| 1385 | -------------------------------------------------*/ |
| 1386 | |
| 1387 | void memory_install_write_port_handler(const address_space *space, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, const char *tag) |
| 1388 | { |
| 1389 | const input_port_config *port = input_port_by_tag(space->machine->portconfig, tag); |
| 1390 | address_space *spacerw = (address_space *)space; |
| 1391 | genf *handler = NULL; |
| 1392 | |
| 1393 | if (port == NULL) |
| 1394 | fatalerror("Non-existent port referenced: '%s'\n", tag); |
| 1395 | switch (space->dbits) |
| 1396 | { |
| 1397 | case 8: handler = (genf *)input_port_write8; break; |
| 1398 | case 16: handler = (genf *)input_port_write16; break; |
| 1399 | case 32: handler = (genf *)input_port_write32; break; |
| 1400 | case 64: handler = (genf *)input_port_write64; break; |
| 1401 | } |
| 1402 | space_map_range(spacerw, ROW_WRITE, space->dbits, 0, addrstart, addrend, addrmask, addrmirror, handler, (void *)port, tag); |
| 1403 | } |
| 1404 | |
| 1405 | |
| 1406 | |
| 1375 | 1407 | /*************************************************************************** |
| 1376 | 1408 | DEBUGGER HELPERS |
| 1377 | 1409 | ***************************************************************************/ |
| r6450 | r6451 | |
| 1744 | 1776 | space_map_range_private(space, ROW_READ, bits, entry->read_mask, entry->addrstart, entry->addrend, entry->addrmask, entry->addrmirror, handler, (void *)port, entry->read_porttag); |
| 1745 | 1777 | } |
| 1746 | 1778 | |
| 1779 | /* if we have a write port tag, look it up */ |
| 1780 | if (entry->write_porttag != NULL) |
| 1781 | { |
| 1782 | const input_port_config *port = input_port_by_tag(machine->portconfig, entry->write_porttag); |
| 1783 | int bits = (entry->write_bits == 0) ? space->dbits : entry->write_bits; |
| 1784 | genf *handler = NULL; |
| 1785 | |
| 1786 | if (port == NULL) |
| 1787 | fatalerror("Non-existent port referenced: '%s'\n", entry->write_porttag); |
| 1788 | switch (bits) |
| 1789 | { |
| 1790 | case 8: handler = (genf *)input_port_write8; break; |
| 1791 | case 16: handler = (genf *)input_port_write16; break; |
| 1792 | case 32: handler = (genf *)input_port_write32; break; |
| 1793 | case 64: handler = (genf *)input_port_write64; break; |
| 1794 | } |
| 1795 | space_map_range_private(space, ROW_WRITE, bits, entry->write_mask, entry->addrstart, entry->addrend, entry->addrmask, entry->addrmirror, handler, (void *)port, entry->write_porttag); |
| 1796 | } |
| 1797 | |
| 1747 | 1798 | /* install the read handler if present */ |
| 1748 | 1799 | if (rhandler.generic != NULL) |
| 1749 | 1800 | { |
| r6450 | r6451 | |
| 2134 | 2185 | entry->read_porttag = TOKEN_GET_STRING(tokens); |
| 2135 | 2186 | break; |
| 2136 | 2187 | |
| 2188 | case ADDRMAP_TOKEN_WRITE_PORT: |
| 2189 | check_entry_field(write_porttag); |
| 2190 | entry->write_porttag = TOKEN_GET_STRING(tokens); |
| 2191 | break; |
| 2192 | |
| 2137 | 2193 | case ADDRMAP_TOKEN_REGION: |
| 2138 | 2194 | check_entry_field(region); |
| 2139 | 2195 | TOKEN_UNGET_UINT32(tokens); |
| r6450 | r6451 | |
| 3540 | 3596 | |
| 3541 | 3597 | |
| 3542 | 3598 | |
| 3599 | /*------------------------------------------------- |
| 3600 | output port handlers |
| 3601 | -------------------------------------------------*/ |
| 3602 | |
| 3603 | static void input_port_write8(const input_port_config *port, offs_t offset, UINT8 data) |
| 3604 | { |
| 3605 | input_port_write_direct(port, data, 0xff); |
| 3606 | } |
| 3607 | |
| 3608 | static void input_port_write16(const input_port_config *port, offs_t offset, UINT16 data, UINT16 mem_mask) |
| 3609 | { |
| 3610 | input_port_write_direct(port, data, mem_mask); |
| 3611 | } |
| 3612 | |
| 3613 | static void input_port_write32(const input_port_config *port, offs_t offset, UINT32 data, UINT32 mem_mask) |
| 3614 | { |
| 3615 | input_port_write_direct(port, data, mem_mask); |
| 3616 | } |
| 3617 | |
| 3618 | static void input_port_write64(const input_port_config *port, offs_t offset, UINT64 data, UINT64 mem_mask) |
| 3619 | { |
| 3620 | input_port_write_direct(port, data, mem_mask); |
| 3621 | } |
| 3622 | |
| 3623 | |
| 3624 | |
| 3543 | 3625 | /*************************************************************************** |
| 3544 | 3626 | STUB HANDLERS THAT MAP TO BYTE READS |
| 3545 | 3627 | ***************************************************************************/ |
src/emu/inptport.c
| r6450 | r6451 | |
| 196 | 196 | }; |
| 197 | 197 | |
| 198 | 198 | |
| 199 | | /* live custom/changed field information */ |
| 200 | | typedef struct _callback_field_info callback_field_info; |
| 201 | | struct _callback_field_info |
| 199 | /* live device field information */ |
| 200 | typedef struct _device_field_info device_field_info; |
| 201 | struct _device_field_info |
| 202 | 202 | { |
| 203 | | callback_field_info * next; /* linked list of info for this port */ |
| 203 | device_field_info * next; /* linked list of info for this port */ |
| 204 | 204 | const input_field_config * field; /* pointer to the input field referenced */ |
| 205 | const device_config * device; /* device */ |
| 205 | 206 | UINT8 shift; /* shift to apply to the final result */ |
| 206 | 207 | }; |
| 207 | 208 | |
| r6450 | r6451 | |
| 224 | 225 | struct _input_port_state |
| 225 | 226 | { |
| 226 | 227 | analog_field_state * analoglist; /* pointer to list of analog port info */ |
| 227 | | callback_field_info * customlist; /* pointer to list of custom port info */ |
| 228 | | callback_field_info * changedlist; /* pointer to list of changed port info */ |
| 228 | device_field_info * readdevicelist; /* pointer to list of input device info */ |
| 229 | device_field_info * writedevicelist; /* pointer to list of output device info */ |
| 229 | 230 | input_port_value defvalue; /* combined default value across the port */ |
| 230 | 231 | input_port_value digital; /* current value from all digital inputs */ |
| 231 | 232 | input_port_value vblank; /* value of all IPT_VBLANK bits */ |
| 232 | 233 | input_port_value lastvalue; /* last value of the port, to detect changes */ |
| 234 | input_port_value lastwrite; /* last value written to the port, to detect changes */ |
| 233 | 235 | }; |
| 234 | 236 | |
| 235 | 237 | |
| r6450 | r6451 | |
| 442 | 444 | static void init_port_types(running_machine *machine); |
| 443 | 445 | static void init_port_state(running_machine *machine); |
| 444 | 446 | static void init_autoselect_devices(const input_port_config *portlist, int type1, int type2, int type3, const char *option, const char *ananame); |
| 445 | | static callback_field_info *init_field_callback_info(const input_field_config *field); |
| 447 | static device_field_info *init_field_device_info(const input_field_config *field,const char *device_name); |
| 446 | 448 | static analog_field_state *init_field_analog_state(const input_field_config *field); |
| 447 | 449 | |
| 448 | 450 | /* once-per-frame updates */ |
| r6450 | r6451 | |
| 622 | 624 | |
| 623 | 625 | |
| 624 | 626 | /*************************************************************************** |
| 627 | CUSTOM DEVICE I/O |
| 628 | ***************************************************************************/ |
| 629 | static READ_LINE_DEVICE_HANDLER( custom_read_line_device ) |
| 630 | { |
| 631 | const device_field_info *device_field = (const device_field_info *) device; |
| 632 | |
| 633 | return (*device_field->field->custom)(device_field->field, device_field->field->custom_param); |
| 634 | } |
| 635 | |
| 636 | static WRITE_LINE_DEVICE_HANDLER( changed_write_line_device ) |
| 637 | { |
| 638 | const device_field_info *device_field = (const device_field_info *) device; |
| 639 | |
| 640 | /* recalculate 'oldval' as it cannot be passed directly */ |
| 641 | input_port_value last = (device_field->field->type == IPT_OUTPUT) ? device_field->field->port->state->lastwrite : device_field->field->port->state->lastvalue; |
| 642 | input_port_value oldval = (last & device_field->field->mask) >> device_field->shift; |
| 643 | |
| 644 | (*device_field->field->changed)(device_field->field, device_field->field->changed_param, oldval, state); |
| 645 | } |
| 646 | |
| 647 | |
| 648 | |
| 649 | /*************************************************************************** |
| 625 | 650 | CORE SYSTEM MANAGEMENT |
| 626 | 651 | ***************************************************************************/ |
| 627 | 652 | |
| r6450 | r6451 | |
| 1203 | 1228 | { |
| 1204 | 1229 | input_port_private *portdata = port->machine->input_port_data; |
| 1205 | 1230 | analog_field_state *analog; |
| 1206 | | callback_field_info *custom; |
| 1231 | device_field_info *device_field; |
| 1207 | 1232 | input_port_value result; |
| 1208 | 1233 | |
| 1209 | 1234 | assert_always(portdata->safe_to_read, "Input ports cannot be read at init time!"); |
| r6450 | r6451 | |
| 1212 | 1237 | result = port->state->digital; |
| 1213 | 1238 | |
| 1214 | 1239 | /* update custom values */ |
| 1215 | | for (custom = port->state->customlist; custom != NULL; custom = custom->next) |
| 1216 | | if (input_condition_true(port->machine, &custom->field->condition)) |
| 1240 | for (device_field = port->state->readdevicelist; device_field != NULL; device_field = device_field->next) |
| 1241 | if (input_condition_true(port->machine, &device_field->field->condition)) |
| 1217 | 1242 | { |
| 1218 | | /* replace the bits with bits from the custom routine */ |
| 1219 | | input_port_value newbits = (*custom->field->custom)(custom->field, custom->field->custom_param); |
| 1220 | | result = (result & ~custom->field->mask) | ((newbits << custom->shift) & custom->field->mask); |
| 1243 | /* replace the bits with bits from the device */ |
| 1244 | input_port_value newval = (*device_field->field->read_line_device)(device_field->device); |
| 1245 | result = (result & ~device_field->field->mask) | ((newval << device_field->shift) & device_field->field->mask); |
| 1221 | 1246 | } |
| 1222 | 1247 | |
| 1223 | 1248 | /* update VBLANK bits */ |
| r6450 | r6451 | |
| 1423 | 1448 | |
| 1424 | 1449 | |
| 1425 | 1450 | /*************************************************************************** |
| 1451 | PORT WRITING |
| 1452 | ***************************************************************************/ |
| 1453 | |
| 1454 | /*------------------------------------------------- |
| 1455 | input_port_write_direct - write a value |
| 1456 | to a port |
| 1457 | -------------------------------------------------*/ |
| 1458 | |
| 1459 | void input_port_write_direct(const input_port_config *port, input_port_value data, input_port_value mem_mask) |
| 1460 | { |
| 1461 | /* call device line changed handlers */ |
| 1462 | device_field_info *device_field; |
| 1463 | input_port_value newvalue = port->state->lastwrite; |
| 1464 | |
| 1465 | COMBINE_DATA(&newvalue); |
| 1466 | |
| 1467 | for (device_field = port->state->writedevicelist; device_field; device_field = device_field->next) |
| 1468 | if (device_field->field->type == IPT_OUTPUT && input_condition_true(port->machine, &device_field->field->condition)) |
| 1469 | { |
| 1470 | input_port_value oldval = (port->state->lastwrite & device_field->field->mask) >> device_field->shift; |
| 1471 | input_port_value newval = (newvalue & device_field->field->mask) >> device_field->shift; |
| 1472 | |
| 1473 | /* if the bits have changed, call the handler */ |
| 1474 | if (oldval != newval) |
| 1475 | (*device_field->field->write_line_device)(device_field->device, newval); |
| 1476 | } |
| 1477 | |
| 1478 | /* remember the last value */ |
| 1479 | port->state->lastwrite = newvalue; |
| 1480 | } |
| 1481 | |
| 1482 | /*------------------------------------------------- |
| 1483 | input_port_write - write a value to a |
| 1484 | port specified by tag |
| 1485 | -------------------------------------------------*/ |
| 1486 | |
| 1487 | void input_port_write(running_machine *machine, const char *tag, input_port_value value, input_port_value mask) |
| 1488 | { |
| 1489 | const input_port_config *port = input_port_by_tag(machine->portconfig, tag); |
| 1490 | if (port == NULL) |
| 1491 | fatalerror("Unable to locate input port '%s'", tag); |
| 1492 | input_port_write_direct(port, value, mask); |
| 1493 | } |
| 1494 | |
| 1495 | /*------------------------------------------------- |
| 1496 | input_port_read_safe - write a value to |
| 1497 | a port, ignore if the port does not exist |
| 1498 | -------------------------------------------------*/ |
| 1499 | |
| 1500 | void input_port_write_safe(running_machine *machine, const char *tag, input_port_value value, input_port_value mask) |
| 1501 | { |
| 1502 | const input_port_config *port = input_port_by_tag(machine->portconfig, tag); |
| 1503 | if (port != NULL) |
| 1504 | input_port_write_direct(port, value, mask); |
| 1505 | } |
| 1506 | |
| 1507 | |
| 1508 | |
| 1509 | /*************************************************************************** |
| 1426 | 1510 | MISC HELPER FUNCTIONS |
| 1427 | 1511 | ***************************************************************************/ |
| 1428 | 1512 | |
| r6450 | r6451 | |
| 1560 | 1644 | for (port = machine->portconfig; port != NULL; port = port->next) |
| 1561 | 1645 | { |
| 1562 | 1646 | analog_field_state **analogstatetail; |
| 1563 | | callback_field_info **custominfotail; |
| 1564 | | callback_field_info **changedinfotail; |
| 1647 | device_field_info **readdevicetail; |
| 1648 | device_field_info **writedevicetail; |
| 1565 | 1649 | input_port_state *portstate; |
| 1566 | 1650 | |
| 1567 | 1651 | /* allocate a new input_port_info structure */ |
| r6450 | r6451 | |
| 1571 | 1655 | |
| 1572 | 1656 | /* start with tail pointers to all the data */ |
| 1573 | 1657 | analogstatetail = &portstate->analoglist; |
| 1574 | | custominfotail = &portstate->customlist; |
| 1575 | | changedinfotail = &portstate->changedlist; |
| 1658 | readdevicetail = &portstate->readdevicelist; |
| 1659 | writedevicetail = &portstate->writedevicelist; |
| 1576 | 1660 | |
| 1577 | 1661 | /* iterate over fields */ |
| 1578 | 1662 | for (field = port->fieldlist; field != NULL; field = field->next) |
| r6450 | r6451 | |
| 1605 | 1689 | fieldstate->joystick->inuse = TRUE; |
| 1606 | 1690 | } |
| 1607 | 1691 | |
| 1608 | | /* if this entry has custom callback, allocate memory for the tracking structure */ |
| 1609 | | if (field->custom != NULL) |
| 1692 | /* if this entry has device input, allocate memory for the tracking structure */ |
| 1693 | if (field->read_line_device != NULL) |
| 1610 | 1694 | { |
| 1611 | | *custominfotail = init_field_callback_info(field); |
| 1612 | | custominfotail = &(*custominfotail)->next; |
| 1695 | *readdevicetail = init_field_device_info(field,field->read_device_name); |
| 1696 | readdevicetail = &(*readdevicetail)->next; |
| 1613 | 1697 | } |
| 1614 | 1698 | |
| 1615 | | /* if this entry has changed callback, allocate memory for the tracking structure */ |
| 1616 | | if (field->changed != NULL) |
| 1699 | /* if this entry has device output, allocate memory for the tracking structure */ |
| 1700 | if (field->write_line_device != NULL) |
| 1617 | 1701 | { |
| 1618 | | *changedinfotail = init_field_callback_info(field); |
| 1619 | | changedinfotail = &(*changedinfotail)->next; |
| 1702 | *writedevicetail = init_field_device_info(field,field->write_device_name); |
| 1703 | writedevicetail = &(*writedevicetail)->next; |
| 1620 | 1704 | } |
| 1621 | 1705 | |
| 1622 | 1706 | #ifdef MESS |
| r6450 | r6451 | |
| 1716 | 1800 | |
| 1717 | 1801 | |
| 1718 | 1802 | /*------------------------------------------------- |
| 1719 | | init_field_callback_info - allocate and populate |
| 1720 | | information about a changed or custom |
| 1721 | | callback |
| 1803 | init_field_device_info - allocate and populate |
| 1804 | information about a device callback |
| 1722 | 1805 | -------------------------------------------------*/ |
| 1723 | 1806 | |
| 1724 | | static callback_field_info *init_field_callback_info(const input_field_config *field) |
| 1807 | static device_field_info *init_field_device_info(const input_field_config *field, const char *device_name) |
| 1725 | 1808 | { |
| 1726 | | callback_field_info *info; |
| 1809 | device_field_info *info; |
| 1727 | 1810 | input_port_value mask; |
| 1728 | 1811 | |
| 1729 | 1812 | /* allocate memory */ |
| 1730 | | info = auto_alloc_clear(field->port->machine, callback_field_info); |
| 1813 | info = auto_alloc_clear(field->port->machine, device_field_info); |
| 1731 | 1814 | |
| 1732 | 1815 | /* fill in the data */ |
| 1733 | 1816 | info->field = field; |
| 1734 | 1817 | for (mask = field->mask; !(mask & 1); mask >>= 1) |
| 1735 | 1818 | info->shift++; |
| 1736 | 1819 | |
| 1820 | if (device_name != NULL) |
| 1821 | info->device = devtag_get_device(field->port->machine, device_name); |
| 1822 | else |
| 1823 | info->device = (const device_config *) info; |
| 1824 | |
| 1737 | 1825 | return info; |
| 1738 | 1826 | } |
| 1739 | 1827 | |
| r6450 | r6451 | |
| 1975 | 2063 | for (port = machine->portconfig; port != NULL; port = port->next) |
| 1976 | 2064 | { |
| 1977 | 2065 | const input_field_config *field; |
| 1978 | | callback_field_info *changed; |
| 2066 | device_field_info *device_field; |
| 1979 | 2067 | input_port_value newvalue; |
| 1980 | 2068 | |
| 1981 | 2069 | /* start with 0 values for the digital and VBLANK bits */ |
| r6450 | r6451 | |
| 2004 | 2092 | mess_input_port_update_hook(machine, port, &port->state->digital); |
| 2005 | 2093 | #endif /* MESS */ |
| 2006 | 2094 | |
| 2007 | | /* call changed handlers */ |
| 2095 | /* call device line changed handlers */ |
| 2008 | 2096 | newvalue = input_port_read_direct(port); |
| 2009 | | for (changed = port->state->changedlist; changed; changed = changed->next) |
| 2010 | | if (input_condition_true(port->machine, &changed->field->condition)) |
| 2097 | for (device_field = port->state->writedevicelist; device_field; device_field = device_field->next) |
| 2098 | if (device_field->field->type != IPT_OUTPUT && input_condition_true(port->machine, &device_field->field->condition)) |
| 2011 | 2099 | { |
| 2012 | | input_port_value oldbits = (port->state->lastvalue & changed->field->mask) >> changed->shift; |
| 2013 | | input_port_value newbits = (newvalue & changed->field->mask) >> changed->shift; |
| 2100 | input_port_value oldval = (port->state->lastvalue & device_field->field->mask) >> device_field->shift; |
| 2101 | input_port_value newval = (newvalue & device_field->field->mask) >> device_field->shift; |
| 2014 | 2102 | |
| 2015 | 2103 | /* if the bits have changed, call the handler */ |
| 2016 | | if (oldbits != newbits) |
| 2017 | | (*changed->field->changed)(changed->field, changed->field->changed_param, oldbits, newbits); |
| 2104 | if (oldval != newval) |
| 2105 | (*device_field->field->write_line_device)(device_field->device, newval); |
| 2018 | 2106 | } |
| 2019 | 2107 | |
| 2020 | 2108 | /* remember the last value */ |
| r6450 | r6451 | |
| 2553 | 2641 | TOKEN_SKIP_PTR(ipt); |
| 2554 | 2642 | break; |
| 2555 | 2643 | } |
| 2644 | curfield->read_line_device = custom_read_line_device; |
| 2645 | curfield->read_device_name = NULL; |
| 2556 | 2646 | curfield->custom = TOKEN_GET_PTR(ipt, customptr); |
| 2557 | 2647 | curfield->custom_param = (void *)TOKEN_GET_PTR(ipt, voidptr); |
| 2558 | 2648 | break; |
| r6450 | r6451 | |
| 2566 | 2656 | TOKEN_SKIP_PTR(ipt); |
| 2567 | 2657 | break; |
| 2568 | 2658 | } |
| 2659 | curfield->write_line_device = changed_write_line_device; |
| 2660 | curfield->write_device_name = NULL; |
| 2569 | 2661 | curfield->changed = TOKEN_GET_PTR(ipt, changedptr); |
| 2570 | 2662 | curfield->changed_param = (void *)TOKEN_GET_PTR(ipt, voidptr); |
| 2571 | 2663 | break; |
| r6450 | r6451 | |
| 2948 | 3040 | curfield->name = TOKEN_GET_STRING(ipt); |
| 2949 | 3041 | break; |
| 2950 | 3042 | |
| 3043 | /* input device handler */ |
| 3044 | case INPUT_TOKEN_READ_LINE_DEVICE: |
| 3045 | if (curfield == NULL) |
| 3046 | { |
| 3047 | error_buf_append(errorbuf, errorbuflen, "INPUT_TOKEN_READ_LINE_DEVICE encountered with no active field\n"); |
| 3048 | TOKEN_SKIP_STRING(ipt); |
| 3049 | TOKEN_SKIP_PTR(ipt); |
| 3050 | break; |
| 3051 | } |
| 3052 | curfield->read_device_name = TOKEN_GET_STRING(ipt); |
| 3053 | curfield->read_line_device = TOKEN_GET_PTR(ipt, read_line_device); |
| 3054 | break; |
| 3055 | |
| 3056 | /* output device handler */ |
| 3057 | case INPUT_TOKEN_WRITE_LINE_DEVICE: |
| 3058 | if (curfield == NULL) |
| 3059 | { |
| 3060 | error_buf_append(errorbuf, errorbuflen, "INPUT_TOKEN_WRITE_LINE_DEVICE encountered with no active field\n"); |
| 3061 | TOKEN_SKIP_STRING(ipt); |
| 3062 | TOKEN_SKIP_PTR(ipt); |
| 3063 | break; |
| 3064 | } |
| 3065 | curfield->write_device_name = TOKEN_GET_STRING(ipt); |
| 3066 | curfield->write_line_device = TOKEN_GET_PTR(ipt, write_line_device); |
| 3067 | break; |
| 3068 | |
| 2951 | 3069 | default: |
| 2952 | 3070 | error_buf_append(errorbuf, errorbuflen, "Invalid token %d in input ports\n", entrytype); |
| 2953 | 3071 | break; |
src/emu/inptport.h
| r6450 | r6451 | |
| 16 | 16 | |
| 17 | 17 | #include <time.h> |
| 18 | 18 | |
| 19 | #include "devcb.h" |
| 19 | 20 | #include "memory.h" |
| 20 | 21 | #include "inputseq.h" |
| 21 | 22 | #include "tokenize.h" |
| r6450 | r6451 | |
| 357 | 358 | |
| 358 | 359 | /* special meaning handled by custom code */ |
| 359 | 360 | IPT_SPECIAL, |
| 361 | IPT_OUTPUT, |
| 360 | 362 | |
| 361 | 363 | __ipt_max |
| 362 | 364 | }; |
| r6450 | r6451 | |
| 418 | 420 | INPUT_TOKEN_CHAR, |
| 419 | 421 | INPUT_TOKEN_CATEGORY, |
| 420 | 422 | INPUT_TOKEN_CATEGORY_NAME, |
| 421 | | INPUT_TOKEN_CATEGORY_SETTING |
| 423 | INPUT_TOKEN_CATEGORY_SETTING, |
| 424 | INPUT_TOKEN_READ_LINE_DEVICE, |
| 425 | INPUT_TOKEN_WRITE_LINE_DEVICE, |
| 422 | 426 | }; |
| 423 | 427 | |
| 424 | 428 | |
| r6450 | r6451 | |
| 583 | 587 | input_field_custom_func customptr; |
| 584 | 588 | input_field_changed_func changedptr; |
| 585 | 589 | input_field_crossmap_func crossmapptr; |
| 590 | read_line_device_func read_line_device; |
| 591 | write_line_device_func write_line_device; |
| 586 | 592 | }; |
| 587 | 593 | |
| 588 | 594 | |
| r6450 | r6451 | |
| 637 | 643 | UINT8 impulse; /* number of frames before reverting to defvalue */ |
| 638 | 644 | const char * name; /* user-friendly name to display */ |
| 639 | 645 | input_seq seq[SEQ_TYPE_TOTAL];/* sequences of all types */ |
| 646 | read_line_device_func read_line_device; /* input device handler */ |
| 647 | const char * read_device_name; /* input device name */ |
| 648 | write_line_device_func write_line_device; /* output device handler */ |
| 649 | const char * write_device_name; /* input device name */ |
| 640 | 650 | input_field_custom_func custom; /* custom callback routine */ |
| 641 | 651 | void * custom_param; /* parameter for custom callback routine */ |
| 642 | 652 | input_field_changed_func changed; /* changed callback routine */ |
| r6450 | r6451 | |
| 903 | 913 | TOKEN_PTR(changedptr, _callback), \ |
| 904 | 914 | TOKEN_PTR(voidptr, _param), |
| 905 | 915 | |
| 916 | /* input device handler */ |
| 917 | #define PORT_READ_LINE_DEVICE(_device, _read_line_device) \ |
| 918 | TOKEN_UINT32_PACK1(INPUT_TOKEN_READ_LINE_DEVICE, 8), \ |
| 919 | TOKEN_STRING(_device), \ |
| 920 | TOKEN_PTR(read_line_device, _read_line_device), |
| 921 | |
| 922 | /* output device handler */ |
| 923 | #define PORT_WRITE_LINE_DEVICE(_device, _write_line_device) \ |
| 924 | TOKEN_UINT32_PACK1(INPUT_TOKEN_WRITE_LINE_DEVICE, 8), \ |
| 925 | TOKEN_STRING(_device), \ |
| 926 | TOKEN_PTR(write_line_device, _write_line_device), |
| 927 | |
| 906 | 928 | /* dip switch definition */ |
| 907 | 929 | #define PORT_DIPNAME(_mask, _default, _name) \ |
| 908 | 930 | TOKEN_UINT32_PACK1(INPUT_TOKEN_DIPNAME, 8), \ |
| r6450 | r6451 | |
| 1092 | 1114 | |
| 1093 | 1115 | |
| 1094 | 1116 | |
| 1117 | /* ----- port writing ----- */ |
| 1118 | |
| 1119 | /* write a value to a port */ |
| 1120 | void input_port_write_direct(const input_port_config *port, input_port_value value, input_port_value mask); |
| 1121 | |
| 1122 | /* write a value to a port specified by tag */ |
| 1123 | void input_port_write(running_machine *machine, const char *tag, input_port_value value, input_port_value mask); |
| 1124 | |
| 1125 | /* write a value to a port, ignore if the port does not exist */ |
| 1126 | void input_port_write_safe(running_machine *machine, const char *tag, input_port_value value, input_port_value mask); |
| 1127 | |
| 1128 | |
| 1129 | |
| 1095 | 1130 | /* ----- misc helper functions ----- */ |
| 1096 | 1131 | |
| 1097 | 1132 | /* return the TRUE if the given condition attached is true */ |