trunk/src/mess/drivers/pc9801.c
| r19175 | r19176 | |
| 14 | 14 | TODO (PC-9801RS): |
| 15 | 15 | - floppy disk hook-up; |
| 16 | 16 | - extra features; |
| 17 | | - clean-up duplicating code; |
| 17 | - clean-up duplicate code; |
| 18 | 18 | |
| 19 | 19 | TODO (PC-9821): |
| 20 | 20 | - fix CPU for some clones; |
| 21 | | - PARITY ERROR, presumably it needs a far better emulation of the i8251 ports |
| 21 | - "cache error", there might be "windowed" RAM at 0x80000-0x9ffff (hence the RAM POST |
| 22 | that stops at 512k) |
| 22 | 23 | |
| 23 | 24 | TODO: (PC-486MU) |
| 24 | 25 | - Tries to read port C of i8255_sys (-> 0x35) at boot without setting up the control |
| r19175 | r19176 | |
| 317 | 318 | /* PC9821 specific */ |
| 318 | 319 | UINT8 m_analog256,m_analog256e; |
| 319 | 320 | UINT8 m_sdip[24], m_sdip_bank; |
| 321 | UINT8 *m_ideram; |
| 322 | UINT8 *m_ext_gvram; |
| 320 | 323 | |
| 321 | 324 | DECLARE_READ8_MEMBER(pc9801_xx_r); |
| 322 | 325 | DECLARE_WRITE8_MEMBER(pc9801_xx_w); |
| r19175 | r19176 | |
| 376 | 379 | DECLARE_WRITE8_MEMBER(pc9821_video_ff_w); |
| 377 | 380 | DECLARE_READ8_MEMBER(pc9821_a0_r); |
| 378 | 381 | DECLARE_WRITE8_MEMBER(pc9821_a0_w); |
| 382 | DECLARE_READ8_MEMBER(pc9821_pit_r); |
| 383 | DECLARE_WRITE8_MEMBER(pc9821_pit_w); |
| 379 | 384 | DECLARE_READ8_MEMBER(ide_status_r); |
| 380 | 385 | DECLARE_READ8_MEMBER(pc9801rs_access_ctrl_r); |
| 381 | 386 | DECLARE_WRITE8_MEMBER(pc9801rs_access_ctrl_w); |
| 387 | DECLARE_READ8_MEMBER(pc9821_memory_r); |
| 388 | DECLARE_WRITE8_MEMBER(pc9821_memory_w); |
| 382 | 389 | |
| 383 | 390 | DECLARE_READ8_MEMBER(sdip_0_r); |
| 384 | 391 | DECLARE_READ8_MEMBER(sdip_1_r); |
| r19175 | r19176 | |
| 406 | 413 | DECLARE_WRITE8_MEMBER(sdip_a_w); |
| 407 | 414 | DECLARE_WRITE8_MEMBER(sdip_b_w); |
| 408 | 415 | |
| 416 | DECLARE_READ8_MEMBER(pc9821_ideram_r); |
| 417 | DECLARE_WRITE8_MEMBER(pc9821_ideram_w); |
| 418 | DECLARE_READ8_MEMBER(pc9821_ext_gvram_r); |
| 419 | DECLARE_WRITE8_MEMBER(pc9821_ext_gvram_w); |
| 420 | |
| 409 | 421 | void fdc_2hd_irq(bool state); |
| 410 | 422 | void fdc_2hd_drq(bool state); |
| 411 | 423 | void fdc_2dd_irq(bool state); |
| r19175 | r19176 | |
| 1305 | 1317 | |
| 1306 | 1318 | READ8_MEMBER(pc9801_state::pc9801rs_knjram_r) |
| 1307 | 1319 | { |
| 1308 | | |
| 1309 | 1320 | UINT8 *KNJRAM = memregion("kanji")->base(); |
| 1310 | 1321 | |
| 1311 | 1322 | return KNJRAM[offset]; |
| r19175 | r19176 | |
| 1664 | 1675 | * |
| 1665 | 1676 | ************************************/ |
| 1666 | 1677 | |
| 1678 | /* Note: not hooking this up causes "MEMORY ERROR" at POST */ |
| 1679 | READ8_MEMBER(pc9801_state::pc9821_ideram_r) |
| 1680 | { |
| 1681 | return m_ideram[offset]; |
| 1682 | } |
| 1683 | |
| 1684 | WRITE8_MEMBER(pc9801_state::pc9821_ideram_w) |
| 1685 | { |
| 1686 | m_ideram[offset] = data; |
| 1687 | } |
| 1688 | |
| 1689 | READ8_MEMBER(pc9801_state::pc9821_ext_gvram_r) |
| 1690 | { |
| 1691 | return m_ext_gvram[offset]; |
| 1692 | } |
| 1693 | |
| 1694 | WRITE8_MEMBER(pc9801_state::pc9821_ext_gvram_w) |
| 1695 | { |
| 1696 | m_ext_gvram[offset] = data; |
| 1697 | } |
| 1698 | |
| 1699 | |
| 1700 | READ8_MEMBER(pc9801_state::pc9821_memory_r) |
| 1701 | { |
| 1702 | if(m_gate_a20 == 0) |
| 1703 | offset &= 0xfffff; |
| 1704 | |
| 1705 | if ( offset <= 0x0007ffff) { return pc9801rs_wram_r(space,offset); } |
| 1706 | else if(offset >= 0x000a0000 && offset <= 0x000a3fff) { return pc9801_tvram_r(space,offset-0xa0000); } |
| 1707 | else if(offset >= 0x000a4000 && offset <= 0x000a4fff) { return pc9801rs_knjram_r(space,offset & 0xfff); } |
| 1708 | else if(offset >= 0x000a8000 && offset <= 0x000bffff) { return pc9801_gvram_r(space,offset-0xa8000); } |
| 1709 | else if(offset >= 0x000da000 && offset <= 0x000dbfff) { return pc9821_ideram_r(space,offset & 0x1fff); } |
| 1710 | else if(offset >= 0x000e0000 && offset <= 0x000fffff) { return pc9801rs_ipl_r(space,offset & 0x1ffff); } |
| 1711 | else if(offset >= 0x00f00000 && offset <= 0x00f9ffff) { return pc9821_ext_gvram_r(space,offset-0x00f00000); } |
| 1712 | else if(offset >= 0x01000000 && offset <= 0x01000000+m_ram_size-1) { return pc9801rs_ex_wram_r(space,offset-0x01000000); } |
| 1713 | else if(offset >= 0xfffe0000 && offset <= 0xffffffff) { return pc9801rs_ipl_r(space,offset & 0x1ffff); } |
| 1714 | |
| 1715 | printf("%08x\n",offset); |
| 1716 | return 0x00; |
| 1717 | } |
| 1718 | |
| 1719 | |
| 1720 | WRITE8_MEMBER(pc9801_state::pc9821_memory_w) |
| 1721 | { |
| 1722 | if(m_gate_a20 == 0) |
| 1723 | offset &= 0xfffff; |
| 1724 | |
| 1725 | if ( offset <= 0x0007ffff) { pc9801rs_wram_w(space,offset,data); } |
| 1726 | else if(offset >= 0x000a0000 && offset <= 0x000a3fff) { pc9801_tvram_w(space,offset-0xa0000,data); } |
| 1727 | else if(offset >= 0x000a4000 && offset <= 0x000a4fff) { pc9801rs_knjram_w(space,offset & 0xfff,data); } |
| 1728 | else if(offset >= 0x000a8000 && offset <= 0x000bffff) { pc9801_gvram_w(space,offset-0xa8000,data); } |
| 1729 | else if(offset >= 0x000da000 && offset <= 0x000dbfff) { pc9821_ideram_w(space,offset & 0x1fff,data); } |
| 1730 | else if(offset >= 0x00f00000 && offset <= 0x00f9ffff) { pc9821_ext_gvram_w(space,offset-0x00f00000,data); } |
| 1731 | else if(offset >= 0x01000000 && offset <= 0x01000000+m_ram_size-1) { pc9801rs_ex_wram_w(space,offset-0x01000000,data); } |
| 1732 | else |
| 1733 | printf("%08x %08x\n",offset,data); |
| 1734 | |
| 1735 | } |
| 1736 | |
| 1667 | 1737 | WRITE8_MEMBER(pc9801_state::pc9821_video_ff_w) |
| 1668 | 1738 | { |
| 1669 | | |
| 1670 | 1739 | if(offset == 2) |
| 1671 | 1740 | { |
| 1672 | 1741 | switch(data & 0xf8) // pc-9821 specific extended registers |
| r19175 | r19176 | |
| 1681 | 1750 | |
| 1682 | 1751 | READ8_MEMBER(pc9801_state::pc9821_a0_r) |
| 1683 | 1752 | { |
| 1684 | | |
| 1685 | 1753 | if((offset & 1) == 0 && offset & 8) |
| 1686 | 1754 | { |
| 1687 | 1755 | if(m_analog256) |
| r19175 | r19176 | |
| 1720 | 1788 | pc9801rs_a0_w(space,offset,data); |
| 1721 | 1789 | } |
| 1722 | 1790 | |
| 1791 | READ8_MEMBER(pc9801_state::pc9821_pit_r) |
| 1792 | { |
| 1793 | if((offset & 1) == 0) |
| 1794 | { |
| 1795 | printf("Read to undefined port [%04x]\n",offset+0x3fd8); |
| 1796 | return 0xff; |
| 1797 | } |
| 1798 | else // odd |
| 1799 | { |
| 1800 | if(offset & 0x08) |
| 1801 | printf("Read to undefined port [%02x]\n",offset+0x3fd8); |
| 1802 | else |
| 1803 | return pit8253_r(machine().device("pit8253"), space, (offset & 6) >> 1); |
| 1804 | } |
| 1805 | |
| 1806 | return 0xff; |
| 1807 | } |
| 1808 | |
| 1809 | WRITE8_MEMBER(pc9801_state::pc9821_pit_w) |
| 1810 | { |
| 1811 | if((offset & 1) == 0) |
| 1812 | { |
| 1813 | printf("Write to undefined port [%04x] <- %02x\n",offset+0x3fd8,data); |
| 1814 | } |
| 1815 | else // odd |
| 1816 | { |
| 1817 | if(offset < 0x08) |
| 1818 | pit8253_w(machine().device("pit8253"), space, (offset & 6) >> 1, data); |
| 1819 | else |
| 1820 | printf("Write to undefined port [%04x] <- %02x\n",offset+0x3fd8,data); |
| 1821 | } |
| 1822 | } |
| 1823 | |
| 1723 | 1824 | READ8_MEMBER(pc9801_state::ide_status_r) |
| 1724 | 1825 | { |
| 1725 | 1826 | return 0x50; // status |
| r19175 | r19176 | |
| 1782 | 1883 | } |
| 1783 | 1884 | |
| 1784 | 1885 | static ADDRESS_MAP_START( pc9821_map, AS_PROGRAM, 32, pc9801_state ) |
| 1785 | | AM_RANGE(0x00000000, 0xffffffff) AM_READWRITE8(pc9801rs_memory_r,pc9801rs_memory_w,0xffffffff) |
| 1886 | AM_RANGE(0x00000000, 0xffffffff) AM_READWRITE8(pc9821_memory_r,pc9821_memory_w,0xffffffff) |
| 1786 | 1887 | ADDRESS_MAP_END |
| 1787 | 1888 | |
| 1788 | 1889 | static ADDRESS_MAP_START( pc9821_io, AS_IO, 32, pc9801_state ) |
| r19175 | r19176 | |
| 1827 | 1928 | // AM_RANGE(0x0c2d, 0x0c2d) cs4231 PCM board hi byte control |
| 1828 | 1929 | // AM_RANGE(0x0cc0, 0x0cc7) SCSI interface / <undefined> |
| 1829 | 1930 | // AM_RANGE(0x0cfc, 0x0cff) PCI bus |
| 1830 | | // AM_RANGE(0x3fd8, 0x3fdf) <undefined> / pit mirror ports |
| 1931 | AM_RANGE(0x3fd8, 0x3fdf) AM_READWRITE8(pc9821_pit_r, pc9821_pit_w, 0xffffffff) // <undefined> / pit mirror ports |
| 1831 | 1932 | // AM_RANGE(0x7fd8, 0x7fdf) <undefined> / mouse ppi8255 ports |
| 1832 | 1933 | AM_RANGE(0x841c, 0x841f) AM_READWRITE8(sdip_0_r,sdip_0_w,0xffffffff) |
| 1833 | 1934 | AM_RANGE(0x851c, 0x851f) AM_READWRITE8(sdip_1_r,sdip_1_w,0xffffffff) |
| r19175 | r19176 | |
| 2616 | 2717 | m_rom_bank = 0; |
| 2617 | 2718 | m_fdc_ctrl = 3; |
| 2618 | 2719 | m_access_ctrl = 0; |
| 2720 | m_keyb_press = 0xff; // temp kludge, for PC-9821 booting |
| 2619 | 2721 | |
| 2620 | 2722 | m_ram_size = machine().device<ram_device>(RAM_TAG)->size() - 0xa0000; |
| 2621 | 2723 | } |
| r19175 | r19176 | |
| 2623 | 2725 | MACHINE_START_MEMBER(pc9801_state,pc9821) |
| 2624 | 2726 | { |
| 2625 | 2727 | MACHINE_START_CALL_MEMBER(pc9801); |
| 2728 | |
| 2729 | m_ideram = auto_alloc_array(machine(), UINT8, 0x2000); |
| 2730 | m_ext_gvram = auto_alloc_array(machine(), UINT8, 0xa0000); |
| 2731 | |
| 2626 | 2732 | state_save_register_global_pointer(machine(), m_sdip, 24); |
| 2733 | state_save_register_global_pointer(machine(), m_ideram, 0x2000); |
| 2734 | state_save_register_global_pointer(machine(), m_ext_gvram, 0xa0000); |
| 2627 | 2735 | } |
| 2628 | 2736 | |
| 2629 | 2737 | INTERRUPT_GEN_MEMBER(pc9801_state::pc9801_vrtc_irq) |