diff --git a/src/mame/apple/mac.cpp b/src/mame/apple/mac.cpp index 8cd53fbc440..55ab3bb1707 100644 --- a/src/mame/apple/mac.cpp +++ b/src/mame/apple/mac.cpp @@ -7,7 +7,6 @@ TODO: - Move RBV machines (IIci/IIsi) to separate driver? - - Move IIfx to separate driver? - Rewrite this driver in the newer (maclc3/maciivx/maclc) style as macii.cpp? ****************************************************************************/ @@ -23,7 +22,6 @@ #include "cpu/m68000/m68020.h" #include "cpu/m68000/m68030.h" #include "cpu/m6805/m6805.h" -#include "machine/applepic.h" #include "machine/iwm.h" #include "machine/swim1.h" #include "machine/swim2.h" @@ -288,96 +286,6 @@ uint16_t mac_state::mac_config_r() return 0xffff; // returns nonzero if no PDS RAM expansion, 0 if present } -// IIfx -uint32_t mac_state::biu_r(offs_t offset, uint32_t mem_mask) -{ -// printf("biu_r @ %x, mask %08x\n", offset, mem_mask); - return 0; -} - -void mac_state::biu_w(offs_t offset, uint32_t data, uint32_t mem_mask) -{ -// printf("biu_w %x @ %x, mask %08x\n", data, offset, mem_mask); -} - -template WRITE_LINE_MEMBER(mac_state::oss_interrupt) -{ - if (state == ASSERT_LINE) - m_oss_regs[N >= 8 ? 0x202 : 0x203] |= 1 << (N & 7); - else - m_oss_regs[N >= 8 ? 0x202 : 0x203] &= ~(1 << (N & 7)); - - int take_interrupt = 0; - for (int n = 0; n < 8; n++) - { - if (BIT(m_oss_regs[0x203], n) && take_interrupt < m_oss_regs[n]) - take_interrupt = m_oss_regs[n]; - if (BIT(m_oss_regs[0x202], n) && take_interrupt < m_oss_regs[8 + n]) - take_interrupt = m_oss_regs[8 + n]; - } - - if (m_last_taken_interrupt > -1) - { - m_maincpu->set_input_line(m_last_taken_interrupt, CLEAR_LINE); - m_last_taken_interrupt = -1; - m_oss_regs[0x200] &= 0x7f; - } - - if (take_interrupt > 0) - { - m_maincpu->set_input_line(take_interrupt, ASSERT_LINE); - m_last_taken_interrupt = take_interrupt; - m_oss_regs[0x200] |= 0x80; - } -} - -TIMER_CALLBACK_MEMBER(mac_state::oss_6015_tick) -{ - m_via1->write_ca1(0); - m_via1->write_ca1(1); - oss_interrupt<10>(ASSERT_LINE); -} - -uint8_t mac_state::oss_r(offs_t offset) -{ -// printf("oss_r @ %x\n", offset); -// if (offset <= 0xe) // for interrupt mask registers, we're intended to return something different than is written in the low 3 bits (?) -// { -// return m_oss_regs[offset]<<4; -// } - - if (offset < std::size(m_oss_regs)) - return m_oss_regs[offset]; - else - return 0; -} - -void mac_state::oss_w(offs_t offset, uint8_t data) -{ -// printf("oss_w %x @ %x\n", data, offset); - if (offset == 0x207) - oss_interrupt<10>(CLEAR_LINE); - else if (offset < std::size(m_oss_regs)) - m_oss_regs[offset] = data; -} - -uint32_t mac_state::buserror_r() -{ - m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE); - m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE); - return 0; -} - -uint8_t mac_state::maciifx_8010_r() -{ - return 0x40; -} - -uint8_t mac_state::maciifx_8040_r() -{ - return 0; -} - /*************************************************************************** ADDRESS MAPS ***************************************************************************/ @@ -434,28 +342,6 @@ void mac_state::macse30_map(address_map &map) map(0xfeffe000, 0xfeffffff).rom().region("se30vrom", 0x0); } -void mac_state::maciifx_map(address_map &map) -{ - map(0x40000000, 0x4007ffff).rom().region("bootrom", 0).mirror(0x0ff80000); - - map(0x50000000, 0x50001fff).rw(FUNC(mac_state::mac_via_r), FUNC(mac_state::mac_via_w)).mirror(0x00f00000); - map(0x50004000, 0x50005fff).rw("sccpic", FUNC(applepic_device::host_r), FUNC(applepic_device::host_w)).mirror(0x00f00000).umask32(0xff00ff00); - map(0x50004000, 0x50005fff).rw("sccpic", FUNC(applepic_device::host_r), FUNC(applepic_device::host_w)).mirror(0x00f00000).umask32(0x00ff00ff); - map(0x50008010, 0x50008010).r(FUNC(mac_state::maciifx_8010_r)).mirror(0x00f00000); - map(0x50008040, 0x50008040).r(FUNC(mac_state::maciifx_8040_r)).mirror(0x00f00000); - map(0x5000a000, 0x5000bfff).rw(FUNC(mac_state::macplus_scsi_r), FUNC(mac_state::macii_scsi_w)).mirror(0x00f00000); - map(0x5000c060, 0x5000c063).r(FUNC(mac_state::macii_scsi_drq_r)).mirror(0x00f00000); - map(0x5000d000, 0x5000d003).w(FUNC(mac_state::macii_scsi_drq_w)).mirror(0x00f00000); - map(0x5000d060, 0x5000d063).r(FUNC(mac_state::macii_scsi_drq_r)).mirror(0x00f00000); - map(0x50010000, 0x50011fff).rw(m_asc, FUNC(asc_device::read), FUNC(asc_device::write)).mirror(0x00f00000); - map(0x50012000, 0x50013fff).rw("swimpic", FUNC(applepic_device::host_r), FUNC(applepic_device::host_w)).mirror(0x00f00000).umask32(0xff00ff00); - map(0x50012000, 0x50013fff).rw("swimpic", FUNC(applepic_device::host_r), FUNC(applepic_device::host_w)).mirror(0x00f00000).umask32(0x00ff00ff); - map(0x50018000, 0x50019fff).rw(FUNC(mac_state::biu_r), FUNC(mac_state::biu_w)).mirror(0x00f00000); - map(0x5001a000, 0x5001bfff).rw(FUNC(mac_state::oss_r), FUNC(mac_state::oss_w)).mirror(0x00f00000); - map(0x50024000, 0x50027fff).r(FUNC(mac_state::buserror_r)).mirror(0x00f00000); // must bus error on access here so ROM can determine we're an FMC - map(0x50040000, 0x50041fff).rw(FUNC(mac_state::mac_via_r), FUNC(mac_state::mac_via_w)).mirror(0x00f00000); -} - /*************************************************************************** MACHINE DRIVERS ***************************************************************************/ @@ -673,64 +559,6 @@ void mac_state::maciihd(machine_config &config) SOFTWARE_LIST(config, "flop35hd_list").set_original("mac_hdflop"); } -void mac_state::maciifx(machine_config &config) -{ - /* basic machine hardware */ - M68030(config, m_maincpu, 40000000); - m_maincpu->set_addrmap(AS_PROGRAM, &mac_state::maciifx_map); - m_maincpu->set_dasm_override(std::function(&mac68k_dasm_override), "mac68k_dasm_override"); - - add_asc(config, asc_device::asc_type::ASC); - add_base_devices(config, true, 1); - add_scsi(config); - - m_asc->irqf_callback().set(FUNC(mac_state::oss_interrupt<8>)); - subdevice("scsi:7")->set_option_machine_config("ncr5380", [this](device_t *device) { - ncr53c80_device &adapter = downcast(*device); - adapter.irq_handler().set(*this, FUNC(mac_state::oss_interrupt<9>)); - adapter.drq_handler().set(m_scsihelp, FUNC(mac_scsi_helper_device::drq_w)); - }); - - R65NC22(config, m_via1, C7M/10); - m_via1->readpa_handler().set(FUNC(mac_state::mac_via_in_a)); - m_via1->readpb_handler().set(FUNC(mac_state::mac_via_in_b_ii)); - m_via1->writepa_handler().set(FUNC(mac_state::mac_via_out_a)); - m_via1->writepb_handler().set(FUNC(mac_state::mac_via_out_b)); - m_via1->cb2_handler().set(FUNC(mac_state::mac_adb_via_out_cb2)); - m_via1->irq_handler().set(FUNC(mac_state::oss_interrupt<11>)); - - applepic_device &sccpic(APPLEPIC(config, "sccpic", C15M)); - sccpic.prd_callback().set(m_scc, FUNC(scc8530_legacy_device::reg_r)); - sccpic.pwr_callback().set(m_scc, FUNC(scc8530_legacy_device::reg_w)); - sccpic.hint_callback().set(FUNC(mac_state::oss_interrupt<7>)); - - m_scc->intrq_callback().set("sccpic", FUNC(applepic_device::pint_w)); - //m_scc->dtr_reqa_callback().set("sccpic", FUNC(applepic_device::reqa_w)); - //m_scc->dtr_reqb_callback().set("sccpic", FUNC(applepic_device::reqb_w)); - - applepic_device &swimpic(APPLEPIC(config, "swimpic", C15M)); - swimpic.prd_callback().set(m_fdc, FUNC(applefdintf_device::read)); - swimpic.pwr_callback().set(m_fdc, FUNC(applefdintf_device::write)); - swimpic.hint_callback().set(FUNC(mac_state::oss_interrupt<6>)); - - m_fdc->dat1byte_cb().set("swimpic", FUNC(applepic_device::reqa_w)); - - RAM(config, m_ram); - m_ram->set_default_size("4M"); - m_ram->set_extra_options("8M,16M,32M,64M,96M,128M"); - - SOFTWARE_LIST(config, "flop35_list").set_original("mac_flop"); - - add_nubus(config); - nubus_device &nubus(*subdevice("nubus")); - nubus.out_irq9_callback().set(FUNC(mac_state::oss_interrupt<0>)); - nubus.out_irqa_callback().set(FUNC(mac_state::oss_interrupt<1>)); - nubus.out_irqb_callback().set(FUNC(mac_state::oss_interrupt<2>)); - nubus.out_irqc_callback().set(FUNC(mac_state::oss_interrupt<3>)); - nubus.out_irqd_callback().set(FUNC(mac_state::oss_interrupt<4>)); - nubus.out_irqe_callback().set(FUNC(mac_state::oss_interrupt<5>)); -} - 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); @@ -935,11 +763,6 @@ ROM_START( macse30 ) ROM_LOAD( "se30vrom.uk6", 0x000000, 0x002000, CRC(b74c3463) SHA1(584201cc67d9452b2488f7aaaf91619ed8ce8f03) ) ROM_END -ROM_START( maciifx ) - ROM_REGION32_BE(0x80000, "bootrom", 0) - ROM_LOAD( "4147dd77.rom", 0x000000, 0x080000, CRC(ef441bbd) SHA1(9fba3d4f672a630745d65788b1d1119afa2c6728) ) -ROM_END - ROM_START( maciici ) ROM_REGION32_BE(0x80000, "bootrom", 0) ROM_LOAD32_BYTE( "341-0736.um12", 0x000000, 0x020000, CRC(7a1906e6) SHA1(3e39c80b52f40798502fcbdfc97b315545c4c4d3) ) @@ -961,5 +784,4 @@ COMP( 1988, maciix, mac2fdhd, 0, maciix, macadb, mac_state, init_maci COMP( 1989, macse30, mac2fdhd, 0, macse30, macadb, mac_state, init_macse30, "Apple Computer", "Macintosh SE/30", MACHINE_SUPPORTS_SAVE ) COMP( 1989, maciicx, mac2fdhd, 0, maciicx, macadb, mac_state, init_maciicx, "Apple Computer", "Macintosh IIcx", MACHINE_SUPPORTS_SAVE ) COMP( 1989, maciici, 0, 0, maciici, maciici, mac_state, init_maciici, "Apple Computer", "Macintosh IIci", MACHINE_SUPPORTS_SAVE ) -COMP( 1990, maciifx, 0, 0, maciifx, macadb, mac_state, init_maciifx, "Apple Computer", "Macintosh IIfx", MACHINE_NOT_WORKING ) COMP( 1990, maciisi, 0, 0, maciisi, maciici, mac_state, init_maciisi, "Apple Computer", "Macintosh IIsi", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/apple/mac.h b/src/mame/apple/mac.h index 64f63f14c61..37c08a9003a 100644 --- a/src/mame/apple/mac.h +++ b/src/mame/apple/mac.h @@ -92,7 +92,6 @@ public: void maciix(machine_config &config, bool nubus_bank1 = true, bool nubus_bank2 = true); void maciicx(machine_config &config); void macse30(machine_config &config); - void maciifx(machine_config &config); void macii(machine_config &config, bool cpu = true, asc_device::asc_type asc_type = asc_device::asc_type::ASC, bool nubus = true, bool nubus_bank1 = true, bool nubus_bank2 = true, int woz_version = 0); void maciihmu(machine_config &config); @@ -101,7 +100,6 @@ public: void init_maciifdhd(); void init_macse30(); void init_macii(); - void init_maciifx(); void init_maciici(); void init_maciix(); void init_maciisi(); @@ -116,7 +114,6 @@ public: MODEL_MAC_IICX, MODEL_MAC_IICI, MODEL_MAC_IISI, - MODEL_MAC_IIFX, MODEL_MAC_SE30 }; @@ -217,16 +214,6 @@ private: uint16_t mac_config_r(); - uint32_t biu_r(offs_t offset, uint32_t mem_mask = ~0); - void biu_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - template DECLARE_WRITE_LINE_MEMBER(oss_interrupt); - TIMER_CALLBACK_MEMBER(oss_6015_tick); - uint8_t oss_r(offs_t offset); - void oss_w(offs_t offset, uint8_t data); - uint32_t buserror_r(); - uint8_t maciifx_8010_r(); - uint8_t maciifx_8040_r(); - DECLARE_WRITE_LINE_MEMBER(nubus_irq_9_w); DECLARE_WRITE_LINE_MEMBER(nubus_irq_a_w); DECLARE_WRITE_LINE_MEMBER(nubus_irq_b_w); @@ -241,11 +228,8 @@ private: void macii_map(address_map &map); void maciici_map(address_map &map); - void maciifx_map(address_map &map); void macse30_map(address_map &map); - uint8_t m_oss_regs[0x400]{}; - int m_via2_ca1_hack = 0; optional_device m_screen; optional_device m_palette; diff --git a/src/mame/apple/mac_m.cpp b/src/mame/apple/mac_m.cpp index cf6ba0f5d08..1362a279b06 100644 --- a/src/mame/apple/mac_m.cpp +++ b/src/mame/apple/mac_m.cpp @@ -15,7 +15,6 @@ CPU FDC Kbd/Mouse PRAM Video - Mac II 020 IWM MacII ADB ext NuBus card - Mac IIx 030 SWIM MacII ADB ext NuBus card - - Mac IIfx 030 SWIM IOP ADB ext NuBus card - Mac SE/30 030 SWIM MacII ADB ext Internal fake NuBus card - Mac IIcx 030 SWIM MacII ADB ext NuBus card - Mac IIci 030 SWIM MacII ADB ext Internal "RBV" type @@ -101,24 +100,17 @@ void mac_state::field_interrupts() { int take_interrupt = -1; - if (m_model != MODEL_MAC_IIFX) + if (m_scc_interrupt) { - if (m_scc_interrupt) - { - take_interrupt = 4; - } - else if (m_via2_interrupt) - { - take_interrupt = 2; - } - else if (m_via_interrupt) - { - take_interrupt = 1; - } + take_interrupt = 4; } - else + else if (m_via2_interrupt) { - return; // no interrupts for IIfx yet + take_interrupt = 2; + } + else if (m_via_interrupt) + { + take_interrupt = 1; } if (m_last_taken_interrupt > -1) @@ -168,7 +160,7 @@ WRITE_LINE_MEMBER(mac_state::mac_asc_irq) rbv_recalc_irqs(); } } - else if (m_model != MODEL_MAC_IIFX) + else { m_via2->write_cb1(state^1); } @@ -245,12 +237,6 @@ void mac_state::set_memory_overlay(int overlay) mac_install_memory(0x40000000, 0x4007ffff, memory_size, memory_data, is_rom); } } - else if (m_model == MODEL_MAC_IIFX) - { - address_space& space = m_maincpu->space(AS_PROGRAM); - 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)) { mac_install_memory(0x00000000, 0x3fffffff, memory_size, memory_data, is_rom); @@ -559,9 +545,6 @@ uint8_t mac_state::mac_via_in_a() case MODEL_MAC_IISI: return 0x81 | PA4 | PA2 | PA1; - case MODEL_MAC_IIFX: - return 0x81 | PA6 | PA4 | PA1; - case MODEL_MAC_IICX: return 0x81 | PA6; @@ -844,10 +827,7 @@ void mac_state::machine_start() m_adbupdate_timer->adjust(attotime::from_hz(70)); } - if (m_model != MODEL_MAC_IIFX) - m_6015_timer = timer_alloc(FUNC(mac_state::mac_6015_tick), this); - else - m_6015_timer = timer_alloc(FUNC(mac_state::oss_6015_tick), this); + m_6015_timer = timer_alloc(FUNC(mac_state::mac_6015_tick), this); m_6015_timer->adjust(attotime::never); save_item(NAME(m_nubus_irq_state)); @@ -869,7 +849,6 @@ void mac_state::machine_start() save_item(NAME(m_via2_interrupt)); save_item(NAME(m_scsi_interrupt)); save_item(NAME(m_last_taken_interrupt)); - save_item(NAME(m_oss_regs)); save_item(NAME(m_via2_ca1_hack)); } @@ -890,7 +869,7 @@ void mac_state::machine_reset() } // start 60.15 Hz timer for most systems - if ((m_model >= MODEL_MAC_IICI) && (m_model <= MODEL_MAC_IIFX)) + if ((m_model >= MODEL_MAC_IICI) && (m_model <= MODEL_MAC_IISI)) { m_6015_timer->adjust(attotime::from_hz(60.15), 0, attotime::from_hz(60.15)); } @@ -909,12 +888,9 @@ void mac_state::machine_reset() /* setup videoram */ this->m_screen_buffer = 1; - if (m_model != MODEL_MAC_IIFX) // prime CB1 for ASC and slot interrupts - { - m_via2_ca1_hack = 1; - m_via2->write_ca1(1); - m_via2->write_cb1(1); - } + m_via2_ca1_hack = 1; + m_via2->write_ca1(1); + m_via2->write_cb1(1); m_scsi_interrupt = 0; @@ -996,7 +972,6 @@ 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(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) @@ -1017,7 +992,7 @@ void mac_state::nubus_slot_interrupt(uint8_t slot, uint32_t state) m_nubus_irq_state |= masks[slot]; } - if ((m_model != MODEL_MAC_IIFX) && (!INTS_RBV)) + if (!INTS_RBV) { if ((m_nubus_irq_state & mask) != mask) { diff --git a/src/mame/apple/maciifx.cpp b/src/mame/apple/maciifx.cpp new file mode 100644 index 00000000000..32c54d1b7e6 --- /dev/null +++ b/src/mame/apple/maciifx.cpp @@ -0,0 +1,607 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/**************************************************************************** + + maciifx.cpp + Mac IIfx + + By R. Belmont + + This was the fastest 68030 Mac, with a 40 MHz clock speed and 2 65C02 + coprocessors plus DMA capability. MacOS used almost none of the extra + hardware so the machine never reached its full potential. + +****************************************************************************/ + +#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/m68030.h" +#include "machine/6522via.h" +#include "machine/8530scc.h" +#include "machine/applefdintf.h" +#include "machine/applepic.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 "sound/asc.h" +#include "macadb.h" +#include "macrtc.h" +#include "macscsi.h" +#include "mactoolbox.h" + +#include "emupal.h" +#include "screen.h" +#include "speaker.h" +#include "softlist_dev.h" + +namespace { + +#define C32M (31.3344_MHz_XTAL) +#define C15M (C32M/2) +#define C7M (C32M/4) + +class maciifx_state : public driver_device +{ +public: + maciifx_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_via1(*this, "via1"), + m_macadb(*this, "macadb"), + m_ram(*this, RAM_TAG), + m_rtc(*this, "rtc"), + 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_asc(*this, "asc"), + m_cur_floppy(nullptr), + m_hdsel(0) + { + } + + void maciifx(machine_config &config); + void maciifx_map(address_map &map); + +private: + required_device m_maincpu; + required_device m_via1; + required_device m_macadb; + required_device m_ram; + required_device m_rtc; + required_device m_fdc; + required_device_array m_floppy; + required_device m_scsibus1; + required_device m_ncr5380; + required_device m_scsihelp; + required_device m_scc; + required_device m_asc; + + virtual void machine_start() override; + virtual void machine_reset() override; + + 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); + } + + floppy_image_device *m_cur_floppy = nullptr; + int m_hdsel; + + void phases_w(uint8_t phases); + void devsel_w(uint8_t devsel); + WRITE_LINE_MEMBER(hdsel_w); + + uint32_t biu_r(offs_t offset, uint32_t mem_mask = ~0); + void biu_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); + template + DECLARE_WRITE_LINE_MEMBER(oss_interrupt); + TIMER_CALLBACK_MEMBER(oss_6015_tick); + uint8_t oss_r(offs_t offset); + void oss_w(offs_t offset, uint8_t data); + uint32_t buserror_r(); + uint8_t maciifx_8010_r(); + uint8_t maciifx_8040_r(); + + uint8_t m_oss_regs[0x400]{}; + int m_last_taken_interrupt; + emu_timer *m_6015_timer; + + uint16_t mac_via_r(offs_t offset); + void mac_via_w(offs_t offset, uint16_t data, uint16_t mem_mask); + uint8_t mac_via_in_a(); + uint8_t mac_via_in_b(); + void mac_via_out_a(uint8_t data); + void mac_via_out_b(uint8_t data); + void mac_via_sync(); + + uint32_t rom_switch_r(offs_t offset); + bool m_overlay; + u32 *m_rom_ptr = nullptr; + u32 m_rom_size = 0; + + int m_adb_in; + void set_adb_line(int linestate) { m_adb_in = (linestate == ASSERT_LINE) ? true : false; } + int adbin_r() { return m_adb_in; } +}; + +void maciifx_state::machine_start() +{ + save_item(NAME(m_hdsel)); + save_item(NAME(m_last_taken_interrupt)); + save_item(NAME(m_adb_in)); + + m_6015_timer = timer_alloc(FUNC(maciifx_state::oss_6015_tick), this); + m_6015_timer->adjust(attotime::never); + + m_rom_ptr = (u32 *)memregion("bootrom")->base(); + m_rom_size = memregion("bootrom")->bytes(); + + m_last_taken_interrupt = -1; + m_adb_in = 0; +} + +void maciifx_state::machine_reset() +{ + // 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); + m_overlay = true; +} + +uint32_t maciifx_state::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->pointer(); + offs_t memory_mirror = memory_end & ~memory_end; + + space.install_ram(0x00000000, memory_end & ~memory_mirror, memory_mirror, memory_data); + m_overlay = false; + } + + // printf("rom_switch_r: offset %08x ROM_size -1 = %08x, masked = %08x\n", offset, m_rom_size-1, offset & ((m_rom_size - 1)>>2)); + + return m_rom_ptr[offset & ((m_rom_size - 1) >> 2)]; +} + +/*************************************************************************** + ADDRESS MAPS +***************************************************************************/ +void maciifx_state::maciifx_map(address_map &map) +{ + map(0x40000000, 0x4007ffff).r(FUNC(maciifx_state::rom_switch_r)).mirror(0x0ff80000); + + map(0x50000000, 0x50001fff).rw(FUNC(maciifx_state::mac_via_r), FUNC(maciifx_state::mac_via_w)).mirror(0x00f00000); + map(0x50004000, 0x50005fff).rw("sccpic", FUNC(applepic_device::host_r), FUNC(applepic_device::host_w)).mirror(0x00f00000).umask32(0xff00ff00); + map(0x50004000, 0x50005fff).rw("sccpic", FUNC(applepic_device::host_r), FUNC(applepic_device::host_w)).mirror(0x00f00000).umask32(0x00ff00ff); + map(0x50008010, 0x50008010).r(FUNC(maciifx_state::maciifx_8010_r)).mirror(0x00f00000); + map(0x50008040, 0x50008040).r(FUNC(maciifx_state::maciifx_8040_r)).mirror(0x00f00000); + map(0x5000a000, 0x5000bfff).rw(FUNC(maciifx_state::scsi_r), FUNC(maciifx_state::scsi_w)).mirror(0x00f00000); + map(0x5000c060, 0x5000c063).r(FUNC(maciifx_state::scsi_drq_r)).mirror(0x00f00000); + map(0x5000d000, 0x5000d003).w(FUNC(maciifx_state::scsi_drq_w)).mirror(0x00f00000); + map(0x5000d060, 0x5000d063).r(FUNC(maciifx_state::scsi_drq_r)).mirror(0x00f00000); + map(0x50010000, 0x50011fff).rw(m_asc, FUNC(asc_device::read), FUNC(asc_device::write)).mirror(0x00f00000); + map(0x50012000, 0x50013fff).rw("swimpic", FUNC(applepic_device::host_r), FUNC(applepic_device::host_w)).mirror(0x00f00000).umask32(0xff00ff00); + map(0x50012000, 0x50013fff).rw("swimpic", FUNC(applepic_device::host_r), FUNC(applepic_device::host_w)).mirror(0x00f00000).umask32(0x00ff00ff); + map(0x50018000, 0x50019fff).rw(FUNC(maciifx_state::biu_r), FUNC(maciifx_state::biu_w)).mirror(0x00f00000); + map(0x5001a000, 0x5001bfff).rw(FUNC(maciifx_state::oss_r), FUNC(maciifx_state::oss_w)).mirror(0x00f00000); + map(0x50024000, 0x50027fff).r(FUNC(maciifx_state::buserror_r)).mirror(0x00f00000); // must bus error on access here so ROM can determine we're an FMC + map(0x50040000, 0x50041fff).rw(FUNC(maciifx_state::mac_via_r), FUNC(maciifx_state::mac_via_w)).mirror(0x00f00000); +} + +void maciifx_state::mac_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)); +} + +uint16_t maciifx_state::mac_via_r(offs_t offset) +{ + uint16_t data; + + offset >>= 8; + offset &= 0x0f; + + if (!machine().side_effects_disabled()) + mac_via_sync(); + + data = m_via1->read(offset); + + return (data & 0xff) | (data << 8); +} + +void maciifx_state::mac_via_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + offset >>= 8; + offset &= 0x0f; + + mac_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); +} + +uint8_t maciifx_state::mac_via_in_a() +{ + return 0xd3; // PA6 | PA4 | PA1 +} + +uint8_t maciifx_state::mac_via_in_b() +{ + int val = m_rtc->data_r(); + + // printf("%s VIA1 IN_B = %02x\n", machine().describe_context().c_str(), val); + + return val; +} + +void maciifx_state::mac_via_out_a(uint8_t data) +{ + int hdsel = BIT(data, 5); + if (hdsel != m_hdsel) + { + if (m_cur_floppy) + { + m_cur_floppy->ss_w(hdsel); + } + } + m_hdsel = hdsel; +} + +void maciifx_state::mac_via_out_b(uint8_t data) +{ + // printf("%s VIA1 OUT B: %02x\n", machine().describe_context().c_str(), data); + + m_rtc->ce_w((data & 0x04) >> 2); + m_rtc->data_w(data & 0x01); + m_rtc->clk_w((data >> 1) & 0x01); +} + +u16 maciifx_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 maciifx_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 maciifx_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 maciifx_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; + } +} + +void maciifx_state::phases_w(uint8_t phases) +{ + if (m_cur_floppy) + m_cur_floppy->seek_phase_w(phases); +} + +void maciifx_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(maciifx_state::hdsel_w) +{ + if (state != m_hdsel) + { + if (m_cur_floppy) + { + m_cur_floppy->ss_w(state); + } + } + m_hdsel = state; +} + +uint32_t maciifx_state::biu_r(offs_t offset, uint32_t mem_mask) +{ + // printf("biu_r @ %x, mask %08x\n", offset, mem_mask); + return 0; +} + +void maciifx_state::biu_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + // printf("biu_w %x @ %x, mask %08x\n", data, offset, mem_mask); +} + +template +WRITE_LINE_MEMBER(maciifx_state::oss_interrupt) +{ + if (state == ASSERT_LINE) + m_oss_regs[N >= 8 ? 0x202 : 0x203] |= 1 << (N & 7); + else + m_oss_regs[N >= 8 ? 0x202 : 0x203] &= ~(1 << (N & 7)); + + int take_interrupt = 0; + for (int n = 0; n < 8; n++) + { + if (BIT(m_oss_regs[0x203], n) && take_interrupt < m_oss_regs[n]) + take_interrupt = m_oss_regs[n]; + if (BIT(m_oss_regs[0x202], n) && take_interrupt < m_oss_regs[8 + n]) + take_interrupt = m_oss_regs[8 + n]; + } + + if (m_last_taken_interrupt > -1) + { + m_maincpu->set_input_line(m_last_taken_interrupt, CLEAR_LINE); + m_last_taken_interrupt = -1; + m_oss_regs[0x200] &= 0x7f; + } + + if (take_interrupt > 0) + { + m_maincpu->set_input_line(take_interrupt, ASSERT_LINE); + m_last_taken_interrupt = take_interrupt; + m_oss_regs[0x200] |= 0x80; + } +} + +TIMER_CALLBACK_MEMBER(maciifx_state::oss_6015_tick) +{ + m_via1->write_ca1(0); + m_via1->write_ca1(1); + oss_interrupt<10>(ASSERT_LINE); +} + +uint8_t maciifx_state::oss_r(offs_t offset) +{ + // printf("oss_r @ %x\n", offset); + // if (offset <= 0xe) // for interrupt mask registers, we're intended to return something different than is written in the low 3 bits (?) + // { + // return m_oss_regs[offset]<<4; + // } + + if (offset < std::size(m_oss_regs)) + return m_oss_regs[offset]; + else + return 0; +} + +void maciifx_state::oss_w(offs_t offset, uint8_t data) +{ + // printf("oss_w %x @ %x\n", data, offset); + if (offset == 0x207) + oss_interrupt<10>(CLEAR_LINE); + else if (offset < std::size(m_oss_regs)) + m_oss_regs[offset] = data; +} + +uint32_t maciifx_state::buserror_r() +{ + m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE); + m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE); + return 0; +} + +uint8_t maciifx_state::maciifx_8010_r() +{ + return 0x40; +} + +uint8_t maciifx_state::maciifx_8040_r() +{ + return 0; +} + +/*************************************************************************** + DEVICE CONFIG +***************************************************************************/ + +static INPUT_PORTS_START( maciifx ) +INPUT_PORTS_END + +/*************************************************************************** + MACHINE DRIVERS +***************************************************************************/ +void maciifx_state::maciifx(machine_config &config) +{ + /* basic machine hardware */ + M68030(config, m_maincpu, 40000000); + m_maincpu->set_addrmap(AS_PROGRAM, &maciifx_state::maciifx_map); + m_maincpu->set_dasm_override(std::function(&mac68k_dasm_override), "mac68k_dasm_override"); + + RTC3430042(config, m_rtc, XTAL(32'768)); + m_rtc->cko_cb().set(m_via1, FUNC(via6522_device::write_ca2)); + + SWIM1(config, m_fdc, C15M); + m_fdc->devsel_cb().set(FUNC(maciifx_state::devsel_w)); + m_fdc->phases_cb().set(FUNC(maciifx_state::phases_w)); + + applefdintf_device::add_35_hd(config, m_floppy[0]); + applefdintf_device::add_35_nc(config, m_floppy[1]); + + SOFTWARE_LIST(config, "flop35hd_list").set_original("mac_hdflop"); + + SCC8530(config, m_scc, C7M); + + 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(*device); + adapter.irq_handler().set(*this, FUNC(maciifx_state::oss_interrupt<9>)); + 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(maciifx_state::scsi_berr_w)); + + SOFTWARE_LIST(config, "hdd_list").set_original("mac_hdd"); + + SPEAKER(config, "lspeaker").front_left(); + SPEAKER(config, "rspeaker").front_right(); + ASC(config, m_asc, C15M, asc_device::asc_type::ASC); + m_asc->add_route(0, "lspeaker", 1.0); + m_asc->add_route(1, "rspeaker", 1.0); + m_asc->irqf_callback().set(FUNC(maciifx_state::oss_interrupt<8>)); + + R65NC22(config, m_via1, C7M / 10); + m_via1->readpa_handler().set(FUNC(maciifx_state::mac_via_in_a)); + m_via1->readpb_handler().set(FUNC(maciifx_state::mac_via_in_b)); + m_via1->writepa_handler().set(FUNC(maciifx_state::mac_via_out_a)); + m_via1->writepb_handler().set(FUNC(maciifx_state::mac_via_out_b)); + m_via1->irq_handler().set(FUNC(maciifx_state::oss_interrupt<11>)); + + applepic_device &sccpic(APPLEPIC(config, "sccpic", C15M)); + sccpic.prd_callback().set(m_scc, FUNC(scc8530_legacy_device::reg_r)); + sccpic.pwr_callback().set(m_scc, FUNC(scc8530_legacy_device::reg_w)); + sccpic.hint_callback().set(FUNC(maciifx_state::oss_interrupt<7>)); + + MACADB(config, m_macadb, C15M); + m_macadb->adb_data_callback().set(FUNC(maciifx_state::set_adb_line)); + + m_scc->intrq_callback().set("sccpic", FUNC(applepic_device::pint_w)); + // m_scc->dtr_reqa_callback().set("sccpic", FUNC(applepic_device::reqa_w)); + // m_scc->dtr_reqb_callback().set("sccpic", FUNC(applepic_device::reqb_w)); + + applepic_device &swimpic(APPLEPIC(config, "swimpic", C15M)); + swimpic.prd_callback().set(m_fdc, FUNC(applefdintf_device::read)); + swimpic.pwr_callback().set(m_fdc, FUNC(applefdintf_device::write)); + swimpic.hint_callback().set(FUNC(maciifx_state::oss_interrupt<6>)); + swimpic.gpout0_callback().set(m_macadb, FUNC(macadb_device::adb_data_w)); + swimpic.gpin_callback().set(FUNC(maciifx_state::adbin_r)); + + m_fdc->dat1byte_cb().set("swimpic", FUNC(applepic_device::reqa_w)); + + RAM(config, m_ram); + m_ram->set_default_size("4M"); + m_ram->set_extra_options("8M,16M,32M,64M,96M,128M"); + + SOFTWARE_LIST(config, "flop35_list").set_original("mac_flop"); + + nubus_device &nubus(NUBUS(config, "nubus", 0)); + nubus.set_space(m_maincpu, AS_PROGRAM); + nubus.out_irq9_callback().set(FUNC(maciifx_state::oss_interrupt<0>)); + nubus.out_irqa_callback().set(FUNC(maciifx_state::oss_interrupt<1>)); + nubus.out_irqb_callback().set(FUNC(maciifx_state::oss_interrupt<2>)); + nubus.out_irqc_callback().set(FUNC(maciifx_state::oss_interrupt<3>)); + nubus.out_irqd_callback().set(FUNC(maciifx_state::oss_interrupt<4>)); + nubus.out_irqe_callback().set(FUNC(maciifx_state::oss_interrupt<5>)); + + NUBUS_SLOT(config, "nb9", "nubus", mac_nubus_cards, "mdc824"); + NUBUS_SLOT(config, "nba", "nubus", mac_nubus_cards, nullptr); + NUBUS_SLOT(config, "nbb", "nubus", mac_nubus_cards, nullptr); + 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); +} + +ROM_START(maciifx) + ROM_REGION32_BE(0x80000, "bootrom", 0) + ROM_LOAD("4147dd77.rom", 0x000000, 0x080000, CRC(ef441bbd) SHA1(9fba3d4f672a630745d65788b1d1119afa2c6728)) +ROM_END + +} // anonymous namespace + +COMP(1990, maciifx, 0, 0, maciifx, maciifx, maciifx_state, empty_init, "Apple Computer", "Macintosh IIfx", MACHINE_NOT_WORKING) diff --git a/src/mame/mame.lst b/src/mame/mame.lst index c055a8704e5..9fff4d896a9 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -824,7 +824,6 @@ mac2fdhd // 1988 Apple Macintosh II (FDHD) macii // 1987 Apple Macintosh II maciici // 1989 Apple Macintosh IIci maciicx // 1989 Apple Macintosh IIcx -maciifx // 1990 Apple Macintosh IIfx maciihmu // 1987 Apple Macintosh II (w/o 68851 MMU) maciisi // 1990 Apple Macintosh IIsi maciix // 1988 Apple Macintosh IIx @@ -841,6 +840,9 @@ macsefd // 1988 Apple Macintosh SE (FDHD) unitron // 1985 Unitron utrn1024 // 1986 Unitron 1024 +@source:apple/maciifx.cpp +maciifx // 1990 Apple Macintosh IIfx + @source:apple/maciivx.cpp maciivx // 1993 Apple Macintosh IIvx maciivi // 1993 Apple Macintosh IIvi