mirror of
https://github.com/holub/mame
synced 2025-06-06 12:53:46 +03:00
heathzenith/h89.cpp: Add initial support for the H-89 (and H-88 and Z-90) slot bus
- Uses the real I/O decoding PROMs - Z-37 and MMS 77316 floppy controllers converted to cards - H-88-3 serial and H-88-5 cassette interfaces converted to cards - Sigmasoft Sound card converted to a card
This commit is contained in:
parent
fe7e897e56
commit
8353b2bd93
@ -5739,3 +5739,29 @@ if (BUSES["PLG1X0"]~=null) then
|
||||
MAME_DIR .. "src/devices/bus/plg1x0/plg150-ap.h",
|
||||
}
|
||||
end
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/bus/h89/h89bus.h,BUSES["H89BUS"] = true
|
||||
---------------------------------------------------
|
||||
|
||||
if (BUSES["H89BUS"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/bus/heathzenith/h89/cards.cpp",
|
||||
MAME_DIR .. "src/devices/bus/heathzenith/h89/cards.h",
|
||||
MAME_DIR .. "src/devices/bus/heathzenith/h89/h89bus.cpp",
|
||||
MAME_DIR .. "src/devices/bus/heathzenith/h89/h89bus.h",
|
||||
MAME_DIR .. "src/devices/bus/heathzenith/h89/h_88_3.cpp",
|
||||
MAME_DIR .. "src/devices/bus/heathzenith/h89/h_88_3.h",
|
||||
MAME_DIR .. "src/devices/bus/heathzenith/h89/h_88_5.cpp",
|
||||
MAME_DIR .. "src/devices/bus/heathzenith/h89/h_88_5.h",
|
||||
MAME_DIR .. "src/devices/bus/heathzenith/h89/mms77316_fdc.cpp",
|
||||
MAME_DIR .. "src/devices/bus/heathzenith/h89/mms77316_fdc.h",
|
||||
MAME_DIR .. "src/devices/bus/heathzenith/h89/sigmasoft_sound.cpp",
|
||||
MAME_DIR .. "src/devices/bus/heathzenith/h89/sigmasoft_sound.h",
|
||||
MAME_DIR .. "src/devices/bus/heathzenith/h89/we_pullup.cpp",
|
||||
MAME_DIR .. "src/devices/bus/heathzenith/h89/we_pullup.h",
|
||||
MAME_DIR .. "src/devices/bus/heathzenith/h89/z37_fdc.cpp",
|
||||
MAME_DIR .. "src/devices/bus/heathzenith/h89/z37_fdc.h",
|
||||
}
|
||||
end
|
||||
|
44
src/devices/bus/heathzenith/h89/cards.cpp
Normal file
44
src/devices/bus/heathzenith/h89/cards.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:R. Belmont
|
||||
/***************************************************************************
|
||||
|
||||
H-89 and Z-90 slot cards
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "cards.h"
|
||||
|
||||
#include "h_88_3.h"
|
||||
#include "h_88_5.h"
|
||||
#include "mms77316_fdc.h"
|
||||
#include "sigmasoft_sound.h"
|
||||
#include "we_pullup.h"
|
||||
#include "z37_fdc.h"
|
||||
|
||||
void h89_left_cards(device_slot_interface &device)
|
||||
{
|
||||
}
|
||||
|
||||
void h89_right_cards(device_slot_interface &device)
|
||||
{
|
||||
device.option_add("h_88_3", H89BUS_H_88_3);
|
||||
device.option_add("ha_88_3", H89BUS_HA_88_3);
|
||||
device.option_add("h_88_5", H89BUS_H_88_5);
|
||||
device.option_add("ss_snd", H89BUS_SIGMASOFT_SND);
|
||||
device.option_add("z37fdc", H89BUS_Z37);
|
||||
}
|
||||
|
||||
void h89_right_cards_mms(device_slot_interface &device)
|
||||
{
|
||||
h89_right_cards(device);
|
||||
device.option_add("mms77316", H89BUS_MMS77316);
|
||||
}
|
||||
|
||||
void h89_right_p506_cards(device_slot_interface &device)
|
||||
{
|
||||
device.option_add("h_88_3", H89BUS_H_88_3);
|
||||
device.option_add("ha_88_3", H89BUS_HA_88_3);
|
||||
device.option_add("ss_snd", H89BUS_SIGMASOFT_SND);
|
||||
device.option_add("we_pullup", H89BUS_WE_PULLUP);
|
||||
}
|
19
src/devices/bus/heathzenith/h89/cards.h
Normal file
19
src/devices/bus/heathzenith/h89/cards.h
Normal file
@ -0,0 +1,19 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:R. Belmont
|
||||
/***************************************************************************
|
||||
|
||||
Heath/Zenith H-89 and Z-90 cards
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef MAME_BUS_HEATHZENITH_H89_CARDS_H
|
||||
#define MAME_BUS_HEATHZENITH_H89_CARDS_H
|
||||
|
||||
#pragma once
|
||||
|
||||
void h89_left_cards(device_slot_interface &device) ATTR_COLD;
|
||||
void h89_right_cards(device_slot_interface &device) ATTR_COLD;
|
||||
void h89_right_cards_mms(device_slot_interface &device) ATTR_COLD;
|
||||
void h89_right_p506_cards(device_slot_interface &device) ATTR_COLD;
|
||||
|
||||
#endif // MAME_BUS_HEATHZENITH_H89_CARDS_H
|
406
src/devices/bus/heathzenith/h89/h89bus.cpp
Normal file
406
src/devices/bus/heathzenith/h89/h89bus.cpp
Normal file
@ -0,0 +1,406 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:R. Belmont
|
||||
/***************************************************************************
|
||||
|
||||
h89bus.cpp - Heath/Zenith H-89/Z-90 bus
|
||||
|
||||
by R. Belmont
|
||||
|
||||
This system is weird. There are 3 left-hand slots. These are intended
|
||||
for RAM expansion and map into the Z80's memory space. They get A0-A12
|
||||
and some select signals decoded by a pair of PROMs at U516 and U517.
|
||||
Notably, these slots don't get the Z80's /RD or /WR signals so actual
|
||||
working boards for these slots always run a cable or jumper(s) to pick
|
||||
signals from the motherboard. These slots also have no way to signal
|
||||
an interrupt.
|
||||
|
||||
There are also 3 right-hand slots. These connect to the Z80's I/O address
|
||||
space and are addressed by a 3-bit offset A0/A1/A2 plus select lines /SER0,
|
||||
/SER1, /LP1 and /CASS (on P504/P510 and P505/P511), or /FLPY (on P506/P512).
|
||||
P506/P512 replaces the /LP1 select line with the /FMWE signal which write-enables
|
||||
the "floppy RAM" at 0x1400. These slots have 3 standard interrupt outputs
|
||||
/INT3, /INT4, and /INT5.
|
||||
|
||||
Notable real-world use cases that we support:
|
||||
- The Sigmasoft parallel card plugs into a left slot but picks the I/O space
|
||||
select signal off the motherboard. This plus the left slots' nearly full
|
||||
set of address lines let it decode the I/O space arbitrarily without
|
||||
having to change the I/O decoder PROM.
|
||||
|
||||
- The MMS 77316 floppy controller has jumpers to replace U553 so that it can
|
||||
intercept the GPP select line output by the PROM and further decode it.
|
||||
This decode appears to check if A0/A1/A2 = b010. The partial schematic for
|
||||
the card doesn't include that logic, but based on what signals it has access
|
||||
to and the fact that the card doesn't respond to A0/A1/A2 = b010 that seems
|
||||
to be a reasonable guess.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "h89bus.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
|
||||
DEFINE_DEVICE_TYPE(H89BUS_LEFT_SLOT, h89bus_left_slot_device, "h89bus_lslot", "H-89 left (memory) slot")
|
||||
|
||||
h89bus_left_slot_device::h89bus_left_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
h89bus_left_slot_device(mconfig, H89BUS_LEFT_SLOT, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
h89bus_left_slot_device::h89bus_left_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, type, tag, owner, clock),
|
||||
device_single_card_slot_interface(mconfig, *this),
|
||||
m_h89bus(*this, finder_base::DUMMY_TAG),
|
||||
m_h89bus_slottag(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void h89bus_left_slot_device::device_start()
|
||||
{
|
||||
}
|
||||
|
||||
void h89bus_left_slot_device::device_resolve_objects()
|
||||
{
|
||||
device_h89bus_left_card_interface *dev = get_card_device();
|
||||
|
||||
if (dev)
|
||||
{
|
||||
dev->set_h89bus_tag(m_h89bus.target(), m_h89bus_slottag);
|
||||
m_h89bus->add_h89bus_left_card(*dev);
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_DEVICE_TYPE(H89BUS_RIGHT_SLOT, h89bus_right_slot_device, "h89bus_rslot", "H-89 right (I/O) slot")
|
||||
|
||||
h89bus_right_slot_device::h89bus_right_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
h89bus_right_slot_device(mconfig, H89BUS_RIGHT_SLOT, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
h89bus_right_slot_device::h89bus_right_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, type, tag, owner, clock),
|
||||
device_single_card_slot_interface(mconfig, *this),
|
||||
m_h89bus(*this, finder_base::DUMMY_TAG),
|
||||
m_h89bus_slottag(nullptr),
|
||||
m_p506_signals(false)
|
||||
{
|
||||
}
|
||||
|
||||
void h89bus_right_slot_device::device_start()
|
||||
{
|
||||
}
|
||||
|
||||
void h89bus_right_slot_device::device_resolve_objects()
|
||||
{
|
||||
device_h89bus_right_card_interface *dev = get_card_device();
|
||||
|
||||
if (dev)
|
||||
{
|
||||
dev->set_h89bus_tag(m_h89bus.target(), m_h89bus_slottag);
|
||||
dev->set_p506_signalling(m_p506_signals);
|
||||
m_h89bus->add_h89bus_right_card(*dev);
|
||||
}
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
DEFINE_DEVICE_TYPE(H89BUS, h89bus_device, "h89bus", "H-89/Z-90 bus")
|
||||
|
||||
ROM_START(h89bus)
|
||||
ROM_REGION(0x100, "iodecode", 0)
|
||||
// H88 I/O decoding
|
||||
ROM_SYSTEM_BIOS(0, "444-43", "Heath/Zenith stock decoding (444-43)")
|
||||
ROMX_LOAD("444-43.bin", 0x000000, 0x000100, CRC(3e0315f4) SHA1(11da9a9145de07f1f3bf1270a10e059dff30c693), ROM_BIOS(0))
|
||||
|
||||
// H89 I/O decoding
|
||||
ROM_SYSTEM_BIOS(1, "444-61", "Z-37 decoding (444-61)")
|
||||
ROMX_LOAD("444-61.bin", 0x000000, 0x000100, CRC(0b3c129f) SHA1(92da6484d1339160400d6bc75578a977c5e4d23e), ROM_BIOS(1))
|
||||
|
||||
// MMS (Magnolia Micro Systems) I/O decoding
|
||||
ROM_SYSTEM_BIOS(2, "444-61c", "MMS decoding (444-61c)")
|
||||
ROMX_LOAD( "444-61c.bin", 0x000000, 0x000100, CRC(e7122061) SHA1(33c124f44c0f9cb99c9b17ad15411b4bc6407eae), ROM_BIOS(2))
|
||||
ROM_END
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// h89bus_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
h89bus_device::h89bus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
h89bus_device(mconfig, H89BUS, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
h89bus_device::h89bus_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, type, tag, owner, clock),
|
||||
m_program_space(*this, finder_base::DUMMY_TAG, -1),
|
||||
m_io_space(*this, finder_base::DUMMY_TAG, -1),
|
||||
m_decode_prom(*this, "iodecode"),
|
||||
m_out_int3_cb(*this),
|
||||
m_out_int4_cb(*this),
|
||||
m_out_int5_cb(*this),
|
||||
m_out_fdcirq_cb(*this),
|
||||
m_out_fdcdrq_cb(*this),
|
||||
m_out_blockirq_cb(*this),
|
||||
m_out_fmwe_cb(*this),
|
||||
m_out_wait_cb(*this),
|
||||
m_in_tlb_cb(*this, 0),
|
||||
m_in_nmi_cb(*this, 0),
|
||||
m_in_gpp_cb(*this, 0),
|
||||
m_out_tlb_cb(*this),
|
||||
m_out_nmi_cb(*this),
|
||||
m_out_gpp_cb(*this)
|
||||
{
|
||||
}
|
||||
|
||||
h89bus_device::~h89bus_device()
|
||||
{
|
||||
}
|
||||
|
||||
const tiny_rom_entry *h89bus_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME(h89bus);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void h89bus_device::device_start()
|
||||
{
|
||||
// don't claim I/O below 0x10 for now
|
||||
m_io_space->install_readwrite_handler(0x0010, 0x00ff, emu::rw_delegate(*this, FUNC(h89bus_device::io_dispatch_r)), emu::rw_delegate(*this, FUNC(h89bus_device::io_dispatch_w)));
|
||||
}
|
||||
|
||||
void h89bus_device::add_h89bus_left_card(device_h89bus_left_card_interface &card)
|
||||
{
|
||||
m_left_device_list.emplace_back(card);
|
||||
}
|
||||
|
||||
void h89bus_device::add_h89bus_right_card(device_h89bus_right_card_interface &card)
|
||||
{
|
||||
m_right_device_list.emplace_back(card);
|
||||
}
|
||||
|
||||
void h89bus_device::set_io0(int state)
|
||||
{
|
||||
m_io0 = state;
|
||||
}
|
||||
|
||||
void h89bus_device::set_io1(int state)
|
||||
{
|
||||
m_io1 = state;
|
||||
}
|
||||
|
||||
void h89bus_device::set_mem0(int state)
|
||||
{
|
||||
m_mem0 = state;
|
||||
}
|
||||
|
||||
void h89bus_device::set_mem1(int state)
|
||||
{
|
||||
m_mem1 = state;
|
||||
}
|
||||
|
||||
int h89bus_device::get_io0()
|
||||
{
|
||||
return m_io0;
|
||||
}
|
||||
|
||||
int h89bus_device::get_io1()
|
||||
{
|
||||
return m_io1;
|
||||
}
|
||||
|
||||
int h89bus_device::get_mem0()
|
||||
{
|
||||
return m_mem0;
|
||||
}
|
||||
|
||||
int h89bus_device::get_mem1()
|
||||
{
|
||||
return m_mem1;
|
||||
}
|
||||
|
||||
u8 h89bus_device::read_gpp()
|
||||
{
|
||||
return m_in_gpp_cb(0);
|
||||
}
|
||||
void h89bus_device::write_gpp(u8 data)
|
||||
{
|
||||
m_out_gpp_cb(0, data);
|
||||
}
|
||||
|
||||
u8 h89bus_device::io_dispatch_r(offs_t offset)
|
||||
{
|
||||
u8 retval = 0;
|
||||
|
||||
offset += 0x10;
|
||||
if (m_decode_prom[offset] != 0xff)
|
||||
{
|
||||
u16 decode = m_decode_prom[offset] ^ 0xff;
|
||||
|
||||
if ((decode & H89_GPP) && ((offset & 7) == 2)) return m_in_gpp_cb(offset);
|
||||
if (decode & H89_NMI) return m_in_nmi_cb(offset);
|
||||
if (decode & H89_TERM) return m_in_tlb_cb(offset & 7);
|
||||
|
||||
if (decode)
|
||||
{
|
||||
for (device_h89bus_right_card_interface &entry : m_right_device_list)
|
||||
{
|
||||
if (entry.m_p506_signals)
|
||||
{
|
||||
// p506 has FLPY but not CASS or LP
|
||||
retval |= entry.read(decode & ~(H89_CASS | H89_LP), offset & 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
// p504/p505 have CASS and LP but not FLPY
|
||||
retval |= entry.read(decode & ~H89_FLPY , offset & 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// service left-slot cards that have a motherboard connection to snoop the I/O space
|
||||
for (device_h89bus_left_card_interface &entry : m_left_device_list)
|
||||
{
|
||||
retval |= entry.read(H89_IO, offset);
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void h89bus_device::io_dispatch_w(offs_t offset, u8 data)
|
||||
{
|
||||
offset += 0x10;
|
||||
if (m_decode_prom[offset] != 0xff)
|
||||
{
|
||||
u16 decode = m_decode_prom[offset] ^ 0xff;
|
||||
|
||||
if (decode & H89_GPP) m_out_gpp_cb(offset, data);
|
||||
if (decode & H89_NMI) { m_out_nmi_cb(offset, data); return; }
|
||||
if (decode & H89_TERM) { m_out_tlb_cb(offset & 7, data); return; }
|
||||
|
||||
if (decode)
|
||||
{
|
||||
for (device_h89bus_right_card_interface &entry : m_right_device_list)
|
||||
{
|
||||
if (entry.m_p506_signals)
|
||||
{
|
||||
// p506 has FLPY but not CASS or LP1
|
||||
entry.write(decode & ~H89_CASS, offset & 7, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
// p504/p505 have LP1 and CASS but not FLPY
|
||||
entry.write(decode & ~H89_FLPY, offset & 7, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// service left-slot cards that have a motherboard connection to snoop the I/O space
|
||||
for (device_h89bus_left_card_interface &entry : m_left_device_list)
|
||||
{
|
||||
entry.write(H89_IO, offset, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void h89bus_device::set_int3_line(int state)
|
||||
{
|
||||
m_out_int3_cb(state);
|
||||
}
|
||||
|
||||
void h89bus_device::set_int4_line(int state)
|
||||
{
|
||||
m_out_int4_cb(state);
|
||||
}
|
||||
|
||||
void h89bus_device::set_int5_line(int state)
|
||||
{
|
||||
m_out_int5_cb(state);
|
||||
}
|
||||
|
||||
void h89bus_device::set_fdcirq_line(int state)
|
||||
{
|
||||
m_out_fdcirq_cb(state);
|
||||
}
|
||||
|
||||
void h89bus_device::set_fdcdrq_line(int state)
|
||||
{
|
||||
m_out_fdcdrq_cb(state);
|
||||
}
|
||||
|
||||
void h89bus_device::set_blockirq_line(int state)
|
||||
{
|
||||
m_out_blockirq_cb(state);
|
||||
}
|
||||
|
||||
void h89bus_device::set_fmwe_line(int state)
|
||||
{
|
||||
m_out_fmwe_cb(state);
|
||||
}
|
||||
|
||||
void h89bus_device::set_wait_line(int state)
|
||||
{
|
||||
m_out_wait_cb(state);
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// DEVICE H89BUS CARD INTERFACE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_h89bus_card_interface - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
device_h89bus_card_interface::device_h89bus_card_interface(const machine_config &mconfig, device_t &device) :
|
||||
device_interface(device, "h89bus"),
|
||||
m_h89bus(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ~device_h89bus_card_interface - destructor
|
||||
//-------------------------------------------------
|
||||
|
||||
device_h89bus_card_interface::~device_h89bus_card_interface()
|
||||
{
|
||||
}
|
||||
|
||||
void device_h89bus_card_interface::interface_pre_start()
|
||||
{
|
||||
if (!m_h89bus)
|
||||
{
|
||||
fatalerror("Can't find H-89 bus device\n");
|
||||
}
|
||||
}
|
||||
|
||||
device_h89bus_left_card_interface::device_h89bus_left_card_interface(const machine_config &mconfig, device_t &device) :
|
||||
device_h89bus_card_interface(mconfig, device)
|
||||
{
|
||||
}
|
||||
|
||||
device_h89bus_left_card_interface::~device_h89bus_left_card_interface()
|
||||
{
|
||||
}
|
||||
|
||||
device_h89bus_right_card_interface::device_h89bus_right_card_interface(const machine_config &mconfig, device_t &device) :
|
||||
device_h89bus_card_interface(mconfig, device),
|
||||
m_p506_signals(false)
|
||||
{
|
||||
}
|
||||
|
||||
device_h89bus_right_card_interface::~device_h89bus_right_card_interface()
|
||||
{
|
||||
}
|
||||
|
424
src/devices/bus/heathzenith/h89/h89bus.h
Normal file
424
src/devices/bus/heathzenith/h89/h89bus.h
Normal file
@ -0,0 +1,424 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:R. Belmont
|
||||
/***************************************************************************
|
||||
|
||||
h89.h - Heath/Zenith H-89/Z-90 bus
|
||||
by R. Belmont
|
||||
|
||||
Left-side slots of the H89 Right-side slots of the H89
|
||||
|
||||
pin P501 P502 P503 P504 P505 P506 pin
|
||||
|
||||
1 GND----------GND----------GND-------------GND----------GND----------GND 1
|
||||
2 D0-----------D0-----------D0--------------D0-----------D0-----------D0 2
|
||||
3 D1-----------D1-----------D1--------------D1-----------D1-----------D1 3
|
||||
4 D2-----------D2-----------D2--------------D2-----------D2-----------D2 4
|
||||
5 D3-----------D3-----------D3--------------D3-----------D3-----------D3 5
|
||||
6 D4-----------D4-----------D4--------------D4-----------D4-----------D4 6
|
||||
7 D5-----------D5-----------D5--------------D5-----------D5-----------D5 7
|
||||
8 D6-----------D6-----------D6--------------D6-----------D6-----------D6 8
|
||||
9 D7-----------D7-----------D7--------------D7-----------D7-----------D7 9
|
||||
10 GND----------GND----------GND-------------GND----------GND----------GND 10
|
||||
|
||||
P507 P508 P509 P510 P511 P512
|
||||
|
||||
1 VCC----------VCC----------VCC-------------VCC----------VCC----------VCC 1
|
||||
2 GND----------GND----------GND-------------GND----------GND----------GND 2
|
||||
3 A0-----------A0-----------A0--------------A0-----------A0-----------A0 3
|
||||
4 A1-----------A1-----------A1--------------A1-----------A1-----------A1 4
|
||||
5 A2-----------A2-----------A2--------------A2-----------A2-----------A2 5
|
||||
6 A3-----------A3-----------A3 /BRD---------/BRD---------/BRD 6
|
||||
7 A4-----------A4-----------A4 /BWR---------/BWR---------/BWR 7
|
||||
8 A5-----------A5-----------A5 /WAIT--------/WAIT--------/WAIT 8
|
||||
9 A6-----------A6-----------A6 /SER0--------/SER0--------/SER0 9
|
||||
10 A7-----------A7-----------A7 /SER1--------/SER1--------/SER1 10
|
||||
11 A8-----------A8-----------A8 /LP1---------/LP1 /FLPY 11
|
||||
12 A9-----------A9-----------A9 /CASS--------/CASS /FMWE 12
|
||||
13 A10----------A10----------A10 2MHz---------2MHz---------2MHz 13
|
||||
14 A11----------A11----------A11 1.8Mhz-------1.8MHz-------1.8MHz 14
|
||||
15 A12----------A12----------A12 /RST---------/RST---------/RST 15
|
||||
16 MEM 0--------MEM 0--------MEM 0 IO 0---------IO 0---------IO 0 16
|
||||
17 MEM 1--------MEM 1--------MEM 1 IO 1---------IO 1---------IO 1 17
|
||||
18 RD5----------RD5----------RD5 /INT3--------/INT3--------/INT3 18
|
||||
19 RD6----------RD6----------RD6 /INT4--------/INT4--------/INT4 19
|
||||
20 RD7----------RD7----------RD7 /INT5--------/INT5--------/INT5 20
|
||||
21 (+12V)-------(+12V)-------(+12V)-----------(+12V)-------(+12V)-------(+12V) 21
|
||||
22 (-12V)-------(-12V)-------(-12V)-----------(-12V)-------(-12V)-------(-12V) 22
|
||||
23 (-5V)--------(-5V)--------(-5V)------------(-5V)--------(-5V)--------(-5V) 23
|
||||
24 (+12V)-------(+12V)-------(+12V)-----------(+12V)-------(+12V)-------(+12V) 24
|
||||
25 GND----------GND----------GND--------------GND----------GND----------GND 25
|
||||
|
||||
|
||||
Signal Description
|
||||
------------------------------------------
|
||||
MEM 0 H Controlled by the GPP port
|
||||
MEM 1 H Controlled by the GPP port
|
||||
RD5 Tied to +5V when CPU jumpers configured as recommended by Heath's configuration
|
||||
guide. Could be jumpered to RAS2 (bank select 2: address 32k-48k) (active low)
|
||||
RD6 Selects the 16k Expansion memory (active low)
|
||||
RD7 Reserved for future use, 444-66 PROM nevers sets this low. (active low)
|
||||
BRD L Board Read (active low)
|
||||
BWR L Board Write (active low)
|
||||
WAIT L Wait state (active low)
|
||||
SER0 L Select line for one of the serial ports on the HA-88-3 (active low)
|
||||
SER1 L Select line for one of the serial ports on the HA-88-3 (active low)
|
||||
LP 1 L Select line for one of the serial ports on the HA-88-3 (active low)
|
||||
CASS L Select line originally for the Cassette Interface board, but when used with later PROM it
|
||||
selected Floppy controllers/interfaces – Z-89-37, Z-89-47, Z-89-67 (active low)
|
||||
2 MHz CPU Clock, actual speed 2.048 MHz
|
||||
1.8 MHz Serial Port Clock, actual speed 1.8432 MHz
|
||||
RST L Reset line (active low)
|
||||
IO 0 H Controlled by the GPP port
|
||||
IO 1 H Controlled by the GPP port
|
||||
INT3 L Interrupt level 3 (active low)
|
||||
INT4 L Interrupt level 4 (active low)
|
||||
INT5 L Interrupt level 5 (active low)
|
||||
FLPY L Select line originally for the H-88-1 hard-sectored controller, but also used for the later
|
||||
Z-89-47 and Z-89-67 when installed in slot P506/P512 (active low)
|
||||
FMWE H Floppy Memory Write Enable
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef MAME_BUS_HEATHZENITH_H89_H89BUS_H
|
||||
#define MAME_BUS_HEATHZENITH_H89_H89BUS_H
|
||||
|
||||
#pragma once
|
||||
#include "emu.h"
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <string.h>
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
class h89bus_device;
|
||||
|
||||
// ======================> device_h89bus_card_interface
|
||||
|
||||
// class representing interface-specific live H-89/Z-89 bus card
|
||||
class device_h89bus_card_interface : public device_interface
|
||||
{
|
||||
friend class h89bus_device;
|
||||
public:
|
||||
// construction/destruction
|
||||
virtual ~device_h89bus_card_interface();
|
||||
|
||||
// inline configuration
|
||||
void set_h89bus_tag(h89bus_device *h89bus, const char *slottag) { m_h89bus = h89bus; m_h89bus_slottag = slottag; }
|
||||
|
||||
protected:
|
||||
device_h89bus_card_interface(const machine_config &mconfig, device_t &device);
|
||||
virtual void interface_pre_start() override;
|
||||
|
||||
h89bus_device &h89bus() { assert(m_h89bus); return *m_h89bus; }
|
||||
|
||||
const char *m_h89bus_slottag;
|
||||
|
||||
private:
|
||||
h89bus_device *m_h89bus;
|
||||
};
|
||||
|
||||
class device_h89bus_left_card_interface : public device_h89bus_card_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
virtual ~device_h89bus_left_card_interface();
|
||||
|
||||
int get_mem0();
|
||||
int get_mem1();
|
||||
|
||||
virtual u8 read(u8 select_lines, u16 offset) { return 0; };
|
||||
virtual void write(u8 select_lines, u16 offset, u8 data) {};
|
||||
|
||||
protected:
|
||||
device_h89bus_left_card_interface(const machine_config &mconfig, device_t &device);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class device_h89bus_right_card_interface : public device_h89bus_card_interface
|
||||
{
|
||||
friend class h89bus_device;
|
||||
|
||||
public:
|
||||
// construction/destruction
|
||||
virtual ~device_h89bus_right_card_interface();
|
||||
|
||||
void set_slot_int3(int state);
|
||||
void set_slot_int4(int state);
|
||||
void set_slot_int5(int state);
|
||||
void set_slot_fdcirq(int state);
|
||||
void set_slot_fdcdrq(int state);
|
||||
void set_slot_blockirq(int state);
|
||||
void set_slot_fmwe(int state);
|
||||
void set_slot_wait(int state);
|
||||
int get_io0();
|
||||
int get_io1();
|
||||
|
||||
virtual u8 read(u8 select_lines, u8 offset) { return 0; };
|
||||
virtual void write(u8 select_lines, u8 offset, u8 data) {};
|
||||
|
||||
void set_p506_signalling(bool val)
|
||||
{
|
||||
m_p506_signals = val;
|
||||
}
|
||||
|
||||
protected:
|
||||
device_h89bus_right_card_interface(const machine_config &mconfig, device_t &device);
|
||||
bool m_p506_signals;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class h89bus_left_slot_device : public device_t, public device_single_card_slot_interface<device_h89bus_left_card_interface>
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
template <typename T, typename U>
|
||||
h89bus_left_slot_device(const machine_config &mconfig, T &&tag, device_t *owner, const char *sltag, U &&opts, const char *dflt)
|
||||
: h89bus_left_slot_device(mconfig, tag, owner, (uint32_t)0)
|
||||
{
|
||||
option_reset();
|
||||
opts(*this);
|
||||
set_default_option(dflt);
|
||||
set_h89bus_slot(std::forward<T>(sltag), tag);
|
||||
}
|
||||
|
||||
h89bus_left_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
// inline configuration
|
||||
template <typename T>
|
||||
void set_h89bus_slot(T &&tag, const char *slottag)
|
||||
{
|
||||
m_h89bus.set_tag(std::forward<T>(tag));
|
||||
m_h89bus_slottag = slottag;
|
||||
}
|
||||
|
||||
protected:
|
||||
h89bus_left_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
// device_t implementation
|
||||
virtual void device_resolve_objects() override ATTR_COLD;
|
||||
virtual void device_start() override ATTR_COLD;
|
||||
|
||||
// configuration
|
||||
required_device<h89bus_device> m_h89bus;
|
||||
const char *m_h89bus_slottag;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(H89BUS_LEFT_SLOT, h89bus_left_slot_device)
|
||||
|
||||
class h89bus_right_slot_device : public device_t, public device_single_card_slot_interface<device_h89bus_right_card_interface>
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
template <typename T, typename U>
|
||||
h89bus_right_slot_device(const machine_config &mconfig, T &&tag, device_t *owner, const char *sltag, U &&opts, const char *dflt)
|
||||
: h89bus_right_slot_device(mconfig, tag, owner, (uint32_t)0)
|
||||
{
|
||||
option_reset();
|
||||
opts(*this);
|
||||
set_default_option(dflt);
|
||||
set_h89bus_slot(std::forward<T>(sltag), tag);
|
||||
}
|
||||
|
||||
h89bus_right_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
// inline configuration
|
||||
template <typename T>
|
||||
void set_h89bus_slot(T &&tag, const char *slottag)
|
||||
{
|
||||
m_h89bus.set_tag(std::forward<T>(tag));
|
||||
m_h89bus_slottag = slottag;
|
||||
}
|
||||
|
||||
void set_p506_signalling(bool val)
|
||||
{
|
||||
m_p506_signals = val;
|
||||
}
|
||||
|
||||
protected:
|
||||
h89bus_right_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
// device_t implementation
|
||||
virtual void device_resolve_objects() override ATTR_COLD;
|
||||
virtual void device_start() override ATTR_COLD;
|
||||
|
||||
// configuration
|
||||
required_device<h89bus_device> m_h89bus;
|
||||
const char *m_h89bus_slottag;
|
||||
bool m_p506_signals;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(H89BUS_RIGHT_SLOT, h89bus_right_slot_device)
|
||||
|
||||
// ======================> h89bus_device
|
||||
class h89bus_device : public device_t
|
||||
{
|
||||
friend class h89bus_left_slot_device;
|
||||
friend class h89bus_right_slot_device;
|
||||
friend class device_h89bus_left_card_interface;
|
||||
friend class device_h89bus_right_card_interface;
|
||||
|
||||
public:
|
||||
// left card select lines
|
||||
static constexpr u8 H89_RD5 = 0x01;
|
||||
static constexpr u8 H89_RD6 = 0x02;
|
||||
static constexpr u8 H89_RD7 = 0x04;
|
||||
// The Sigmasoft parallel card plugs into the left slot and has a jumper to
|
||||
// get the memory / I/O select signal from the motherboard. This plus the left
|
||||
// slots' A0-A13 lines means it can claim arbitrary I/O ranges that the PROM doesn't
|
||||
// select anything at.
|
||||
static constexpr u8 H89_IO = 0x80;
|
||||
|
||||
// right card and on-board I/O space select lines
|
||||
static constexpr u8 H89_GPP = 0x01;
|
||||
static constexpr u8 H89_NMI = 0x02;
|
||||
static constexpr u8 H89_TERM = 0x04;
|
||||
static constexpr u8 H89_SER1 = 0x08;
|
||||
static constexpr u8 H89_SER0 = 0x10;
|
||||
static constexpr u8 H89_LP = 0x20;
|
||||
static constexpr u8 H89_CASS = 0x40;
|
||||
static constexpr u8 H89_FLPY = 0x80;
|
||||
|
||||
// construction/destruction
|
||||
h89bus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
~h89bus_device();
|
||||
|
||||
void set_io0(int state);
|
||||
void set_io1(int state);
|
||||
void set_mem0(int state);
|
||||
void set_mem1(int state);
|
||||
int get_io0();
|
||||
int get_io1();
|
||||
int get_mem0();
|
||||
int get_mem1();
|
||||
|
||||
// inline configuration
|
||||
template <typename T> void set_program_space(T &&tag, int spacenum) { m_program_space.set_tag(std::forward<T>(tag), spacenum); }
|
||||
template <typename T> void set_io_space(T &&tag, int spacenum) { m_io_space.set_tag(std::forward<T>(tag), spacenum); }
|
||||
auto out_int3_callback() { return m_out_int3_cb.bind(); }
|
||||
auto out_int4_callback() { return m_out_int4_cb.bind(); }
|
||||
auto out_int5_callback() { return m_out_int5_cb.bind(); }
|
||||
auto out_fdcirq_callback() { return m_out_fdcirq_cb.bind(); }
|
||||
auto out_fdcdrq_callback() { return m_out_fdcdrq_cb.bind(); }
|
||||
auto out_blockirq_callback() { return m_out_blockirq_cb.bind(); }
|
||||
auto out_fmwe_callback() { return m_out_fmwe_cb.bind(); }
|
||||
auto out_wait_callback() { return m_out_wait_cb.bind(); }
|
||||
auto in_tlb_callback() { return m_in_tlb_cb.bind(); }
|
||||
auto in_nmi_callback() { return m_in_nmi_cb.bind(); }
|
||||
auto in_gpp_callback() { return m_in_gpp_cb.bind(); }
|
||||
auto out_tlb_callback() { return m_out_tlb_cb.bind(); }
|
||||
auto out_nmi_callback() { return m_out_nmi_cb.bind(); }
|
||||
auto out_gpp_callback() { return m_out_gpp_cb.bind(); }
|
||||
|
||||
protected:
|
||||
h89bus_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
// device_t implementation
|
||||
virtual void device_start() override ATTR_COLD;
|
||||
virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD;
|
||||
|
||||
// bus-internal handlers
|
||||
void add_h89bus_left_card(device_h89bus_left_card_interface &card);
|
||||
void add_h89bus_right_card(device_h89bus_right_card_interface &card);
|
||||
void set_int3_line(int state);
|
||||
void set_int4_line(int state);
|
||||
void set_int5_line(int state);
|
||||
void set_fdcirq_line(int state);
|
||||
void set_fdcdrq_line(int state);
|
||||
void set_blockirq_line(int state);
|
||||
void set_fmwe_line(int state);
|
||||
void set_wait_line(int state);
|
||||
u8 read_gpp();
|
||||
void write_gpp(u8 data);
|
||||
|
||||
// internal state
|
||||
required_address_space m_program_space, m_io_space;
|
||||
required_region_ptr<uint8_t> m_decode_prom;
|
||||
int m_io0, m_io1, m_mem0, m_mem1;
|
||||
|
||||
private:
|
||||
devcb_write_line m_out_int3_cb, m_out_int4_cb, m_out_int5_cb, m_out_fdcirq_cb, m_out_fdcdrq_cb, m_out_blockirq_cb;
|
||||
devcb_write_line m_out_fmwe_cb, m_out_wait_cb;
|
||||
devcb_read8 m_in_tlb_cb, m_in_nmi_cb, m_in_gpp_cb;
|
||||
devcb_write8 m_out_tlb_cb, m_out_nmi_cb, m_out_gpp_cb;
|
||||
|
||||
std::vector<std::reference_wrapper<device_h89bus_left_card_interface>> m_left_device_list;
|
||||
std::vector<std::reference_wrapper<device_h89bus_right_card_interface>> m_right_device_list;
|
||||
|
||||
u8 io_dispatch_r(offs_t offset);
|
||||
void io_dispatch_w(offs_t offset, u8 data);
|
||||
};
|
||||
|
||||
inline int device_h89bus_left_card_interface::get_mem0()
|
||||
{
|
||||
return h89bus().get_mem0();
|
||||
}
|
||||
|
||||
inline int device_h89bus_left_card_interface::get_mem1()
|
||||
{
|
||||
return h89bus().get_mem1();
|
||||
}
|
||||
|
||||
inline int device_h89bus_right_card_interface::get_io0()
|
||||
{
|
||||
return h89bus().get_io0();
|
||||
}
|
||||
|
||||
inline int device_h89bus_right_card_interface::get_io1()
|
||||
{
|
||||
return h89bus().get_io1();
|
||||
}
|
||||
|
||||
inline void device_h89bus_right_card_interface::set_slot_int3(int state)
|
||||
{
|
||||
h89bus().set_int3_line(state);
|
||||
}
|
||||
|
||||
inline void device_h89bus_right_card_interface::set_slot_int4(int state)
|
||||
{
|
||||
h89bus().set_int4_line(state);
|
||||
}
|
||||
|
||||
inline void device_h89bus_right_card_interface::set_slot_int5(int state)
|
||||
{
|
||||
h89bus().set_int5_line(state);
|
||||
}
|
||||
|
||||
inline void device_h89bus_right_card_interface::set_slot_fdcirq(int state)
|
||||
{
|
||||
h89bus().set_fdcirq_line(state);
|
||||
}
|
||||
|
||||
inline void device_h89bus_right_card_interface::set_slot_fdcdrq(int state)
|
||||
{
|
||||
h89bus().set_fdcdrq_line(state);
|
||||
}
|
||||
|
||||
inline void device_h89bus_right_card_interface::set_slot_blockirq(int state)
|
||||
{
|
||||
h89bus().set_blockirq_line(state);
|
||||
}
|
||||
|
||||
inline void device_h89bus_right_card_interface::set_slot_fmwe(int state)
|
||||
{
|
||||
if (m_p506_signals)
|
||||
{
|
||||
h89bus().set_fmwe_line(state);
|
||||
}
|
||||
}
|
||||
|
||||
inline void device_h89bus_right_card_interface::set_slot_wait(int state)
|
||||
{
|
||||
h89bus().set_wait_line(state);
|
||||
}
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(H89BUS, h89bus_device)
|
||||
|
||||
#endif // MAME_BUS_HEATHZENITH_H89_H89BUS_H
|
323
src/devices/bus/heathzenith/h89/h_88_3.cpp
Normal file
323
src/devices/bus/heathzenith/h89/h_88_3.cpp
Normal file
@ -0,0 +1,323 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Mark Garlanger, R. Belmont
|
||||
/***************************************************************************
|
||||
|
||||
Heath H-88-3 3-port serial port card
|
||||
Came with 2 serial ports and space to add an additional serial port.
|
||||
|
||||
Heath HA-88-3 3-port serial port card
|
||||
Came standard with 3 serial ports.
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "h_88_3.h"
|
||||
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "machine/ins8250.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class h_88_3_device : public device_t, public device_h89bus_right_card_interface
|
||||
{
|
||||
public:
|
||||
h_88_3_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = XTAL(1'843'200).value());
|
||||
|
||||
virtual void write(u8 select_lines, u8 offset, u8 data) override;
|
||||
virtual u8 read(u8 select_lines, u8 offset) override;
|
||||
|
||||
protected:
|
||||
h_88_3_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
virtual void device_start() override ATTR_COLD;
|
||||
virtual void device_reset() override ATTR_COLD;
|
||||
virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
|
||||
virtual ioport_constructor device_input_ports() const override ATTR_COLD;
|
||||
|
||||
devcb_write_line::array<4> m_int_cb;
|
||||
|
||||
required_device<ins8250_device> m_lp;
|
||||
required_device<ins8250_device> m_aux;
|
||||
required_device<ins8250_device> m_modem;
|
||||
required_ioport m_cfg_lp;
|
||||
required_ioport m_cfg_aux;
|
||||
required_ioport m_cfg_modem;
|
||||
|
||||
bool m_lp_enabled;
|
||||
bool m_aux_enabled;
|
||||
bool m_modem_enabled;
|
||||
|
||||
u8 m_lp_int_idx;
|
||||
u8 m_aux_int_idx;
|
||||
u8 m_modem_int_idx;
|
||||
private:
|
||||
void lp_w(offs_t reg, u8 val);
|
||||
u8 lp_r(offs_t reg);
|
||||
|
||||
void aux_w(offs_t reg, u8 val);
|
||||
u8 aux_r(offs_t reg);
|
||||
|
||||
void modem_w(offs_t reg, u8 val);
|
||||
u8 modem_r(offs_t reg);
|
||||
|
||||
void lp_int(int data);
|
||||
void aux_int(int data);
|
||||
void modem_int(int data);
|
||||
};
|
||||
|
||||
class ha_88_3_device : public h_88_3_device
|
||||
{
|
||||
public:
|
||||
ha_88_3_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = XTAL(1'843'200).value());
|
||||
|
||||
protected:
|
||||
virtual ioport_constructor device_input_ports() const override;
|
||||
};
|
||||
|
||||
h_88_3_device::h_88_3_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
|
||||
h_88_3_device(mconfig, H89BUS_H_88_3, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
h_88_3_device::h_88_3_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock):
|
||||
device_t(mconfig, type, tag, owner, clock),
|
||||
device_h89bus_right_card_interface(mconfig, *this),
|
||||
m_int_cb(*this),
|
||||
m_lp(*this, "lp"),
|
||||
m_aux(*this, "aux"),
|
||||
m_modem(*this, "modem"),
|
||||
m_cfg_lp(*this, "CFG_LP"),
|
||||
m_cfg_aux(*this, "CFG_AUX"),
|
||||
m_cfg_modem(*this, "CFG_MODEM")
|
||||
{
|
||||
}
|
||||
|
||||
u8 h_88_3_device::read(u8 select_lines, u8 offset)
|
||||
{
|
||||
if ((select_lines & h89bus_device::H89_SER0) && (m_aux_enabled))
|
||||
{
|
||||
return aux_r(offset);
|
||||
}
|
||||
|
||||
if ((select_lines & h89bus_device::H89_SER1) && (m_modem_enabled))
|
||||
{
|
||||
return modem_r(offset);
|
||||
}
|
||||
|
||||
if ((select_lines & h89bus_device::H89_LP) && (m_lp_enabled))
|
||||
{
|
||||
return lp_r(offset);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void h_88_3_device::write(u8 select_lines, u8 offset, u8 data)
|
||||
{
|
||||
if ((select_lines & h89bus_device::H89_SER0) && (m_aux_enabled))
|
||||
{
|
||||
aux_w(offset, data);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((select_lines & h89bus_device::H89_SER1) && (m_modem_enabled))
|
||||
{
|
||||
modem_w(offset, data);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((select_lines & h89bus_device::H89_LP) && (m_lp_enabled))
|
||||
{
|
||||
lp_w(offset, data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
u8 h_88_3_device::lp_r(offs_t reg)
|
||||
{
|
||||
return m_lp->ins8250_r(reg);
|
||||
}
|
||||
|
||||
void h_88_3_device::lp_w(offs_t reg, u8 val)
|
||||
{
|
||||
m_lp->ins8250_w(reg, val);
|
||||
}
|
||||
|
||||
u8 h_88_3_device::aux_r(offs_t reg)
|
||||
{
|
||||
return m_aux->ins8250_r(reg);
|
||||
}
|
||||
|
||||
void h_88_3_device::aux_w(offs_t reg, u8 val)
|
||||
{
|
||||
m_aux->ins8250_w(reg, val);
|
||||
}
|
||||
|
||||
u8 h_88_3_device::modem_r(offs_t reg)
|
||||
{
|
||||
return m_modem->ins8250_r(reg);
|
||||
}
|
||||
|
||||
void h_88_3_device::modem_w(offs_t reg, u8 val)
|
||||
{
|
||||
m_modem->ins8250_w(reg, val);
|
||||
}
|
||||
|
||||
void h_88_3_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_lp_enabled));
|
||||
save_item(NAME(m_lp_int_idx));
|
||||
save_item(NAME(m_aux_enabled));
|
||||
save_item(NAME(m_aux_int_idx));
|
||||
save_item(NAME(m_modem_enabled));
|
||||
save_item(NAME(m_modem_int_idx));
|
||||
}
|
||||
|
||||
void h_88_3_device::device_reset()
|
||||
{
|
||||
ioport_value const cfg_lp(m_cfg_lp->read());
|
||||
ioport_value const cfg_aux(m_cfg_aux->read());
|
||||
ioport_value const cfg_modem(m_cfg_modem->read());
|
||||
|
||||
m_lp_enabled = bool(BIT(cfg_lp, 0));
|
||||
m_aux_enabled = bool(BIT(cfg_aux, 0));
|
||||
m_modem_enabled = bool(BIT(cfg_modem, 0));
|
||||
|
||||
// LP Interrupt level
|
||||
m_lp_int_idx = BIT(cfg_lp, 1, 2);
|
||||
|
||||
// AUX Interrupt level
|
||||
m_aux_int_idx = BIT(cfg_aux, 1, 2);
|
||||
|
||||
// MODEM Interrupt level
|
||||
m_modem_int_idx = BIT(cfg_modem, 1, 2);
|
||||
}
|
||||
|
||||
void h_88_3_device::lp_int(int data)
|
||||
{
|
||||
m_int_cb[m_lp_int_idx](data);
|
||||
}
|
||||
|
||||
void h_88_3_device::aux_int(int data)
|
||||
{
|
||||
m_int_cb[m_aux_int_idx](data);
|
||||
}
|
||||
|
||||
void h_88_3_device::modem_int(int data)
|
||||
{
|
||||
m_int_cb[m_modem_int_idx](data);
|
||||
}
|
||||
|
||||
void h_88_3_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
// LP DCE 0xE0-0xE7 (340 - 347 octal)
|
||||
INS8250(config, m_lp, m_clock);
|
||||
m_lp->out_tx_callback().set("dce1", FUNC(rs232_port_device::write_txd));
|
||||
m_lp->out_dtr_callback().set("dce1", FUNC(rs232_port_device::write_dtr));
|
||||
m_lp->out_rts_callback().set("dce1", FUNC(rs232_port_device::write_rts));
|
||||
m_lp->out_int_callback().set(FUNC(h_88_3_device::lp_int));
|
||||
|
||||
rs232_port_device &dce1(RS232_PORT(config, "dce1", default_rs232_devices, "printer"));
|
||||
dce1.rxd_handler().set(m_lp, FUNC(ins8250_device::rx_w));
|
||||
dce1.dcd_handler().set(m_lp, FUNC(ins8250_device::dcd_w));
|
||||
dce1.dsr_handler().set(m_lp, FUNC(ins8250_device::dsr_w));
|
||||
dce1.cts_handler().set(m_lp, FUNC(ins8250_device::cts_w));
|
||||
dce1.ri_handler().set(m_lp, FUNC(ins8250_device::ri_w));
|
||||
|
||||
|
||||
// AUX DCE 0xD0-0xD7 (320 - 327 octal)
|
||||
INS8250(config, m_aux, m_clock);
|
||||
m_aux->out_tx_callback().set("dce2", FUNC(rs232_port_device::write_txd));
|
||||
m_aux->out_dtr_callback().set("dce2", FUNC(rs232_port_device::write_dtr));
|
||||
m_aux->out_rts_callback().set("dce2", FUNC(rs232_port_device::write_rts));
|
||||
m_aux->out_int_callback().set(FUNC(h_88_3_device::aux_int));
|
||||
|
||||
rs232_port_device &dce2(RS232_PORT(config, "dce2", default_rs232_devices, "loopback"));
|
||||
dce2.rxd_handler().set(m_aux, FUNC(ins8250_device::rx_w));
|
||||
dce2.dcd_handler().set(m_aux, FUNC(ins8250_device::dcd_w));
|
||||
dce2.dsr_handler().set(m_aux, FUNC(ins8250_device::dsr_w));
|
||||
dce2.cts_handler().set(m_aux, FUNC(ins8250_device::cts_w));
|
||||
dce2.ri_handler().set(m_aux, FUNC(ins8250_device::ri_w));
|
||||
|
||||
|
||||
// Modem DTE 0xD7-0xDF (330 - 337 octal)
|
||||
INS8250(config, m_modem, m_clock);
|
||||
m_modem->out_tx_callback().set("dte", FUNC(rs232_port_device::write_txd));
|
||||
m_modem->out_dtr_callback().set("dte", FUNC(rs232_port_device::write_dtr));
|
||||
m_modem->out_rts_callback().set("dte", FUNC(rs232_port_device::write_rts));
|
||||
m_modem->out_int_callback().set(FUNC(h_88_3_device::modem_int));
|
||||
|
||||
rs232_port_device &dte(RS232_PORT(config, "dte", default_rs232_devices, "loopback"));
|
||||
dte.rxd_handler().set(m_modem, FUNC(ins8250_device::rx_w));
|
||||
dte.dcd_handler().set(m_modem, FUNC(ins8250_device::dcd_w));
|
||||
dte.dsr_handler().set(m_modem, FUNC(ins8250_device::dsr_w));
|
||||
dte.cts_handler().set(m_modem, FUNC(ins8250_device::cts_w));
|
||||
dte.ri_handler().set(m_modem, FUNC(ins8250_device::ri_w));
|
||||
}
|
||||
|
||||
|
||||
static INPUT_PORTS_START( h_88_3_device )
|
||||
|
||||
PORT_START("CFG_LP")
|
||||
PORT_CONFNAME(0x01, 0x01, "LP - DCE (340 octal) Enabled" )
|
||||
PORT_CONFSETTING( 0x00, DEF_STR( No ))
|
||||
PORT_CONFSETTING( 0x01, DEF_STR( Yes ))
|
||||
PORT_CONFNAME(0x06, 0x00, "LP - DCE (340 octal) Interrupt level")
|
||||
PORT_CONFSETTING( 0x00, DEF_STR( None ))
|
||||
PORT_CONFSETTING( 0x02, "3")
|
||||
PORT_CONFSETTING( 0x04, "4")
|
||||
PORT_CONFSETTING( 0x06, "5")
|
||||
|
||||
PORT_START("CFG_AUX")
|
||||
PORT_CONFNAME(0x01, 0x00, "AUX - DCE (320 octal) Enabled" )
|
||||
PORT_CONFSETTING( 0x00, DEF_STR( No ))
|
||||
PORT_CONFSETTING( 0x01, DEF_STR( Yes ))
|
||||
PORT_CONFNAME(0x06, 0x00, "AUX - DCE (320 octal) Interrupt level")
|
||||
PORT_CONFSETTING( 0x00, DEF_STR( None ))
|
||||
PORT_CONFSETTING( 0x02, "3")
|
||||
PORT_CONFSETTING( 0x04, "4")
|
||||
PORT_CONFSETTING( 0x06, "5")
|
||||
|
||||
PORT_START("CFG_MODEM")
|
||||
PORT_CONFNAME(0x01, 0x01, "MODEM - DTE (330 octal) Enabled" )
|
||||
PORT_CONFSETTING( 0x00, DEF_STR( No ))
|
||||
PORT_CONFSETTING( 0x01, DEF_STR( Yes ))
|
||||
PORT_CONFNAME(0x06, 0x00, "MODEM - DTE (330 octal) Interrupt level")
|
||||
PORT_CONFSETTING( 0x00, DEF_STR( None ))
|
||||
PORT_CONFSETTING( 0x02, "3")
|
||||
PORT_CONFSETTING( 0x04, "4")
|
||||
PORT_CONFSETTING( 0x06, "5")
|
||||
|
||||
INPUT_PORTS_END
|
||||
|
||||
static INPUT_PORTS_START( ha_88_3_device )
|
||||
PORT_INCLUDE( h_88_3_device )
|
||||
|
||||
PORT_MODIFY("CFG_AUX")
|
||||
PORT_CONFNAME(0x01, 0x01, "AUX - DCE (320 octal) Enabled" )
|
||||
PORT_CONFSETTING( 0x00, DEF_STR( No ))
|
||||
PORT_CONFSETTING( 0x01, DEF_STR( Yes ))
|
||||
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
ioport_constructor h_88_3_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME(h_88_3_device);
|
||||
}
|
||||
|
||||
ioport_constructor ha_88_3_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME(ha_88_3_device);
|
||||
}
|
||||
|
||||
ha_88_3_device::ha_88_3_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
|
||||
h_88_3_device(mconfig, H89BUS_HA_88_3, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
DEFINE_DEVICE_TYPE_PRIVATE(H89BUS_H_88_3, device_h89bus_right_card_interface, h_88_3_device, "h89h_88_3", "Heath H-88-3 3-port Serial Board");
|
||||
DEFINE_DEVICE_TYPE_PRIVATE(H89BUS_HA_88_3, device_h89bus_right_card_interface, ha_88_3_device, "h89ha_88_3", "Heath HA-88-3 3-port Serial Board");
|
13
src/devices/bus/heathzenith/h89/h_88_3.h
Normal file
13
src/devices/bus/heathzenith/h89/h_88_3.h
Normal file
@ -0,0 +1,13 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:R. Belmont
|
||||
#ifndef MAME_BUS_HEATHZENITH_H89_H_88_3_H
|
||||
#define MAME_BUS_HEATHZENITH_H89_H_88_3_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "h89bus.h"
|
||||
|
||||
DECLARE_DEVICE_TYPE(H89BUS_H_88_3, device_h89bus_right_card_interface)
|
||||
DECLARE_DEVICE_TYPE(H89BUS_HA_88_3, device_h89bus_right_card_interface)
|
||||
|
||||
#endif // MAME_BUS_HEATHZENITH_H89_H_88_3_H
|
94
src/mame/heathzenith/h_88_cass.cpp → src/devices/bus/heathzenith/h89/h_88_5.cpp
Normal file → Executable file
94
src/mame/heathzenith/h_88_cass.cpp → src/devices/bus/heathzenith/h89/h_88_5.cpp
Normal file → Executable file
@ -11,17 +11,22 @@
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "h_88_cass.h"
|
||||
#include "h_88_5.h"
|
||||
|
||||
#include "formats/h8_cas.h"
|
||||
#include "imagedev/cassette.h"
|
||||
#include "machine/clock.h"
|
||||
#include "machine/i8251.h"
|
||||
#include "machine/timer.h"
|
||||
|
||||
#include "softlist_dev.h"
|
||||
#include "speaker.h"
|
||||
|
||||
#define LOG_REG (1U << 1)
|
||||
#define LOG_LINES (1U << 2)
|
||||
#define LOG_CASS (1U << 3)
|
||||
#define LOG_FUNC (1U << 4)
|
||||
//#define VERBOSE (0xff)
|
||||
#define VERBOSE (0xff)
|
||||
|
||||
#include "logmacro.h"
|
||||
|
||||
@ -36,33 +41,70 @@
|
||||
#define FUNCNAME __PRETTY_FUNCTION__
|
||||
#endif
|
||||
|
||||
DEFINE_DEVICE_TYPE(HEATH_H88_CASS, heath_h_88_cass_device, "heath_h_88_cass_device", "Heath H-88-5 Cassette Interface");
|
||||
namespace {
|
||||
|
||||
heath_h_88_cass_device::heath_h_88_cass_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock):
|
||||
device_t(mconfig, HEATH_H88_CASS, tag, owner, 0),
|
||||
class h_88_5_device : public device_t, public device_h89bus_right_card_interface
|
||||
{
|
||||
public:
|
||||
h_88_5_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
|
||||
|
||||
virtual void write(u8 select_lines, u8 offset, u8 data) override;
|
||||
virtual u8 read(u8 select_lines, u8 offset) override;
|
||||
|
||||
protected:
|
||||
virtual void device_start() override ATTR_COLD;
|
||||
virtual void device_reset() override ATTR_COLD;
|
||||
virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
|
||||
|
||||
void uart_rts(u8 data);
|
||||
void uart_tx_empty(u8 data);
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(kansas_r);
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(kansas_w);
|
||||
|
||||
required_device<i8251_device> m_uart;
|
||||
required_device<cassette_image_device> m_cass_player;
|
||||
required_device<cassette_image_device> m_cass_recorder;
|
||||
|
||||
u8 m_cass_data[4];
|
||||
bool m_cassbit;
|
||||
bool m_cassold;
|
||||
};
|
||||
|
||||
h_88_5_device::h_88_5_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock):
|
||||
device_t(mconfig, H89BUS_H_88_5, tag, owner, 0),
|
||||
device_h89bus_right_card_interface(mconfig, *this),
|
||||
m_uart(*this, "uart"),
|
||||
m_cass_player(*this, "cassette_player"),
|
||||
m_cass_recorder(*this, "cassette_recorder")
|
||||
{
|
||||
}
|
||||
|
||||
void heath_h_88_cass_device::write(offs_t reg, u8 val)
|
||||
void h_88_5_device::write(u8 select_lines, u8 reg, u8 val)
|
||||
{
|
||||
LOGREG("%s: reg: %d val: 0x%02x\n", FUNCNAME, reg, val);
|
||||
if (select_lines & h89bus_device::H89_CASS)
|
||||
{
|
||||
LOGREG("%s: reg: %d val: 0x%02x\n", FUNCNAME, reg, val);
|
||||
|
||||
m_uart->write(reg, val);
|
||||
m_uart->write(reg, val);
|
||||
}
|
||||
}
|
||||
|
||||
u8 heath_h_88_cass_device::read(offs_t reg)
|
||||
u8 h_88_5_device::read(u8 select_lines, u8 reg)
|
||||
{
|
||||
u8 val = m_uart->read(reg);
|
||||
if (select_lines & h89bus_device::H89_CASS)
|
||||
{
|
||||
u8 val = m_uart->read(reg);
|
||||
|
||||
LOGREG("%s: reg: %d val: 0x%02x\n", FUNCNAME, reg, val);
|
||||
LOGREG("%s: reg: %d val: 0x%02x\n", FUNCNAME, reg, val);
|
||||
|
||||
return val;
|
||||
return val;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(heath_h_88_cass_device::kansas_w)
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(h_88_5_device::kansas_w)
|
||||
{
|
||||
m_cass_data[3]++;
|
||||
|
||||
@ -81,7 +123,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(heath_h_88_cass_device::kansas_w)
|
||||
m_cass_recorder->output(BIT(m_cass_data[3], bit_pos) ? -1.0 : +1.0);
|
||||
}
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(heath_h_88_cass_device::kansas_r)
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(h_88_5_device::kansas_r)
|
||||
{
|
||||
// cassette - turn 1200/2400Hz to a bit
|
||||
m_cass_data[1]++;
|
||||
@ -98,28 +140,28 @@ TIMER_DEVICE_CALLBACK_MEMBER(heath_h_88_cass_device::kansas_r)
|
||||
}
|
||||
}
|
||||
|
||||
void heath_h_88_cass_device::uart_rts(u8 data)
|
||||
void h_88_5_device::uart_rts(u8 data)
|
||||
{
|
||||
LOGLINES("%s: data: %d\n", FUNCNAME, data);
|
||||
|
||||
m_cass_player->change_state(bool(data) ? CASSETTE_STOPPED : CASSETTE_PLAY, CASSETTE_MASK_UISTATE);
|
||||
}
|
||||
|
||||
void heath_h_88_cass_device::uart_tx_empty(u8 data)
|
||||
void h_88_5_device::uart_tx_empty(u8 data)
|
||||
{
|
||||
LOGLINES("%s: data: %d\n", FUNCNAME, data);
|
||||
|
||||
m_cass_recorder->change_state(bool(data) ? CASSETTE_STOPPED : CASSETTE_RECORD, CASSETTE_MASK_UISTATE);
|
||||
}
|
||||
|
||||
void heath_h_88_cass_device::device_start()
|
||||
void h_88_5_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_cass_data));
|
||||
save_item(NAME(m_cassbit));
|
||||
save_item(NAME(m_cassold));
|
||||
}
|
||||
|
||||
void heath_h_88_cass_device::device_reset()
|
||||
void h_88_5_device::device_reset()
|
||||
{
|
||||
LOGFUNC("%s\n", FUNCNAME);
|
||||
|
||||
@ -136,12 +178,12 @@ void heath_h_88_cass_device::device_reset()
|
||||
m_uart->write_rxd(0);
|
||||
}
|
||||
|
||||
void heath_h_88_cass_device::device_add_mconfig(machine_config &config)
|
||||
void h_88_5_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
I8251(config, m_uart, 0);
|
||||
m_uart->txd_handler().set([this] (bool state) { m_cassbit = state; });
|
||||
m_uart->rts_handler().set(FUNC(heath_h_88_cass_device::uart_rts));
|
||||
m_uart->txempty_handler().set(FUNC(heath_h_88_cass_device::uart_tx_empty));
|
||||
m_uart->rts_handler().set(FUNC(h_88_5_device::uart_rts));
|
||||
m_uart->txempty_handler().set(FUNC(h_88_5_device::uart_tx_empty));
|
||||
|
||||
clock_device &cassette_clock(CLOCK(config, "cassette_clock", 4800));
|
||||
cassette_clock.signal_handler().set(m_uart, FUNC(i8251_device::write_txc));
|
||||
@ -161,6 +203,12 @@ void heath_h_88_cass_device::device_add_mconfig(machine_config &config)
|
||||
m_cass_recorder->add_route(ALL_OUTPUTS, "mono", 0.15);
|
||||
m_cass_recorder->set_interface("h88_cass_recorder");
|
||||
|
||||
TIMER(config, "kansas_w").configure_periodic(FUNC(heath_h_88_cass_device::kansas_w), attotime::from_hz(4800));
|
||||
TIMER(config, "kansas_r").configure_periodic(FUNC(heath_h_88_cass_device::kansas_r), attotime::from_hz(40000));
|
||||
SOFTWARE_LIST(config, "cass_list").set_original("h88_cass");
|
||||
|
||||
TIMER(config, "kansas_w").configure_periodic(FUNC(h_88_5_device::kansas_w), attotime::from_hz(4800));
|
||||
TIMER(config, "kansas_r").configure_periodic(FUNC(h_88_5_device::kansas_r), attotime::from_hz(40000));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DEFINE_DEVICE_TYPE_PRIVATE(H89BUS_H_88_5, device_h89bus_right_card_interface, h_88_5_device, "h89h_88_5", "Heath H-88-5 Cassette Interface Board");
|
12
src/devices/bus/heathzenith/h89/h_88_5.h
Normal file
12
src/devices/bus/heathzenith/h89/h_88_5.h
Normal file
@ -0,0 +1,12 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:R. Belmont
|
||||
#ifndef MAME_BUS_HEATHZENITH_H89_H_88_5_H
|
||||
#define MAME_BUS_HEATHZENITH_H89_H_88_5_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "h89bus.h"
|
||||
|
||||
DECLARE_DEVICE_TYPE(H89BUS_H_88_5, device_h89bus_right_card_interface)
|
||||
|
||||
#endif // MAME_BUS_HEATHZENITH_H89_H_88_5_H
|
@ -14,6 +14,9 @@
|
||||
|
||||
#include "mms77316_fdc.h"
|
||||
|
||||
#include "imagedev/floppy.h"
|
||||
#include "machine/wd_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
|
||||
@ -40,13 +43,58 @@
|
||||
#define FUNCNAME __PRETTY_FUNCTION__
|
||||
#endif
|
||||
|
||||
DEFINE_DEVICE_TYPE(MMS77316_FDC, mms77316_fdc_device, "mms77316_fdc", "Magnolia MicroSystems 77316 Soft-sectored Controller");
|
||||
namespace {
|
||||
|
||||
class mms77316_fdc_device : public device_t, public device_h89bus_right_card_interface
|
||||
{
|
||||
public:
|
||||
mms77316_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
|
||||
|
||||
virtual void write(u8 select_lines, u8 offset, u8 data) override;
|
||||
virtual u8 read(u8 select_lines, u8 offset) override;
|
||||
|
||||
protected:
|
||||
virtual void device_start() override ATTR_COLD;
|
||||
virtual void device_reset() override ATTR_COLD;
|
||||
virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
|
||||
|
||||
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 burst_mode_r() { return !m_drq_allowed; }
|
||||
|
||||
private:
|
||||
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;
|
||||
};
|
||||
|
||||
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_wait_cb(*this),
|
||||
device_t(mconfig, H89BUS_MMS77316, tag, owner, 0),
|
||||
device_h89bus_right_card_interface(mconfig, *this),
|
||||
m_fdc(*this, "mms_fdc"),
|
||||
m_floppies(*this, "mms_fdc:%u", 0U)
|
||||
{
|
||||
@ -69,13 +117,13 @@ void mms77316_fdc_device::ctrl_w(u8 val)
|
||||
|
||||
if (m_irq_allowed)
|
||||
{
|
||||
m_irq_cb(m_irq);
|
||||
m_drq_cb(m_drq);
|
||||
set_slot_fdcirq(m_irq);
|
||||
set_slot_fdcdrq(m_drq);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_irq_cb(CLEAR_LINE);
|
||||
m_drq_cb(CLEAR_LINE);
|
||||
set_slot_fdcirq(CLEAR_LINE);
|
||||
set_slot_fdcdrq(CLEAR_LINE);
|
||||
}
|
||||
|
||||
LOGDRIVE("%s: floppydrive: %d, 5.25 in: %d\n", FUNCNAME, floppy_drive, five_in_drv);
|
||||
@ -107,16 +155,21 @@ void mms77316_fdc_device::data_w(u8 val)
|
||||
{
|
||||
LOGBURST("%s: burst_mode_r\n", FUNCNAME);
|
||||
|
||||
m_wait_cb(ASSERT_LINE);
|
||||
set_slot_wait(ASSERT_LINE);
|
||||
return;
|
||||
}
|
||||
|
||||
m_fdc->data_w(val);
|
||||
}
|
||||
|
||||
void mms77316_fdc_device::write(offs_t reg, u8 val)
|
||||
void mms77316_fdc_device::write(u8 select_lines, u8 reg, u8 val)
|
||||
{
|
||||
LOGREG("%s: reg: %d val: 0x%02x\n", FUNCNAME, reg, val);
|
||||
if (!(select_lines & h89bus_device::H89_GPP))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (reg != 2) LOGREG("%s: reg: %d val: 0x%02x\n", FUNCNAME, reg, val);
|
||||
|
||||
switch (reg)
|
||||
{
|
||||
@ -153,7 +206,7 @@ u8 mms77316_fdc_device::data_r()
|
||||
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
m_wait_cb(ASSERT_LINE);
|
||||
set_slot_wait(ASSERT_LINE);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -166,8 +219,13 @@ u8 mms77316_fdc_device::data_r()
|
||||
return data;
|
||||
}
|
||||
|
||||
u8 mms77316_fdc_device::read(offs_t reg)
|
||||
u8 mms77316_fdc_device::read(u8 select_lines, u8 reg)
|
||||
{
|
||||
if (!(select_lines & h89bus_device::H89_GPP))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// default return for the h89
|
||||
u8 value = 0xff;
|
||||
|
||||
@ -215,9 +273,9 @@ void mms77316_fdc_device::device_reset()
|
||||
m_irq = false;
|
||||
m_drq_count = 0;
|
||||
|
||||
m_irq_cb(CLEAR_LINE);
|
||||
m_drq_cb(CLEAR_LINE);
|
||||
m_wait_cb(CLEAR_LINE);
|
||||
set_slot_fdcirq(CLEAR_LINE);
|
||||
set_slot_fdcdrq(CLEAR_LINE);
|
||||
set_slot_wait(CLEAR_LINE);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
@ -293,11 +351,11 @@ void mms77316_fdc_device::set_irq(int state)
|
||||
|
||||
if (m_irq)
|
||||
{
|
||||
m_wait_cb(CLEAR_LINE);
|
||||
set_slot_wait(CLEAR_LINE);
|
||||
m_drq_count = 0;
|
||||
}
|
||||
|
||||
m_irq_cb(m_irq_allowed ? m_irq : CLEAR_LINE);
|
||||
set_slot_fdcirq(m_irq_allowed ? m_irq : CLEAR_LINE);
|
||||
}
|
||||
|
||||
void mms77316_fdc_device::set_drq(int state)
|
||||
@ -312,13 +370,17 @@ void mms77316_fdc_device::set_drq(int state)
|
||||
|
||||
if (m_drq)
|
||||
{
|
||||
m_wait_cb(CLEAR_LINE);
|
||||
set_slot_wait(CLEAR_LINE);
|
||||
}
|
||||
|
||||
m_drq_cb(m_drq_count == 0 ? m_drq : CLEAR_LINE);
|
||||
set_slot_fdcdrq(m_drq_count == 0 ? m_drq : CLEAR_LINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_drq_cb(m_drq_allowed ? m_drq : CLEAR_LINE);
|
||||
set_slot_fdcdrq(m_drq_allowed ? m_drq : CLEAR_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
DEFINE_DEVICE_TYPE_PRIVATE(H89BUS_MMS77316, device_h89bus_right_card_interface, mms77316_fdc_device, "mms77316_fdc", "Magnolia MicroSystems 77316 Soft-sectored Controller");
|
18
src/devices/bus/heathzenith/h89/mms77316_fdc.h
Normal file
18
src/devices/bus/heathzenith/h89/mms77316_fdc.h
Normal file
@ -0,0 +1,18 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Mark Garlanger
|
||||
/***************************************************************************
|
||||
|
||||
Magnolia Microsystems 77316 soft-sectored floppy controller
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef MAME_BUS_HEATHZENITH_H89_MMS77316_FDC_H
|
||||
#define MAME_BUS_HEATHZENITH_H89_MMS77316_FDC_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "h89bus.h"
|
||||
|
||||
DECLARE_DEVICE_TYPE(H89BUS_MMS77316, device_h89bus_right_card_interface)
|
||||
|
||||
#endif // MAME_BUS_HEATHZENITH_H89_MMS77316_FDC_H
|
216
src/devices/bus/heathzenith/h89/sigmasoft_sound.cpp
Normal file
216
src/devices/bus/heathzenith/h89/sigmasoft_sound.cpp
Normal file
@ -0,0 +1,216 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Mark Garlanger
|
||||
/***************************************************************************
|
||||
|
||||
SigmaSoft Sound Effects Board
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "sound/ay8910.h"
|
||||
#include "speaker.h"
|
||||
|
||||
#include "sigmasoft_sound.h"
|
||||
|
||||
//
|
||||
// Logging defines
|
||||
//
|
||||
#define LOG_REG (1U << 1) // Shows register setup
|
||||
#define LOG_FUNC (1U << 2) // Function calls
|
||||
#define LOG_ERR (1U << 3)
|
||||
|
||||
#define VERBOSE (0)
|
||||
|
||||
#include "logmacro.h"
|
||||
|
||||
#define LOGREG(...) LOGMASKED(LOG_REG, __VA_ARGS__)
|
||||
#define LOGFUNC(...) LOGMASKED(LOG_FUNC, __VA_ARGS__)
|
||||
#define LOGERR(...) LOGMASKED(LOG_ERR, __VA_ARGS__)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define FUNCNAME __func__
|
||||
#else
|
||||
#define FUNCNAME __PRETTY_FUNCTION__
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
class h89bus_sigmasoft_snd_device : public device_t, public device_h89bus_right_card_interface
|
||||
{
|
||||
public:
|
||||
h89bus_sigmasoft_snd_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
|
||||
|
||||
virtual u8 read(u8 select_lines, u8 reg) override;
|
||||
virtual void write(u8 select_lines, u8 reg, u8 val) override;
|
||||
|
||||
protected:
|
||||
virtual void device_start() override ATTR_COLD;
|
||||
virtual void device_reset() override ATTR_COLD;
|
||||
virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
|
||||
virtual ioport_constructor device_input_ports() const override ATTR_COLD;
|
||||
|
||||
u8 read_joystick();
|
||||
|
||||
u8 transform_joystick_input(u8 raw_value);
|
||||
|
||||
private:
|
||||
required_device<ay8910_device> m_ay8910;
|
||||
required_ioport m_joystick1, m_joystick2;
|
||||
required_ioport m_config;
|
||||
|
||||
u8 port_selection;
|
||||
};
|
||||
|
||||
//**************************************************************************
|
||||
// INPUT PORTS
|
||||
//**************************************************************************
|
||||
static INPUT_PORTS_START( sigma_sound )
|
||||
PORT_START("joystick_p1")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
|
||||
|
||||
PORT_START("joystick_p2")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
|
||||
|
||||
PORT_START("CONFIG")
|
||||
PORT_CONFNAME(0x03, 0x01, "Port selection")
|
||||
PORT_CONFSETTING( 0x00, "Disabled")
|
||||
PORT_CONFSETTING( 0x01, "AUX - 320 Octal (0xD0)")
|
||||
PORT_CONFSETTING( 0x02, "MODEM - 330 Octal (0xD8)")
|
||||
PORT_CONFSETTING( 0x03, "LP - 340 Octal (0xE0)")
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
h89bus_sigmasoft_snd_device::h89bus_sigmasoft_snd_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock):
|
||||
device_t(mconfig, H89BUS_SIGMASOFT_SND, tag, owner, clock),
|
||||
device_h89bus_right_card_interface(mconfig, *this),
|
||||
m_ay8910(*this, "ay8910"),
|
||||
m_joystick1(*this, "joystick_p1"),
|
||||
m_joystick2(*this, "joystick_p2"),
|
||||
m_config(*this, "CONFIG")
|
||||
{
|
||||
}
|
||||
|
||||
void h89bus_sigmasoft_snd_device::write(u8 select_lines, u8 reg, u8 val)
|
||||
{
|
||||
// we respond to the SER0 decode
|
||||
if (!(select_lines & port_selection))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LOGFUNC("%s: reg: %d val: %d\n", FUNCNAME, reg, val);
|
||||
|
||||
switch (reg)
|
||||
{
|
||||
case 0:
|
||||
m_ay8910->data_w(val);
|
||||
break;
|
||||
case 1:
|
||||
m_ay8910->address_w(val);
|
||||
break;
|
||||
default:
|
||||
LOGERR("%s: unexpected port write: %d - 0x%02x]n", FUNCNAME, reg, val);
|
||||
}
|
||||
}
|
||||
|
||||
u8 h89bus_sigmasoft_snd_device::read(u8 select_lines, u8 reg)
|
||||
{
|
||||
if (!(select_lines & port_selection))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 value = 0x00;
|
||||
|
||||
switch (reg)
|
||||
{
|
||||
case 0:
|
||||
value = m_ay8910->data_r();
|
||||
break;
|
||||
case 1:
|
||||
value = this->read_joystick();
|
||||
break;
|
||||
default:
|
||||
LOGERR("%s: unexpected port read: %d\n", FUNCNAME, reg);
|
||||
}
|
||||
|
||||
LOGFUNC("%s: reg: %d val: %d\n", FUNCNAME, reg, value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
u8 h89bus_sigmasoft_snd_device::transform_joystick_input(u8 raw_value)
|
||||
{
|
||||
// when button on joystick is pressed, return 0xf
|
||||
if (raw_value & 0x10)
|
||||
{
|
||||
return 0xf;
|
||||
}
|
||||
|
||||
return raw_value & 0xf;
|
||||
}
|
||||
|
||||
// high nibble is for left joystick, low nibble is for right joystick
|
||||
// when the button is pressed nibble will be set to 0xf
|
||||
//
|
||||
// note: 2 bits may be set if the direction of the joystick is diagonal, such as 0x9 for left & up.
|
||||
//
|
||||
u8 h89bus_sigmasoft_snd_device::read_joystick()
|
||||
{
|
||||
u8 joy1 = m_joystick1->read();
|
||||
u8 joy2 = m_joystick2->read();
|
||||
|
||||
return this->transform_joystick_input(joy1) << 4 & this->transform_joystick_input(joy2);
|
||||
}
|
||||
|
||||
void h89bus_sigmasoft_snd_device::device_start()
|
||||
{
|
||||
}
|
||||
|
||||
void h89bus_sigmasoft_snd_device::device_reset()
|
||||
{
|
||||
ioport_value const config(m_config->read());
|
||||
|
||||
|
||||
switch (config & 0x03)
|
||||
{
|
||||
case 0x00:
|
||||
port_selection = 0;
|
||||
break;
|
||||
case 0x01:
|
||||
port_selection = h89bus_device::H89_SER0;
|
||||
break;
|
||||
case 0x02:
|
||||
port_selection = h89bus_device::H89_SER1;
|
||||
break;
|
||||
case 0x03:
|
||||
port_selection = h89bus_device::H89_LP;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ioport_constructor h89bus_sigmasoft_snd_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME( sigma_sound );
|
||||
}
|
||||
|
||||
void h89bus_sigmasoft_snd_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
SPEAKER(config, "mono").front_center();
|
||||
|
||||
AY8910(config, m_ay8910, XTAL(8'000'000)/4); /* ??? 2.000 MHz */
|
||||
m_ay8910->add_route(ALL_OUTPUTS, "mono", 0.25);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
DEFINE_DEVICE_TYPE_PRIVATE(H89BUS_SIGMASOFT_SND, device_h89bus_right_card_interface, h89bus_sigmasoft_snd_device, "h89sigmasnd", "SigmaSoft Sound Effects Board");
|
18
src/devices/bus/heathzenith/h89/sigmasoft_sound.h
Normal file
18
src/devices/bus/heathzenith/h89/sigmasoft_sound.h
Normal file
@ -0,0 +1,18 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Mark Garlanger
|
||||
/***************************************************************************
|
||||
|
||||
SigmaSoft Sound Effects Board
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef MAME_BUS_HEATHZENITH_H89_SIGMASOFT_SOUND_H
|
||||
#define MAME_BUS_HEATHZENITH_H89_SIGMASOFT_SOUND_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "h89bus.h"
|
||||
|
||||
DECLARE_DEVICE_TYPE(H89BUS_SIGMASOFT_SND, device_h89bus_right_card_interface)
|
||||
|
||||
#endif // MAME_BUS_HEATHZENITH_H89_SIGMASOFT_SOUND_H
|
45
src/devices/bus/heathzenith/h89/we_pullup.cpp
Normal file
45
src/devices/bus/heathzenith/h89/we_pullup.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Mark Garlanger
|
||||
/***************************************************************************
|
||||
|
||||
Heathkit Write enable pull
|
||||
|
||||
On
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "we_pullup.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class h89bus_we_pullup_device : public device_t, public device_h89bus_right_card_interface
|
||||
{
|
||||
public:
|
||||
h89bus_we_pullup_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
|
||||
|
||||
protected:
|
||||
virtual void device_start() override ATTR_COLD;
|
||||
virtual void device_reset() override ATTR_COLD;
|
||||
};
|
||||
|
||||
h89bus_we_pullup_device::h89bus_we_pullup_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock):
|
||||
device_t(mconfig, H89BUS_WE_PULLUP, tag, owner, 0),
|
||||
device_h89bus_right_card_interface(mconfig, *this)
|
||||
{
|
||||
}
|
||||
|
||||
void h89bus_we_pullup_device::device_start()
|
||||
{
|
||||
}
|
||||
|
||||
void h89bus_we_pullup_device::device_reset()
|
||||
{
|
||||
set_slot_fmwe(ASSERT_LINE);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
DEFINE_DEVICE_TYPE_PRIVATE(H89BUS_WE_PULLUP, device_h89bus_right_card_interface, h89bus_we_pullup_device, "h89_we_pullup", "Pullup resistor needed when P506 slot is empty");
|
18
src/devices/bus/heathzenith/h89/we_pullup.h
Normal file
18
src/devices/bus/heathzenith/h89/we_pullup.h
Normal file
@ -0,0 +1,18 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Mark Garlanger
|
||||
/***************************************************************************
|
||||
|
||||
Heathkit Write Enable Pullup
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef MAME_BUS_HEATHZENITH_H89_WE_PULLUP_H
|
||||
#define MAME_BUS_HEATHZENITH_H89_WE_PULLUP_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "h89bus.h"
|
||||
|
||||
DECLARE_DEVICE_TYPE(H89BUS_WE_PULLUP, device_h89bus_right_card_interface)
|
||||
|
||||
#endif // MAME_BUS_HEATHZENITH_H89_WE_PULLUP_H
|
@ -10,6 +10,9 @@
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "imagedev/floppy.h"
|
||||
#include "machine/wd_fdc.h"
|
||||
|
||||
#include "z37_fdc.h"
|
||||
|
||||
#define LOG_REG (1U << 1) // Shows register setup
|
||||
@ -32,20 +35,66 @@
|
||||
#define FUNCNAME __PRETTY_FUNCTION__
|
||||
#endif
|
||||
|
||||
DEFINE_DEVICE_TYPE(HEATH_Z37_FDC, heath_z37_fdc_device, "heath_z37_fdc", "Heath H/Z-37 Soft-sectored Controller");
|
||||
namespace {
|
||||
|
||||
heath_z37_fdc_device::heath_z37_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock):
|
||||
device_t(mconfig, HEATH_Z37_FDC, tag, owner, 0),
|
||||
m_irq_cb(*this),
|
||||
m_drq_cb(*this),
|
||||
m_block_interrupt_cb(*this),
|
||||
class h89bus_z37_device : public device_t, public device_h89bus_right_card_interface
|
||||
{
|
||||
public:
|
||||
h89bus_z37_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
|
||||
|
||||
virtual void write(u8 select_lines, u8 offset, u8 data) override;
|
||||
virtual u8 read(u8 select_lines, u8 offset) override;
|
||||
|
||||
protected:
|
||||
virtual void device_start() override ATTR_COLD;
|
||||
virtual void device_reset() override ATTR_COLD;
|
||||
virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
|
||||
|
||||
void ctrl_w(u8 val);
|
||||
|
||||
void intf_w(u8 val);
|
||||
|
||||
void cmd_w(u8 val);
|
||||
u8 stat_r();
|
||||
|
||||
void data_w(u8 val);
|
||||
u8 data_r();
|
||||
|
||||
void set_irq(int state);
|
||||
void set_drq(int state);
|
||||
|
||||
private:
|
||||
required_device<fd1797_device> m_fdc;
|
||||
required_device_array<floppy_connector, 4> m_floppies;
|
||||
|
||||
bool m_irq_allowed;
|
||||
bool m_drq_allowed;
|
||||
bool m_access_track_sector;
|
||||
|
||||
/// Bits set in cmd_ControlPort_c - DK.CON
|
||||
static constexpr u8 ctrl_EnableIntReq_c = 0;
|
||||
static constexpr u8 ctrl_EnableDrqInt_c = 1;
|
||||
static constexpr u8 ctrl_SetMFMRecording_c = 2;
|
||||
static constexpr u8 ctrl_MotorsOn_c = 3;
|
||||
static constexpr u8 ctrl_Drive_0_c = 4;
|
||||
static constexpr u8 ctrl_Drive_1_c = 5;
|
||||
static constexpr u8 ctrl_Drive_2_c = 6;
|
||||
static constexpr u8 ctrl_Drive_3_c = 7;
|
||||
|
||||
/// Bits to set alternate registers on InterfaceControl_c - DK.INT
|
||||
static constexpr u8 if_SelectSectorTrack_c = 0;
|
||||
};
|
||||
|
||||
h89bus_z37_device::h89bus_z37_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock):
|
||||
device_t(mconfig, H89BUS_Z37, tag, owner, 0),
|
||||
device_h89bus_right_card_interface(mconfig, *this),
|
||||
m_fdc(*this, "z37_fdc"),
|
||||
m_floppies(*this, "z37_fdc:%u", 0U)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void heath_z37_fdc_device::ctrl_w(u8 val)
|
||||
void h89bus_z37_device::ctrl_w(u8 val)
|
||||
{
|
||||
bool motor_on = bool(BIT(val, ctrl_MotorsOn_c));
|
||||
|
||||
@ -58,12 +107,12 @@ void heath_z37_fdc_device::ctrl_w(u8 val)
|
||||
|
||||
if (m_drq_allowed)
|
||||
{
|
||||
m_block_interrupt_cb(1);
|
||||
set_slot_blockirq(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_block_interrupt_cb(0);
|
||||
m_drq_cb(0);
|
||||
set_slot_blockirq(0);
|
||||
set_slot_fdcdrq(0);
|
||||
}
|
||||
|
||||
if (BIT(val, ctrl_Drive_0_c))
|
||||
@ -102,60 +151,70 @@ void heath_z37_fdc_device::ctrl_w(u8 val)
|
||||
}
|
||||
}
|
||||
|
||||
void heath_z37_fdc_device::intf_w(u8 val)
|
||||
void h89bus_z37_device::intf_w(u8 val)
|
||||
{
|
||||
m_access_track_sector = bool(BIT(val, if_SelectSectorTrack_c));
|
||||
|
||||
LOGREG("access track/sector: %d\n", m_access_track_sector);
|
||||
}
|
||||
|
||||
void heath_z37_fdc_device::cmd_w(u8 val)
|
||||
void h89bus_z37_device::cmd_w(u8 val)
|
||||
{
|
||||
m_access_track_sector ? m_fdc->sector_w(val) : m_fdc->cmd_w(val);
|
||||
}
|
||||
|
||||
u8 heath_z37_fdc_device::stat_r()
|
||||
u8 h89bus_z37_device::stat_r()
|
||||
{
|
||||
return m_access_track_sector ? m_fdc->sector_r() : m_fdc->status_r();
|
||||
}
|
||||
|
||||
void heath_z37_fdc_device::data_w(u8 val)
|
||||
void h89bus_z37_device::data_w(u8 val)
|
||||
{
|
||||
m_access_track_sector ? m_fdc->track_w(val) : m_fdc->data_w(val);
|
||||
}
|
||||
|
||||
u8 heath_z37_fdc_device::data_r()
|
||||
u8 h89bus_z37_device::data_r()
|
||||
{
|
||||
return m_access_track_sector ? m_fdc->track_r() : m_fdc->data_r();
|
||||
}
|
||||
|
||||
void heath_z37_fdc_device::write(offs_t reg, u8 val)
|
||||
void h89bus_z37_device::write(u8 select_lines, u8 offset, u8 data)
|
||||
{
|
||||
LOGFUNC("%s: reg: %d val: 0x%02x\n", FUNCNAME, reg, val);
|
||||
if (!(select_lines & h89bus_device::H89_CASS))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (reg)
|
||||
LOGFUNC("%s: reg: %d val: 0x%02x\n", FUNCNAME, offset, data);
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0:
|
||||
ctrl_w(val);
|
||||
ctrl_w(data);
|
||||
break;
|
||||
case 1:
|
||||
intf_w(val);
|
||||
intf_w(data);
|
||||
break;
|
||||
case 2:
|
||||
cmd_w(val);
|
||||
cmd_w(data);
|
||||
break;
|
||||
case 3:
|
||||
data_w(val);
|
||||
data_w(data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
u8 heath_z37_fdc_device::read(offs_t reg)
|
||||
u8 h89bus_z37_device::read(u8 select_lines, u8 offset)
|
||||
{
|
||||
if (!(select_lines & h89bus_device::H89_CASS))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// default return for the h89
|
||||
u8 value = 0xff;
|
||||
|
||||
switch (reg)
|
||||
switch (offset)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
@ -169,27 +228,27 @@ u8 heath_z37_fdc_device::read(offs_t reg)
|
||||
break;
|
||||
}
|
||||
|
||||
LOGFUNC("%s: reg: %d val: 0x%02x\n", FUNCNAME, reg, value);
|
||||
LOGFUNC("%s: reg: %d val: 0x%02x\n", FUNCNAME, offset, value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void heath_z37_fdc_device::device_start()
|
||||
void h89bus_z37_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_irq_allowed));
|
||||
save_item(NAME(m_drq_allowed));
|
||||
save_item(NAME(m_access_track_sector));
|
||||
}
|
||||
|
||||
void heath_z37_fdc_device::device_reset()
|
||||
void h89bus_z37_device::device_reset()
|
||||
{
|
||||
m_irq_allowed = false;
|
||||
m_drq_allowed = false;
|
||||
m_access_track_sector = false;
|
||||
|
||||
m_irq_cb(0);
|
||||
m_drq_cb(0);
|
||||
m_block_interrupt_cb(0);
|
||||
set_slot_fdcirq(0);
|
||||
set_slot_fdcdrq(0);
|
||||
set_slot_blockirq(0);
|
||||
}
|
||||
|
||||
static void z37_floppies(device_slot_interface &device)
|
||||
@ -204,11 +263,11 @@ static void z37_floppies(device_slot_interface &device)
|
||||
device.option_add("qd", FLOPPY_525_QD);
|
||||
}
|
||||
|
||||
void heath_z37_fdc_device::device_add_mconfig(machine_config &config)
|
||||
void h89bus_z37_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
FD1797(config, m_fdc, 16_MHz_XTAL / 16);
|
||||
m_fdc->intrq_wr_callback().set(FUNC(heath_z37_fdc_device::set_irq));
|
||||
m_fdc->drq_wr_callback().set(FUNC(heath_z37_fdc_device::set_drq));
|
||||
m_fdc->intrq_wr_callback().set(FUNC(h89bus_z37_device::set_irq));
|
||||
m_fdc->drq_wr_callback().set(FUNC(h89bus_z37_device::set_drq));
|
||||
// Z-89-37 schematics show the ready line tied high.
|
||||
m_fdc->set_force_ready(true);
|
||||
|
||||
@ -222,16 +281,20 @@ void heath_z37_fdc_device::device_add_mconfig(machine_config &config)
|
||||
m_floppies[3]->enable_sound(true);
|
||||
}
|
||||
|
||||
void heath_z37_fdc_device::set_irq(int state)
|
||||
void h89bus_z37_device::set_irq(int state)
|
||||
{
|
||||
LOGLINES("set irq, allowed: %d state: %d\n", m_irq_allowed, state);
|
||||
|
||||
m_irq_cb(m_irq_allowed ? state : CLEAR_LINE);
|
||||
set_slot_fdcirq(m_irq_allowed ? state : CLEAR_LINE);
|
||||
}
|
||||
|
||||
void heath_z37_fdc_device::set_drq(int state)
|
||||
void h89bus_z37_device::set_drq(int state)
|
||||
{
|
||||
LOGLINES("set drq, allowed: %d state: %d\n", m_drq_allowed, state);
|
||||
|
||||
m_drq_cb(m_drq_allowed ? state : CLEAR_LINE);
|
||||
set_slot_fdcdrq(m_drq_allowed ? state : CLEAR_LINE);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
DEFINE_DEVICE_TYPE_PRIVATE(H89BUS_Z37, device_h89bus_right_card_interface, h89bus_z37_device, "h89_z37", "Heathkit Z-37 Floppy Disk Controller");
|
18
src/devices/bus/heathzenith/h89/z37_fdc.h
Normal file
18
src/devices/bus/heathzenith/h89/z37_fdc.h
Normal file
@ -0,0 +1,18 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Mark Garlanger
|
||||
/***************************************************************************
|
||||
|
||||
Heathkit Z-37 Floppy Disk Controller
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef MAME__Z37_FDC_H
|
||||
#define MAME_BUS_HEATHZENITH_H89_Z37_FDC_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "h89bus.h"
|
||||
|
||||
DECLARE_DEVICE_TYPE(H89BUS_Z37, device_h89bus_right_card_interface)
|
||||
|
||||
#endif // MAME_BUS_HEATHZENITH_H89_Z37_FDC_H
|
@ -43,13 +43,13 @@
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#include "h_88_cass.h"
|
||||
#include "intr_cntrl.h"
|
||||
#include "mms77316_fdc.h"
|
||||
//#include "mms77316_fdc.h"
|
||||
#include "sigmasoft_parallel_port.h"
|
||||
#include "tlb.h"
|
||||
#include "z37_fdc.h"
|
||||
|
||||
#include "bus/heathzenith/h89/h89bus.h"
|
||||
#include "bus/heathzenith/h89/cards.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "machine/ins8250.h"
|
||||
#include "machine/ram.h"
|
||||
@ -86,11 +86,10 @@ protected:
|
||||
m_floppy_ram(*this, "floppyram"),
|
||||
m_tlbc(*this, "tlbc"),
|
||||
m_intr_socket(*this, "intr_socket"),
|
||||
m_h89bus(*this, "h89bus"),
|
||||
m_console(*this, "console"),
|
||||
m_serial1(*this, "serial1"),
|
||||
m_serial2(*this, "serial2"),
|
||||
m_serial3(*this, "serial3"),
|
||||
m_config(*this, "CONFIG")
|
||||
m_config(*this, "CONFIG"),
|
||||
m_sw501(*this, "SW501")
|
||||
{
|
||||
}
|
||||
|
||||
@ -103,11 +102,9 @@ protected:
|
||||
required_shared_ptr<u8> m_floppy_ram;
|
||||
required_device<heath_tlb_connector> m_tlbc;
|
||||
required_device<heath_intr_socket> m_intr_socket;
|
||||
required_device<h89bus_device> m_h89bus;
|
||||
required_device<ins8250_device> m_console;
|
||||
required_device<ins8250_device> m_serial1;
|
||||
required_device<ins8250_device> m_serial2;
|
||||
required_device<ins8250_device> m_serial3;
|
||||
required_ioport m_config;
|
||||
required_ioport m_config, m_sw501;
|
||||
memory_access<16, 0, 0, ENDIANNESS_LITTLE>::specific m_program;
|
||||
|
||||
// General Purpose Port (GPP)
|
||||
@ -129,16 +126,18 @@ protected:
|
||||
static constexpr XTAL H89_CLOCK = XTAL(12'288'000) / 6;
|
||||
static constexpr XTAL INS8250_CLOCK = XTAL(1'843'200);
|
||||
|
||||
static constexpr u8 GPP_SINGLE_STEP_BIT = 0;
|
||||
static constexpr u8 GPP_ENABLE_TIMER_INTERRUPT_BIT = 1;
|
||||
static constexpr u8 GPP_SPEED_SELECT_BIT = 4;
|
||||
static constexpr u8 GPP_DISABLE_ROM_BIT = 5;
|
||||
static constexpr u8 GPP_H17_SIDE_SELECT_BIT = 6;
|
||||
static constexpr u8 GPP_SINGLE_STEP_BIT = 0;
|
||||
static constexpr u8 GPP_ENABLE_TIMER_INTERRUPT_BIT = 1;
|
||||
static constexpr u8 GPP_MEM1_BIT = 2;
|
||||
static constexpr u8 GPP_MEM0_BIT = 4;
|
||||
static constexpr u8 GPP_DISABLE_ROM_BIT = 5;
|
||||
static constexpr u8 GPP_IO0_BIT = 6;
|
||||
static constexpr u8 GPP_IO1_BIT = 7;
|
||||
|
||||
void update_mem_view();
|
||||
|
||||
void update_gpp(u8 gpp);
|
||||
void port_f2_w(u8 data);
|
||||
void port_f2_w(offs_t offset, u8 data);
|
||||
|
||||
virtual void machine_start() override ATTR_COLD;
|
||||
virtual void machine_reset() override ATTR_COLD;
|
||||
@ -157,6 +156,8 @@ protected:
|
||||
void console_intr(int data);
|
||||
void reset_line(int data);
|
||||
void reset_single_step_state();
|
||||
|
||||
template <int line> void slot_irq(int state);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -169,17 +170,14 @@ class h88_state : public h89_base_state
|
||||
{
|
||||
public:
|
||||
h88_state(const machine_config &mconfig, device_type type, const char *tag):
|
||||
h89_base_state(mconfig, type, tag),
|
||||
m_cassette(*this, "h_88_5")
|
||||
h89_base_state(mconfig, type, tag)
|
||||
{
|
||||
}
|
||||
|
||||
void h88(machine_config &config);
|
||||
|
||||
protected:
|
||||
required_device<heath_h_88_cass_device> m_cassette;
|
||||
|
||||
void h88_io(address_map &map) ATTR_COLD;
|
||||
void h88_io(address_map &map);
|
||||
};
|
||||
|
||||
|
||||
@ -192,20 +190,13 @@ class h89_state : public h89_base_state
|
||||
{
|
||||
public:
|
||||
h89_state(const machine_config &mconfig, device_type type, const char *tag):
|
||||
h89_base_state(mconfig, type, tag),
|
||||
m_h37(*this, "h37")
|
||||
h89_base_state(mconfig, type, tag)
|
||||
{
|
||||
}
|
||||
|
||||
void h89(machine_config &config);
|
||||
|
||||
protected:
|
||||
required_device<heath_z37_fdc_device> m_h37;
|
||||
|
||||
void h89_io(address_map &map) ATTR_COLD;
|
||||
};
|
||||
|
||||
|
||||
class h89_sigmasoft_state : public h89_state
|
||||
{
|
||||
public:
|
||||
@ -220,7 +211,7 @@ public:
|
||||
protected:
|
||||
required_device<sigmasoft_parallel_port> m_sigma_parallel;
|
||||
|
||||
void h89_sigmasoft_io(address_map &map) ATTR_COLD;
|
||||
void h89_sigmasoft_io(address_map &map);
|
||||
};
|
||||
|
||||
|
||||
@ -248,17 +239,15 @@ 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_mms316(*this, "mms77316")
|
||||
h89_base_state(mconfig, type, tag)
|
||||
{
|
||||
}
|
||||
|
||||
void h89_mms(machine_config &config);
|
||||
|
||||
protected:
|
||||
required_device<mms77316_fdc_device> m_mms316;
|
||||
|
||||
void h89_mms_io(address_map &map) ATTR_COLD;
|
||||
u8 port_f2_mms_r(offs_t offset);
|
||||
void port_f2_mms_w(offs_t offset, u8 data);
|
||||
};
|
||||
|
||||
|
||||
@ -389,46 +378,11 @@ void h89_base_state::h89_base_io(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map.global_mask(0xff);
|
||||
|
||||
// 8250 UART DCE 0320 (0xd0)
|
||||
map(0xd0, 0xd7).rw(m_serial1, FUNC(ins8250_device::ins8250_r), FUNC(ins8250_device::ins8250_w));
|
||||
// 8250 UART DTE 0330 (0xd8) - typically used for modem
|
||||
map(0xd8, 0xdf).rw(m_serial2, FUNC(ins8250_device::ins8250_r), FUNC(ins8250_device::ins8250_w));
|
||||
// 8250 UART DCE 0340 (0xe0) - typically used for printer
|
||||
map(0xe0, 0xe7).rw(m_serial3, FUNC(ins8250_device::ins8250_r), FUNC(ins8250_device::ins8250_w));
|
||||
|
||||
// 8250 UART console - this connects internally to the Terminal Logic board that is also used in the H19.
|
||||
map(0xe8, 0xef).rw(m_console, FUNC(ins8250_device::ins8250_r), FUNC(ins8250_device::ins8250_w));
|
||||
|
||||
// ports defined on the H8. On the H89, access to these addresses causes a NMI
|
||||
map(0xf0, 0xf1).rw(FUNC(h89_base_state::raise_NMI_r),FUNC(h89_base_state::raise_NMI_w));
|
||||
|
||||
// General Purpose Port (GPP)
|
||||
map(0xf2, 0xf2).w(FUNC(h89_base_state::port_f2_w)).portr("SW501");
|
||||
|
||||
// port defined on the H8. On the H89, access to these addresses causes a NMI
|
||||
map(0xfa, 0xfb).rw(FUNC(h89_base_state::raise_NMI_r), FUNC(h89_base_state::raise_NMI_w));
|
||||
}
|
||||
|
||||
void h88_state::h88_io(address_map &map)
|
||||
{
|
||||
h89_base_state::h89_base_io(map);
|
||||
|
||||
// Cassette I/O (uses 0xf8 - 0xf9) - Requires MTR-88 ROM
|
||||
map(0xf8, 0xf9).rw(m_cassette, FUNC(heath_h_88_cass_device::read), FUNC(heath_h_88_cass_device::write));
|
||||
}
|
||||
|
||||
void h89_state::h89_io(address_map &map)
|
||||
{
|
||||
h89_base_state::h89_base_io(map);
|
||||
|
||||
// H37 5-1/4" Soft-sectored Controller - Requires MTR-90 ROM
|
||||
map(0x78, 0x7b).rw(m_h37, FUNC(heath_z37_fdc_device::read), FUNC(heath_z37_fdc_device::write));
|
||||
}
|
||||
|
||||
void h89_sigmasoft_state::h89_sigmasoft_io(address_map &map)
|
||||
{
|
||||
h89_io(map);
|
||||
h89_base_io(map);
|
||||
|
||||
// Add SigmaSoft parallel port board, required for IGC graphics
|
||||
map(0x08,0x0f).rw(m_sigma_parallel, FUNC(sigmasoft_parallel_port::read), FUNC(sigmasoft_parallel_port::write));
|
||||
@ -463,14 +417,6 @@ void h89_sigmasoft_state::h89_sigmasoft_io(address_map &map)
|
||||
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_mms316, FUNC(mms77316_fdc_device::read), FUNC(mms77316_fdc_device::write));
|
||||
}
|
||||
|
||||
|
||||
// Input ports
|
||||
static INPUT_PORTS_START( h88 )
|
||||
@ -818,6 +764,15 @@ void h89_base_state::console_intr(int data)
|
||||
m_intr_socket->set_irq_level(3, data);
|
||||
}
|
||||
|
||||
template <int line> void h89_base_state::slot_irq(int state)
|
||||
{
|
||||
m_intr_socket->set_irq_level(line, state);
|
||||
}
|
||||
|
||||
template void h89_base_state::slot_irq<3>(int state);
|
||||
template void h89_base_state::slot_irq<4>(int state);
|
||||
template void h89_base_state::slot_irq<5>(int state);
|
||||
|
||||
void h89_base_state::reset_line(int data)
|
||||
{
|
||||
if (bool(data))
|
||||
@ -870,6 +825,11 @@ void h89_base_state::update_gpp(u8 gpp)
|
||||
|
||||
m_timer_intr_enabled = bool(BIT(m_gpp, GPP_ENABLE_TIMER_INTERRUPT_BIT));
|
||||
|
||||
m_h89bus->set_mem0(BIT(m_gpp, GPP_MEM0_BIT));
|
||||
m_h89bus->set_mem1(BIT(m_gpp, GPP_MEM1_BIT));
|
||||
m_h89bus->set_io0(BIT(m_gpp, GPP_IO0_BIT));
|
||||
m_h89bus->set_io1(BIT(m_gpp, GPP_IO1_BIT));
|
||||
|
||||
if (BIT(changed_gpp, GPP_SINGLE_STEP_BIT))
|
||||
{
|
||||
LOGSS("single step enable: %d\n", BIT(m_gpp, GPP_SINGLE_STEP_BIT));
|
||||
@ -888,21 +848,46 @@ void h89_base_state::update_gpp(u8 gpp)
|
||||
update_mem_view();
|
||||
}
|
||||
|
||||
if (BIT(changed_gpp, GPP_SPEED_SELECT_BIT))
|
||||
if (BIT(changed_gpp, GPP_MEM0_BIT))
|
||||
{
|
||||
m_maincpu->set_clock(BIT(m_gpp, GPP_SPEED_SELECT_BIT) ?
|
||||
m_maincpu->set_clock(BIT(m_gpp, GPP_MEM0_BIT) ?
|
||||
H89_CLOCK * m_cpu_speed_multiplier : H89_CLOCK);
|
||||
}
|
||||
}
|
||||
|
||||
// General Purpose Port
|
||||
void h89_base_state::port_f2_w(u8 data)
|
||||
void h89_base_state::port_f2_w(offs_t offset, u8 data)
|
||||
{
|
||||
update_gpp(data);
|
||||
|
||||
m_intr_socket->set_irq_level(1, CLEAR_LINE);
|
||||
}
|
||||
|
||||
// MMS intercepts the GPIO decoding so the GPIO pin on
|
||||
// the right slots can be used as a card select without
|
||||
// interfering with normal GPIO port operation.
|
||||
u8 h89_mms_state::port_f2_mms_r(offs_t offset)
|
||||
{
|
||||
if ((offset & 7) != 2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return m_sw501->read();
|
||||
}
|
||||
|
||||
void h89_mms_state::port_f2_mms_w(offs_t offset, u8 data)
|
||||
{
|
||||
if ((offset & 7) != 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
update_gpp(data);
|
||||
|
||||
m_intr_socket->set_irq_level(1, CLEAR_LINE);
|
||||
}
|
||||
|
||||
static void tlb_options(device_slot_interface &device)
|
||||
{
|
||||
device.option_add("heath", HEATH_TLB);
|
||||
@ -940,6 +925,7 @@ void h89_base_state::h89_base(machine_config &config)
|
||||
Z80(config, m_maincpu, H89_CLOCK);
|
||||
m_maincpu->set_m1_map(&h89_base_state::map_fetch);
|
||||
m_maincpu->set_memory_map(&h89_base_state::h89_mem);
|
||||
m_maincpu->set_io_map(&h88_state::h89_base_io);
|
||||
m_maincpu->set_irq_acknowledge_callback("intr_socket", FUNC(heath_intr_socket::irq_callback));
|
||||
|
||||
RAM(config, m_ram).set_default_size("64K").set_extra_options("16K,32K,48K").set_default_value(0x00);
|
||||
@ -962,10 +948,28 @@ void h89_base_state::h89_base(machine_config &config)
|
||||
|
||||
m_tlbc->reset_cb().set(FUNC(h89_base_state::reset_line));
|
||||
|
||||
// H-88-3 3-port serial board
|
||||
INS8250(config, m_serial1, INS8250_CLOCK);
|
||||
INS8250(config, m_serial2, INS8250_CLOCK);
|
||||
INS8250(config, m_serial3, INS8250_CLOCK);
|
||||
H89BUS(config, m_h89bus, 0);
|
||||
m_h89bus->set_program_space(m_maincpu, AS_PROGRAM);
|
||||
m_h89bus->set_io_space(m_maincpu, AS_IO);
|
||||
m_h89bus->in_tlb_callback().set(m_console, FUNC(ins8250_device::ins8250_r));
|
||||
m_h89bus->out_tlb_callback().set(m_console, FUNC(ins8250_device::ins8250_w));
|
||||
m_h89bus->in_nmi_callback().set(FUNC(h89_base_state::raise_NMI_r));
|
||||
m_h89bus->out_nmi_callback().set(FUNC(h89_base_state::raise_NMI_w));
|
||||
m_h89bus->in_gpp_callback().set_ioport("SW501");
|
||||
m_h89bus->out_gpp_callback().set(FUNC(h89_base_state::port_f2_w));
|
||||
m_h89bus->out_int3_callback().set(FUNC(h89_base_state::slot_irq<3>));
|
||||
m_h89bus->out_int4_callback().set(FUNC(h89_base_state::slot_irq<4>));
|
||||
m_h89bus->out_int5_callback().set(FUNC(h89_base_state::slot_irq<5>));
|
||||
m_h89bus->out_wait_callback().set(FUNC(h89_base_state::set_wait_state));
|
||||
m_h89bus->out_fdcirq_callback().set(m_intr_socket, FUNC(heath_intr_socket::set_irq));
|
||||
m_h89bus->out_fdcdrq_callback().set(m_intr_socket, FUNC(heath_intr_socket::set_drq));
|
||||
m_h89bus->out_blockirq_callback().set(m_intr_socket, FUNC(heath_intr_socket::block_interrupts));
|
||||
H89BUS_LEFT_SLOT(config, "p501", "h89bus", h89_left_cards, nullptr);
|
||||
H89BUS_LEFT_SLOT(config, "p502", "h89bus", h89_left_cards, nullptr);
|
||||
H89BUS_LEFT_SLOT(config, "p503", "h89bus", h89_left_cards, nullptr);
|
||||
H89BUS_RIGHT_SLOT(config, "p504", "h89bus", h89_right_cards, nullptr);
|
||||
H89BUS_RIGHT_SLOT(config, "p505", "h89bus", h89_right_cards, "ha_88_3");
|
||||
H89BUS_RIGHT_SLOT(config, "p506", "h89bus", h89_right_p506_cards, "we_pullup").set_p506_signalling(true);
|
||||
|
||||
// H89 interrupt interval is 2mSec
|
||||
TIMER(config, "irq_timer", 0).configure_periodic(FUNC(h89_base_state::h89_irq_timer), attotime::from_msec(2));
|
||||
@ -974,37 +978,31 @@ void h89_base_state::h89_base(machine_config &config)
|
||||
void h88_state::h88(machine_config &config)
|
||||
{
|
||||
h89_base(config);
|
||||
|
||||
m_maincpu->set_io_map(&h88_state::h88_io);
|
||||
m_h89bus->set_default_bios_tag("444-43");
|
||||
|
||||
m_intr_socket->set_default_option("original");
|
||||
m_intr_socket->set_fixed(true);
|
||||
|
||||
SOFTWARE_LIST(config, "cass_list").set_original("h88_cass");
|
||||
|
||||
// H-88-5 Cassette interface board
|
||||
HEATH_H88_CASS(config, m_cassette, H89_CLOCK);
|
||||
H89BUS_RIGHT_SLOT(config.replace(), "p504", "h89bus", h89_right_cards, "h_88_5");
|
||||
}
|
||||
|
||||
void h89_state::h89(machine_config &config)
|
||||
{
|
||||
h89_base(config);
|
||||
m_h89bus->set_default_bios_tag("444-61");
|
||||
|
||||
m_maincpu->set_io_map(&h89_state::h89_io);
|
||||
m_maincpu->set_io_map(&h89_state::h89_base_io);
|
||||
|
||||
m_intr_socket->set_default_option("h37");
|
||||
m_intr_socket->set_fixed(true);
|
||||
|
||||
// Z-89-37 Soft-sectored controller
|
||||
HEATH_Z37_FDC(config, m_h37);
|
||||
m_h37->drq_cb().set(m_intr_socket, FUNC(heath_intr_socket::set_drq));
|
||||
m_h37->irq_cb().set(m_intr_socket, FUNC(heath_intr_socket::set_irq));
|
||||
m_h37->block_interrupt_cb().set(m_intr_socket, FUNC(heath_intr_socket::block_interrupts));
|
||||
H89BUS_RIGHT_SLOT(config.replace(), "p504", "h89bus", h89_right_cards, "z37fdc");
|
||||
}
|
||||
|
||||
void h89_sigmasoft_state::h89_sigmasoft(machine_config &config)
|
||||
{
|
||||
h89(config);
|
||||
m_h89bus->set_default_bios_tag("444-61");
|
||||
m_maincpu->set_addrmap(AS_IO, &h89_sigmasoft_state::h89_sigmasoft_io);
|
||||
|
||||
sigma_tlb_options(m_tlbc);
|
||||
@ -1023,15 +1021,18 @@ void h89_sigmasoft_state::h89_sigmasoft(machine_config &config)
|
||||
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_h89bus->set_default_bios_tag("444-61c");
|
||||
|
||||
m_h89bus->in_gpp_callback().set(FUNC(h89_mms_state::port_f2_mms_r));
|
||||
m_h89bus->out_gpp_callback().set(FUNC(h89_mms_state::port_f2_mms_w));
|
||||
|
||||
// the card selection is different with the MMS mapping PROM
|
||||
H89BUS_RIGHT_SLOT(config.replace(), "p504", "h89bus", h89_right_cards_mms, "mms77316");
|
||||
H89BUS_RIGHT_SLOT(config.replace(), "p505", "h89bus", h89_right_cards_mms, "ha_88_3");
|
||||
H89BUS_RIGHT_SLOT(config.replace(), "p506", "h89bus", h89_right_cards_mms, nullptr).set_p506_signalling(true);
|
||||
|
||||
m_intr_socket->set_default_option("mms");
|
||||
m_intr_socket->set_fixed(true);
|
||||
|
||||
MMS77316_FDC(config, m_mms316);
|
||||
m_mms316->drq_cb().set(m_intr_socket, FUNC(heath_intr_socket::set_drq));
|
||||
m_mms316->irq_cb().set(m_intr_socket, FUNC(heath_intr_socket::set_irq));
|
||||
m_mms316->wait_cb().set(FUNC(h89_mms_state::set_wait_state));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,53 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Mark Garlanger
|
||||
/***************************************************************************
|
||||
|
||||
Heathkit H-88-5 Cassette Interface card
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef MAME_HEATHKIT_H_88_CASS_H
|
||||
#define MAME_HEATHKIT_H_88_CASS_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "imagedev/cassette.h"
|
||||
#include "machine/i8251.h"
|
||||
#include "machine/timer.h"
|
||||
|
||||
#include "formats/h8_cas.h"
|
||||
|
||||
|
||||
class heath_h_88_cass_device : public device_t
|
||||
{
|
||||
public:
|
||||
heath_h_88_cass_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);
|
||||
|
||||
protected:
|
||||
|
||||
virtual void device_start() override ATTR_COLD;
|
||||
virtual void device_reset() override ATTR_COLD;
|
||||
virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
|
||||
|
||||
void uart_rts(u8 data);
|
||||
void uart_tx_empty(u8 data);
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(kansas_r);
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(kansas_w);
|
||||
|
||||
required_device<i8251_device> m_uart;
|
||||
required_device<cassette_image_device> m_cass_player;
|
||||
required_device<cassette_image_device> m_cass_recorder;
|
||||
|
||||
u8 m_cass_data[4];
|
||||
bool m_cassbit;
|
||||
bool m_cassold;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(HEATH_H88_CASS, heath_h_88_cass_device)
|
||||
|
||||
|
||||
#endif // MAME_HEATHKIT_H_88_CASS_H
|
@ -1,80 +0,0 @@
|
||||
// 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(); }
|
||||
auto wait_cb() { return m_wait_cb.bind(); }
|
||||
|
||||
protected:
|
||||
|
||||
virtual void device_start() override ATTR_COLD;
|
||||
virtual void device_reset() override ATTR_COLD;
|
||||
virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
|
||||
|
||||
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 burst_mode_r() { return !m_drq_allowed; }
|
||||
|
||||
private:
|
||||
|
||||
devcb_write_line m_irq_cb;
|
||||
devcb_write_line m_drq_cb;
|
||||
devcb_write_line m_wait_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
|
@ -1,78 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Mark Garlanger
|
||||
/***************************************************************************
|
||||
|
||||
Heathkit Z-37 Floppy Disk Controller
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef MAME_HEATHKIT_Z37_FDC_H
|
||||
#define MAME_HEATHKIT_Z37_FDC_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "imagedev/floppy.h"
|
||||
#include "machine/wd_fdc.h"
|
||||
|
||||
|
||||
class heath_z37_fdc_device : public device_t
|
||||
{
|
||||
public:
|
||||
heath_z37_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(); }
|
||||
|
||||
auto block_interrupt_cb() { return m_block_interrupt_cb.bind(); }
|
||||
|
||||
protected:
|
||||
|
||||
virtual void device_start() override ATTR_COLD;
|
||||
virtual void device_reset() override ATTR_COLD;
|
||||
virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
|
||||
|
||||
void ctrl_w(u8 val);
|
||||
|
||||
void intf_w(u8 val);
|
||||
|
||||
void cmd_w(u8 val);
|
||||
u8 stat_r();
|
||||
|
||||
void data_w(u8 val);
|
||||
u8 data_r();
|
||||
|
||||
void set_irq(int state);
|
||||
void set_drq(int state);
|
||||
|
||||
private:
|
||||
devcb_write_line m_irq_cb;
|
||||
devcb_write_line m_drq_cb;
|
||||
devcb_write_line m_block_interrupt_cb;
|
||||
|
||||
required_device<fd1797_device> m_fdc;
|
||||
required_device_array<floppy_connector, 4> m_floppies;
|
||||
|
||||
bool m_irq_allowed;
|
||||
bool m_drq_allowed;
|
||||
bool m_access_track_sector;
|
||||
|
||||
/// Bits set in cmd_ControlPort_c - DK.CON
|
||||
static constexpr u8 ctrl_EnableIntReq_c = 0;
|
||||
static constexpr u8 ctrl_EnableDrqInt_c = 1;
|
||||
static constexpr u8 ctrl_SetMFMRecording_c = 2;
|
||||
static constexpr u8 ctrl_MotorsOn_c = 3;
|
||||
static constexpr u8 ctrl_Drive_0_c = 4;
|
||||
static constexpr u8 ctrl_Drive_1_c = 5;
|
||||
static constexpr u8 ctrl_Drive_2_c = 6;
|
||||
static constexpr u8 ctrl_Drive_3_c = 7;
|
||||
|
||||
/// Bits to set alternate registers on InterfaceControl_c - DK.INT
|
||||
static constexpr u8 if_SelectSectorTrack_c = 0;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(HEATH_Z37_FDC, heath_z37_fdc_device)
|
||||
|
||||
|
||||
#endif // MAME_HEATHKIT_Z37_FDC_H
|
Loading…
Reference in New Issue
Block a user