mirror of
https://github.com/holub/mame
synced 2025-04-24 09:20:02 +03:00
heathkit/h89.cpp: Add Magnolia Microsystems DD controller and h89-mms system (#12413)
This commit is contained in:
parent
9d849dde70
commit
d1846f21e7
@ -45,6 +45,7 @@
|
||||
|
||||
#include "h_88_cass.h"
|
||||
#include "intr_cntrl.h"
|
||||
#include "mms77316_fdc.h"
|
||||
#include "sigmasoft_parallel_port.h"
|
||||
#include "tlb.h"
|
||||
#include "z37_fdc.h"
|
||||
@ -221,6 +222,44 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Heathkit H89 with MMS hardware
|
||||
* - MMS 77316 - DD controller
|
||||
*
|
||||
* Functionality already implemented/Same as Heath options
|
||||
* - MMS 77311 - 16k RAM
|
||||
* - MMS 77312 - ORG-0 CP/M Mod
|
||||
*
|
||||
* Hardware currently planned to be implemented:
|
||||
* - MMS 77318 - 128k RAM board
|
||||
* - MMS 77319 - Video Output
|
||||
* - MMS 77320 - SASI board
|
||||
* - MMS 77322 - Network Controller
|
||||
*
|
||||
* Other hardware MMS offered
|
||||
* - MMS 77314 - Remex H47 / IMI(Corvus) / 3 serial port
|
||||
* - MMS 77315 - Cameo I/o
|
||||
* - MMS 77317 - ACT/XCOMP I/O
|
||||
*
|
||||
*/
|
||||
class h89_mms_state : public h89_base_state
|
||||
{
|
||||
public:
|
||||
h89_mms_state(const machine_config &mconfig, device_type type, const char *tag):
|
||||
h89_base_state(mconfig, type, tag),
|
||||
m_mms(*this, "mms_fdc")
|
||||
{
|
||||
}
|
||||
|
||||
void h89_mms(machine_config &config);
|
||||
|
||||
protected:
|
||||
required_device<mms77316_fdc_device> m_mms;
|
||||
|
||||
void h89_mms_io(address_map &map);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
The H89 supported 16K, 32K, 48K, or 64K of RAM. The first 8K of address space
|
||||
is reserved for the monitor ROM, floppy ROM, and scratch pad RAM. For 16k-48K
|
||||
@ -327,8 +366,8 @@ u8 h89_base_state::m1_r(offs_t offset)
|
||||
DCE Serial I/O | EO-E7 | 340-347
|
||||
Console I/O | E8-EF | 350-357
|
||||
NMI | F0-F1 | 360-361
|
||||
General purpose port | F2 | 362
|
||||
Cassette I/O(MTR-88) | F8-F9 | 370-371
|
||||
General purpose port | F2 | 362
|
||||
Cassette I/O(MTR-88 only)| F8-F9 | 370-371
|
||||
NMI | FA-FB | 372-373
|
||||
|
||||
Disk I/O #1 - 0170-0173 (0x78-0x7b)
|
||||
@ -393,6 +432,43 @@ void h89_sigmasoft_state::h89_sigmasoft_io(address_map &map)
|
||||
map(0x08,0x0f).rw(m_sigma_parallel, FUNC(sigmasoft_parallel_port::read), FUNC(sigmasoft_parallel_port::write));
|
||||
}
|
||||
|
||||
/*
|
||||
Memory Map for MMS 444-61C PROM
|
||||
|
||||
PORT
|
||||
Use | Hex |
|
||||
----------------------------+-------+
|
||||
Not specified, available | 0-37 |
|
||||
MMS 77316 | 38-3F |
|
||||
MMS Internal test fixtures | 40-47 |
|
||||
MMS 77317 ACT/XCOMP I/O | 48-4F |
|
||||
MMS 77315 CAMEO I/O | 50-56 |
|
||||
Unused | 57 |
|
||||
MMS 77314 Corvus I/O | 58-59 |
|
||||
MMS 77314 REMEX I/O | 5A-5B |
|
||||
MMS 77314,15,17 Conf Port | 5C |
|
||||
Unused | 5D-77 |
|
||||
Disk I/O #1 | 78-7B |
|
||||
Disk I/O #2 | 7C-7F |
|
||||
HDOS reserved | 80-CF |
|
||||
DCE Serial I/O | D0-D7 |
|
||||
DTE Serial I/O | D8-DF |
|
||||
DCE Serial I/O | EO-E7 |
|
||||
Console I/O | E8-EF |
|
||||
NMI | F0-F1 |
|
||||
General purpose port | F2 |
|
||||
Unused | F8-F9 |
|
||||
NMI | FA-FB |
|
||||
Unused | FC-FF |
|
||||
*/
|
||||
void h89_mms_state::h89_mms_io(address_map &map)
|
||||
{
|
||||
h89_base_state::h89_base_io(map);
|
||||
|
||||
// Add MMS 77316 Double Density Controller
|
||||
map(0x38,0x3f).rw(m_mms, FUNC(mms77316_fdc_device::read), FUNC(mms77316_fdc_device::write));
|
||||
}
|
||||
|
||||
|
||||
// Input ports
|
||||
static INPUT_PORTS_START( h88 )
|
||||
@ -835,6 +911,7 @@ static void intr_ctrl_options(device_slot_interface &device)
|
||||
{
|
||||
device.option_add("original", HEATH_INTR_CNTRL);
|
||||
device.option_add("h37", HEATH_Z37_INTR_CNTRL);
|
||||
device.option_add("mms", HEATH_MMS_INTR_CNTRL);
|
||||
}
|
||||
|
||||
void h89_base_state::h89_base(machine_config &config)
|
||||
@ -907,7 +984,7 @@ void h89_state::h89(machine_config &config)
|
||||
m_h37->block_interrupt_cb().set(m_intr_socket, FUNC(heath_intr_socket::block_interrupts));
|
||||
}
|
||||
|
||||
void h89_sigmasoft_state::h89_sigmasoft(machine_config & config)
|
||||
void h89_sigmasoft_state::h89_sigmasoft(machine_config &config)
|
||||
{
|
||||
h89(config);
|
||||
m_maincpu->set_addrmap(AS_IO, &h89_sigmasoft_state::h89_sigmasoft_io);
|
||||
@ -925,6 +1002,19 @@ void h89_sigmasoft_state::h89_sigmasoft(machine_config & config)
|
||||
m_sigma_parallel->ctrl_cb().set(m_tlbc, FUNC(heath_tlb_connector::sigma_ctrl_w));
|
||||
}
|
||||
|
||||
void h89_mms_state::h89_mms(machine_config &config)
|
||||
{
|
||||
h89_base(config);
|
||||
m_maincpu->set_addrmap(AS_IO, &h89_mms_state::h89_mms_io);
|
||||
|
||||
m_intr_socket->set_default_option("mms");
|
||||
m_intr_socket->set_fixed(true);
|
||||
|
||||
MMS77316_FDC(config, m_mms);
|
||||
m_mms->drq_cb().set(m_intr_socket, FUNC(heath_intr_socket::set_drq));
|
||||
m_mms->irq_cb().set(m_intr_socket, FUNC(heath_intr_socket::set_irq));
|
||||
}
|
||||
|
||||
|
||||
ROM_START( h88 )
|
||||
ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASEFF )
|
||||
@ -996,6 +1086,28 @@ ROM_START( h89_sigmasoft )
|
||||
ROMX_LOAD("2716_mtrhex.u518", 0x0000, 0x0800, CRC(842a306a) SHA1(ddbc2b8bb127464af9eda8e7c56e6be7c8b43a16), ROM_BIOS(7))
|
||||
ROM_END
|
||||
|
||||
ROM_START( h89_mms )
|
||||
ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASEFF )
|
||||
ROM_DEFAULT_BIOS("mms84b")
|
||||
|
||||
ROM_LOAD( "2716_444-19_h17.u520", 0x1800, 0x0800, CRC(26e80ae3) SHA1(0c0ee95d7cb1a760f924769e10c0db1678f2435c))
|
||||
|
||||
ROM_SYSTEM_BIOS(0, "mms84b", "MMS 444-84B")
|
||||
ROMX_LOAD("2732_444_84b_mms.u518", 0x0000, 0x1000, CRC(7e75d6f4) SHA1(baf34e036388d1a191197e31f8a93209f04fc58b), ROM_BIOS(0))
|
||||
|
||||
ROM_SYSTEM_BIOS(1, "kmr-100", "Kres KMR-100 V3.a.02")
|
||||
ROMX_LOAD("2732_kmr100_v3_a_02.u518", 0x0000, 0x1000, CRC(fd491592) SHA1(3d5803f95c38b237b07cd230353cd9ddc9858c13), ROM_BIOS(1))
|
||||
|
||||
ROM_SYSTEM_BIOS(2, "mtrhex_4k", "Ultimeth 4k ROM")
|
||||
ROMX_LOAD("2732_mtrhex_4k.u518", 0x0000, 0x1000, CRC(e26b29a9) SHA1(ba13d6c9deef682a9a8262bc910d46b577929a13), ROM_BIOS(2))
|
||||
|
||||
ROM_SYSTEM_BIOS(3, "mms84a", "MMS 444-84A (Superseded by MMS 444-84B)")
|
||||
ROMX_LOAD("2732_444_84a_mms.u518", 0x0000, 0x1000, CRC(0e541a7e) SHA1(b1deb620fc89c1068e2e663e14be69d1f337a4b9), ROM_BIOS(3))
|
||||
|
||||
ROM_SYSTEM_BIOS(4, "mtrhex", "Ultimeth 2k ROM")
|
||||
ROMX_LOAD("2716_mtrhex.u518", 0x0000, 0x0800, CRC(842a306a) SHA1(ddbc2b8bb127464af9eda8e7c56e6be7c8b43a16), ROM_BIOS(4))
|
||||
ROM_END
|
||||
|
||||
ROM_START( z90 )
|
||||
ROM_REGION( 0x2000, "maincpu", ROMREGION_ERASEFF )
|
||||
ROM_DEFAULT_BIOS("mtr90")
|
||||
@ -1027,5 +1139,6 @@ ROM_END
|
||||
// year name parent compat machine input class init company fullname flags
|
||||
COMP( 1979, h88, h89, 0, h88, h88, h88_state, empty_init, "Heath Company", "H-88", MACHINE_SUPPORTS_SAVE)
|
||||
COMP( 1979, h89, 0, 0, h89, h89, h89_state, empty_init, "Heath Company", "H-89", MACHINE_SUPPORTS_SAVE)
|
||||
COMP( 1981, h89_mms, h89, 0, h89_mms, h89, h89_mms_state, empty_init, "Heath Company", "H-89 with MMS Equipment", MACHINE_SUPPORTS_SAVE)
|
||||
COMP( 1981, z90, h89, 0, h89, h89, h89_state, empty_init, "Zenith Data Systems", "Z-90", MACHINE_SUPPORTS_SAVE)
|
||||
COMP( 1984, h89_sigmasoft, h89, 0, h89_sigmasoft, h89, h89_sigmasoft_state, empty_init, "Heath Company", "H-89 with SigmaSoft IGC", MACHINE_SUPPORTS_SAVE)
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
DEFINE_DEVICE_TYPE(HEATH_INTR_CNTRL, heath_intr_cntrl, "heath_intr_cntrl", "Heath H/Z-89 Interrupt Controller");
|
||||
DEFINE_DEVICE_TYPE(HEATH_Z37_INTR_CNTRL, z37_intr_cntrl, "heath_z37_intr_cntrl", "Heath H/Z-89 with Z-37 Interrupt Controller");
|
||||
DEFINE_DEVICE_TYPE(HEATH_MMS_INTR_CNTRL, mms_intr_cntrl, "heath_mms_intr_cntrl", "Heath H/Z-89 with MMS Interrupt Controller");
|
||||
|
||||
DEFINE_DEVICE_TYPE(HEATH_INTR_SOCKET, heath_intr_socket, "heath_intr_socket", "Heath Interrupt Socket");
|
||||
|
||||
@ -107,6 +108,43 @@ u8 heath_intr_cntrl::get_instruction()
|
||||
return 0xc7 | ((level & 0x7) << 3);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Base interrupt controller for soft-sectored controller.
|
||||
*
|
||||
*/
|
||||
ss_intr_cntrl::ss_intr_cntrl(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock):
|
||||
heath_intr_cntrl(mconfig, type, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
void ss_intr_cntrl::set_drq(int state)
|
||||
{
|
||||
m_drq_raised = bool(state);
|
||||
|
||||
update_intr_line();
|
||||
}
|
||||
|
||||
|
||||
void ss_intr_cntrl::set_irq(int state)
|
||||
{
|
||||
m_irq_raised = bool(state);
|
||||
|
||||
update_intr_line();
|
||||
}
|
||||
|
||||
void ss_intr_cntrl::device_start()
|
||||
{
|
||||
heath_intr_cntrl::device_start();
|
||||
|
||||
save_item(NAME(m_drq_raised));
|
||||
save_item(NAME(m_irq_raised));
|
||||
|
||||
m_drq_raised = false;
|
||||
m_irq_raised = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Interrupt controller for the Z37 soft-sectored controller.
|
||||
*
|
||||
@ -114,7 +152,7 @@ u8 heath_intr_cntrl::get_instruction()
|
||||
* interrupts while it is waiting for Z37 events.
|
||||
*/
|
||||
z37_intr_cntrl::z37_intr_cntrl(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock):
|
||||
heath_intr_cntrl(mconfig, HEATH_Z37_INTR_CNTRL, tag, owner, clock)
|
||||
ss_intr_cntrl(mconfig, HEATH_Z37_INTR_CNTRL, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
@ -150,32 +188,13 @@ u8 z37_intr_cntrl::get_instruction()
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void z37_intr_cntrl::set_drq(int state)
|
||||
{
|
||||
m_drq_raised = bool(state);
|
||||
|
||||
update_intr_line();
|
||||
}
|
||||
|
||||
|
||||
void z37_intr_cntrl::set_irq(int state)
|
||||
{
|
||||
m_irq_raised = bool(state);
|
||||
|
||||
update_intr_line();
|
||||
}
|
||||
|
||||
void z37_intr_cntrl::device_start()
|
||||
{
|
||||
heath_intr_cntrl::device_start();
|
||||
ss_intr_cntrl::device_start();
|
||||
|
||||
save_item(NAME(m_intr_blocked));
|
||||
save_item(NAME(m_drq_raised));
|
||||
save_item(NAME(m_irq_raised));
|
||||
|
||||
m_intr_blocked = false;
|
||||
m_drq_raised = false;
|
||||
m_irq_raised = false;
|
||||
}
|
||||
|
||||
void z37_intr_cntrl::block_interrupts(u8 data)
|
||||
@ -186,6 +205,43 @@ void z37_intr_cntrl::block_interrupts(u8 data)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Interrupt controller for the mms 77316 soft-sectored controller.
|
||||
*
|
||||
*/
|
||||
mms_intr_cntrl::mms_intr_cntrl(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock):
|
||||
ss_intr_cntrl(mconfig, HEATH_MMS_INTR_CNTRL, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
void mms_intr_cntrl::update_intr_line()
|
||||
{
|
||||
m_socket->raise_irq((m_irq_raised || m_drq_raised || (m_intr_lines != 0)) ? 1 : 0);
|
||||
}
|
||||
|
||||
u8 mms_intr_cntrl::get_instruction()
|
||||
{
|
||||
if (m_irq_raised)
|
||||
{
|
||||
// RST 30H (Interrupt 6)
|
||||
return 0xf7;
|
||||
}
|
||||
|
||||
if (m_drq_raised)
|
||||
{
|
||||
// EI
|
||||
return 0xfb;
|
||||
}
|
||||
|
||||
return heath_intr_cntrl::get_instruction();
|
||||
}
|
||||
|
||||
void mms_intr_cntrl::device_start()
|
||||
{
|
||||
ss_intr_cntrl::device_start();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Heath Interrupt socket
|
||||
*
|
||||
|
@ -58,17 +58,36 @@ protected:
|
||||
u8 m_intr_lines;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Base interrupt controller for multiple soft-sectored controllers.
|
||||
*
|
||||
*/
|
||||
class ss_intr_cntrl : public heath_intr_cntrl
|
||||
{
|
||||
public:
|
||||
virtual void set_drq(int state) override;
|
||||
virtual void set_irq(int state) override;
|
||||
|
||||
protected:
|
||||
ss_intr_cntrl(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock = 0);
|
||||
|
||||
virtual void device_start() override;
|
||||
|
||||
bool m_drq_raised;
|
||||
bool m_irq_raised;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Interrupt controller when the Z37 soft-sectored controller is installed.
|
||||
*
|
||||
*/
|
||||
class z37_intr_cntrl : public heath_intr_cntrl
|
||||
class z37_intr_cntrl : public ss_intr_cntrl
|
||||
{
|
||||
public:
|
||||
z37_intr_cntrl(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
|
||||
|
||||
virtual void set_drq(int state) override;
|
||||
virtual void set_irq(int state) override;
|
||||
virtual void block_interrupts(u8 data) override;
|
||||
|
||||
protected:
|
||||
@ -77,14 +96,30 @@ protected:
|
||||
|
||||
virtual void device_start() override;
|
||||
|
||||
private:
|
||||
bool m_intr_blocked;
|
||||
bool m_drq_raised;
|
||||
bool m_irq_raised;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Interrupt controller when the mms soft-sectored controller is installed.
|
||||
*
|
||||
*/
|
||||
class mms_intr_cntrl : public ss_intr_cntrl
|
||||
{
|
||||
public:
|
||||
mms_intr_cntrl(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
|
||||
|
||||
protected:
|
||||
virtual u8 get_instruction() override;
|
||||
virtual void update_intr_line() override;
|
||||
|
||||
virtual void device_start() override;
|
||||
};
|
||||
|
||||
|
||||
DECLARE_DEVICE_TYPE(HEATH_INTR_CNTRL, heath_intr_cntrl)
|
||||
DECLARE_DEVICE_TYPE(HEATH_Z37_INTR_CNTRL, z37_intr_cntrl)
|
||||
DECLARE_DEVICE_TYPE(HEATH_MMS_INTR_CNTRL, mms_intr_cntrl);
|
||||
|
||||
|
||||
class heath_intr_socket : public device_t,
|
||||
|
290
src/mame/heathzenith/mms77316_fdc.cpp
Normal file
290
src/mame/heathzenith/mms77316_fdc.cpp
Normal file
@ -0,0 +1,290 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Mark Garlanger
|
||||
/***************************************************************************
|
||||
|
||||
Magnolia Microsystems 77316 soft-sectored floppy controller
|
||||
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "mms77316_fdc.h"
|
||||
|
||||
#define LOG_REG (1U << 1) // Shows register setup
|
||||
#define LOG_LINES (1U << 2) // Show control lines
|
||||
#define LOG_DRIVE (1U << 3) // Show drive select
|
||||
#define LOG_FUNC (1U << 4) // Function calls
|
||||
#define LOG_ERR (1U << 5) // log errors
|
||||
#define LOG_BURST (1U << 6) // burst mode
|
||||
|
||||
#define VERBOSE (0)
|
||||
|
||||
#include "logmacro.h"
|
||||
|
||||
#define LOGREG(...) LOGMASKED(LOG_REG, __VA_ARGS__)
|
||||
#define LOGLINES(...) LOGMASKED(LOG_LINES, __VA_ARGS__)
|
||||
#define LOGDRIVE(...) LOGMASKED(LOG_DRIVE, __VA_ARGS__)
|
||||
#define LOGFUNC(...) LOGMASKED(LOG_FUNC, __VA_ARGS__)
|
||||
#define LOGERR(...) LOGMASKED(LOG_ERR, __VA_ARGS__)
|
||||
#define LOGBURST(...) LOGMASKED(LOG_BURST, __VA_ARGS__)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define FUNCNAME __func__
|
||||
#else
|
||||
#define FUNCNAME __PRETTY_FUNCTION__
|
||||
#endif
|
||||
|
||||
DEFINE_DEVICE_TYPE(MMS77316_FDC, mms77316_fdc_device, "mms77316_fdc", "Magnolia MicroSystems 77316 Soft-sectored Controller");
|
||||
|
||||
mms77316_fdc_device::mms77316_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock):
|
||||
device_t(mconfig, MMS77316_FDC, tag, owner, 0),
|
||||
m_irq_cb(*this),
|
||||
m_drq_cb(*this),
|
||||
m_fdc(*this, "mms_fdc"),
|
||||
m_floppies(*this, "mms_fdc:%u", 0U)
|
||||
{
|
||||
}
|
||||
|
||||
void mms77316_fdc_device::ctrl_w(u8 val)
|
||||
{
|
||||
u8 floppy_drive = BIT(val, 0, 3);
|
||||
u8 five_in_drv = bool(BIT(val, ctrl_525DriveSel_c));
|
||||
|
||||
m_drq_count = 0;
|
||||
m_irq_allowed = bool(BIT(val, ctrl_EnableIntReq_c));
|
||||
m_drq_allowed = m_irq_allowed && bool(BIT(val, ctrl_EnableDrqInt_c));
|
||||
|
||||
m_fdc->dden_w(BIT(val, ctrl_SetMFMRecording_c));
|
||||
|
||||
if (m_irq_allowed)
|
||||
{
|
||||
m_irq_cb(m_irq);
|
||||
m_drq_cb(m_drq);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_irq_cb(CLEAR_LINE);
|
||||
m_drq_cb(CLEAR_LINE);
|
||||
}
|
||||
|
||||
LOGREG("%s: floppydrive: %d\n", FUNCNAME, floppy_drive);
|
||||
|
||||
m_fdc->set_floppy(m_floppies[floppy_drive]->get_device());
|
||||
|
||||
LOGREG("%s: intrq allowed: %d, drq allowed: %d\n", FUNCNAME, m_irq_allowed, m_drq_allowed);
|
||||
|
||||
m_fdc->set_clock(five_in_drv ? FIVE_IN_CLOCK : EIGHT_IN_CLOCK);
|
||||
|
||||
for (int i = 4; i < 8; i++)
|
||||
{
|
||||
auto elem = m_floppies[i];
|
||||
if (elem)
|
||||
{
|
||||
floppy_image_device *floppy = elem->get_device();
|
||||
if (floppy)
|
||||
{
|
||||
// turn on all installed 5" floppies
|
||||
floppy->mon_w(!five_in_drv);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mms77316_fdc_device::data_w(u8 val)
|
||||
{
|
||||
if (burstMode())
|
||||
{
|
||||
// TODO add wait states in burst mode, currently blocked on Z80 properly supporting wait states
|
||||
LOGBURST("%s: burst_mode: %d\n", FUNCNAME, val);
|
||||
}
|
||||
|
||||
m_fdc->data_w(val);
|
||||
}
|
||||
|
||||
void mms77316_fdc_device::write(offs_t reg, u8 val)
|
||||
{
|
||||
LOGFUNC("%s: reg: %d val: 0x%02x\n", FUNCNAME, reg, val);
|
||||
|
||||
switch (reg)
|
||||
{
|
||||
case 0:
|
||||
ctrl_w(val);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
LOGFUNC("%s: Unexpected port write reg: %d val: 0x%02x\n", FUNCNAME, reg, val);
|
||||
break;
|
||||
case 4:
|
||||
m_fdc->cmd_w(val);
|
||||
break;
|
||||
case 5:
|
||||
m_fdc->track_w(val);
|
||||
break;
|
||||
case 6:
|
||||
m_fdc->sector_w(val);
|
||||
break;
|
||||
case 7:
|
||||
data_w(val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
u8 mms77316_fdc_device::data_r()
|
||||
{
|
||||
if (burstMode())
|
||||
{
|
||||
// TODO add wait states in burst mode, currently blocked on Z80 properly supporting wait states
|
||||
LOGBURST("%s: burst_mode\n", FUNCNAME);
|
||||
}
|
||||
|
||||
return m_fdc->data_r();
|
||||
}
|
||||
|
||||
u8 mms77316_fdc_device::read(offs_t reg)
|
||||
{
|
||||
// default return for the h89
|
||||
u8 value = 0xff;
|
||||
|
||||
switch (reg)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
// read not supported on these addresses
|
||||
LOGERR("%s: Unexpected port read reg: %d\n", FUNCNAME, reg);
|
||||
break;
|
||||
case 4:
|
||||
value = m_fdc->status_r();
|
||||
break;
|
||||
case 5:
|
||||
value = m_fdc->track_r();
|
||||
break;
|
||||
case 6:
|
||||
value = m_fdc->sector_r();
|
||||
break;
|
||||
case 7:
|
||||
value = data_r();
|
||||
break;
|
||||
}
|
||||
|
||||
LOGFUNC("%s: reg: %d val: 0x%02x\n", FUNCNAME, reg, value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void mms77316_fdc_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_irq_allowed));
|
||||
save_item(NAME(m_drq_allowed));
|
||||
save_item(NAME(m_irq));
|
||||
save_item(NAME(m_drq));
|
||||
save_item(NAME(m_drq_count));
|
||||
}
|
||||
|
||||
void mms77316_fdc_device::device_reset()
|
||||
{
|
||||
m_irq_allowed = false;
|
||||
m_drq_allowed = false;
|
||||
m_irq = false;
|
||||
m_drq_count = 0;
|
||||
|
||||
m_irq_cb(0);
|
||||
m_drq_cb(0);
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
auto elem = m_floppies[i];
|
||||
if (elem)
|
||||
{
|
||||
floppy_image_device *floppy = elem->get_device();
|
||||
if (floppy)
|
||||
{
|
||||
// turn on motor of all installed 8" floppies
|
||||
floppy->mon_w(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mms_5_in_floppies(device_slot_interface &device)
|
||||
{
|
||||
// H-17-1 -- SS 48tpi
|
||||
device.option_add("5_ssdd", FLOPPY_525_SSDD);
|
||||
// SS 96tpi
|
||||
device.option_add("5_ssqd", FLOPPY_525_SSQD);
|
||||
// DS 48tpi
|
||||
device.option_add("5_dd", FLOPPY_525_DD);
|
||||
// H-17-4 / H-17-5 -- DS 96tpi
|
||||
device.option_add("5_qd", FLOPPY_525_QD);
|
||||
}
|
||||
|
||||
static void mms_8_in_floppies(device_slot_interface &device)
|
||||
{
|
||||
// 8" DSDD
|
||||
device.option_add("8_sssd", FLOPPY_8_SSSD);
|
||||
// 8" SSDD
|
||||
device.option_add("8_dssd", FLOPPY_8_DSSD);
|
||||
// 8" DSDD
|
||||
device.option_add("8_ssdd", FLOPPY_8_SSDD);
|
||||
// 8" SSDD
|
||||
device.option_add("8_dsdd", FLOPPY_8_DSDD);
|
||||
}
|
||||
|
||||
void mms77316_fdc_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
FD1797(config, m_fdc, EIGHT_IN_CLOCK);
|
||||
m_fdc->intrq_wr_callback().set(FUNC(mms77316_fdc_device::set_irq));
|
||||
m_fdc->drq_wr_callback().set(FUNC(mms77316_fdc_device::set_drq));
|
||||
|
||||
// 8" Floppy drives
|
||||
FLOPPY_CONNECTOR(config, m_floppies[0], mms_8_in_floppies, "8_dsdd", floppy_image_device::default_mfm_floppy_formats);
|
||||
m_floppies[0]->enable_sound(true);
|
||||
FLOPPY_CONNECTOR(config, m_floppies[1], mms_8_in_floppies, "8_dsdd", floppy_image_device::default_mfm_floppy_formats);
|
||||
m_floppies[1]->enable_sound(true);
|
||||
FLOPPY_CONNECTOR(config, m_floppies[2], mms_8_in_floppies, "8_dsdd", floppy_image_device::default_mfm_floppy_formats);
|
||||
m_floppies[2]->enable_sound(true);
|
||||
FLOPPY_CONNECTOR(config, m_floppies[3], mms_8_in_floppies, "8_dsdd", floppy_image_device::default_mfm_floppy_formats);
|
||||
m_floppies[3]->enable_sound(true);
|
||||
|
||||
// 5" Floppy drives
|
||||
FLOPPY_CONNECTOR(config, m_floppies[4], mms_5_in_floppies, "5_qd", floppy_image_device::default_mfm_floppy_formats);
|
||||
m_floppies[4]->enable_sound(true);
|
||||
FLOPPY_CONNECTOR(config, m_floppies[5], mms_5_in_floppies, "5_qd", floppy_image_device::default_mfm_floppy_formats);
|
||||
m_floppies[5]->enable_sound(true);
|
||||
FLOPPY_CONNECTOR(config, m_floppies[6], mms_5_in_floppies, "5_qd", floppy_image_device::default_mfm_floppy_formats);
|
||||
m_floppies[6]->enable_sound(true);
|
||||
FLOPPY_CONNECTOR(config, m_floppies[7], mms_5_in_floppies, "5_qd", floppy_image_device::default_mfm_floppy_formats);
|
||||
m_floppies[7]->enable_sound(true);
|
||||
}
|
||||
|
||||
void mms77316_fdc_device::set_irq(int state)
|
||||
{
|
||||
LOGLINES("set irq, allowed: %d state: %d\n", m_irq_allowed, state);
|
||||
|
||||
if (state)
|
||||
{
|
||||
m_drq_count = 0;
|
||||
}
|
||||
|
||||
m_irq = state;
|
||||
|
||||
m_irq_cb(m_irq_allowed ? m_irq : CLEAR_LINE);
|
||||
}
|
||||
|
||||
void mms77316_fdc_device::set_drq(int state)
|
||||
{
|
||||
bool drq_allowed = false;
|
||||
|
||||
LOGLINES("set drq, allowed: %d state: %d\n", m_drq_allowed, state);
|
||||
m_drq = state;
|
||||
|
||||
if (m_drq)
|
||||
{
|
||||
// even if drq bit is not set, trigger if the first one after an IRQ.
|
||||
drq_allowed = m_drq_allowed || (m_drq_count++ == 0);
|
||||
}
|
||||
|
||||
m_drq_cb(drq_allowed ? m_drq : CLEAR_LINE);
|
||||
}
|
78
src/mame/heathzenith/mms77316_fdc.h
Normal file
78
src/mame/heathzenith/mms77316_fdc.h
Normal file
@ -0,0 +1,78 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Mark Garlanger
|
||||
/***************************************************************************
|
||||
|
||||
Magnolia Microsystems 77316 soft-sectored floppy controller
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef MAME_HEATHKIT_MMS77316_FDC_H
|
||||
#define MAME_HEATHKIT_MMS77316_FDC_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "imagedev/floppy.h"
|
||||
#include "machine/wd_fdc.h"
|
||||
|
||||
|
||||
class mms77316_fdc_device : public device_t
|
||||
{
|
||||
public:
|
||||
|
||||
mms77316_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
|
||||
|
||||
void write(offs_t reg, u8 val);
|
||||
u8 read(offs_t reg);
|
||||
|
||||
auto irq_cb() { return m_irq_cb.bind(); }
|
||||
auto drq_cb() { return m_drq_cb.bind(); }
|
||||
|
||||
protected:
|
||||
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
|
||||
void ctrl_w(u8 val);
|
||||
void data_w(u8 val);
|
||||
u8 data_r();
|
||||
|
||||
void set_irq(int state);
|
||||
void set_drq(int state);
|
||||
|
||||
// Burst mode was required for a 2 MHz Z80 to handle 8" DD data rates.
|
||||
// The typical irq/drq was too slow, this utilizes wait states to read the
|
||||
// WD1797 data port once the drq line is high.
|
||||
inline bool burstMode() { return !m_drq_allowed; }
|
||||
|
||||
private:
|
||||
|
||||
devcb_write_line m_irq_cb;
|
||||
devcb_write_line m_drq_cb;
|
||||
|
||||
required_device<fd1797_device> m_fdc;
|
||||
required_device_array<floppy_connector, 8> m_floppies;
|
||||
|
||||
bool m_irq_allowed;
|
||||
bool m_drq_allowed;
|
||||
|
||||
bool m_irq;
|
||||
bool m_drq;
|
||||
u32 m_drq_count;
|
||||
|
||||
/// Bits set in cmd_ControlPort_c
|
||||
static constexpr u8 ctrl_525DriveSel_c = 2;
|
||||
static constexpr u8 ctrl_EnableIntReq_c = 3;
|
||||
static constexpr u8 ctrl_EnableDrqInt_c = 5;
|
||||
static constexpr u8 ctrl_SetMFMRecording_c = 6;
|
||||
|
||||
static constexpr XTAL MASTER_CLOCK = XTAL(8'000'000);
|
||||
static constexpr XTAL FIVE_IN_CLOCK = MASTER_CLOCK / 8;
|
||||
static constexpr XTAL EIGHT_IN_CLOCK = MASTER_CLOCK / 4;
|
||||
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(MMS77316_FDC, mms77316_fdc_device)
|
||||
|
||||
|
||||
#endif // MAME_HEATHKIT_MMS77316_FDC_H
|
@ -229,7 +229,7 @@ void heath_z37_fdc_device::set_irq(int state)
|
||||
|
||||
void heath_z37_fdc_device::set_drq(int state)
|
||||
{
|
||||
LOGLINES("set drq, allowed: %d state: %d\n", m_irq_allowed, state);
|
||||
LOGLINES("set drq, allowed: %d state: %d\n", m_drq_allowed, state);
|
||||
|
||||
m_drq_cb(m_drq_allowed ? state : CLEAR_LINE);
|
||||
}
|
||||
|
@ -19435,6 +19435,7 @@ h19 // Heath H19
|
||||
@source:heathzenith/h89.cpp
|
||||
h89 // Heath H89 (WH89)
|
||||
h88 // Heath H88 (with cassette tape)
|
||||
h89_mms // Heath H89 with Magnolia MicroSystems(MMS) hardware
|
||||
h89_sigmasoft // H89 with the SigmaSoft IGC card
|
||||
z90 // Zenith Z-90
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user