src/mess/drivers/fmtowns.c
| r9347 | r9348 | |
| 126 | 126 | #include "devices/messram.h" |
| 127 | 127 | #include "includes/fmtowns.h" |
| 128 | 128 | #include "machine/nvram.h" |
| 129 | #include "devices/harddriv.h" |
| 130 | #include "machine/scsi.h" |
| 131 | #include "machine/scsibus.h" |
| 129 | 132 | |
| 130 | 133 | // CD controller IRQ types |
| 131 | 134 | #define TOWNS_CD_IRQ_MPU 1 |
| r9347 | r9348 | |
| 362 | 365 | if(tstate->towns_fdc_irq6mask == 0) |
| 363 | 366 | state = 0; |
| 364 | 367 | pic8259_ir6_w(device, state); // IRQ6 = FDC |
| 365 | | logerror("PIC: IRQ6 (FDC) set to %i\n",state); |
| 368 | if(IRQ_LOG) logerror("PIC: IRQ6 (FDC) set to %i\n",state); |
| 366 | 369 | } |
| 367 | 370 | |
| 368 | 371 | static WRITE_LINE_DEVICE_HANDLER( towns_mb8877a_drq_w ) |
| r9347 | r9348 | |
| 533 | 536 | if(state->towns_kb_irq1_enable) |
| 534 | 537 | { |
| 535 | 538 | pic8259_ir1_w(dev, 1); |
| 536 | | logerror("PIC: IRQ1 (keyboard) set high\n"); |
| 539 | if(IRQ_LOG) logerror("PIC: IRQ1 (keyboard) set high\n"); |
| 537 | 540 | } |
| 538 | 541 | logerror("KB: sending scancode 0x%02x\n",scancode); |
| 539 | 542 | } |
| r9347 | r9348 | |
| 576 | 579 | ret = state->towns_kb_output; |
| 577 | 580 | //logerror("KB: read keyboard output port, returning %02x\n",ret); |
| 578 | 581 | pic8259_ir1_w(state->pic_master, 0); |
| 579 | | logerror("PIC: IRQ1 (keyboard) set low\n"); |
| 582 | if(IRQ_LOG) logerror("PIC: IRQ1 (keyboard) set low\n"); |
| 580 | 583 | if(state->towns_kb_extend != 0xff) |
| 581 | 584 | { |
| 582 | 585 | towns_kb_sendcode(space->machine,state->towns_kb_extend,2); |
| r9347 | r9348 | |
| 721 | 724 | state->towns_pcm_channel_flag = 0; |
| 722 | 725 | state->towns_pcm_irq_flag = 0; |
| 723 | 726 | pic8259_ir5_w(state->pic_slave, 0); |
| 724 | | logerror("PIC: IRQ13 (PCM) set low\n"); |
| 727 | if(IRQ_LOG) logerror("PIC: IRQ13 (PCM) set low\n"); |
| 725 | 728 | break; |
| 726 | 729 | // default: |
| 727 | 730 | //logerror("FM: unimplemented port 0x%04x read\n",offset + 0x4e8); |
| r9347 | r9348 | |
| 1139 | 1142 | { |
| 1140 | 1143 | tstate->towns_cd.status |= 0x80; |
| 1141 | 1144 | pic8259_ir1_w(tstate->pic_slave, 1); |
| 1142 | | logerror("PIC: IRQ9 (CD-ROM) set high\n"); |
| 1145 | if(IRQ_LOG) logerror("PIC: IRQ9 (CD-ROM) set high\n"); |
| 1143 | 1146 | } |
| 1144 | 1147 | } |
| 1145 | 1148 | else |
| r9347 | r9348 | |
| 1149 | 1152 | { |
| 1150 | 1153 | tstate->towns_cd.status &= ~0x80; |
| 1151 | 1154 | pic8259_ir1_w(tstate->pic_slave, 0); |
| 1152 | | logerror("PIC: IRQ9 (CD-ROM) set low\n"); |
| 1155 | if(IRQ_LOG) logerror("PIC: IRQ9 (CD-ROM) set low\n"); |
| 1153 | 1156 | } |
| 1154 | 1157 | break; |
| 1155 | 1158 | case TOWNS_CD_IRQ_DMA: |
| r9347 | r9348 | |
| 1161 | 1164 | { |
| 1162 | 1165 | tstate->towns_cd.status |= 0x40; |
| 1163 | 1166 | pic8259_ir1_w(tstate->pic_slave, 1); |
| 1164 | | logerror("PIC: IRQ9 (CD-ROM DMA) set high\n"); |
| 1167 | if(IRQ_LOG) logerror("PIC: IRQ9 (CD-ROM DMA) set high\n"); |
| 1165 | 1168 | } |
| 1166 | 1169 | } |
| 1167 | 1170 | else |
| r9347 | r9348 | |
| 1171 | 1174 | { |
| 1172 | 1175 | tstate->towns_cd.status &= ~0x40; |
| 1173 | 1176 | pic8259_ir1_w(tstate->pic_slave, 0); |
| 1174 | | logerror("PIC: IRQ9 (CD-ROM DMA) set low\n"); |
| 1177 | if(IRQ_LOG) logerror("PIC: IRQ9 (CD-ROM DMA) set low\n"); |
| 1175 | 1178 | } |
| 1176 | 1179 | break; |
| 1177 | 1180 | } |
| r9347 | r9348 | |
| 1760 | 1763 | } |
| 1761 | 1764 | |
| 1762 | 1765 | // SCSI controller - I/O ports 0xc30 and 0xc32 |
| 1766 | // info from Toshiya Takeda's e-FMR50 source (the Towns uses the same controller?) |
| 1767 | // 0xc30 = Data register |
| 1768 | // 0xc32 = Status register (read) |
| 1769 | // bit 7 = REQ |
| 1770 | // bit 6 = IO |
| 1771 | // bit 5 = MSG |
| 1772 | // bit 4 = CD |
| 1773 | // bit 3 = BUSY |
| 1774 | // bit 1 = INT |
| 1775 | // bit 0 = PERR |
| 1776 | // 0xc32 = Control register (write) |
| 1777 | // bit 7 = WEN |
| 1778 | // bit 6 = IMSK |
| 1779 | // bit 4 = ATN |
| 1780 | // bit 2 = SEL |
| 1781 | // bit 1 = DMAE |
| 1782 | // bit 0 = RST |
| 1763 | 1783 | static READ8_HANDLER(towns_scsi_r) |
| 1764 | 1784 | { |
| 1765 | | logerror("scsi_r (offset %i) read\n",offset); |
| 1766 | | if(offset == 2) |
| 1767 | | return 0x08; |
| 1785 | towns_state* state = space->machine->driver_data<towns_state>(); |
| 1786 | UINT8 ret = 0x00; |
| 1787 | // logerror("scsi_r (offset %i) read\n",offset); |
| 1788 | switch(offset) |
| 1789 | { |
| 1790 | case 0x00: |
| 1791 | return scsi_data_r(state->scsibus); |
| 1792 | case 0x02: |
| 1793 | ret |= (get_scsi_line(state->scsibus,SCSI_LINE_REQ)) ? 0x00 : 0x80; |
| 1794 | ret |= (get_scsi_line(state->scsibus,SCSI_LINE_IO)) ? 0x00 : 0x40; |
| 1795 | ret |= (get_scsi_line(state->scsibus,SCSI_LINE_MSG)) ? 0x00 : 0x20; |
| 1796 | ret |= (get_scsi_line(state->scsibus,SCSI_LINE_CD)) ? 0x00 : 0x10; |
| 1797 | ret |= (get_scsi_line(state->scsibus,SCSI_LINE_BSY)) ? 0x00 : 0x08; |
| 1798 | return ret; |
| 1799 | } |
| 1768 | 1800 | return 0x00; |
| 1769 | 1801 | } |
| 1770 | 1802 | |
| 1803 | static WRITE8_HANDLER(towns_scsi_w) |
| 1804 | { |
| 1805 | towns_state* state = space->machine->driver_data<towns_state>(); |
| 1806 | switch(offset) |
| 1807 | { |
| 1808 | case 0x00: |
| 1809 | scsi_data_w(state->scsibus,data); |
| 1810 | set_scsi_line(state->scsibus,SCSI_LINE_ACK,0); |
| 1811 | logerror("SCSI data write %02x\n",data); |
| 1812 | break; |
| 1813 | case 0x02: |
| 1814 | set_scsi_line(state->scsibus,SCSI_LINE_SEL,data & 0x04); |
| 1815 | if(data & 0x01) |
| 1816 | { |
| 1817 | set_scsi_line(state->scsibus,SCSI_LINE_RESET,data & 0x01); |
| 1818 | } |
| 1819 | logerror("SCSI control write %02x\n",data); |
| 1820 | break; |
| 1821 | } |
| 1822 | } |
| 1823 | |
| 1824 | void towns_scsi_linechange(running_device *device, UINT8 line, UINT8 state) |
| 1825 | { |
| 1826 | towns_state* tstate = device->machine->driver_data<towns_state>(); |
| 1827 | |
| 1828 | if(state == 0) |
| 1829 | { |
| 1830 | switch(line) |
| 1831 | { |
| 1832 | case SCSI_LINE_REQ: |
| 1833 | break; |
| 1834 | case SCSI_LINE_IO: |
| 1835 | break; |
| 1836 | case SCSI_LINE_MSG: |
| 1837 | break; |
| 1838 | case SCSI_LINE_CD: |
| 1839 | break; |
| 1840 | case SCSI_LINE_BSY: |
| 1841 | break; |
| 1842 | } |
| 1843 | } |
| 1844 | else |
| 1845 | { |
| 1846 | switch(line) |
| 1847 | { |
| 1848 | case SCSI_LINE_REQ: |
| 1849 | set_scsi_line(tstate->scsibus,SCSI_LINE_ACK,1); |
| 1850 | break; |
| 1851 | case SCSI_LINE_IO: |
| 1852 | break; |
| 1853 | case SCSI_LINE_MSG: |
| 1854 | break; |
| 1855 | case SCSI_LINE_CD: |
| 1856 | break; |
| 1857 | case SCSI_LINE_BSY: |
| 1858 | break; |
| 1859 | } |
| 1860 | } |
| 1861 | |
| 1862 | } |
| 1863 | |
| 1771 | 1864 | // Volume ports - I/O ports 0x4e0-0x4e3 |
| 1772 | | // 0x4e3 = channel select |
| 1773 | | // (4 and 5 = CD-DA left and right channels) |
| 1774 | | // (6 = MIC?) |
| 1775 | | // 0x4e2 = volume level |
| 1865 | // 0x4e0 = input volume level |
| 1866 | // 0x4e1 = input channel select |
| 1867 | // 4 = Line in, left channel |
| 1868 | // 5 = Line in, right channel |
| 1869 | // 0x4e2 = output volume level |
| 1870 | // 0x4e3 = output channel select |
| 1871 | // 2 = MIC |
| 1872 | // 3 = MODEM |
| 1873 | // 4 = CD-DA left channel |
| 1874 | // 5 = CD-DA right channel |
| 1776 | 1875 | static READ8_HANDLER(towns_volume_r) |
| 1777 | 1876 | { |
| 1778 | 1877 | towns_state* state = space->machine->driver_data<towns_state>(); |
| r9347 | r9348 | |
| 1843 | 1942 | { |
| 1844 | 1943 | state->towns_fm_irq_flag = 1; |
| 1845 | 1944 | pic8259_ir5_w(pic, 1); |
| 1846 | | logerror("PIC: IRQ13 (FM) set high\n"); |
| 1945 | if(IRQ_LOG) logerror("PIC: IRQ13 (FM) set high\n"); |
| 1847 | 1946 | } |
| 1848 | 1947 | else |
| 1849 | 1948 | { |
| 1850 | 1949 | state->towns_fm_irq_flag = 0; |
| 1851 | 1950 | pic8259_ir5_w(pic, 0); |
| 1852 | | logerror("PIC: IRQ13 (FM) set low\n"); |
| 1951 | if(IRQ_LOG) logerror("PIC: IRQ13 (FM) set low\n"); |
| 1853 | 1952 | } |
| 1854 | 1953 | } |
| 1855 | 1954 | |
| r9347 | r9348 | |
| 1864 | 1963 | state->towns_pcm_irq_flag = 1; |
| 1865 | 1964 | state->towns_pcm_channel_flag |= (1 << channel); |
| 1866 | 1965 | pic8259_ir5_w(pic, 1); |
| 1867 | | logerror("PIC: IRQ13 (PCM) set high (channel %i)\n",channel); |
| 1966 | if(IRQ_LOG) logerror("PIC: IRQ13 (PCM) set high (channel %i)\n",channel); |
| 1868 | 1967 | } |
| 1869 | 1968 | } |
| 1870 | 1969 | |
| r9347 | r9348 | |
| 1882 | 1981 | if(tstate->towns_timer_mask & 0x01) |
| 1883 | 1982 | { |
| 1884 | 1983 | pic8259_ir0_w(dev, state); |
| 1885 | | logerror("PIC: IRQ0 (PIT Timer) set to %i\n",state); |
| 1984 | if(IRQ_LOG) logerror("PIC: IRQ0 (PIT Timer) set to %i\n",state); |
| 1886 | 1985 | } |
| 1887 | 1986 | } |
| 1888 | 1987 | |
| r9347 | r9348 | |
| 1989 | 2088 | // Keyboard (8042 MCU) |
| 1990 | 2089 | AM_RANGE(0x0600,0x0607) AM_READWRITE8(towns_keyboard_r, towns_keyboard_w,0x00ff00ff) |
| 1991 | 2090 | // SCSI controller |
| 1992 | | AM_RANGE(0x0c30,0x0c33) AM_READ8(towns_scsi_r,0xffffffff) |
| 2091 | AM_RANGE(0x0c30,0x0c33) AM_READWRITE8(towns_scsi_r,towns_scsi_w,0xffffffff) |
| 1993 | 2092 | // CMOS |
| 1994 | 2093 | AM_RANGE(0x3000,0x3fff) AM_READWRITE8(towns_cmos8_r, towns_cmos8_w,0x00ff00ff) |
| 1995 | 2094 | // Something (MS-DOS wants this 0x41ff to be 1) |
| r9347 | r9348 | |
| 2232 | 2331 | state->towns_cd.read_timer = timer_alloc(machine,towns_cdrom_read_byte,(void*)machine->device("dma_1")); |
| 2233 | 2332 | |
| 2234 | 2333 | cpu_set_irq_callback(machine->device("maincpu"), towns_irq_callback); |
| 2334 | init_scsibus(machine->device("scsibus")); |
| 2235 | 2335 | } |
| 2236 | 2336 | |
| 2237 | 2337 | static DRIVER_INIT( marty ) |
| r9347 | r9348 | |
| 2254 | 2354 | state->messram = machine->device("messram"); |
| 2255 | 2355 | state->cdrom = machine->device("cdrom"); |
| 2256 | 2356 | state->cdda = machine->device("cdda"); |
| 2357 | state->scsibus = machine->device("scsibus"); |
| 2358 | state->hd0 = machine->device("harddisk0"); |
| 2359 | state->hd1 = machine->device("harddisk1"); |
| 2360 | state->hd2 = machine->device("harddisk2"); |
| 2361 | state->hd3 = machine->device("harddisk3"); |
| 2362 | state->hd4 = machine->device("harddisk4"); |
| 2257 | 2363 | state->ftimer = 0x00; |
| 2258 | 2364 | state->nmi_mask = 0x00; |
| 2259 | 2365 | state->compat_mode = 0x00; |
| r9347 | r9348 | |
| 2352 | 2458 | towns_pcm_irq |
| 2353 | 2459 | }; |
| 2354 | 2460 | |
| 2461 | static const SCSIConfigTable towns_scsi_device_table = |
| 2462 | { |
| 2463 | 5, /* 5 SCSI devices */ |
| 2464 | { |
| 2465 | { SCSI_ID_0, "harddisk0", SCSI_DEVICE_HARDDISK }, |
| 2466 | { SCSI_ID_1, "harddisk1", SCSI_DEVICE_HARDDISK }, |
| 2467 | { SCSI_ID_2, "harddisk2", SCSI_DEVICE_HARDDISK }, |
| 2468 | { SCSI_ID_3, "harddisk3", SCSI_DEVICE_HARDDISK }, |
| 2469 | { SCSI_ID_4, "harddisk4", SCSI_DEVICE_HARDDISK }, |
| 2470 | } |
| 2471 | }; |
| 2472 | |
| 2473 | static const SCSIBus_interface towns_scsi_config = |
| 2474 | { |
| 2475 | &towns_scsi_device_table, |
| 2476 | &towns_scsi_linechange |
| 2477 | }; |
| 2478 | |
| 2355 | 2479 | static const gfx_layout fnt_chars_16x16 = |
| 2356 | 2480 | { |
| 2357 | 2481 | 16,16, |
| r9347 | r9348 | |
| 2421 | 2545 | |
| 2422 | 2546 | MDRV_CDROM_ADD("cdrom") |
| 2423 | 2547 | |
| 2548 | MDRV_HARDDISK_ADD("harddisk0") |
| 2549 | MDRV_HARDDISK_ADD("harddisk1") |
| 2550 | MDRV_HARDDISK_ADD("harddisk2") |
| 2551 | MDRV_HARDDISK_ADD("harddisk3") |
| 2552 | MDRV_HARDDISK_ADD("harddisk4") |
| 2553 | MDRV_SCSIBUS_ADD("scsibus",towns_scsi_config) |
| 2554 | |
| 2424 | 2555 | MDRV_UPD71071_ADD("dma_1",towns_dma_config) |
| 2425 | 2556 | MDRV_UPD71071_ADD("dma_2",towns_dma_config) |
| 2426 | 2557 | |