trunk/src/mame/drivers/namcos23.c
| r243801 | r243802 | |
| 84 | 84 | return |
| 85 | 85 | |
| 86 | 86 | |
| 87 | c8000000: |
| 88 | 8011e384: |
| 89 | if((a2000000.w & 0xfff0 != 0x0080) (c417_r, 808e or 008e) |
| 90 | +10.w = 2 |
| 91 | +16.w = 42 |
| 92 | +16.w = 23c0 |
| 93 | +10.w = 3 |
| 94 | 801deaf0.w *0x28 -> +12.w (fixed) |
| 95 | |
| 96 | |
| 97 | |
| 98 | |
| 99 | ':maincpu' (801142FC): unmapped program memory write to 0C800010 = 00020000 & FFFF0000 |
| 100 | ':maincpu' (801143A8): unmapped program memory write to 0C800010 = 00020000 & FFFF0000 |
| 101 | ':maincpu' (801143B4): unmapped program memory write to 0C800014 = 00000042 & 0000FFFF |
| 102 | ':maincpu' (801143C0): unmapped program memory write to 0C800014 = 000023C0 & 0000FFFF |
| 103 | ':maincpu' (801143CC): unmapped program memory write to 0C800010 = 00030000 & FFFF0000 |
| 104 | ':maincpu' (801143E0): unmapped program memory write to 0C800010 = 00000000 & 0000FFFF |
| 105 | ':maincpu' (801143E0): unmapped program memory write to 0C800010 = 00000000 & 0000FFFF |
| 106 | ':maincpu' (801143E0): unmapped program memory write to 0C800010 = 00000000 & 0000FFFF |
| 107 | ':maincpu' (801143E0): unmapped program memory write to 0C800010 = 00000000 & 0000FFFF |
| 108 | |
| 87 | 109 | **************************************************************************** |
| 88 | 110 | |
| 89 | 111 | Namco System 23 and Super System 23 Hardware Overview (last updated 7th April 2013 at 12.49am) |
| r243801 | r243802 | |
| 1520 | 1542 | UINT16 nthword(const UINT32 *pSource, int offs); |
| 1521 | 1543 | inline INT32 u32_to_s24(UINT32 v); |
| 1522 | 1544 | inline INT32 u32_to_s10(UINT32 v); |
| 1545 | float f24_to_f32(UINT32 v); |
| 1546 | |
| 1523 | 1547 | INT32 *c435_getv(UINT16 id); |
| 1524 | 1548 | INT16 *c435_getm(UINT16 id); |
| 1525 | 1549 | |
| 1550 | void c435_state_set_interrupt(const UINT16 *param); |
| 1551 | void c435_state_set_projection_matrix_line(const UINT16 *param); |
| 1552 | void c435_state_set(UINT16 type, const UINT16 *param); |
| 1553 | int c435_get_state_entry_size(UINT16 type); |
| 1554 | |
| 1526 | 1555 | void c435_matrix_matrix_mul(); |
| 1527 | 1556 | void c435_matrix_set(); |
| 1528 | 1557 | void c435_vector_set(); |
| 1529 | 1558 | void c435_matrix_vector_mul(); |
| 1530 | 1559 | void c435_vector_matrix_mul(); |
| 1560 | void c435_state_set(); |
| 1531 | 1561 | void c435_scaling_set(); |
| 1532 | | void c435_state_set_interrupt(); |
| 1533 | | void c435_state_set(); |
| 1534 | 1562 | void c435_render(); |
| 1535 | 1563 | void c435_flush(); |
| 1536 | 1564 | |
| r243801 | r243802 | |
| 1580 | 1608 | return v & 0x200 ? v | 0xfffffe00 : v & 0x1ff; |
| 1581 | 1609 | } |
| 1582 | 1610 | |
| 1611 | float namcos23_state::f24_to_f32(UINT32 v) |
| 1612 | { |
| 1613 | // 8 bits exponent, 16 mantissa |
| 1614 | // mantissa is 16-bits signed, 2-complement |
| 1615 | // value is m * 2**(e-46) |
| 1616 | // 1 is e=32, m=0x4000, -1 is e=31, m=0x8000 |
| 1583 | 1617 | |
| 1618 | // This code turns it into a standard float |
| 1619 | if(!v) |
| 1620 | return 0; |
| 1621 | |
| 1622 | UINT32 r = v & 0x8000 ? 0x80000000 : 0; |
| 1623 | UINT16 m = r ? -v : v; |
| 1624 | UINT8 e = (v >> 16) + 0x60; |
| 1625 | while(!(m & 0x8000)) { |
| 1626 | m <<= 1; |
| 1627 | e--; |
| 1628 | } |
| 1629 | |
| 1630 | r = r | (e << 23) | ((m & 0x7fff) << 8); |
| 1631 | return *(float *)&r; |
| 1632 | } |
| 1633 | |
| 1584 | 1634 | INLINE UINT8 light(UINT8 c, float l) |
| 1585 | 1635 | { |
| 1586 | 1636 | if(l < 1) |
| r243801 | r243802 | |
| 1612 | 1662 | return m_matrices[id]; |
| 1613 | 1663 | } |
| 1614 | 1664 | |
| 1665 | void namcos23_state::c435_state_set_interrupt(const UINT16 *param) |
| 1666 | { |
| 1667 | if(param[0] & 1) |
| 1668 | update_main_interrupts(m_main_irqcause | MAIN_C435_IRQ); |
| 1669 | else |
| 1670 | update_main_interrupts(m_main_irqcause & ~MAIN_C435_IRQ); |
| 1671 | } |
| 1672 | |
| 1673 | void namcos23_state::c435_state_set_projection_matrix_line(const UINT16 *param) |
| 1674 | { |
| 1675 | // timecrs2: |
| 1676 | // sx = 640/2, sy = 480/2, t = tan(fov/2) (fov=45 degrees) |
| 1677 | // line 1: 1 0 -(sx-a)/(sx/t) 0 -1 0 -(sx+a)/(sx/t) 0 |
| 1678 | // line 2: 0 1 -(sy-b)/(sx/t) 0 0 -1 -(sy+b)/(sx/t) 0 |
| 1679 | // line 3: 0 0 -1 c 0 0 0 sx/t |
| 1680 | |
| 1681 | logerror("projection matrix line:"); |
| 1682 | for(int i=0; i<8; i++) |
| 1683 | logerror(" %f", f24_to_f32((param[2*i+1] << 16) | param[2*i+2])); |
| 1684 | logerror("\n"); |
| 1685 | } |
| 1686 | |
| 1687 | void namcos23_state::c435_state_set(UINT16 type, const UINT16 *param) |
| 1688 | { |
| 1689 | switch(type) { |
| 1690 | case 0x0001: c435_state_set_interrupt(param); break; |
| 1691 | case 0x00c8: c435_state_set_projection_matrix_line(param); break; |
| 1692 | default: |
| 1693 | // logerror("WARNING: Unhandled state type %04x\n", type); |
| 1694 | break; |
| 1695 | } |
| 1696 | } |
| 1697 | |
| 1698 | int namcos23_state::c435_get_state_entry_size(UINT16 type) |
| 1699 | { |
| 1700 | switch(type) { |
| 1701 | case 0x0001: return 1; |
| 1702 | case 0x0009: return 19; |
| 1703 | case 0x0042: return 41; |
| 1704 | case 0x0046: return 13; |
| 1705 | case 0x00c0: return 33; |
| 1706 | case 0x00c6: return 13; |
| 1707 | case 0x00c8: return 17; |
| 1708 | default: |
| 1709 | logerror("WARNING: Unknown size for state type %04x\n", type); |
| 1710 | return -1; |
| 1711 | } |
| 1712 | } |
| 1713 | |
| 1615 | 1714 | void namcos23_state::c435_matrix_matrix_mul() // 0.0 |
| 1616 | 1715 | { |
| 1617 | 1716 | if((m_c435_buffer[0] & 0xf) != 4) |
| r243801 | r243802 | |
| 1622 | 1721 | if(m_c435_buffer[3] != 0xffff) |
| 1623 | 1722 | logerror("WARNING: c435_matrix_matrix_mul with +2=%04x\n", m_c435_buffer[3]); |
| 1624 | 1723 | |
| 1724 | |
| 1725 | if(0 && m_c435_buffer[0] != 0x0004) |
| 1726 | fprintf(stderr, "c435_matrix_matrix_mul header %04x\n", m_c435_buffer[0]); |
| 1727 | if(m_c435_buffer[3] != 0xffff) |
| 1728 | fprintf(stderr, "c435_matrix_matrix_mul with +2=%04x\n", m_c435_buffer[3]); |
| 1729 | |
| 1730 | |
| 1625 | 1731 | INT16 *t = c435_getm(m_c435_buffer[1]); |
| 1626 | 1732 | const INT16 *m2 = c435_getm(m_c435_buffer[2]); |
| 1627 | 1733 | const INT16 *m1 = c435_getm(m_c435_buffer[4]); |
| r243801 | r243802 | |
| 1645 | 1751 | return; |
| 1646 | 1752 | } |
| 1647 | 1753 | |
| 1754 | if(1 && m_c435_buffer[0] != 0x0814 && m_c435_buffer[0] != 0x1014) |
| 1755 | fprintf(stderr, "c435_matrix_vector_mul header %04x\n", m_c435_buffer[0]); |
| 1756 | |
| 1757 | |
| 1648 | 1758 | if(m_c435_buffer[3] != 0xffff) { |
| 1649 | 1759 | INT32 *t = c435_getv(m_c435_buffer[1]); |
| 1650 | 1760 | const INT16 *m = c435_getm(m_c435_buffer[2]); |
| r243801 | r243802 | |
| 1673 | 1783 | logerror("WARNING: c435_matrix_set with size %d\n", m_c435_buffer[0] & 0xf); |
| 1674 | 1784 | return; |
| 1675 | 1785 | } |
| 1786 | |
| 1787 | if(m_c435_buffer[0] != 0x004a) |
| 1788 | fprintf(stderr, "c435_matrix_set header %04x\n", m_c435_buffer[0]); |
| 1789 | |
| 1676 | 1790 | INT16 *t = c435_getm(m_c435_buffer[1]); |
| 1677 | 1791 | for(int i=0; i<9; i++) |
| 1678 | 1792 | t[i] = m_c435_buffer[i+2]; |
| r243801 | r243802 | |
| 1685 | 1799 | logerror("WARNING: c435_vector_set with size %d\n", m_c435_buffer[0] & 0xf); |
| 1686 | 1800 | return; |
| 1687 | 1801 | } |
| 1802 | if(m_c435_buffer[0] != 0x057) |
| 1803 | fprintf(stderr, "c435_vector_set header %04x\n", m_c435_buffer[0]); |
| 1804 | |
| 1688 | 1805 | INT32 *t = c435_getv(m_c435_buffer[1]); |
| 1689 | 1806 | for(int i=0; i<3; i++) |
| 1690 | 1807 | t[i] = u32_to_s24((m_c435_buffer[2*i+2] << 16) | m_c435_buffer[2*i+3]); |
| r243801 | r243802 | |
| 1700 | 1817 | m_scaling = m_c435_buffer[1]; |
| 1701 | 1818 | } |
| 1702 | 1819 | |
| 1703 | | void namcos23_state::c435_state_set_interrupt() // 4.f.0001 |
| 1820 | void namcos23_state::c435_state_set() // 4.f |
| 1704 | 1821 | { |
| 1705 | | if(m_c435_buffer[0] != 0x4f02) |
| 1822 | if((m_c435_buffer[0] & 0xff) == 0) |
| 1706 | 1823 | { |
| 1707 | | logerror("WARNING: c435_state_set_interrupt with size %d\n", m_c435_buffer[0] & 0xff); |
| 1824 | logerror("WARNING: c435_state_set with zero size\n"); |
| 1708 | 1825 | return; |
| 1709 | 1826 | } |
| 1710 | | if(m_c435_buffer[2] & 1) |
| 1711 | | update_main_interrupts(m_main_irqcause | MAIN_C435_IRQ); |
| 1712 | | else |
| 1713 | | update_main_interrupts(m_main_irqcause & ~MAIN_C435_IRQ); |
| 1714 | | } |
| 1715 | | |
| 1716 | | void namcos23_state::c435_state_set() // 4.f |
| 1717 | | { |
| 1718 | | if((m_c435_buffer[0] & 0xff) == 0) |
| 1827 | int size = c435_get_state_entry_size(m_c435_buffer[1]); |
| 1828 | if(size != (m_c435_buffer[0] & 0xff)-1) |
| 1719 | 1829 | { |
| 1720 | | logerror("WARNING: c435_state_set with size %d\n", m_c435_buffer[0] & 0xff); |
| 1830 | logerror("WARNING: c435_state_set size disagreement (type=%04x, got %d, expected %d)\n", m_c435_buffer[1], (m_c435_buffer[0] & 0xff)-1, size); |
| 1721 | 1831 | return; |
| 1722 | 1832 | } |
| 1723 | | switch(m_c435_buffer[1]) { |
| 1724 | | case 0x0001: c435_state_set_interrupt(); break; |
| 1725 | | default: |
| 1726 | | logerror("WARNING: c435_state_set(%04x, ...)\n", m_c435_buffer[1]); |
| 1727 | | break; |
| 1728 | | } |
| 1833 | |
| 1834 | c435_state_set(m_c435_buffer[1], m_c435_buffer+2); |
| 1729 | 1835 | } |
| 1730 | 1836 | |
| 1731 | 1837 | void namcos23_state::c435_render() // 8 |
| 1732 | 1838 | { |
| 1733 | 1839 | if((m_c435_buffer[0] & 0xf) != 3) |
| 1734 | 1840 | { |
| 1735 | | logerror("WARNING: c435_render with size %d, header %04x", m_c435_buffer[0] & 0xf, m_c435_buffer[0]); |
| 1841 | logerror("WARNING: c435_render with size %d, header %04x\n", m_c435_buffer[0] & 0xf, m_c435_buffer[0]); |
| 1736 | 1842 | return; |
| 1737 | 1843 | } |
| 1738 | 1844 | |
| r243801 | r243802 | |
| 1757 | 1863 | re->model.scaling = use_scaling ? m_scaling / 16384.0 : 1.0; |
| 1758 | 1864 | memcpy(re->model.m, m, sizeof(re->model.m)); |
| 1759 | 1865 | memcpy(re->model.v, v, sizeof(re->model.v)); |
| 1866 | // re->model.v[2] *= 768/420.0; |
| 1867 | |
| 1760 | 1868 | if(0) |
| 1761 | | fprintf(stderr, "Render %04x (%f %f %f %f %f %f %f %f %f) (%f %f %f)\n", |
| 1869 | fprintf(stderr, "Render %04x (%f %f %f %f %f %f %f %f %f) (%f %f %f) %f\n", |
| 1762 | 1870 | re->model.model, |
| 1763 | 1871 | re->model.m[0]/16384.0, re->model.m[1]/16384.0, re->model.m[2]/16384.0, |
| 1764 | 1872 | re->model.m[3]/16384.0, re->model.m[4]/16384.0, re->model.m[5]/16384.0, |
| 1765 | 1873 | re->model.m[6]/16384.0, re->model.m[7]/16384.0, re->model.m[8]/16384.0, |
| 1766 | | re->model.v[0]/16384.0, re->model.v[1]/16384.0, re->model.v[2]/16384.0); |
| 1874 | re->model.v[0]/16384.0, re->model.v[1]/16384.0, re->model.v[2]/16384.0, |
| 1875 | re->model.scaling); |
| 1767 | 1876 | |
| 1768 | 1877 | render.count[render.cur]++; |
| 1769 | 1878 | } |
| r243801 | r243802 | |
| 1839 | 1948 | |
| 1840 | 1949 | void namcos23_state::c435_dma(address_space &space, UINT32 adr, UINT32 size) |
| 1841 | 1950 | { |
| 1951 | UINT32 oadr = adr; |
| 1842 | 1952 | adr &= 0x1fffffff; |
| 1843 | 1953 | |
| 1954 | |
| 1955 | for(int pos=0; pos < size; pos += 2) { |
| 1956 | UINT16 v0, v1; |
| 1957 | v0 = space.read_word(adr+pos); |
| 1958 | v1 = space.read_word(adr+pos+2); |
| 1959 | |
| 1960 | if(v0 == 0x8083 && v1 == 0x0d9e) |
| 1961 | fprintf(stderr, "adr=%x %04x %04x\n", oadr+pos, v0, v1); |
| 1962 | } |
| 1963 | |
| 1844 | 1964 | for(int pos=0; pos < size; pos += 2) |
| 1845 | 1965 | c435_pio_w(space.read_word(adr+pos)); |
| 1846 | 1966 | } |
| r243801 | r243802 | |
| 1932 | 2052 | // 480/(2.34375/3.75) = 768 |
| 1933 | 2053 | |
| 1934 | 2054 | float w = pv.p[0] ? 1/pv.p[0] : 0; |
| 2055 | #if 1 |
| 1935 | 2056 | pv.x = 320 + 768*w*pv.x; |
| 1936 | 2057 | pv.y = 240 - 768*w*pv.y; |
| 2058 | #else |
| 2059 | pv.x = 320 + 410*w*pv.x; |
| 2060 | pv.y = 240 - 410*w*pv.y; |
| 2061 | #endif |
| 1937 | 2062 | pv.p[0] = w; |
| 1938 | 2063 | } |
| 1939 | 2064 | |
| r243801 | r243802 | |
| 1959 | 2084 | void namcos23_state::render_one_model(const namcos23_render_entry *re) |
| 1960 | 2085 | { |
| 1961 | 2086 | render_t &render = m_render; |
| 2087 | if(re->model.model < 0x80) { |
| 2088 | logerror("WARNING: model %02x requested\n", re->model.model); |
| 2089 | return; |
| 2090 | } |
| 2091 | |
| 2092 | if(re->model.model == 3486) |
| 2093 | return; |
| 2094 | |
| 1962 | 2095 | UINT32 adr = m_ptrom[re->model.model]; |
| 1963 | 2096 | if(adr >= m_ptrom_limit) |
| 1964 | 2097 | { |