src/mess/video/mac.c
| r6200 | r6201 | |
| 97 | 97 | return 0; |
| 98 | 98 | } |
| 99 | 99 | |
| 100 | /* |
| 101 | RasterOps ColorBoard 264: fixed resolution 640x480 NuBus video card, 1/4/8/16/24 bit color |
| 102 | 1.5? MB of VRAM (tests up to 0x1fffff), Bt473 RAMDAC, and two custom gate arrays. |
| 103 | |
| 104 | - 0xfsff6004 is color depth: 0 for 1bpp, 1 for 2bpp, 2 for 4bpp, 3 for 8bpp, 4 for 24bpp (resolution is fixed 640x480) |
| 105 | - 0xfsff6014 is VBL ack: write 1 to ack |
| 106 | - 0xfsff603c is VBL disable: write 1 to disable, 0 to enable |
| 107 | */ |
| 108 | |
| 109 | UINT32 *mac_cb264_vram; |
| 110 | static UINT32 cb264_mode, cb264_vbl_disable, cb264_toggle; |
| 111 | static UINT32 cb264_palette[256], cb264_colors[3], cb264_count, cb264_clutoffs; |
| 112 | |
| 113 | VIDEO_START( mac_cb264 ) |
| 114 | { |
| 115 | cb264_toggle = 0; |
| 116 | cb264_count = 0; |
| 117 | cb264_clutoffs = 0; |
| 118 | cb264_vbl_disable = 1; |
| 119 | cb264_mode = 0; |
| 120 | } |
| 121 | |
| 122 | // we do this here because VIDEO_UPDATE is called constantly when stepping in the debugger, |
| 123 | // which makes it hard to get accurate timings (or escape the VIA2 IRQ handler) |
| 124 | INTERRUPT_GEN( mac_cb264_vbl ) |
| 125 | { |
| 126 | if (!cb264_vbl_disable) |
| 127 | { |
| 128 | mac_nubus_slot_interrupt(device->machine, 0xe, 1); |
| 129 | } |
| 130 | } |
| 131 | |
| 132 | VIDEO_UPDATE( mac_cb264 ) |
| 133 | { |
| 134 | UINT32 *scanline, *base; |
| 135 | int x, y; |
| 136 | |
| 137 | switch (cb264_mode) |
| 138 | { |
| 139 | case 0: // 1 bpp |
| 140 | { |
| 141 | UINT8 *vram8 = (UINT8 *)mac_cb264_vram; |
| 142 | UINT8 pixels; |
| 143 | |
| 144 | for (y = 0; y < 480; y++) |
| 145 | { |
| 146 | scanline = BITMAP_ADDR32(bitmap, y, 0); |
| 147 | for (x = 0; x < 640/8; x++) |
| 148 | { |
| 149 | pixels = vram8[(y * 1024) + (x^3)]; |
| 150 | |
| 151 | *scanline++ = cb264_palette[pixels&0x80]; |
| 152 | *scanline++ = cb264_palette[(pixels<<1)&0x80]; |
| 153 | *scanline++ = cb264_palette[(pixels<<2)&0x80]; |
| 154 | *scanline++ = cb264_palette[(pixels<<3)&0x80]; |
| 155 | *scanline++ = cb264_palette[(pixels<<4)&0x80]; |
| 156 | *scanline++ = cb264_palette[(pixels<<5)&0x80]; |
| 157 | *scanline++ = cb264_palette[(pixels<<6)&0x80]; |
| 158 | *scanline++ = cb264_palette[(pixels<<7)&0x80]; |
| 159 | } |
| 160 | } |
| 161 | } |
| 162 | break; |
| 163 | |
| 164 | case 1: // 2 bpp (3f/7f/bf/ff) |
| 165 | { |
| 166 | UINT8 *vram8 = (UINT8 *)mac_cb264_vram; |
| 167 | UINT8 pixels; |
| 168 | |
| 169 | for (y = 0; y < 480; y++) |
| 170 | { |
| 171 | scanline = BITMAP_ADDR32(bitmap, y, 0); |
| 172 | for (x = 0; x < 640/4; x++) |
| 173 | { |
| 174 | pixels = vram8[(y * 1024) + (x^3)]; |
| 175 | |
| 176 | *scanline++ = cb264_palette[pixels&0xc0]; |
| 177 | *scanline++ = cb264_palette[(pixels<<2)&0xc0]; |
| 178 | *scanline++ = cb264_palette[(pixels<<4)&0xc0]; |
| 179 | *scanline++ = cb264_palette[(pixels<<6)&0xc0]; |
| 180 | } |
| 181 | } |
| 182 | } |
| 183 | break; |
| 184 | |
| 185 | case 2: // 4 bpp |
| 186 | { |
| 187 | UINT8 *vram8 = (UINT8 *)mac_cb264_vram; |
| 188 | UINT8 pixels; |
| 189 | |
| 190 | for (y = 0; y < 480; y++) |
| 191 | { |
| 192 | scanline = BITMAP_ADDR32(bitmap, y, 0); |
| 193 | |
| 194 | for (x = 0; x < 640/2; x++) |
| 195 | { |
| 196 | pixels = vram8[(y * 1024) + (x^3)]; |
| 197 | |
| 198 | *scanline++ = cb264_palette[pixels&0xf0]; |
| 199 | *scanline++ = cb264_palette[(pixels<<4)&0xf0]; |
| 200 | } |
| 201 | } |
| 202 | } |
| 203 | break; |
| 204 | |
| 205 | case 3: // 8 bpp |
| 206 | { |
| 207 | UINT8 *vram8 = (UINT8 *)mac_cb264_vram; |
| 208 | UINT8 pixels; |
| 209 | |
| 210 | for (y = 0; y < 480; y++) |
| 211 | { |
| 212 | scanline = BITMAP_ADDR32(bitmap, y, 0); |
| 213 | |
| 214 | for (x = 0; x < 640; x++) |
| 215 | { |
| 216 | pixels = vram8[(y * 1024) + (x^3)]; |
| 217 | *scanline++ = cb264_palette[pixels]; |
| 218 | } |
| 219 | } |
| 220 | } |
| 221 | break; |
| 222 | |
| 223 | case 4: // 24 bpp |
| 224 | case 7: // ??? |
| 225 | for (y = 0; y < 480; y++) |
| 226 | { |
| 227 | scanline = BITMAP_ADDR32(bitmap, y, 0); |
| 228 | base = &mac_cb264_vram[y * 1024]; |
| 229 | for (x = 0; x < 640; x++) |
| 230 | { |
| 231 | *scanline++ = *base++; |
| 232 | } |
| 233 | } |
| 234 | break; |
| 235 | |
| 236 | default: |
| 237 | fatalerror("cb264: unknown video mode %d\n", cb264_mode); |
| 238 | break; |
| 239 | |
| 240 | } |
| 241 | |
| 242 | return 0; |
| 243 | } |
| 244 | |
| 245 | READ32_HANDLER( mac_cb264_r ) |
| 246 | { |
| 247 | switch (offset) |
| 248 | { |
| 249 | case 0x0c/4: |
| 250 | case 0x28/4: |
| 251 | break; |
| 252 | |
| 253 | case 0x34/4: |
| 254 | cb264_toggle ^= 1; |
| 255 | return cb264_toggle; // bit 0 is vblank? |
| 256 | |
| 257 | default: |
| 258 | logerror("cb264_r: reg %x (mask %x PC %x)\n", offset*4, mem_mask, cpu_get_pc(space->cpu)); |
| 259 | break; |
| 260 | } |
| 261 | |
| 262 | return 0; |
| 263 | } |
| 264 | |
| 265 | WRITE32_HANDLER( mac_cb264_w ) |
| 266 | { |
| 267 | switch (offset) |
| 268 | { |
| 269 | case 0x4/4: // 0 = 1 bpp, 1 = 2bpp, 2 = 4bpp, 3 = 8bpp, 4 = 24bpp |
| 270 | cb264_mode = data; |
| 271 | break; |
| 272 | |
| 273 | case 0x14/4: // VBL ack |
| 274 | mac_nubus_slot_interrupt(space->machine, 0xe, 0); |
| 275 | break; |
| 276 | |
| 277 | case 0x3c/4: // VBL disable |
| 278 | cb264_vbl_disable = data; |
| 279 | break; |
| 280 | |
| 281 | default: |
| 282 | // printf("cb264_w: %x to reg %x (mask %x PC %x)\n", data, offset*4, mem_mask, cpu_get_pc(space->cpu)); |
| 283 | break; |
| 284 | } |
| 285 | } |
| 286 | |
| 287 | WRITE32_HANDLER( mac_cb264_ramdac_w ) |
| 288 | { |
| 289 | switch (offset) |
| 290 | { |
| 291 | case 0: |
| 292 | cb264_clutoffs = data>>24; |
| 293 | cb264_count = 0; |
| 294 | break; |
| 295 | |
| 296 | case 1: |
| 297 | cb264_colors[cb264_count++] = data>>24; |
| 298 | |
| 299 | if (cb264_count == 3) |
| 300 | { |
| 301 | palette_set_color(space->machine, cb264_clutoffs, MAKE_RGB(cb264_colors[0], cb264_colors[1], cb264_colors[2])); |
| 302 | cb264_palette[cb264_clutoffs] = MAKE_RGB(cb264_colors[0], cb264_colors[1], cb264_colors[2]); |
| 303 | cb264_clutoffs++; |
| 304 | cb264_count = 0; |
| 305 | } |
| 306 | break; |
| 307 | |
| 308 | default: |
| 309 | // printf("%x to unknown RAMDAC register @ %x\n", data, offset); |
| 310 | break; |
| 311 | } |
| 312 | } |
| 313 | |
src/mess/machine/mac.c
| r6200 | r6201 | |
| 52 | 52 | LC 55x, LC 57x, LC 58x, Quadra 630, Quadra 660AV, Quadra 840AV, PowerMac 6100/7100/8100, |
| 53 | 53 | IIcx, IIci, and PowerMac 5200. |
| 54 | 54 | |
| 55 | | TODO: |
| 55 | ` TODO: |
| 56 | 56 | - Mac Portable and PowerBook 100 are similar to this hardware, but we need ROMs! |
| 57 | 57 | - Call the RTC timer |
| 58 | 58 | - SE FDHD and Classic require SWIM support. SWIM is IWM compatible with 800k drives, but |
| r6200 | r6201 | |
| 61 | 61 | (IM-III seems to say it does not on Mac 128k, 512k, and 512ke). |
| 62 | 62 | - What on earth are 0x700000-0x7fffff mapped to ? |
| 63 | 63 | |
| 64 | | |
| 65 | 64 | ****************************************************************************/ |
| 66 | 65 | |
| 67 | 66 | #include <time.h> |
| r6200 | r6201 | |
| 165 | 164 | static int mac_scsiirq_enable = 0; |
| 166 | 165 | |
| 167 | 166 | static UINT32 mac_via2_vbl = 0, mac_se30_vbl_enable = 0; |
| 167 | static UINT8 mac_nubus_irq_state, via2_ca1 = 0; |
| 168 | 168 | |
| 169 | 169 | // returns non-zero if this Mac has ADB |
| 170 | 170 | static int has_adb(void) |
| r6200 | r6201 | |
| 849 | 849 | scsiRd+sBSR $580050 Bus and Status Register |
| 850 | 850 | scsiRd+sIDR $580060 Input Data Register |
| 851 | 851 | scsiRd+sRESET $580070 Reset Parity/Interrupt |
| 852 | | |
| 853 | 852 | */ |
| 854 | 853 | |
| 855 | 854 | READ16_HANDLER ( macplus_scsi_r ) |
| r6200 | r6201 | |
| 868 | 867 | |
| 869 | 868 | READ32_HANDLER (macii_scsi_drq_r) |
| 870 | 869 | { |
| 871 | | return ncr5380_r(space, R5380_CURDATA_DTACK)<<24; |
| 870 | switch (mem_mask) |
| 871 | { |
| 872 | case 0xff000000: |
| 873 | return ncr5380_r(space, R5380_CURDATA_DTACK)<<24; |
| 874 | |
| 875 | case 0xffff0000: |
| 876 | return (ncr5380_r(space, R5380_CURDATA_DTACK)<<24) | (ncr5380_r(space, R5380_CURDATA_DTACK)<<16); |
| 877 | |
| 878 | case 0xffffffff: |
| 879 | return (ncr5380_r(space, R5380_CURDATA_DTACK)<<24) | (ncr5380_r(space, R5380_CURDATA_DTACK)<<16) | (ncr5380_r(space, R5380_CURDATA_DTACK)<<8) | ncr5380_r(space, R5380_CURDATA_DTACK); |
| 880 | |
| 881 | default: |
| 882 | logerror("macii_scsi_drq_r: unknown mem_mask %08x\n", mem_mask); |
| 883 | } |
| 884 | |
| 885 | return 0; |
| 872 | 886 | } |
| 873 | 887 | |
| 874 | 888 | WRITE16_HANDLER ( macplus_scsi_w ) |
| r6200 | r6201 | |
| 1147 | 1161 | case 0: case 1: case 2: case 3: /* seconds register */ |
| 1148 | 1162 | case 4: case 5: case 6: case 7: /* ??? (not described in IM III) */ |
| 1149 | 1163 | /* after various tries, I assumed rtc_seconds[4+i] is mapped to rtc_seconds[i] */ |
| 1150 | | if (LOG_RTC) |
| 1164 | if (LOG_RTC) |
| 1151 | 1165 | logerror("RTC clock write, address = %X, data = %X\n", i, (int) rtc_data_byte); |
| 1152 | 1166 | rtc_seconds[i & 3] = rtc_data_byte; |
| 1153 | 1167 | break; |
| r6200 | r6201 | |
| 1562 | 1576 | } |
| 1563 | 1577 | else |
| 1564 | 1578 | { |
| 1565 | | timer_adjust_oneshot(mac_adb_timer, attotime_make(0, DOUBLE_TO_ATTOSECONDS(0.001)), 0); |
| 1579 | timer_adjust_oneshot(mac_adb_timer, attotime_make(0, ATTOSECONDS_IN_USEC(200)), 0); |
| 1566 | 1580 | } |
| 1567 | 1581 | } |
| 1568 | 1582 | |
| r6200 | r6201 | |
| 1635 | 1649 | } |
| 1636 | 1650 | |
| 1637 | 1651 | // no matter what, generate 8 clocks (should this happen on IDLE?) |
| 1638 | | timer_adjust_oneshot(mac_adb_timer, attotime_make(0, DOUBLE_TO_ATTOSECONDS(0.001)), 0); |
| 1652 | timer_adjust_oneshot(mac_adb_timer, attotime_make(0, ATTOSECONDS_IN_USEC(100)), 0); |
| 1639 | 1653 | } |
| 1640 | 1654 | } |
| 1641 | 1655 | |
| r6200 | r6201 | |
| 1708 | 1722 | * |
| 1709 | 1723 | */ |
| 1710 | 1724 | |
| 1725 | #define PA6 0x40 |
| 1726 | #define PA4 0x10 |
| 1727 | #define PA2 0x04 |
| 1728 | #define PA1 0x02 |
| 1729 | |
| 1711 | 1730 | static READ8_DEVICE_HANDLER(mac_via_in_a) |
| 1712 | 1731 | { |
| 1713 | 1732 | // printf("VIA1 IN_A (PC %x)\n", cpu_get_pc(cputag_get_cpu(device->machine, "maincpu"))); |
| 1714 | 1733 | |
| 1715 | | if ((mac_model == MODEL_MAC_CLASSIC) || (mac_model == MODEL_MAC_LC) || |
| 1734 | if ((mac_model == MODEL_MAC_CLASSIC) || |
| 1716 | 1735 | (mac_model == MODEL_MAC_LC_II) || (mac_model == MODEL_MAC_II) || |
| 1717 | | (mac_model == MODEL_MAC_II_FDHD) || (mac_model == MODEL_MAC_IIX) || |
| 1718 | | (mac_model == MODEL_MAC_SE30)) |
| 1736 | (mac_model == MODEL_MAC_II_FDHD) || (mac_model == MODEL_MAC_IIX)) |
| 1719 | 1737 | { |
| 1720 | 1738 | return 0x81; // bit 0 must be set to avoid attempting to boot from AppleTalk |
| 1721 | 1739 | } |
| 1722 | 1740 | |
| 1741 | if (mac_model == MODEL_MAC_SE30) |
| 1742 | { |
| 1743 | return 0x81 | PA6; |
| 1744 | } |
| 1745 | |
| 1746 | if (mac_model == MODEL_MAC_LC) |
| 1747 | { |
| 1748 | return 0x81 | PA6 | PA4 | PA2; |
| 1749 | } |
| 1750 | |
| 1723 | 1751 | if (mac_model == MODEL_MAC_IICI) |
| 1724 | 1752 | { |
| 1725 | | return 0xc7; // 0x40 = IIcx/IIci/IIfx | 0x06 = IIci |
| 1753 | return 0xc7; // 0x40 = IIcx/IIci/IIfx/SE30 | 0x06 = IIci |
| 1726 | 1754 | } |
| 1727 | 1755 | |
| 1756 | if (mac_model == MODEL_MAC_IISI) |
| 1757 | { |
| 1758 | return 0x81 | PA4 | PA2 | PA1; |
| 1759 | } |
| 1760 | |
| 1728 | 1761 | if (mac_model == MODEL_MAC_IIFX) |
| 1729 | 1762 | { |
| 1730 | | return 0xc3; // 0x40 = IIcx/IIci/IIfx | 0x02 = IIfx |
| 1763 | return 0xc3; // 0x40 = IIcx/IIci/IIfx/SE30 | 0x02 = IIfx |
| 1731 | 1764 | } |
| 1732 | 1765 | |
| 1733 | 1766 | if (mac_model == MODEL_MAC_IICX) |
| r6200 | r6201 | |
| 1827 | 1860 | { |
| 1828 | 1861 | // 0x40 = 0 means enable vblank on SE/30 |
| 1829 | 1862 | mac_se30_vbl_enable = (data & 0x40) ? 0 : 1; |
| 1863 | |
| 1864 | // clear the interrupt if we disabled it |
| 1865 | if (!mac_se30_vbl_enable) |
| 1866 | { |
| 1867 | mac_nubus_slot_interrupt(device->machine, 0xe, 0); |
| 1868 | } |
| 1830 | 1869 | } |
| 1831 | 1870 | |
| 1832 | 1871 | rtc_write_rTCEnb(data & 0x04); |
| r6200 | r6201 | |
| 1905 | 1944 | const device_config *via_1 = devtag_get_device(space->machine, "via6522_1"); |
| 1906 | 1945 | |
| 1907 | 1946 | offset >>= 8; |
| 1908 | | offset &= 0x0f; |
| 1947 | offset &= 0x0f; |
| 1909 | 1948 | |
| 1910 | 1949 | if (LOG_VIA) |
| 1911 | 1950 | logerror("mac_via2_w: offset=0x%02x data=0x%08x\n", offset, data); |
| r6200 | r6201 | |
| 1917 | 1956 | |
| 1918 | 1957 | static READ8_DEVICE_HANDLER(mac_via2_in_a) |
| 1919 | 1958 | { |
| 1920 | | UINT8 result = 0xff; |
| 1959 | UINT8 result = 0xc0 | mac_nubus_irq_state; |
| 1921 | 1960 | |
| 1922 | | // logerror("VIA2 IN A (PC %x)\n", cpu_get_pc(cputag_get_cpu(device->machine, "maincpu"))); |
| 1923 | | |
| 1924 | 1961 | if ((mac_model == MODEL_MAC_IICI) || (mac_model == MODEL_MAC_IISI)) |
| 1925 | 1962 | { |
| 1926 | 1963 | result &= ~0x40; // RBV wants this clear to boot |
| 1927 | 1964 | } |
| 1928 | 1965 | |
| 1929 | | if (mac_via2_vbl) |
| 1930 | | { |
| 1931 | | result &= ~0x20; // indicate slot interrupt |
| 1932 | | } |
| 1933 | | |
| 1934 | 1966 | return result; |
| 1935 | 1967 | } |
| 1936 | 1968 | |
| r6200 | r6201 | |
| 1938 | 1970 | { |
| 1939 | 1971 | // logerror("VIA2 IN B (PC %x)\n", cpu_get_pc(cputag_get_cpu(device->machine, "maincpu"))); |
| 1940 | 1972 | |
| 1941 | | return 0xff; |
| 1973 | if (mac_model == MODEL_MAC_SE30) |
| 1974 | { |
| 1975 | return 0x87; // bits 3 and 6 are tied low on SE/30 |
| 1976 | } |
| 1977 | |
| 1978 | return 0xcf; // indicate no NuBus transaction error |
| 1942 | 1979 | } |
| 1943 | 1980 | |
| 1944 | 1981 | static WRITE8_DEVICE_HANDLER(mac_via2_out_a) |
| r6200 | r6201 | |
| 1953 | 1990 | // logerror("VIA2 OUT B: %02x (PC %x)\n", data, cpu_get_pc(cputag_get_cpu(device->machine, "maincpu"))); |
| 1954 | 1991 | |
| 1955 | 1992 | // chain 60.15 Hz to VIA1 |
| 1956 | | if ((mac_model != MODEL_MAC_IICI) && (mac_model != MODEL_MAC_IISI)) |
| 1957 | | { |
| 1958 | | via_ca1_w(via_0, 0, data>>7); |
| 1959 | | } |
| 1993 | via_ca1_w(via_0, 0, data>>7); |
| 1960 | 1994 | } |
| 1961 | 1995 | |
| 1962 | 1996 | /* ************************************************************************* |
| r6200 | r6201 | |
| 1999 | 2033 | } |
| 2000 | 2034 | |
| 2001 | 2035 | scsi_interrupt = 0; |
| 2036 | via2_ca1 = 0; |
| 2037 | mac_nubus_irq_state = 0xff; |
| 2002 | 2038 | |
| 2003 | 2039 | mac_scanline_timer = timer_alloc(machine, mac_scanline_tick, NULL); |
| 2004 | 2040 | timer_adjust_oneshot(mac_scanline_timer, video_screen_get_time_until_pos(machine->primary_screen, 0, 0), 0); |
| r6200 | r6201 | |
| 2107 | 2143 | |
| 2108 | 2144 | static const SCSIConfigTable dev_table = |
| 2109 | 2145 | { |
| 2110 | | 1, /* 2 SCSI devices */ |
| 2146 | 2, /* 2 SCSI devices */ |
| 2111 | 2147 | { |
| 2112 | | { SCSI_ID_5, "harddisk1", SCSI_DEVICE_HARDDISK }, /* SCSI ID 5, using CHD 1, and it's a harddisk */ |
| 2113 | | // { SCSI_ID_6, "harddisk2", SCSI_DEVICE_HARDDISK } /* SCSI ID 6, using CHD 0, and it's a harddisk */ |
| 2148 | { SCSI_ID_6, "harddisk1", SCSI_DEVICE_HARDDISK }, /* SCSI ID 6, using disk1, and it's a harddisk */ |
| 2149 | { SCSI_ID_5, "harddisk2", SCSI_DEVICE_HARDDISK } /* SCSI ID 5, using disk2, and it's a harddisk */ |
| 2114 | 2150 | } |
| 2115 | 2151 | }; |
| 2116 | | // 41a868 41a5ac = data copy |
| 2152 | |
| 2117 | 2153 | static const struct NCR5380interface macplus_5380intf = |
| 2118 | 2154 | { |
| 2119 | 2155 | &dev_table, // SCSI device table |
| r6200 | r6201 | |
| 2157 | 2193 | mac_driver_init(machine, MODEL_MAC_LC_II); |
| 2158 | 2194 | } |
| 2159 | 2195 | |
| 2196 | // make the appletalk init fail instead of hanging on the II FDHD/IIx/IIcx/SE30 ROM |
| 2197 | void patch_appletalk_iix(running_machine *machine) |
| 2198 | { |
| 2199 | UINT32 *ROM = (UINT32 *)memory_region(machine, "user1"); |
| 2200 | |
| 2201 | ROM[0x2cc94/4] = 0x6bbe709e; // bmi 82cc54 moveq #-$62, d0 |
| 2202 | ROM[0x370c/4] = 0x4e714e71; // nop nop - disable ROM checksum |
| 2203 | ROM[0x3710/4] = 0x4e714ed6; // nop jmp (a6) - disable ROM checksum |
| 2204 | } |
| 2205 | |
| 2160 | 2206 | DRIVER_INIT(maciicx) |
| 2161 | 2207 | { |
| 2208 | patch_appletalk_iix(machine); |
| 2162 | 2209 | mac_driver_init(machine, MODEL_MAC_IICX); |
| 2163 | 2210 | } |
| 2164 | 2211 | |
| 2165 | 2212 | DRIVER_INIT(maciifdhd) |
| 2166 | 2213 | { |
| 2214 | patch_appletalk_iix(machine); |
| 2167 | 2215 | mac_driver_init(machine, MODEL_MAC_II_FDHD); |
| 2168 | 2216 | } |
| 2169 | 2217 | |
| 2170 | 2218 | DRIVER_INIT(maciix) |
| 2171 | 2219 | { |
| 2220 | patch_appletalk_iix(machine); |
| 2172 | 2221 | mac_driver_init(machine, MODEL_MAC_IIX); |
| 2173 | 2222 | } |
| 2174 | 2223 | |
| r6200 | r6201 | |
| 2184 | 2233 | |
| 2185 | 2234 | DRIVER_INIT(macse30) |
| 2186 | 2235 | { |
| 2236 | patch_appletalk_iix(machine); |
| 2187 | 2237 | mac_driver_init(machine, MODEL_MAC_SE30); |
| 2188 | 2238 | } |
| 2189 | 2239 | |
| r6200 | r6201 | |
| 2192 | 2242 | mac_driver_init(machine, MODEL_MAC_CLASSIC_II); |
| 2193 | 2243 | } |
| 2194 | 2244 | |
| 2245 | void mac_nubus_slot_interrupt(running_machine *machine, UINT8 slot, UINT32 state) |
| 2246 | { |
| 2247 | UINT8 masks[6] = { 0x1, 0x2, 0x4, 0x8, 0x10, 0x20 }; |
| 2248 | |
| 2249 | // NuBus slot must be 9 through E |
| 2250 | assert((slot < 9) || (slot > 0xe)); |
| 2251 | |
| 2252 | slot -= 9; |
| 2253 | |
| 2254 | if (state) |
| 2255 | { |
| 2256 | mac_nubus_irq_state &= ~masks[slot]; |
| 2257 | } |
| 2258 | else |
| 2259 | { |
| 2260 | mac_nubus_irq_state |= masks[slot]; |
| 2261 | } |
| 2262 | |
| 2263 | if ((mac_nubus_irq_state & 0x3f) != 0x3f) |
| 2264 | { |
| 2265 | const device_config *via_1 = devtag_get_device(machine, "via6522_1"); |
| 2266 | |
| 2267 | via2_ca1 ^= 1; |
| 2268 | via_ca1_w(via_1, 0, via2_ca1); |
| 2269 | } |
| 2270 | } |
| 2271 | |
| 2195 | 2272 | static void mac_vblank_irq(running_machine *machine) |
| 2196 | 2273 | { |
| 2197 | 2274 | static int irq_count = 0, ca1_data = 0, ca2_data = 0; |
| r6200 | r6201 | |
| 2220 | 2297 | } |
| 2221 | 2298 | |
| 2222 | 2299 | /* signal VBlank on CA1 input on the VIA */ |
| 2223 | | if ((mac_model < MODEL_MAC_II) || (mac_model == MODEL_MAC_IICI) || (mac_model != MODEL_MAC_IISI)) |
| 2300 | if (mac_model < MODEL_MAC_II) |
| 2224 | 2301 | { |
| 2225 | 2302 | ca1_data ^= 1; |
| 2226 | 2303 | via_ca1_w(via_0, 0, ca1_data); |
| r6200 | r6201 | |
| 2237 | 2314 | rtc_incticks(); |
| 2238 | 2315 | } |
| 2239 | 2316 | |
| 2240 | | // try generating a slot interrupt every frame too |
| 2241 | | if (mac_model >= MODEL_MAC_II) |
| 2317 | // handle SE/30 vblank IRQ |
| 2318 | if (mac_model == MODEL_MAC_SE30) |
| 2242 | 2319 | { |
| 2243 | | const device_config *via_1 = devtag_get_device(machine, "via6522_1"); |
| 2244 | | |
| 2245 | | if (mac_model == MODEL_MAC_SE30) |
| 2320 | if (mac_se30_vbl_enable) |
| 2246 | 2321 | { |
| 2247 | | if (mac_se30_vbl_enable) |
| 2322 | mac_via2_vbl ^= 1; |
| 2323 | if (!mac_via2_vbl) |
| 2248 | 2324 | { |
| 2249 | | mac_via2_vbl ^= 1; |
| 2250 | | via_ca1_w(via_1, 0, mac_via2_vbl); |
| 2325 | mac_nubus_slot_interrupt(machine, 0xe, 1); |
| 2251 | 2326 | } |
| 2252 | 2327 | } |
| 2253 | | else if ((mac_model != MODEL_MAC_IICI) && (mac_model != MODEL_MAC_IISI)) |
| 2254 | | { |
| 2255 | | mac_via2_vbl ^= 1; |
| 2256 | | via_ca1_w(via_1, 0, mac_via2_vbl); |
| 2257 | | } |
| 2258 | 2328 | } |
| 2259 | 2329 | } |
| 2260 | 2330 | |
| 2261 | | |
| 2262 | | |
| 2263 | 2331 | static TIMER_CALLBACK(mac_scanline_tick) |
| 2264 | 2332 | { |
| 2265 | 2333 | int scanline; |
src/mess/drivers/mac.c
| r6200 | r6201 | |
| 35 | 35 | PB_EXT from mouse Y circuitry |
| 36 | 36 | PA_EXT from mouse X circuitry |
| 37 | 37 | |
| 38 | RBV @ 43f80, alt 48000 |
| 39 | |
| 38 | 40 | ****************************************************************************/ |
| 39 | 41 | |
| 40 | 42 | #include "driver.h" |
| r6200 | r6201 | |
| 138 | 140 | return 0x17171717; |
| 139 | 141 | } |
| 140 | 142 | |
| 141 | | /* |
| 142 | | RasterOps ColorBoard 264: fixed resolution 640x480 NuBus video card, 1/4/8/16/24 bit color |
| 143 | | 1.5? MB of VRAM (tests up to 0x1fffff), Bt473 RAMDAC, and two custom gate arrays. |
| 144 | | */ |
| 145 | | |
| 146 | | static UINT32 *cb264_vram; |
| 147 | | static UINT32 cb264_mode = 0; // 0 = true color, 2 = 1bpp monochrome, others unknown |
| 148 | | static UINT32 cb264_palette[256]; |
| 149 | | |
| 150 | | static VIDEO_START( cb264 ) |
| 151 | | { |
| 152 | | } |
| 153 | | |
| 154 | | static VIDEO_UPDATE( cb264 ) |
| 155 | | { |
| 156 | | UINT32 *scanline, *base; |
| 157 | | int x, y; |
| 158 | | |
| 159 | | if (cb264_mode == 0) |
| 160 | | { |
| 161 | | for (y = 0; y < 480; y++) |
| 162 | | { |
| 163 | | scanline = BITMAP_ADDR32(bitmap, y, 0); |
| 164 | | base = &cb264_vram[y * 1024]; |
| 165 | | for (x = 0; x < 640; x++) |
| 166 | | { |
| 167 | | *scanline++ = *base++; |
| 168 | | } |
| 169 | | } |
| 170 | | } |
| 171 | | else if (cb264_mode == 2) |
| 172 | | { |
| 173 | | UINT8 *vram8 = (UINT8 *)cb264_vram; //, *base8; |
| 174 | | UINT8 pixels; |
| 175 | | |
| 176 | | for (y = 0; y < 480; y++) |
| 177 | | { |
| 178 | | scanline = BITMAP_ADDR32(bitmap, y, 0); |
| 179 | | for (x = 0; x < 640; x+=8) |
| 180 | | { |
| 181 | | pixels = vram8[(y * 1024) + ((x/8)^3)]; |
| 182 | | |
| 183 | | *scanline++ = cb264_palette[(pixels>>7)^1]; |
| 184 | | *scanline++ = cb264_palette[((pixels>>6)&1)^1]; |
| 185 | | *scanline++ = cb264_palette[((pixels>>5)&1)^1]; |
| 186 | | *scanline++ = cb264_palette[((pixels>>4)&1)^1]; |
| 187 | | *scanline++ = cb264_palette[((pixels>>3)&1)^1]; |
| 188 | | *scanline++ = cb264_palette[((pixels>>2)&1)^1]; |
| 189 | | *scanline++ = cb264_palette[((pixels>>1)&1)^1]; |
| 190 | | *scanline++ = cb264_palette[(pixels&1)^1]; |
| 191 | | } |
| 192 | | } |
| 193 | | } |
| 194 | | else |
| 195 | | { |
| 196 | | fatalerror("cb264: unknown video mode %d\n", cb264_mode); |
| 197 | | } |
| 198 | | |
| 199 | | return 0; |
| 200 | | } |
| 201 | | |
| 202 | | static WRITE32_HANDLER( cb264_mode_w ) |
| 203 | | { |
| 204 | | cb264_mode = data; |
| 205 | | } |
| 206 | | |
| 207 | | static UINT32 cb264_toggle = 0; |
| 208 | | static READ32_HANDLER( cb264_status_r ) |
| 209 | | { |
| 210 | | cb264_toggle ^= 1; |
| 211 | | return cb264_toggle; // probably bit 0 is vblank |
| 212 | | } |
| 213 | | |
| 214 | | static UINT32 cb264_colors[3], cb264_count, cb264_clutoffs; |
| 215 | | static WRITE32_HANDLER( cb264_ramdac_w ) |
| 216 | | { |
| 217 | | if (!offset) |
| 218 | | { |
| 219 | | cb264_clutoffs = data>>24; |
| 220 | | cb264_count = 0; |
| 221 | | } |
| 222 | | else |
| 223 | | { |
| 224 | | cb264_colors[cb264_count++] = data>>24; |
| 225 | | |
| 226 | | if (cb264_count == 3) |
| 227 | | { |
| 228 | | cb264_count = 0; |
| 229 | | cb264_clutoffs++; |
| 230 | | palette_set_color(space->machine, cb264_clutoffs, MAKE_RGB(cb264_colors[0], cb264_colors[1], cb264_colors[2])); |
| 231 | | cb264_palette[cb264_clutoffs] = MAKE_RGB(cb264_colors[0], cb264_colors[1], cb264_colors[2]); |
| 232 | | } |
| 233 | | } |
| 234 | | } |
| 235 | | |
| 236 | 143 | // IIci/IIsi RAM-Based Video (RBV) |
| 237 | 144 | |
| 238 | | // 512x384x1 framebuffer at fb008000 |
| 239 | | // 640x480x1 framebuffer at fee00000 |
| 145 | // 512x384x1 framebuffer at fb008000? |
| 146 | // 640x480x1 framebuffer at fee00000? |
| 240 | 147 | |
| 241 | 148 | static UINT32 *rbv_vram; |
| 242 | 149 | |
| r6200 | r6201 | |
| 299 | 206 | int data; |
| 300 | 207 | const device_config *via_1 = devtag_get_device(space->machine, "via6522_1"); |
| 301 | 208 | |
| 302 | | // logerror("rbv_r: %x, mask %x\n", offset, mem_mask); |
| 209 | logerror("rbv_r: %x, mask %x\n", offset, mem_mask); |
| 303 | 210 | |
| 304 | 211 | if (offset == 1) |
| 305 | 212 | { |
| r6200 | r6201 | |
| 328 | 235 | { |
| 329 | 236 | const device_config *via_1 = devtag_get_device(space->machine, "via6522_1"); |
| 330 | 237 | |
| 331 | | // logerror("rbv_w: %x to offset %x, mask %x\n", data, offset, mem_mask); |
| 238 | logerror("rbv_w: %x to offset %x, mask %x\n", data, offset, mem_mask); |
| 332 | 239 | |
| 333 | 240 | offset >>= 8; |
| 334 | 241 | offset &= 0x0f; |
| r6200 | r6201 | |
| 384 | 291 | AM_RANGE(0x50f00000, 0x50f01fff) AM_READWRITE16(mac_via_r, mac_via_w, 0xffffffff) |
| 385 | 292 | AM_RANGE(0x50f02000, 0x50f03fff) AM_READWRITE16(mac_via2_r, mac_via2_w, 0xffffffff) |
| 386 | 293 | AM_RANGE(0x50f04000, 0x50f05fff) AM_READWRITE16(mac_scc_r, mac_scc_2_w, 0xffffffff) |
| 294 | AM_RANGE(0x50f06060, 0x50f06063) AM_READ(macii_scsi_drq_r) |
| 387 | 295 | |
| 388 | 296 | AM_RANGE(0x50f10000, 0x50f11fff) AM_READWRITE16(macplus_scsi_r, macii_scsi_w, 0xffffffff) |
| 389 | 297 | AM_RANGE(0x50f12060, 0x50f12063) AM_READ(macii_scsi_drq_r) |
| r6200 | r6201 | |
| 394 | 302 | AM_RANGE(0x50f40000, 0x50f41fff) AM_READWRITE16(mac_via_r, mac_via_w, 0xffffffff) // mirror |
| 395 | 303 | |
| 396 | 304 | // RasterOps 264 640x480 fixed-res color video card (8, 16, or 24 bit) |
| 397 | | AM_RANGE(0xfe000000, 0xfe1fffff) AM_RAM AM_BASE(&cb264_vram) // supposed to be 1.5 megs of VRAM, but every other word? |
| 398 | | AM_RANGE(0xfeff6018, 0xfeff601b) AM_WRITE( cb264_mode_w ) |
| 399 | | AM_RANGE(0xfeff6034, 0xfeff6037) AM_READ( cb264_status_r ) |
| 400 | | AM_RANGE(0xfeff7000, 0xfeff7007) AM_WRITE( cb264_ramdac_w ) |
| 305 | AM_RANGE(0xfe000000, 0xfe1fffff) AM_RAM AM_BASE(&mac_cb264_vram) // supposed to be 1.5 megs of VRAM, but every other word? |
| 306 | AM_RANGE(0xfeff6000, 0xfeff60ff) AM_READWRITE( mac_cb264_r, mac_cb264_w ) |
| 307 | AM_RANGE(0xfeff7000, 0xfeff7fff) AM_WRITE( mac_cb264_ramdac_w ) |
| 401 | 308 | AM_RANGE(0xfeff8000, 0xfeffffff) AM_ROM AM_REGION("rops264", 0) |
| 402 | 309 | ADDRESS_MAP_END |
| 403 | 310 | |
| r6200 | r6201 | |
| 422 | 329 | |
| 423 | 330 | AM_RANGE(0x50f00000, 0x50f01fff) AM_READWRITE16(mac_via_r, mac_via_w, 0xffffffff) |
| 424 | 331 | AM_RANGE(0x50f04000, 0x50f05fff) AM_READWRITE16(mac_scc_r, mac_scc_2_w, 0xffffffff) |
| 332 | AM_RANGE(0x50f06060, 0x50f06063) AM_READ(macii_scsi_drq_r) |
| 425 | 333 | |
| 426 | 334 | AM_RANGE(0x50f10000, 0x50f11fff) AM_READWRITE16(macplus_scsi_r, macii_scsi_w, 0xffffffff) |
| 427 | 335 | AM_RANGE(0x50f12060, 0x50f12063) AM_READ(macii_scsi_drq_r) |
| r6200 | r6201 | |
| 436 | 344 | |
| 437 | 345 | // mirror video declaration ROM |
| 438 | 346 | AM_RANGE(0xfee00000, 0xfee7ffff) AM_RAM AM_BASE(&rbv_vram) |
| 439 | | AM_RANGE(0xfeff8000, 0xfeffffff) AM_ROM AM_REGION("user1", 0x78000) |
| 347 | // AM_RANGE(0xfeff8000, 0xfeffffff) AM_ROM AM_REGION("user1", 0x78000) |
| 440 | 348 | ADDRESS_MAP_END |
| 441 | 349 | |
| 442 | 350 | static ADDRESS_MAP_START(macse30_map, ADDRESS_SPACE_PROGRAM, 32) |
| r6200 | r6201 | |
| 450 | 358 | AM_RANGE(0x50f10000, 0x50f11fff) AM_READWRITE16(macplus_scsi_r, macii_scsi_w, 0xffffffff) |
| 451 | 359 | AM_RANGE(0x50f12060, 0x50f12063) AM_READ(macii_scsi_drq_r) |
| 452 | 360 | AM_RANGE(0x50f14000, 0x50f15fff) AM_READ8(mac_asc_r, 0xffffffff) AM_WRITE8(mac_asc_w, 0xffffffff) |
| 453 | | AM_RANGE(0x50f16000, 0x50f17fff) AM_READ(mac_swim_r) AM_WRITENOP |
| 361 | AM_RANGE(0x50f16000, 0x50f17fff) AM_READWRITE16(mac_iwm_r, mac_iwm_w, 0xffffffff) |
| 454 | 362 | |
| 455 | 363 | AM_RANGE(0x50f40000, 0x50f41fff) AM_READWRITE16(mac_via_r, mac_via_w, 0xffffffff) // mirror |
| 456 | 364 | |
| r6200 | r6201 | |
| 616 | 524 | /* basic machine hardware */ |
| 617 | 525 | MDRV_CPU_ADD("maincpu", M68020_68851, 7833600*2) |
| 618 | 526 | MDRV_CPU_PROGRAM_MAP(macii_map) |
| 527 | MDRV_CPU_VBLANK_INT("screen", mac_cb264_vbl) |
| 528 | |
| 619 | 529 | MDRV_SCREEN_ADD("screen", RASTER) |
| 620 | | MDRV_SCREEN_REFRESH_RATE(60.15) |
| 621 | | MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(1260)) |
| 622 | | MDRV_QUANTUM_TIME(HZ(60)) |
| 530 | // dot clock, htotal, hstart, hend, vtotal, vstart, vend |
| 531 | MDRV_SCREEN_RAW_PARAMS(25175000, 800, 0, 640, 525, 0, 480) |
| 623 | 532 | |
| 624 | 533 | MDRV_MACHINE_START(macscsi) |
| 625 | 534 | MDRV_MACHINE_RESET( mac ) |
| r6200 | r6201 | |
| 631 | 540 | MDRV_SCREEN_VISIBLE_AREA(0, 640-1, 0, 480-1) |
| 632 | 541 | MDRV_PALETTE_LENGTH(256) |
| 633 | 542 | |
| 634 | | MDRV_VIDEO_START(cb264) |
| 635 | | MDRV_VIDEO_UPDATE(cb264) |
| 543 | MDRV_VIDEO_START(mac_cb264) |
| 544 | MDRV_VIDEO_UPDATE(mac_cb264) |
| 636 | 545 | |
| 637 | 546 | /* sound hardware */ |
| 638 | 547 | MDRV_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") |