diff options
author | 2022-07-17 22:33:22 -0400 | |
---|---|---|
committer | 2022-07-17 22:33:22 -0400 | |
commit | 6f2d0788c567c44f264864df410e1628d538a191 (patch) | |
tree | 02143eb17beef6201691ac5c1a93db3c1f0b1397 /src | |
parent | d01d1a0029872b51b9e2244e7e00caf658a90a78 (diff) |
mac.cpp: moved maciivx and maciivi to their own driver. [R. Belmont]
Diffstat (limited to 'src')
-rw-r--r-- | src/mame/apple/mac.cpp | 59 | ||||
-rw-r--r-- | src/mame/apple/mac.h | 13 | ||||
-rw-r--r-- | src/mame/apple/mac_m.cpp | 55 | ||||
-rw-r--r-- | src/mame/apple/mac_v.cpp | 137 | ||||
-rw-r--r-- | src/mame/apple/maciivx.cpp | 401 | ||||
-rw-r--r-- | src/mame/apple/vasp.cpp | 756 | ||||
-rw-r--r-- | src/mame/apple/vasp.h | 108 | ||||
-rw-r--r-- | src/mame/mame.lst | 6 |
8 files changed, 1281 insertions, 254 deletions
diff --git a/src/mame/apple/mac.cpp b/src/mame/apple/mac.cpp index adf57c066d9..391080bf2ae 100644 --- a/src/mame/apple/mac.cpp +++ b/src/mame/apple/mac.cpp @@ -7,7 +7,6 @@ TODO: - V8 and friends (LC, LC2, Classic 2, Color Classic) to own driver - - IIvx / IIvi to own driver ****************************************************************************/ @@ -461,25 +460,6 @@ void mac_state::maclc_map(address_map &map) map(0xf40000, 0xfbffff).ram().share("vram"); } -void mac_state::maclc3_map(address_map &map) -{ - map(0x40000000, 0x400fffff).rom().region("bootrom", 0).mirror(0x0ff00000); - - map(0x50000000, 0x50001fff).rw(FUNC(mac_state::mac_via_r), FUNC(mac_state::mac_via_w)).mirror(0x00f00000); - map(0x50004000, 0x50005fff).rw(FUNC(mac_state::mac_scc_r), FUNC(mac_state::mac_scc_2_w)).mirror(0x00f00000); - map(0x50006000, 0x50007fff).rw(FUNC(mac_state::macii_scsi_drq_r), FUNC(mac_state::macii_scsi_drq_w)).mirror(0x00f00000); - map(0x50010000, 0x50011fff).rw(FUNC(mac_state::macplus_scsi_r), FUNC(mac_state::macii_scsi_w)).mirror(0x00f00000); - map(0x50012000, 0x50013fff).rw(FUNC(mac_state::macii_scsi_drq_r), FUNC(mac_state::macii_scsi_drq_w)).mirror(0x00f00000); - map(0x50014000, 0x50015fff).rw(m_asc, FUNC(asc_device::read), FUNC(asc_device::write)).mirror(0x00f00000); - map(0x50016000, 0x50017fff).rw(FUNC(mac_state::mac_iwm_r), FUNC(mac_state::mac_iwm_w)).mirror(0x00f00000); - map(0x50024000, 0x50025fff).w(FUNC(mac_state::ariel_ramdac_w)).mirror(0x00f00000); - map(0x50026000, 0x50027fff).rw(FUNC(mac_state::mac_rbv_r), FUNC(mac_state::mac_rbv_w)).mirror(0x00f00000); - - map(0x5ffffffc, 0x5fffffff).r(FUNC(mac_state::mac_read_id)); - - map(0x60000000, 0x600fffff).ram().mirror(0x0ff00000).share("vram"); -} - void mac_state::macii_map(address_map &map) { map(0x40000000, 0x4003ffff).rom().region("bootrom", 0).mirror(0x0ffc0000); @@ -908,33 +888,6 @@ void mac_state::maccclas(machine_config &config) m_via1->writepb_handler().set(FUNC(mac_state::mac_via_out_b_cdadb)); } -void mac_state::maciivx(machine_config &config) -{ - maclc(config, false, true, asc_device::asc_type::VASP); - - M68030(config, m_maincpu, C32M); - m_maincpu->set_addrmap(AS_PROGRAM, &mac_state::maclc3_map); - m_maincpu->set_dasm_override(FUNC(mac_state::mac_dasm_override)); - - MCFG_VIDEO_START_OVERRIDE(mac_state,macv8) - MCFG_VIDEO_RESET_OVERRIDE(mac_state,macrbv) - - m_screen->set_screen_update(FUNC(mac_state::screen_update_macrbvvram)); - - add_nubus(config, false); - - m_ram->set_default_size("4M"); - m_ram->set_extra_options("8M,12M,16M,20M,24M,28M,32M,36M,40M,44M,48M,52M,56M,60M,64M"); - - m_egret->set_type(EGRET_341S0851); -} - -void mac_state::maciivi(machine_config &config) -{ - maciivx(config); - m_maincpu->set_clock(C15M); -} - void mac_state::maciix(machine_config &config, bool nubus_bank1, bool nubus_bank2) { macii(config, false, asc_device::asc_type::ASC, true, nubus_bank1, nubus_bank2); @@ -1161,16 +1114,6 @@ ROM_START( maciisi ) ROM_LOAD( "36b7fb6c.rom", 0x000000, 0x080000, CRC(f304d973) SHA1(f923de4125aae810796527ff6e25364cf1d54eec) ) ROM_END -ROM_START( maciivx ) - ROM_REGION32_BE(0x100000, "bootrom", 0) - ROM_LOAD( "4957eb49.rom", 0x000000, 0x100000, CRC(61be06e5) SHA1(560ce203d65178657ad09d03f532f86fa512bb40) ) -ROM_END - -ROM_START( maciivi ) - ROM_REGION32_BE(0x100000, "bootrom", 0) - ROM_LOAD( "4957eb49.rom", 0x000000, 0x100000, CRC(61be06e5) SHA1(560ce203d65178657ad09d03f532f86fa512bb40) ) -ROM_END - ROM_START( macclas2 ) ROM_REGION32_BE(0x100000, "bootrom", 0) // 3193670e //ROM_LOAD( "3193670e.rom", 0x000000, 0x080000, CRC(96d2e1fd) SHA1(50df69c1b6e805e12a405dc610bc2a1471b2eac2) ) @@ -1208,5 +1151,3 @@ COMP( 1990, maciisi, 0, 0, maciisi, maciici, mac_state, init_maci COMP( 1991, macclas2, 0, 0, macclas2, macadb, mac_state, init_macclassic2, "Apple Computer", "Macintosh Classic II", MACHINE_SUPPORTS_SAVE|MACHINE_IMPERFECT_SOUND ) COMP( 1991, maclc2, 0, 0, maclc2, maciici, mac_state, init_maclc2, "Apple Computer", "Macintosh LC II", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_SOUND ) COMP( 1993, maccclas, 0, 0, maccclas, macadb, mac_state, init_maclrcclassic, "Apple Computer", "Macintosh Color Classic", MACHINE_NOT_WORKING ) -COMP( 1993, maciivx, 0, 0, maciivx, maciici, mac_state, init_maciivx, "Apple Computer", "Macintosh IIvx", MACHINE_SUPPORTS_SAVE|MACHINE_IMPERFECT_SOUND ) -COMP( 1993, maciivi, maciivx, 0, maciivi, maciici, mac_state, init_maciivi, "Apple Computer", "Macintosh IIvi", MACHINE_SUPPORTS_SAVE|MACHINE_IMPERFECT_SOUND ) diff --git a/src/mame/apple/mac.h b/src/mame/apple/mac.h index 32e6e0ddb29..90aa578ab82 100644 --- a/src/mame/apple/mac.h +++ b/src/mame/apple/mac.h @@ -2,9 +2,9 @@ // copyright-holders:Nathan Woods, Raphael Nabet, R. Belmont /***************************************************************************** * - * includes/mac.h + * mac.h * - * Macintosh driver declarations + * Macintosh II driver declarations * ****************************************************************************/ #ifndef MAME_INCLUDES_MAC_H @@ -93,14 +93,10 @@ public: void maclc(machine_config &config, bool cpu = true, bool egret = true, asc_device::asc_type asc_type = asc_device::asc_type::V8, int woz_version = 1); void maciisi(machine_config &config); void maclc2(machine_config &config, bool egret = true, int woz_version = 1); - void maclc3(machine_config &config, bool egret = true); void macpd210(machine_config &config); void maciici(machine_config &config); void maciix(machine_config &config, bool nubus_bank1 = true, bool nubus_bank2 = true); - void maclc520(machine_config &config); - void maciivx(machine_config &config); void maccclas(machine_config &config); - void maciivi(machine_config &config); void maciicx(machine_config &config); void macse30(machine_config &config); void maciifx(machine_config &config); @@ -113,20 +109,15 @@ public: void init_maclc2(); void init_maciifdhd(); void init_macse30(); - void init_maciivx(); - void init_maciivi(); void init_macii(); void init_macclassic2(); void init_maciifx(); void init_maclc(); - void init_maclc520(); void init_maciici(); void init_maciix(); void init_maclrcclassic(); void init_maciisi(); void init_maciicx(); - void init_maclc3(); - void init_maclc3plus(); /* tells which model is being emulated (set by macxxx_init) */ enum model_t diff --git a/src/mame/apple/mac_m.cpp b/src/mame/apple/mac_m.cpp index f4d8a771f99..ebd30a177dc 100644 --- a/src/mame/apple/mac_m.cpp +++ b/src/mame/apple/mac_m.cpp @@ -2,7 +2,7 @@ // copyright-holders:Nathan Woods, Raphael Nabet, R. Belmont /**************************************************************************** - machine/mac.c + mac_m.cpp Mac II series hardware @@ -20,10 +20,8 @@ - Mac IIcx 030 SWIM MacII ADB ext NuBus card - Mac IIci 030 SWIM MacII ADB ext Internal "RBV" type - Mac IIsi 030 SWIM Egret ADB n/a Internal "RBV" type - - Mac IIvx/IIvi 030 SWIM Egret ADB n/a Internal "VASP" type - Mac LC 020 SWIM Egret ADB n/a Internal "V8" type - Mac LC II 030 SWIM Egret ADB n/a Internal "V8" type - - Mac LC III 030 SWIM Egret ADB n/a Internal "Sonora" type - Mac Classic II 030 SWIM Egret ADB n/a Internal "Eagle" type (V8 clone) - Mac Color Classic 030 SWIM Cuda ADB n/a Internal "Spice" type (V8 clone) @@ -320,7 +318,7 @@ void mac_state::set_memory_overlay(int overlay) } /* install the memory */ - if (((m_model >= MODEL_MAC_LC) && (m_model <= MODEL_MAC_COLOR_CLASSIC) && ((m_model != MODEL_MAC_LC_III) && (m_model != MODEL_MAC_LC_III_PLUS))) || (m_model == MODEL_MAC_CLASSIC_II)) + if (((m_model >= MODEL_MAC_LC) && (m_model <= MODEL_MAC_COLOR_CLASSIC)) || (m_model == MODEL_MAC_CLASSIC_II)) { m_overlay = overlay; v8_resize(); @@ -345,24 +343,10 @@ void mac_state::set_memory_overlay(int overlay) space.unmap_write(0x000000, 0x9fffff); mac_install_memory(0x000000, memory_size-1, memory_size, memory_data, is_rom); } - else if ((m_model >= MODEL_MAC_II) && (m_model <= MODEL_MAC_SE30) && (m_model != MODEL_MAC_IIVX) && (m_model != MODEL_MAC_IIVI)) + else if ((m_model >= MODEL_MAC_II) && (m_model <= MODEL_MAC_SE30)) { mac_install_memory(0x00000000, 0x3fffffff, memory_size, memory_data, is_rom); } - else if ((m_model == MODEL_MAC_IIVX) || (m_model == MODEL_MAC_IIVI) || (m_model == MODEL_MAC_LC_III) || (m_model == MODEL_MAC_LC_III_PLUS) || (m_model >= MODEL_MAC_LC_475 && m_model <= MODEL_MAC_LC_580)) // up to 36 MB - { - mac_install_memory(0x00000000, memory_size-1, memory_size, memory_data, is_rom); - - if (is_rom) - { - m_maincpu->space(AS_PROGRAM).install_read_handler(0x40000000, 0x4fffffff, read32sm_delegate(*this, FUNC(mac_state::rom_switch_r)), 0xffffffff); - } - else - { - size_t rom_mirror = 0xfffffff ^ (m_rom_size - 1); - m_maincpu->space(AS_PROGRAM).install_rom(0x40000000, 0x4fffffff & ~rom_mirror, rom_mirror, m_rom_ptr); - } - } else { mac_install_memory(0x00000000, 0x003fffff, memory_size, memory_data, is_rom); @@ -672,8 +656,6 @@ uint8_t mac_state::mac_via_in_a() case MODEL_MAC_LC: case MODEL_MAC_LC_II: - case MODEL_MAC_IIVX: - case MODEL_MAC_IIVI: return 0x81 | PA6 | PA4 | PA2; case MODEL_MAC_IICI: @@ -1064,15 +1046,7 @@ void mac_state::machine_reset() if (m_overlay_timeout != (emu_timer *)nullptr) { - if ((m_model == MODEL_MAC_LC_III) || (m_model == MODEL_MAC_LC_III_PLUS) || (m_model >= MODEL_MAC_LC_475 && m_model <= MODEL_MAC_LC_580)) // up to 36 MB - { - m_overlay_timeout->adjust(attotime::never); - } - else if (((m_model >= MODEL_MAC_LC) && (m_model <= MODEL_MAC_COLOR_CLASSIC) && ((m_model != MODEL_MAC_LC_III) && (m_model != MODEL_MAC_LC_III_PLUS))) || (m_model == MODEL_MAC_CLASSIC_II)) - { - m_overlay_timeout->adjust(attotime::never); - } - else if ((m_model >= MODEL_MAC_IIVX) && (m_model <= MODEL_MAC_IIVI)) + if (((m_model >= MODEL_MAC_LC) && (m_model <= MODEL_MAC_COLOR_CLASSIC)) || (m_model == MODEL_MAC_CLASSIC_II)) { m_overlay_timeout->adjust(attotime::never); } @@ -1138,18 +1112,9 @@ uint32_t mac_state::mac_read_id() switch (m_model) { - case MODEL_MAC_LC_III: - return 0xa55a0001; // 25 MHz LC III - - case MODEL_MAC_LC_III_PLUS: - return 0xa55a0003; // 33 MHz LC III+ - case MODEL_MAC_LC_475: return 0xa55a2221; - case MODEL_MAC_LC_520: - return 0xa55a0100; - case MODEL_MAC_LC_550: return 0xa55a0101; @@ -1177,9 +1142,6 @@ uint32_t mac_state::mac_read_id() case MODEL_MAC_QUADRA_840AV: return 0xa55a2830; - case MODEL_MAC_IIVX: - return 0xa55a2015; - default: return 0; } @@ -1202,8 +1164,8 @@ void mac_state::mac_driver_init(model_t model) memset(m_ram->pointer(), 0, m_ram->size()); - if ((model == MODEL_MAC_CLASSIC_II) || (model == MODEL_MAC_LC) || (model == MODEL_MAC_COLOR_CLASSIC) || (model >= MODEL_MAC_LC_475 && model <= MODEL_MAC_LC_580) || - (model == MODEL_MAC_LC_II) || (model == MODEL_MAC_LC_III) || (model == MODEL_MAC_LC_III_PLUS) || ((m_model >= MODEL_MAC_II) && (m_model <= MODEL_MAC_SE30))) + if ((model == MODEL_MAC_CLASSIC_II) || (model == MODEL_MAC_LC) || (model == MODEL_MAC_COLOR_CLASSIC) || + (model == MODEL_MAC_LC_II) || ((m_model >= MODEL_MAC_II) && (m_model <= MODEL_MAC_SE30))) { m_overlay_timeout = timer_alloc(FUNC(mac_state::overlay_timeout_func), this); } @@ -1224,21 +1186,16 @@ void mac_state::init_##label() \ MAC_DRIVER_INIT(maclc, MODEL_MAC_LC) MAC_DRIVER_INIT(maclc2, MODEL_MAC_LC_II) -MAC_DRIVER_INIT(maclc3, MODEL_MAC_LC_III) -MAC_DRIVER_INIT(maclc3plus, MODEL_MAC_LC_III_PLUS) MAC_DRIVER_INIT(maciici, MODEL_MAC_IICI) MAC_DRIVER_INIT(maciisi, MODEL_MAC_IISI) MAC_DRIVER_INIT(macii, MODEL_MAC_II) MAC_DRIVER_INIT(macse30, MODEL_MAC_SE30) MAC_DRIVER_INIT(macclassic2, MODEL_MAC_CLASSIC_II) MAC_DRIVER_INIT(maclrcclassic, MODEL_MAC_COLOR_CLASSIC) -MAC_DRIVER_INIT(maciivx, MODEL_MAC_IIVX) -MAC_DRIVER_INIT(maciivi, MODEL_MAC_IIVI) MAC_DRIVER_INIT(maciifx, MODEL_MAC_IIFX) MAC_DRIVER_INIT(maciicx, MODEL_MAC_IICX) MAC_DRIVER_INIT(maciifdhd, MODEL_MAC_II_FDHD) MAC_DRIVER_INIT(maciix, MODEL_MAC_IIX) -MAC_DRIVER_INIT(maclc520, MODEL_MAC_LC_520) void mac_state::nubus_slot_interrupt(uint8_t slot, uint32_t state) { diff --git a/src/mame/apple/mac_v.cpp b/src/mame/apple/mac_v.cpp index dea55dd698c..bebf10372ef 100644 --- a/src/mame/apple/mac_v.cpp +++ b/src/mame/apple/mac_v.cpp @@ -2,16 +2,12 @@ // copyright-holders:Nathan Woods, Raphael Nabet, R. Belmont /*************************************************************************** - video/mac.c + video/mac.cpp Macintosh video hardware - Emulates the video hardware for compact Macintosh series (original - Macintosh (128k, 512k, 512ke), Macintosh Plus, Macintosh SE, Macintosh - Classic) - - Also emulates on-board video for systems with the - RBV, V8, Eagle, and DAFB chips. + Emulates the video hardware for systems with the + RBV, V8, and Eagle chips. ---------------------------------------------------------------------- Monitor sense codes @@ -52,7 +48,6 @@ Apple color FPD 01 11 10 (FPD = Full Page Display) ***************************************************************************/ - #include "emu.h" #include "sound/asc.h" #include "mac.h" @@ -84,7 +79,7 @@ uint32_t mac_state::screen_update_macse30(screen_device &screen, bitmap_ind16 &b return 0; } -// IIci/IIsi RAM-Based Video (RBV) and children: V8, Eagle, Spice, VASP +// IIci/IIsi RAM-Based Video (RBV) and children: V8, Eagle, Spice VIDEO_START_MEMBER(mac_state,macrbv) { @@ -272,130 +267,6 @@ uint32_t mac_state::screen_update_macrbv(screen_device &screen, bitmap_rgb32 &bi return 0; } -uint32_t mac_state::screen_update_macrbvvram(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - int hres, vres; - switch (m_rbv_montype) - { - case 1: // 15" portrait display - hres = 640; - vres = 870; - break; - - case 2: // 12" RGB - hres = 512; - vres = 384; - break; - - case 6: // 13" RGB - default: - hres = 640; - vres = 480; - break; - } - - switch (m_rbv_regs[0x10] & 7) - { - case 0: // 1bpp - { - auto const vram8 = util::big_endian_cast<uint8_t const>(m_vram.target()); - - for (int y = 0; y < vres; y++) - { - uint32_t *scanline = &bitmap.pix(y); - for (int x = 0; x < hres; x+=8) - { - uint8_t const pixels = vram8[(y * 2048) + (x / 8)]; - - *scanline++ = m_rbv_palette[0x7f|(pixels&0x80)]; - *scanline++ = m_rbv_palette[0x7f|((pixels<<1)&0x80)]; - *scanline++ = m_rbv_palette[0x7f|((pixels<<2)&0x80)]; - *scanline++ = m_rbv_palette[0x7f|((pixels<<3)&0x80)]; - *scanline++ = m_rbv_palette[0x7f|((pixels<<4)&0x80)]; - *scanline++ = m_rbv_palette[0x7f|((pixels<<5)&0x80)]; - *scanline++ = m_rbv_palette[0x7f|((pixels<<6)&0x80)]; - *scanline++ = m_rbv_palette[0x7f|((pixels<<7)&0x80)]; - } - } - } - break; - - case 1: // 2bpp - { - auto const vram8 = util::big_endian_cast<uint8_t const>(m_vram.target()); - - for (int y = 0; y < vres; y++) - { - uint32_t *scanline = &bitmap.pix(y); - for (int x = 0; x < hres/4; x++) - { - uint8_t const pixels = vram8[(y * 2048) + x]; - - *scanline++ = m_rbv_palette[0x3f|(pixels&0xc0)]; - *scanline++ = m_rbv_palette[0x3f|((pixels<<2)&0xc0)]; - *scanline++ = m_rbv_palette[0x3f|((pixels<<4)&0xc0)]; - *scanline++ = m_rbv_palette[0x3f|((pixels<<6)&0xc0)]; - } - } - } - break; - - case 2: // 4bpp - { - auto const vram8 = util::big_endian_cast<uint8_t const>(m_vram.target()); - - for (int y = 0; y < vres; y++) - { - uint32_t *scanline = &bitmap.pix(y); - - for (int x = 0; x < hres/2; x++) - { - uint8_t const pixels = vram8[(y * 2048) + x]; - - *scanline++ = m_rbv_palette[0x0f|(pixels&0xf0)]; - *scanline++ = m_rbv_palette[0x0f|((pixels<<4)&0xf0)]; - } - } - } - break; - - case 3: // 8bpp - { - auto const vram8 = util::big_endian_cast<uint8_t const>(m_vram.target()); - - for (int y = 0; y < vres; y++) - { - uint32_t *scanline = &bitmap.pix(y); - - for (int x = 0; x < hres; x++) - { - uint8_t const pixels = vram8[(y * 2048) + x]; - *scanline++ = m_rbv_palette[pixels]; - } - } - } - break; - - case 4: // 16bpp - { - auto const vram16 = util::big_endian_cast<uint16_t const>(m_vram.target()); - - for (int y = 0; y < vres; y++) - { - uint32_t *scanline = &bitmap.pix(y); - for (int x = 0; x < hres; x++) - { - uint16_t const pixels = vram16[(y * 1024) + x]; - *scanline++ = rgb_t(((pixels >> 10) & 0x1f) << 3, ((pixels >> 5) & 0x1f) << 3, (pixels & 0x1f) << 3); - } - } - } - break; - } - - return 0; -} - uint32_t mac_state::screen_update_macv8(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { int hres, vres; diff --git a/src/mame/apple/maciivx.cpp b/src/mame/apple/maciivx.cpp new file mode 100644 index 00000000000..7934114483a --- /dev/null +++ b/src/mame/apple/maciivx.cpp @@ -0,0 +1,401 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/**************************************************************************** + + maciivx.cpp + Mac IIvx + Mac IIvi + + By R. Belmont + + These 68030 machines were the last Mac IIs, and had development rushed + after then-CEO John Sculley told MacWorld Tokyo that Apple would soon + ship machines with a built-in CD-ROM drive. + + They run on the "VASP" system ASIC, which is basically V8 with slightly + different video and the RAM size limit lifted to 68 MB. + +****************************************************************************/ + +#include "emu.h" + +#include "bus/nscsi/devices.h" +#include "bus/nubus/nubus.h" +#include "bus/nubus/cards.h" +#include "bus/rs232/rs232.h" +#include "cpu/m68000/m68000.h" +#include "machine/applefdintf.h" +#include "machine/ncr5380.h" +#include "machine/nscsi_bus.h" +#include "machine/ram.h" +#include "machine/swim1.h" +#include "machine/timer.h" +#include "machine/z80scc.h" +#include "cuda.h" +#include "egret.h" +#include "macadb.h" +#include "macscsi.h" +#include "vasp.h" + +#include "emupal.h" +#include "screen.h" +#include "softlist_dev.h" + +namespace { + +#define C32M (31.3344_MHz_XTAL) +#define C15M (C32M/2) +#define C7M (C32M/4) + +class maciivx_state : public driver_device +{ +public: + maciivx_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_macadb(*this, "macadb"), + m_ram(*this, RAM_TAG), + m_vasp(*this, "vasp"), + m_fdc(*this, "fdc"), + m_floppy(*this, "fdc:%d", 0U), + m_scsibus1(*this, "scsi"), + m_ncr5380(*this, "scsi:7:ncr5380"), + m_scsihelp(*this, "scsihelp"), + m_scc(*this, "scc"), + m_egret(*this, "egret"), + m_cur_floppy(nullptr), + m_hdsel(0) + { + } + + void maciiv_base(machine_config &config); + void maciivx(machine_config &config); + void maciivi(machine_config &config); + void base_map(address_map &map); + void maciivx_map(address_map &map); + void maciivi_map(address_map &map); + +private: + required_device<m68030_device> m_maincpu; + required_device<macadb_device> m_macadb; + required_device<ram_device> m_ram; + required_device<vasp_device> m_vasp; + required_device<applefdintf_device> m_fdc; + required_device_array<floppy_connector, 2> m_floppy; + required_device<nscsi_bus_device> m_scsibus1; + required_device<ncr5380_device> m_ncr5380; + required_device<mac_scsi_helper_device> m_scsihelp; + required_device<z80scc_device> m_scc; + required_device<egret_device> m_egret; + + virtual void machine_start() override; + + u16 scc_r(offs_t offset) + { + u16 result = m_scc->dc_ab_r(offset); + return (result << 8) | result; + } + void scc_w(offs_t offset, u16 data) + { + m_scc->dc_ab_w(offset, data >> 8); + } + + u16 scsi_r(offs_t offset, u16 mem_mask = ~0); + void scsi_w(offs_t offset, u16 data, u16 mem_mask = ~0); + u32 scsi_drq_r(offs_t offset, u32 mem_mask = ~0); + void scsi_drq_w(offs_t offset, u32 data, u32 mem_mask = ~0); + + void scsi_berr_w(u8 data) + { + m_maincpu->pulse_input_line(M68K_LINE_BUSERROR, attotime::zero); + } + + WRITE_LINE_MEMBER(cuda_reset_w) + { + m_maincpu->set_input_line(INPUT_LINE_HALT, state); + m_maincpu->set_input_line(INPUT_LINE_RESET, state); + } + + floppy_image_device *m_cur_floppy = nullptr; + int m_hdsel; + + void phases_w(uint8_t phases); + void devsel_w(uint8_t devsel); + uint16_t swim_r(offs_t offset, u16 mem_mask); + void swim_w(offs_t offset, u16 data, u16 mem_mask); + WRITE_LINE_MEMBER(hdsel_w); +}; + +void maciivx_state::machine_start() +{ + m_vasp->set_ram_info((u32 *) m_ram->pointer(), m_ram->size()); + + save_item(NAME(m_hdsel)); +} + +/*************************************************************************** + ADDRESS MAPS +***************************************************************************/ +void maciivx_state::base_map(address_map &map) +{ + // RAM, ROM, and base I/O mappings come from VASP + map(0x40000000, 0x600fffff).m(m_vasp, FUNC(vasp_device::map)); + + map(0x50004000, 0x50005fff).rw(FUNC(maciivx_state::scc_r), FUNC(maciivx_state::scc_w)).mirror(0x00f00000); + map(0x50006000, 0x50007fff).rw(FUNC(maciivx_state::scsi_drq_r), FUNC(maciivx_state::scsi_drq_w)).mirror(0x00f00000); + map(0x50010000, 0x50011fff).rw(FUNC(maciivx_state::scsi_r), FUNC(maciivx_state::scsi_w)).mirror(0x00f00000); + map(0x50012000, 0x50013fff).rw(FUNC(maciivx_state::scsi_drq_r), FUNC(maciivx_state::scsi_drq_w)).mirror(0x00f00000); + map(0x50016000, 0x50017fff).rw(FUNC(maciivx_state::swim_r), FUNC(maciivx_state::swim_w)).mirror(0x00f00000); +} + +void maciivx_state::maciivx_map(address_map &map) +{ + base_map(map); + map(0x5ffffffc, 0x5fffffff).lr32(NAME([](offs_t offset) { return 0xa55a2015; })); +} + +void maciivx_state::maciivi_map(address_map &map) +{ + base_map(map); + map(0x5ffffffc, 0x5fffffff).lr32(NAME([](offs_t offset) { return 0xa55a2016; })); +} + +u16 maciivx_state::scsi_r(offs_t offset, u16 mem_mask) +{ + const int reg = (offset >> 3) & 0xf; + const bool pseudo_dma = (reg == 6) && (offset == 0x130); + + return m_scsihelp->read_wrapper(pseudo_dma, reg) << 8; +} + +void maciivx_state::scsi_w(offs_t offset, u16 data, u16 mem_mask) +{ + const int reg = (offset >> 3) & 0xf; + const bool pseudo_dma = (reg == 0) && (offset == 0x100); + + m_scsihelp->write_wrapper(pseudo_dma, reg, data >> 8); +} + +u32 maciivx_state::scsi_drq_r(offs_t offset, u32 mem_mask) +{ + switch (mem_mask) + { + case 0xff000000: + return m_scsihelp->read_wrapper(true, 6) << 24; + + case 0xffff0000: + return (m_scsihelp->read_wrapper(true, 6) << 24) | (m_scsihelp->read_wrapper(true, 6) << 16); + + case 0xffffffff: + return (m_scsihelp->read_wrapper(true, 6) << 24) | (m_scsihelp->read_wrapper(true, 6) << 16) | (m_scsihelp->read_wrapper(true, 6) << 8) | m_scsihelp->read_wrapper(true, 6); + + default: + logerror("scsi_drq_r: unknown mem_mask %08x\n", mem_mask); + } + + return 0; +} + +void maciivx_state::scsi_drq_w(offs_t offset, u32 data, u32 mem_mask) +{ + switch (mem_mask) + { + case 0xff000000: + m_scsihelp->write_wrapper(true, 0, data >> 24); + break; + + case 0xffff0000: + m_scsihelp->write_wrapper(true, 0, data >> 24); + m_scsihelp->write_wrapper(true, 0, data >> 16); + break; + + case 0xffffffff: + m_scsihelp->write_wrapper(true, 0, data >> 24); + m_scsihelp->write_wrapper(true, 0, data >> 16); + m_scsihelp->write_wrapper(true, 0, data >> 8); + m_scsihelp->write_wrapper(true, 0, data & 0xff); + break; + + default: + logerror("scsi_drq_w: unknown mem_mask %08x\n", mem_mask); + break; + } +} + +uint16_t maciivx_state::swim_r(offs_t offset, u16 mem_mask) +{ + if (!machine().side_effects_disabled()) + { + m_maincpu->adjust_icount(-5); + } + + u16 result = m_fdc->read((offset >> 8) & 0xf); + return result << 8; +} +void maciivx_state::swim_w(offs_t offset, u16 data, u16 mem_mask) +{ + if (ACCESSING_BITS_0_7) + m_fdc->write((offset >> 8) & 0xf, data & 0xff); + else + m_fdc->write((offset >> 8) & 0xf, data >> 8); +} + +void maciivx_state::phases_w(uint8_t phases) +{ + if (m_cur_floppy) + m_cur_floppy->seek_phase_w(phases); +} + +void maciivx_state::devsel_w(uint8_t devsel) +{ + if (devsel == 1) + m_cur_floppy = m_floppy[0]->get_device(); + else if (devsel == 2) + m_cur_floppy = m_floppy[1]->get_device(); + else + m_cur_floppy = nullptr; + + m_fdc->set_floppy(m_cur_floppy); + if (m_cur_floppy) + m_cur_floppy->ss_w(m_hdsel); +} + +WRITE_LINE_MEMBER(maciivx_state::hdsel_w) +{ + if (state != m_hdsel) + { + if (m_cur_floppy) + { + m_cur_floppy->ss_w(state); + } + } + m_hdsel = state; +} + +/*************************************************************************** + DEVICE CONFIG +***************************************************************************/ + +static INPUT_PORTS_START( maciivx ) +INPUT_PORTS_END + +/*************************************************************************** + MACHINE DRIVERS +***************************************************************************/ + +void maciivx_state::maciiv_base(machine_config &config) +{ + RAM(config, m_ram); + m_ram->set_default_size("4M"); + m_ram->set_extra_options("8M,16M,32M,36M,48M,64M,68M"); + + NSCSI_BUS(config, "scsi"); + NSCSI_CONNECTOR(config, "scsi:0", mac_scsi_devices, nullptr); + NSCSI_CONNECTOR(config, "scsi:1", mac_scsi_devices, nullptr); + NSCSI_CONNECTOR(config, "scsi:2", mac_scsi_devices, nullptr); + NSCSI_CONNECTOR(config, "scsi:3", mac_scsi_devices, nullptr); + NSCSI_CONNECTOR(config, "scsi:4", mac_scsi_devices, "cdrom"); + NSCSI_CONNECTOR(config, "scsi:5", mac_scsi_devices, nullptr); + NSCSI_CONNECTOR(config, "scsi:6", mac_scsi_devices, "harddisk"); + NSCSI_CONNECTOR(config, "scsi:7").option_set("ncr5380", NCR53C80).machine_config([this](device_t *device) + { + ncr53c80_device &adapter = downcast<ncr53c80_device &>(*device); + adapter.drq_handler().set(m_scsihelp, FUNC(mac_scsi_helper_device::drq_w)); + }); + + MAC_SCSI_HELPER(config, m_scsihelp); + m_scsihelp->scsi_read_callback().set(m_ncr5380, FUNC(ncr53c80_device::read)); + m_scsihelp->scsi_write_callback().set(m_ncr5380, FUNC(ncr53c80_device::write)); + m_scsihelp->scsi_dma_read_callback().set(m_ncr5380, FUNC(ncr53c80_device::dma_r)); + m_scsihelp->scsi_dma_write_callback().set(m_ncr5380, FUNC(ncr53c80_device::dma_w)); + m_scsihelp->cpu_halt_callback().set_inputline(m_maincpu, INPUT_LINE_HALT); + m_scsihelp->timeout_error_callback().set(FUNC(maciivx_state::scsi_berr_w)); + + SOFTWARE_LIST(config, "hdd_list").set_original("mac_hdd"); + SOFTWARE_LIST(config, "flop35hd_list").set_original("mac_hdflop"); + + SCC85C30(config, m_scc, C7M); + m_scc->configure_channels(3'686'400, 3'686'400, 3'686'400, 3'686'400); + m_scc->out_int_callback().set(m_vasp, FUNC(vasp_device::scc_irq_w)); + m_scc->out_txda_callback().set("printer", FUNC(rs232_port_device::write_txd)); + m_scc->out_txdb_callback().set("modem", FUNC(rs232_port_device::write_txd)); + + rs232_port_device &rs232a(RS232_PORT(config, "printer", default_rs232_devices, nullptr)); + rs232a.rxd_handler().set(m_scc, FUNC(z80scc_device::rxa_w)); + rs232a.dcd_handler().set(m_scc, FUNC(z80scc_device::dcda_w)); + rs232a.cts_handler().set(m_scc, FUNC(z80scc_device::ctsa_w)); + + rs232_port_device &rs232b(RS232_PORT(config, "modem", default_rs232_devices, nullptr)); + rs232b.rxd_handler().set(m_scc, FUNC(z80scc_device::rxb_w)); + rs232b.dcd_handler().set(m_scc, FUNC(z80scc_device::dcdb_w)); + rs232b.cts_handler().set(m_scc, FUNC(z80scc_device::ctsb_w)); + + VASP(config, m_vasp, C15M); + m_vasp->set_maincpu_tag("maincpu"); + m_vasp->set_rom_tag(":bootrom"); + m_vasp->hdsel_callback().set(FUNC(maciivx_state::hdsel_w)); + + MACADB(config, m_macadb, C15M); + m_macadb->set_mcu_mode(true); + + nubus_device &nubus(NUBUS(config, "nubus", 0)); + nubus.set_space(m_maincpu, AS_PROGRAM); + nubus.out_irqc_callback().set(m_vasp, FUNC(vasp_device::slot0_irq_w)); + nubus.out_irqd_callback().set(m_vasp, FUNC(vasp_device::slot1_irq_w)); + nubus.out_irqe_callback().set(m_vasp, FUNC(vasp_device::slot2_irq_w)); + + NUBUS_SLOT(config, "nbc", "nubus", mac_nubus_cards, nullptr); + NUBUS_SLOT(config, "nbd", "nubus", mac_nubus_cards, nullptr); + NUBUS_SLOT(config, "nbe", "nubus", mac_nubus_cards, nullptr); + + SWIM1(config, m_fdc, C15M); + m_fdc->devsel_cb().set(FUNC(maciivx_state::devsel_w)); + m_fdc->phases_cb().set(FUNC(maciivx_state::phases_w)); + + applefdintf_device::add_35_hd(config, m_floppy[0]); + applefdintf_device::add_35_nc(config, m_floppy[1]); +} + +void maciivx_state::maciivx(machine_config &config) +{ + M68030(config, m_maincpu, C32M); + m_maincpu->set_addrmap(AS_PROGRAM, &maciivx_state::maciivx_map); + + maciiv_base(config); + + EGRET(config, m_egret, EGRET_341S0851); + m_egret->reset_callback().set(FUNC(maciivx_state::cuda_reset_w)); + m_egret->linechange_callback().set(m_macadb, FUNC(macadb_device::adb_linechange_w)); + m_egret->via_clock_callback().set(m_vasp, FUNC(vasp_device::cb1_w)); + m_egret->via_data_callback().set(m_vasp, FUNC(vasp_device::cb2_w)); + m_macadb->adb_data_callback().set(m_egret, FUNC(egret_device::set_adb_line)); + config.set_perfect_quantum(m_maincpu); + + m_vasp->pb3_callback().set(m_egret, FUNC(egret_device::get_xcvr_session)); + m_vasp->pb4_callback().set(m_egret, FUNC(egret_device::set_via_full)); + m_vasp->pb5_callback().set(m_egret, FUNC(egret_device::set_sys_session)); + m_vasp->cb2_callback().set(m_egret, FUNC(egret_device::set_via_data)); +} + +void maciivx_state::maciivi(machine_config &config) +{ + maciivx(config); + + M68030(config.replace(), m_maincpu, C15M); + m_maincpu->set_addrmap(AS_PROGRAM, &maciivx_state::maciivi_map); +} + +ROM_START(maciivx) + ROM_REGION32_BE(0x100000, "bootrom", 0) + ROM_LOAD("4957eb49.rom", 0x000000, 0x100000, CRC(61be06e5) SHA1(560ce203d65178657ad09d03f532f86fa512bb40)) +ROM_END + +ROM_START(maciivi) + ROM_REGION32_BE(0x100000, "bootrom", 0) + ROM_LOAD("4957eb49.rom", 0x000000, 0x100000, CRC(61be06e5) SHA1(560ce203d65178657ad09d03f532f86fa512bb40)) +ROM_END + +} // anonymous namespace + +COMP(1993, maciivx, 0, 0, maciivx, maciivx, maciivx_state, empty_init, "Apple Computer", "Macintosh IIvx", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND) +COMP(1993, maciivi, maciivx, 0, maciivi, maciivx, maciivx_state, empty_init, "Apple Computer", "Macintosh IIvi", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND) diff --git a/src/mame/apple/vasp.cpp b/src/mame/apple/vasp.cpp new file mode 100644 index 00000000000..43ed98b9e36 --- /dev/null +++ b/src/mame/apple/vasp.cpp @@ -0,0 +1,756 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/* + Apple "VASP Integrated Controller" system ASIC + Emulation by R. Belmont + + VASP contains the following: + - A memory controller for up to 68 MB (4 MB on the motherboard + one 64 MB SIMM) + - A VRAM controller and framebuffer controller, supporting monitor ID selection + - A full VIA (VIA1) and a "pseudo-VIA", which is basically a combination GPIO and + interrupt controller that looks somewhat like a VIA with no timers and no shift register + - An ASC-like 4-channel audio controller + - Support logic for various external subsystems (ADB, FDC, NuBus, SCC, SCSI) +*/ + +#include "emu.h" +#include "vasp.h" + +#include "formats/ap_dsk35.h" +#include "layout/generic.h" + +static constexpr u32 C7M = 7833600; +static constexpr u32 C15M = (C7M * 2); + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(VASP, vasp_device, "vasp", "Apple VASP system ASIC") + +static INPUT_PORTS_START( vasp ) + PORT_START("MONTYPE") + PORT_CONFNAME(0x0f, 0x06, "Connected monitor") + PORT_CONFSETTING( 0x01, "15\" Portrait Display (640x870)") + PORT_CONFSETTING( 0x02, "12\" RGB (512x384)") + PORT_CONFSETTING( 0x06, "13\" RGB (640x480)") +INPUT_PORTS_END + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor vasp_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( vasp ); +} + +//------------------------------------------------- +// ADDRESS_MAP +//------------------------------------------------- + +void vasp_device::map(address_map &map) +{ + map(0x00000000, 0x000fffff).r(FUNC(vasp_device::rom_switch_r)).mirror(0x0ff00000); + + map(0x10000000, 0x10001fff).rw(FUNC(vasp_device::mac_via_r), FUNC(vasp_device::mac_via_w)).mirror(0x00f00000); + map(0x10014000, 0x10015fff).rw(m_asc, FUNC(asc_device::read), FUNC(asc_device::write)).mirror(0x00f00000); + map(0x10024000, 0x10025fff).rw(FUNC(vasp_device::dac_r), FUNC(vasp_device::dac_w)).mirror(0x00f00000); + map(0x10026000, 0x10027fff).rw(FUNC(vasp_device::pseudovia_r), FUNC(vasp_device::pseudovia_w)).mirror(0x00f00000); + + map(0x20000000, 0x200fffff).ram().mirror(0x0ff00000).rw(FUNC(vasp_device::vram_r), FUNC(vasp_device::vram_w)); +} + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void vasp_device::device_add_mconfig(machine_config &config) +{ + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_raw(25175000, 800, 0, 640, 525, 0, 480); + m_screen->set_size(1024, 768); + m_screen->set_visarea(0, 640 - 1, 0, 480 - 1); + m_screen->set_screen_update(FUNC(vasp_device::screen_update)); + m_screen->screen_vblank().set(FUNC(vasp_device::vbl_w)); + config.set_default_layout(layout_monitors); + + PALETTE(config, m_palette).set_entries(256); + + R65NC22(config, m_via1, C7M / 10); + m_via1->readpa_handler().set(FUNC(vasp_device::via_in_a)); + m_via1->readpb_handler().set(FUNC(vasp_device::via_in_b)); + m_via1->writepa_handler().set(FUNC(vasp_device::via_out_a)); + m_via1->writepb_handler().set(FUNC(vasp_device::via_out_b)); + m_via1->cb2_handler().set(FUNC(vasp_device::via_out_cb2)); + m_via1->irq_handler().set(FUNC(vasp_device::via1_irq)); + + SPEAKER(config, "lspeaker").front_left(); + SPEAKER(config, "rspeaker").front_right(); + ASC(config, m_asc, C15M, asc_device::asc_type::VASP); + m_asc->add_route(0, "lspeaker", 1.0); + m_asc->add_route(1, "rspeaker", 1.0); +} + +//------------------------------------------------- +// vasp_device - constructor +//------------------------------------------------- + +vasp_device::vasp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, VASP, tag, owner, clock), + write_pb4(*this), + write_pb5(*this), + write_cb2(*this), + write_hdsel(*this), + read_pb3(*this), + m_maincpu(*this, finder_base::DUMMY_TAG), + m_montype(*this, "MONTYPE"), + m_screen(*this, "screen"), + m_palette(*this, "palette"), + m_via1(*this, "via1"), + m_asc(*this, "asc"), + m_rom(*this, finder_base::DUMMY_TAG), + m_overlay(false) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void vasp_device::device_start() +{ + m_vram = std::make_unique<u32[]>(0x100000 / sizeof(u32)); + + write_pb4.resolve_safe(); + write_pb5.resolve_safe(); + write_cb2.resolve_safe(); + write_hdsel.resolve_safe(); + read_pb3.resolve_safe(0); + + m_6015_timer = timer_alloc(FUNC(vasp_device::mac_6015_tick), this); + m_6015_timer->adjust(attotime::never); + + save_pointer(NAME(m_vram), 0x100000/sizeof(u32)); + save_item(NAME(m_via_interrupt)); + save_item(NAME(m_via2_interrupt)); + save_item(NAME(m_scc_interrupt)); + save_item(NAME(m_last_taken_interrupt)); + save_item(NAME(m_pseudovia_regs)); + save_item(NAME(m_pseudovia_ier)); + save_item(NAME(m_pseudovia_ifr)); + save_item(NAME(m_pal_address)); + save_item(NAME(m_pal_idx)); + save_item(NAME(m_pal_control)); + save_item(NAME(m_pal_colkey)); + save_item(NAME(m_overlay)); + + m_rom_ptr = &m_rom[0]; + m_rom_size = m_rom.length() << 2; +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void vasp_device::device_reset() +{ + // start 60.15 Hz timer + m_6015_timer->adjust(attotime::from_hz(60.15), 0, attotime::from_hz(60.15)); + + std::fill_n(m_pseudovia_regs, 256, 0); + m_pseudovia_regs[0] = 0x4f; + m_pseudovia_regs[1] = 0x06; + m_pseudovia_regs[2] = 0x7f; + m_pseudovia_regs[3] = 0; + m_via_interrupt = m_via2_interrupt = m_scc_interrupt = 0; + m_last_taken_interrupt = -1; + + // main cpu shouldn't start until Egret wakes it up + m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); + + m_overlay = true; + + // put ROM mirror at 0 + address_space &space = m_maincpu->space(AS_PROGRAM); + const u32 memory_size = std::min((u32)0x3fffff, m_rom_size); + const u32 memory_end = memory_size - 1; + offs_t memory_mirror = memory_end & ~(memory_size - 1); + + space.unmap_write(0x00000000, memory_end); + space.install_rom(0x00000000, memory_end & ~memory_mirror, memory_mirror, m_rom_ptr); +} + +u32 vasp_device::rom_switch_r(offs_t offset) +{ + // disable the overlay + if (m_overlay) + { + address_space &space = m_maincpu->space(AS_PROGRAM); + const u32 memory_end = m_ram_size - 1; + void *memory_data = m_ram_ptr; + offs_t memory_mirror = memory_end & ~memory_end; + + space.install_ram(0x00000000, memory_end & ~memory_mirror, memory_mirror, memory_data); + m_overlay = false; + } + + return m_rom_ptr[offset & ((m_rom_size - 1) >> 2)]; +} + +void vasp_device::set_ram_info(u32 *ram, u32 size) +{ + m_ram_ptr = ram; + m_ram_size = size; +} + +TIMER_CALLBACK_MEMBER(vasp_device::mac_6015_tick) +{ + m_via1->write_ca1(CLEAR_LINE); + m_via1->write_ca1(ASSERT_LINE); +} + +uint8_t vasp_device::via_in_a() +{ + return 0xd5; +} + +uint8_t vasp_device::via_in_b() +{ + return read_pb3() << 3; +} + +WRITE_LINE_MEMBER(vasp_device::via_out_cb2) +{ + write_cb2(state & 1); +} + +void vasp_device::via_out_a(uint8_t data) +{ + write_hdsel(BIT(data, 5)); +} + +void vasp_device::via_out_b(uint8_t data) +{ + write_pb4(BIT(data, 4)); + write_pb5(BIT(data, 5)); +} + +WRITE_LINE_MEMBER(vasp_device::via1_irq) +{ + m_via_interrupt = state; + field_interrupts(); +} + +WRITE_LINE_MEMBER(vasp_device::via2_irq) +{ + m_via2_interrupt = state; + field_interrupts(); +} + +void vasp_device::field_interrupts() +{ + int take_interrupt = -1; + + if (m_scc_interrupt) + { + take_interrupt = 4; + } + else if (m_via2_interrupt) + { + take_interrupt = 2; + } + else if (m_via_interrupt) + { + take_interrupt = 1; + } + + if (m_last_taken_interrupt > -1) + { + m_maincpu->set_input_line(m_last_taken_interrupt, CLEAR_LINE); + m_last_taken_interrupt = -1; + } + + if (take_interrupt > -1) + { + m_maincpu->set_input_line(take_interrupt, ASSERT_LINE); + m_last_taken_interrupt = take_interrupt; + } +} + +WRITE_LINE_MEMBER(vasp_device::scc_irq_w) +{ + m_scc_interrupt = (state == ASSERT_LINE); + field_interrupts(); +} + +WRITE_LINE_MEMBER(vasp_device::vbl_w) +{ + if (!state) + { + return; + } + + m_pseudovia_regs[2] &= ~0x40; // set vblank signal + + if (m_pseudovia_regs[0x12] & 0x40) + { + pseudovia_recalc_irqs(); + } +} + +WRITE_LINE_MEMBER(vasp_device::slot0_irq_w) +{ + if (state) + { + m_pseudovia_regs[2] &= ~0x08; + } + else + { + m_pseudovia_regs[2] |= 0x08; + } + + pseudovia_recalc_irqs(); +} + +WRITE_LINE_MEMBER(vasp_device::slot1_irq_w) +{ + if (state) + { + m_pseudovia_regs[2] &= ~0x10; + } + else + { + m_pseudovia_regs[2] |= 0x10; + } + + pseudovia_recalc_irqs(); +} + +WRITE_LINE_MEMBER(vasp_device::slot2_irq_w) +{ + if (state) + { + m_pseudovia_regs[2] &= ~0x20; + } + else + { + m_pseudovia_regs[2] |= 0x20; + } + + pseudovia_recalc_irqs(); +} + +void vasp_device::pseudovia_recalc_irqs() +{ + // check slot interrupts and bubble them down to IFR + uint8_t slot_irqs = (~m_pseudovia_regs[2]) & 0x78; + slot_irqs &= (m_pseudovia_regs[0x12] & 0x78); + + if (slot_irqs) + { + m_pseudovia_regs[3] |= 2; // any slot + } + else // no slot irqs, clear the pending bit + { + m_pseudovia_regs[3] &= ~2; // any slot + } + + uint8_t ifr = (m_pseudovia_regs[3] & m_pseudovia_ier) & 0x1b; + + if (ifr != 0) + { + m_pseudovia_regs[3] = ifr | 0x80; + m_pseudovia_ifr = ifr | 0x80; + + via2_irq(ASSERT_LINE); + } + else + { + via2_irq(CLEAR_LINE); + } +} + +uint8_t vasp_device::pseudovia_r(offs_t offset) +{ + int data = 0; + + if (offset < 0x100) + { + data = m_pseudovia_regs[offset]; + + if (offset == 0x10) + { + data &= ~0x38; + data |= (m_montype->read() << 3); + } + + // bit 7 of these registers always reads as 0 on pseudo-VIAs + if ((offset == 0x12) || (offset == 0x13)) + { + data &= ~0x80; + } + } + else + { + offset >>= 9; + + switch (offset) + { + case 13: // IFR + data = m_pseudovia_ifr; + break; + + case 14: // IER + data = m_pseudovia_ier; + break; + + default: + logerror("pseudovia_r: Unknown pseudo-VIA register %d access\n", offset); + break; + } + } + return data; +} + +void vasp_device::pseudovia_w(offs_t offset, uint8_t data) +{ + if (offset < 0x100) + { + switch (offset) + { + case 0x02: + m_pseudovia_regs[offset] |= (data & 0x40); + pseudovia_recalc_irqs(); + break; + + case 0x03: // write here to ack + if (data & 0x80) // 1 bits write 1s + { + m_pseudovia_regs[offset] |= data & 0x7f; + m_pseudovia_ifr |= data & 0x7f; + } + else // 1 bits write 0s + { + m_pseudovia_regs[offset] &= ~(data & 0x7f); + m_pseudovia_ifr &= ~(data & 0x7f); + } + pseudovia_recalc_irqs(); + break; + + case 0x10: + m_pseudovia_regs[offset] = data; + break; + + case 0x12: + if (data & 0x80) // 1 bits write 1s + { + m_pseudovia_regs[offset] |= data & 0x7f; + } + else // 1 bits write 0s + { + m_pseudovia_regs[offset] &= ~(data & 0x7f); + } + pseudovia_recalc_irqs(); + break; + + case 0x13: + if (data & 0x80) // 1 bits write 1s + { + m_pseudovia_regs[offset] |= data & 0x7f; + + if (data == 0xff) + m_pseudovia_regs[offset] = 0x1f; // I don't know why this is special, but the IIci ROM's POST demands it + } + else // 1 bits write 0s + { + m_pseudovia_regs[offset] &= ~(data & 0x7f); + } + break; + + default: + m_pseudovia_regs[offset] = data; + break; + } + } + else + { + offset >>= 9; + + switch (offset) + { + case 13: // IFR + if (data & 0x80) + { + data = 0x7f; + } + pseudovia_recalc_irqs(); + break; + + case 14: // IER + if (data & 0x80) // 1 bits write 1s + { + m_pseudovia_ier |= data & 0x7f; + } + else // 1 bits write 0s + { + m_pseudovia_ier &= ~(data & 0x7f); + } + pseudovia_recalc_irqs(); + break; + + default: + logerror("pseudovia_w: Unknown extended pseudo-VIA register %d access\n", offset); + break; + } + } +} + +WRITE_LINE_MEMBER(vasp_device::cb1_w) +{ + m_via1->write_cb1(state); +} + +WRITE_LINE_MEMBER(vasp_device::cb2_w) +{ + m_via1->write_cb2(state); +} + +uint16_t vasp_device::mac_via_r(offs_t offset) +{ + uint16_t data; + + offset >>= 8; + offset &= 0x0f; + + if (!machine().side_effects_disabled()) + via_sync(); + + data = m_via1->read(offset); + + return (data & 0xff) | (data << 8); +} + +void vasp_device::mac_via_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + offset >>= 8; + offset &= 0x0f; + + via_sync(); + + if (ACCESSING_BITS_0_7) + m_via1->write(offset, data & 0xff); + if (ACCESSING_BITS_8_15) + m_via1->write(offset, (data >> 8) & 0xff); +} + +void vasp_device::via_sync() +{ + // The via runs at 783.36KHz while the main cpu runs at 15MHz or + // more, so we need to sync the access with the via clock. Plus + // the whole access takes half a (via) cycle and ends when synced + // with the main cpu again. + + // Get the main cpu time + u64 cycle = m_maincpu->total_cycles(); + + // Get the number of the cycle the via is in at that time + u64 via_cycle = cycle * m_via1->clock() / m_maincpu->clock(); + + // The access is going to start at via_cycle+1 and end at + // via_cycle+1.5, compute what that means in maincpu cycles (the + // +1 rounds up, since the clocks are too different to ever be + // synced). + u64 main_cycle = (via_cycle * 2 + 3) * m_maincpu->clock() / (2 * m_via1->clock()) + 1; + + // Finally adjust the main cpu icount as needed. + m_maincpu->adjust_icount(-int(main_cycle - cycle)); +} + +u32 vasp_device::vram_r(offs_t offset) +{ + return m_vram[offset]; +} + +void vasp_device::vram_w(offs_t offset, u32 data, u32 mem_mask) +{ + COMBINE_DATA(&m_vram[offset]); +} + +u8 vasp_device::dac_r(offs_t offset) +{ + switch (offset) + { + case 2: + return m_pal_control; + + default: + return 0; + } +} + +void vasp_device::dac_w(offs_t offset, u8 data) +{ + switch (offset) + { + case 0: + m_pal_address = data; + m_pal_idx = 0; + break; + + case 1: + switch (m_pal_idx) + { + case 0: + m_palette->set_pen_red_level(m_pal_address, data); + break; + case 1: + m_palette->set_pen_green_level(m_pal_address, data); + break; + case 2: + m_palette->set_pen_blue_level(m_pal_address, data); + break; + } + m_pal_idx++; + if (m_pal_idx == 3) + { + m_pal_idx = 0; + m_pal_address++; + } + break; + + case 2: + m_pal_control = data; + break; + + case 3: + m_pal_colkey = data; + break; + } +} + +u32 vasp_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + int hres, vres; + switch (m_montype->read()) + { + case 1: // 15" portrait display + hres = 640; + vres = 870; + break; + + case 2: // 12" RGB + hres = 512; + vres = 384; + break; + + case 6: // 13" RGB + default: + hres = 640; + vres = 480; + break; + } + + const pen_t *pens = m_palette->pens(); + + switch (m_pseudovia_regs[0x10] & 7) + { + case 0: // 1bpp + { + auto const vram8 = util::big_endian_cast<uint8_t const>(&m_vram[0]); + + for (int y = 0; y < vres; y++) + { + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < hres; x += 8) + { + uint8_t const pixels = vram8[(y * 2048) + (x / 8)]; + + *scanline++ = pens[0x7f | (pixels & 0x80)]; + *scanline++ = pens[0x7f | ((pixels << 1) & 0x80)]; + *scanline++ = pens[0x7f | ((pixels << 2) & 0x80)]; + *scanline++ = pens[0x7f | ((pixels << 3) & 0x80)]; + *scanline++ = pens[0x7f | ((pixels << 4) & 0x80)]; + *scanline++ = pens[0x7f | ((pixels << 5) & 0x80)]; + *scanline++ = pens[0x7f | ((pixels << 6) & 0x80)]; + *scanline++ = pens[0x7f | ((pixels << 7) & 0x80)]; + } + } + } + break; + + case 1: // 2bpp + { + auto const vram8 = util::big_endian_cast<uint8_t const>(&m_vram[0]); + + for (int y = 0; y < vres; y++) + { + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < hres / 4; x++) + { + uint8_t const pixels = vram8[(y * 2048) + x]; + + *scanline++ = pens[0x3f | (pixels & 0xc0)]; + *scanline++ = pens[0x3f | ((pixels << 2) & 0xc0)]; + *scanline++ = pens[0x3f | ((pixels << 4) & 0xc0)]; + *scanline++ = pens[0x3f | ((pixels << 6) & 0xc0)]; + } + } + } + break; + + case 2: // 4bpp + { + auto const vram8 = util::big_endian_cast<uint8_t const>(&m_vram[0]); + + for (int y = 0; y < vres; y++) + { + uint32_t *scanline = &bitmap.pix(y); + + for (int x = 0; x < hres / 2; x++) + { + uint8_t const pixels = vram8[(y * 2048) + x]; + + *scanline++ = pens[0x0f | (pixels & 0xf0)]; + *scanline++ = pens[0x0f | ((pixels << 4) & 0xf0)]; + } + } + } + break; + + case 3: // 8bpp + { + auto const vram8 = util::big_endian_cast<uint8_t const>(&m_vram[0]); + + for (int y = 0; y < vres; y++) + { + uint32_t *scanline = &bitmap.pix(y); + + for (int x = 0; x < hres; x++) + { + uint8_t const pixels = vram8[(y * 2048) + x]; + *scanline++ = pens[pixels]; + } + } + } + break; + + case 4: // 16bpp + { + auto const vram16 = util::big_endian_cast<uint16_t const>(&m_vram[0]); + + for (int y = 0; y < vres; y++) + { + uint32_t *scanline = &bitmap.pix(y); + for (int x = 0; x < hres; x++) + { + uint16_t const pixels = vram16[(y * 1024) + x]; + *scanline++ = rgb_t(((pixels >> 10) & 0x1f) << 3, ((pixels >> 5) & 0x1f) << 3, (pixels & 0x1f) << 3); + } + } + } + break; + } + + return 0; +} diff --git a/src/mame/apple/vasp.h b/src/mame/apple/vasp.h new file mode 100644 index 00000000000..ec1cfb16714 --- /dev/null +++ b/src/mame/apple/vasp.h @@ -0,0 +1,108 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont + +#ifndef MAME_APPLE_VASP_H +#define MAME_APPLE_VASP_H + +#pragma once + +#include "machine/6522via.h" +#include "sound/asc.h" +#include "emupal.h" +#include "speaker.h" +#include "screen.h" + +// ======================> vasp_device + +class vasp_device : public device_t +{ +public: + // construction/destruction + vasp_device(const machine_config &mconfig, const char *tag, device_t *owner) + : vasp_device(mconfig, tag, owner, (uint32_t)0) + { + } + + vasp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // interface routines + auto pb4_callback() { return write_pb4.bind(); } + auto pb5_callback() { return write_pb5.bind(); } + auto cb2_callback() { return write_cb2.bind(); } + auto hdsel_callback() { return write_hdsel.bind(); } + auto pb3_callback() { return read_pb3.bind(); } + + void map(address_map &map); + + template <typename... T> void set_maincpu_tag(T &&... args) { m_maincpu.set_tag(std::forward<T>(args)...); } + template <typename... T> void set_rom_tag(T &&... args) { m_rom.set_tag(std::forward<T>(args)...); } + void set_ram_info(u32 *ram, u32 size); + + DECLARE_WRITE_LINE_MEMBER(cb1_w); + DECLARE_WRITE_LINE_MEMBER(cb2_w); + DECLARE_WRITE_LINE_MEMBER(vbl_w); + DECLARE_WRITE_LINE_MEMBER(scc_irq_w); + DECLARE_WRITE_LINE_MEMBER(slot0_irq_w); + DECLARE_WRITE_LINE_MEMBER(slot1_irq_w); + DECLARE_WRITE_LINE_MEMBER(slot2_irq_w); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + virtual void device_add_mconfig(machine_config &config) override; + virtual ioport_constructor device_input_ports() const override; + +private: + devcb_write_line write_pb4, write_pb5, write_cb2, write_hdsel; + devcb_read_line read_pb3; + + required_device<cpu_device> m_maincpu; + required_ioport m_montype; + required_device<screen_device> m_screen; + required_device<palette_device> m_palette; + required_device<via6522_device> m_via1; + required_device<asc_device> m_asc; + required_region_ptr<u32> m_rom; + + std::unique_ptr<u32[]> m_vram; + emu_timer *m_6015_timer; + int m_via_interrupt, m_via2_interrupt, m_scc_interrupt, m_last_taken_interrupt; + u8 m_pseudovia_regs[256], m_pseudovia_ier, m_pseudovia_ifr; + u8 m_pal_address, m_pal_idx, m_pal_control, m_pal_colkey; + bool m_overlay; + u32 *m_ram_ptr, *m_rom_ptr; + u32 m_ram_size, m_rom_size; + + u32 rom_switch_r(offs_t offset); + + uint8_t pseudovia_r(offs_t offset); + void pseudovia_w(offs_t offset, uint8_t data); + void pseudovia_recalc_irqs(); + + uint16_t mac_via_r(offs_t offset); + void mac_via_w(offs_t offset, uint16_t data, uint16_t mem_mask); + + uint8_t via_in_a(); + uint8_t via_in_b(); + void via_out_a(uint8_t data); + void via_out_b(uint8_t data); + void via_sync(); + void field_interrupts(); + DECLARE_WRITE_LINE_MEMBER(via_out_cb2); + DECLARE_WRITE_LINE_MEMBER(via1_irq); + DECLARE_WRITE_LINE_MEMBER(via2_irq); + TIMER_CALLBACK_MEMBER(mac_6015_tick); + + u32 vram_r(offs_t offset); + void vram_w(offs_t offset, u32 data, u32 mem_mask); + u8 dac_r(offs_t offset); + void dac_w(offs_t offset, u8 data); + + u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); +}; + +// device type definition +DECLARE_DEVICE_TYPE(VASP, vasp_device) + +#endif // MAME_APPLE_VASP_H diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 1cb0b584426..0496e9c8bb1 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -20734,13 +20734,15 @@ maciicx // 1989 Apple Macintosh IIcx maciifx // 1990 Apple Macintosh IIfx maciihmu // 1987 Apple Macintosh II (w/o 68851 MMU) maciisi // 1990 Apple Macintosh IIsi -maciivi // 1993 Apple Macintosh IIvi -maciivx // 1993 Apple Macintosh IIvx maciix // 1988 Apple Macintosh IIx maclc // 1990 Apple Macintosh LC maclc2 // 1991 Apple Macintosh LC II macse30 // 1989 Apple Macintosh SE/30 +@source:apple/maciivx.cpp +maciivx // 1993 Apple Macintosh IIvx +maciivi // 1993 Apple Macintosh IIvi + @source:apple/maclc3.cpp maclc3 // 1993 Apple Macintosh LC III maclc520 // 1993 Apple Macintosh LC 520 |