heathzenith/h89.cpp: Convert SigmaSoft parallel port into an h89 left card. (#13024)

This commit is contained in:
Mark Garlanger 2024-11-28 11:46:25 -06:00 committed by GitHub
parent 54af069e4e
commit 0e62ff6dcd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 319 additions and 335 deletions

View File

@ -5765,9 +5765,23 @@ if (BUSES["H89BUS"]~=null) then
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/sigmasoft_parallel_port.cpp",
MAME_DIR .. "src/devices/bus/heathzenith/h89/sigmasoft_parallel_port.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
---------------------------------------------------
--
--@src/devices/bus/heathzenith/h19/tlb.h,BUSES["HEATH_TLB_CONNECTOR"] = true
---------------------------------------------------
if (BUSES["HEATH_TLB_CONNECTOR"]~=null) then
files {
MAME_DIR .. "src/devices/bus/heathzenith/h19/tlb.cpp",
MAME_DIR .. "src/devices/bus/heathzenith/h19/tlb.h",
}
end

View File

@ -12,12 +12,14 @@
#include "h_88_3.h"
#include "h_88_5.h"
#include "mms77316_fdc.h"
#include "sigmasoft_parallel_port.h"
#include "sigmasoft_sound.h"
#include "we_pullup.h"
#include "z37_fdc.h"
void h89_left_cards(device_slot_interface &device)
{
device.option_add("ss_parallel", H89BUS_SIGMASOFT_PARALLEL);
}
void h89_right_cards(device_slot_interface &device)

View File

@ -1,5 +1,5 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont
// copyright-holders:R. Belmont, Mark Garlanger
/***************************************************************************
h89bus.cpp - Heath/Zenith H-89/Z-90 bus
@ -175,8 +175,7 @@ const tiny_rom_entry *h89bus_device::device_rom_region() const
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)));
m_io_space->install_readwrite_handler(0x0000, 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)
@ -242,37 +241,33 @@ 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;
u16 decode = m_decode_prom[offset] ^ 0xff;
if (decode)
{
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)
{
for (device_h89bus_right_card_interface &entry : m_right_device_list)
if (entry.m_p506_signals)
{
if (entry.m_p506_signals)
{
// p506 does not have CASS or LP
retval |= entry.read(decode & ~(H89_CASS | H89_LP), offset & 7);
}
else
{
// p504/p505 does not have FLPY
retval |= entry.read(decode & ~H89_FLPY , offset & 7);
}
// p506 does not have CASS or LP
retval |= entry.read(decode & ~(H89_CASS | H89_LP), offset & 7);
}
else
{
// p504/p505 does not have 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);
}
// 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 & 0x1fff);
}
return retval;
@ -280,37 +275,33 @@ u8 h89bus_device::io_dispatch_r(offs_t offset)
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;
u16 decode = m_decode_prom[offset] ^ 0xff;
if (decode)
{
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)
{
for (device_h89bus_right_card_interface &entry : m_right_device_list)
if (entry.m_p506_signals)
{
if (entry.m_p506_signals)
{
// p506 does not have CASS or LP
entry.write(decode & ~(H89_CASS | H89_LP), offset & 7, data);
}
else
{
// p504/p505 does not have FLPY
entry.write(decode & ~H89_FLPY, offset & 7, data);
}
// p506 does not have CASS or LP
entry.write(decode & ~(H89_CASS | H89_LP), offset & 7, data);
}
else
{
// p504/p505 does not have 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);
}
// 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);
}
}

View File

@ -0,0 +1,245 @@
// license:BSD-3-Clause
// copyright-holders:Mark Garlanger
/***************************************************************************
SigmaSoft Universal Parallel Interface Board
****************************************************************************/
#include "emu.h"
#include "bus/heathzenith/h19/tlb.h"
#include "sigmasoft_parallel_port.h"
//
// Logging defines
//
#define LOG_REG (1U << 1) // Shows register setup
#define LOG_FUNC (1U << 2) // Function calls
#define VERBOSE (0)
#include "logmacro.h"
#define LOGREG(...) LOGMASKED(LOG_REG, __VA_ARGS__)
#define LOGFUNC(...) LOGMASKED(LOG_FUNC, __VA_ARGS__)
#ifdef _MSC_VER
#define FUNCNAME __func__
#else
#define FUNCNAME __PRETTY_FUNCTION__
#endif
// TODO make this configurable with jumper config
static constexpr u8 BASE_ADDR = 0x08;
class sigmasoft_parallel_port : public device_t, public device_h89bus_left_card_interface
{
public:
sigmasoft_parallel_port(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
virtual u8 read(u8 select_lines, u16 offset) override;
virtual void write(u8 select_lines, u16 offset, u8 data) override;
auto ctrl_r_cb() { return m_ctrl_r.bind(); }
auto video_mem_r_cb() { return m_video_mem_r.bind(); }
auto video_mem_cb() { return m_video_mem_w.bind(); }
auto io_lo_cb() { return m_io_lo_addr.bind(); }
auto io_hi_cb() { return m_io_hi_addr.bind(); }
auto window_lo_cb() { return m_window_lo_addr.bind(); }
auto window_hi_cb() { return m_window_hi_addr.bind(); }
auto ctrl_cb() { return m_ctrl_w.bind(); }
protected:
virtual void device_start() override ATTR_COLD;
virtual void device_add_mconfig(machine_config& config) override ATTR_COLD;;
u8 video_mem_r();
void video_mem_w(u8 val);
void io_lo_addr_w(u8 val);
void io_hi_addr_w(u8 val);
void window_lo_addr_w(u8 val);
void window_hi_addr_w(u8 val);
void ctrl_w(u8 val);
u8 ctrl_r();
private:
// Reads
devcb_read8 m_ctrl_r;
devcb_read8 m_video_mem_r;
// Writes
devcb_write8 m_video_mem_w;
devcb_write8 m_io_lo_addr;
devcb_write8 m_io_hi_addr;
devcb_write8 m_window_lo_addr;
devcb_write8 m_window_hi_addr;
devcb_write8 m_ctrl_w;
};
sigmasoft_parallel_port::sigmasoft_parallel_port(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock):
device_t(mconfig, H89BUS_SIGMASOFT_PARALLEL, tag, owner, clock),
device_h89bus_left_card_interface(mconfig, *this),
m_ctrl_r(*this, 0x00),
m_video_mem_r(*this, 0x00),
m_video_mem_w(*this),
m_io_lo_addr(*this),
m_io_hi_addr(*this),
m_window_lo_addr(*this),
m_window_hi_addr(*this),
m_ctrl_w(*this)
{
}
void sigmasoft_parallel_port::video_mem_w(u8 val)
{
m_video_mem_w(val);
}
void sigmasoft_parallel_port::io_lo_addr_w(u8 val)
{
m_io_lo_addr(val);
}
void sigmasoft_parallel_port::io_hi_addr_w(u8 val)
{
m_io_hi_addr(val);
}
void sigmasoft_parallel_port::window_lo_addr_w(u8 val)
{
m_window_lo_addr(val);
}
void sigmasoft_parallel_port::window_hi_addr_w(u8 val)
{
m_window_hi_addr(val);
}
void sigmasoft_parallel_port::ctrl_w(u8 val)
{
m_ctrl_w(val);
}
void sigmasoft_parallel_port::write(u8 select_lines, u16 offset, u8 data)
{
offset -= BASE_ADDR;
if (!(select_lines & h89bus_device::H89_IO) || offset >= 8)
{
return;
}
LOGFUNC("%s: reg: %d val: %d\n", FUNCNAME, offset, data);
switch (offset)
{
case 0:
video_mem_w(data);
break;
case 1:
io_lo_addr_w(data);
break;
case 2:
io_hi_addr_w(data);
break;
case 3:
window_lo_addr_w(data);
break;
case 4:
window_hi_addr_w(data);
break;
case 5:
ctrl_w(data);
break;
case 6:
// TODO - Centronics interface
break;
case 7:
// TODO - Centronics interface
break;
}
}
u8 sigmasoft_parallel_port::video_mem_r()
{
// get video memory value from igc device
return m_video_mem_r();
}
u8 sigmasoft_parallel_port::ctrl_r()
{
// get control register from igc device
return m_ctrl_r();
}
u8 sigmasoft_parallel_port::read(u8 select_lines, u16 offset)
{
offset -= BASE_ADDR;
u8 value = 0x00;
if (!(select_lines & h89bus_device::H89_IO) || offset >= 8)
{
return value;
}
switch (offset)
{
case 0:
value = video_mem_r();
break;
case 1:
// TODO - Light Pen Low address
break;
case 2:
// TODO - Light Pen High address
break;
case 3:
// TODO - Left input device
break;
case 4:
// TODO - Right input device
break;
case 5:
// Control Register
value = ctrl_r();
break;
case 6:
// TODO - Centronics interface
break;
case 7:
// TODO - Centronics interface
break;
}
LOGFUNC("%s: reg: %d val: %d\n", FUNCNAME, offset, value);
return value;
}
void sigmasoft_parallel_port::device_start()
{
}
void sigmasoft_parallel_port::device_add_mconfig(machine_config &config)
{
// connect callbacks to TLB
ctrl_r_cb().set("^^tlbc", FUNC(heath_tlb_connector::sigma_ctrl_r));
video_mem_r_cb().set("^^tlbc", FUNC(heath_tlb_connector::sigma_video_mem_r));
video_mem_cb().set("^^tlbc", FUNC(heath_tlb_connector::sigma_video_mem_w));
io_lo_cb().set("^^tlbc", FUNC(heath_tlb_connector::sigma_io_lo_addr_w));
io_hi_cb().set("^^tlbc", FUNC(heath_tlb_connector::sigma_io_hi_addr_w));
window_lo_cb().set("^^tlbc", FUNC(heath_tlb_connector::sigma_window_lo_addr_w));
window_hi_cb().set("^^tlbc", FUNC(heath_tlb_connector::sigma_window_hi_addr_w));
ctrl_cb().set("^^tlbc", FUNC(heath_tlb_connector::sigma_ctrl_w));
}
DEFINE_DEVICE_TYPE_PRIVATE(H89BUS_SIGMASOFT_PARALLEL, device_h89bus_left_card_interface, sigmasoft_parallel_port, "sigmasoft_parallel_port", "SigmaSoft Universal Parallel Board");

View File

@ -0,0 +1,18 @@
// license:BSD-3-Clause
// copyright-holders:Mark Garlanger
/***************************************************************************
SigmaSoft Universal Parallel Interface Board
****************************************************************************/
#ifndef MAME_BUS_HEATHZENITH_H89_SIGMASOFT_PARALLEL_PORT_H
#define MAME_BUS_HEATHZENITH_H89_SIGMASOFT_PARALLEL_PORT_H
#pragma once
#include "h89bus.h"
DECLARE_DEVICE_TYPE(H89BUS_SIGMASOFT_PARALLEL, device_h89bus_left_card_interface)
#endif // MAME_BUS_HEATHZENITH_H89_SIGMASOFT_PARALLEL_PORT_H

View File

@ -12,7 +12,7 @@
#include "emu.h"
#include "tlb.h"
#include "bus/heathzenith/h19/tlb.h"
#include "bus/rs232/rs232.h"
#include "h19.lh"

View File

@ -44,9 +44,8 @@
#include "emu.h"
#include "intr_cntrl.h"
#include "sigmasoft_parallel_port.h"
#include "tlb.h"
#include "bus/heathzenith/h19/tlb.h"
#include "bus/heathzenith/h89/h89bus.h"
#include "bus/heathzenith/h89/cards.h"
#include "cpu/z80/z80.h"
@ -198,17 +197,11 @@ class h89_sigmasoft_state : public h89_state
{
public:
h89_sigmasoft_state(const machine_config &mconfig, device_type type, const char *tag):
h89_state(mconfig, type, tag),
m_sigma_parallel(*this, "sigma_parallel")
h89_state(mconfig, type, tag)
{
}
void h89_sigmasoft(machine_config &config);
protected:
required_device<sigmasoft_parallel_port> m_sigma_parallel;
void h89_sigmasoft_io(address_map &map);
};
@ -377,44 +370,6 @@ void h89_base_state::h89_base_io(address_map &map)
map.global_mask(0xff);
}
void h89_sigmasoft_state::h89_sigmasoft_io(address_map &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));
}
/*
Memory Map for MMS 444-61C PROM
PORT
Use | Hex |
----------------------------+-------+
Not specified, available | 0-37 |
MMS 77316 | 38-3F |
MMS Internal test fixtures | 40-47 |
MMS 77317 ACT/XCOMP I/O | 48-4F |
MMS 77315 CAMEO I/O | 50-56 |
Unused | 57 |
MMS 77314 Corvus I/O | 58-59 |
MMS 77314 REMEX I/O | 5A-5B |
MMS 77314,15,17 Conf Port | 5C |
Unused | 5D-77 |
Disk I/O #1 | 78-7B |
Disk I/O #2 | 7C-7F |
HDOS reserved | 80-CF |
DCE Serial I/O | D0-D7 |
DTE Serial I/O | D8-DF |
DCE Serial I/O | EO-E7 |
Console I/O | E8-EF |
NMI | F0-F1 |
General purpose port | F2 |
Unused | F8-F9 |
NMI | FA-FB |
Unused | FC-FF |
*/
// Input ports
static INPUT_PORTS_START( h88 )
@ -1032,19 +987,10 @@ 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);
SIGMASOFT_PARALLEL_PORT(config, m_sigma_parallel);
m_sigma_parallel->ctrl_r_cb().set(m_tlbc, FUNC(heath_tlb_connector::sigma_ctrl_r));
m_sigma_parallel->video_mem_r_cb().set(m_tlbc, FUNC(heath_tlb_connector::sigma_video_mem_r));
m_sigma_parallel->video_mem_cb().set(m_tlbc, FUNC(heath_tlb_connector::sigma_video_mem_w));
m_sigma_parallel->io_lo_cb().set(m_tlbc, FUNC(heath_tlb_connector::sigma_io_lo_addr_w));
m_sigma_parallel->io_hi_cb().set(m_tlbc, FUNC(heath_tlb_connector::sigma_io_hi_addr_w));
m_sigma_parallel->window_lo_cb().set(m_tlbc, FUNC(heath_tlb_connector::sigma_window_lo_addr_w));
m_sigma_parallel->window_hi_cb().set(m_tlbc, FUNC(heath_tlb_connector::sigma_window_hi_addr_w));
m_sigma_parallel->ctrl_cb().set(m_tlbc, FUNC(heath_tlb_connector::sigma_ctrl_w));
H89BUS_LEFT_SLOT(config.replace(), "p501", "h89bus", h89_left_cards, "ss_parallel");
}
void h89_mms_state::h89_mms(machine_config &config)

View File

@ -1,165 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Mark Garlanger
/***************************************************************************
SigmaSoft Universal Parallel Interface Board
****************************************************************************/
#include "emu.h"
#include "sigmasoft_parallel_port.h"
//
// Logging defines
//
#define LOG_REG (1U << 1) // Shows register setup
#define LOG_FUNC (1U << 2) // Function calls
#define VERBOSE (0)
#include "logmacro.h"
#define LOGREG(...) LOGMASKED(LOG_REG, __VA_ARGS__)
#define LOGFUNC(...) LOGMASKED(LOG_FUNC, __VA_ARGS__)
#ifdef _MSC_VER
#define FUNCNAME __func__
#else
#define FUNCNAME __PRETTY_FUNCTION__
#endif
DEFINE_DEVICE_TYPE(SIGMASOFT_PARALLEL_PORT, sigmasoft_parallel_port, "sigmasoft_parallel_port", "SigmaSoft Universal Parallel Board");
sigmasoft_parallel_port::sigmasoft_parallel_port(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock):
device_t(mconfig, SIGMASOFT_PARALLEL_PORT, tag, owner, clock),
m_ctrl_r(*this, 0x00),
m_video_mem_r(*this, 0x00),
m_video_mem_w(*this),
m_io_lo_addr(*this),
m_io_hi_addr(*this),
m_window_lo_addr(*this),
m_window_hi_addr(*this),
m_ctrl_w(*this)
{
}
void sigmasoft_parallel_port::video_mem_w(u8 val)
{
m_video_mem_w(val);
}
void sigmasoft_parallel_port::io_lo_addr_w(u8 val)
{
m_io_lo_addr(val);
}
void sigmasoft_parallel_port::io_hi_addr_w(u8 val)
{
m_io_hi_addr(val);
}
void sigmasoft_parallel_port::window_lo_addr_w(u8 val)
{
m_window_lo_addr(val);
}
void sigmasoft_parallel_port::window_hi_addr_w(u8 val)
{
m_window_hi_addr(val);
}
void sigmasoft_parallel_port::ctrl_w(u8 val)
{
m_ctrl_w(val);
}
void sigmasoft_parallel_port::write(offs_t reg, u8 val)
{
LOGFUNC("%s: reg: %d val: %d\n", FUNCNAME, reg, val);
switch (reg)
{
case 0:
video_mem_w(val);
break;
case 1:
io_lo_addr_w(val);
break;
case 2:
io_hi_addr_w(val);
break;
case 3:
window_lo_addr_w(val);
break;
case 4:
window_hi_addr_w(val);
break;
case 5:
ctrl_w(val);
break;
case 6:
// TODO - Centronics interface
break;
case 7:
// TODO - Centronics interface
break;
}
}
u8 sigmasoft_parallel_port::video_mem_r()
{
// get video memory value from igc device
return m_video_mem_r();
}
u8 sigmasoft_parallel_port::ctrl_r()
{
// get control register from igc device
return m_ctrl_r();
}
u8 sigmasoft_parallel_port::read(offs_t reg)
{
// default return for the h89
u8 value = 0xff;
switch (reg)
{
case 0:
value = video_mem_r();
break;
case 1:
// TODO - Light Pen Low address
break;
case 2:
// TODO - Light Pen High address
break;
case 3:
// TODO - Left input device
break;
case 4:
// TODO - Right input device
break;
case 5:
// Control Register
value = ctrl_r();
break;
case 6:
// TODO - Centronics interface
break;
case 7:
// TODO - Centronics interface
break;
}
LOGFUNC("%s: reg: %d val: %d\n", FUNCNAME, reg, value);
return value;
}
void sigmasoft_parallel_port::device_start()
{
}

View File

@ -1,67 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Mark Garlanger
/***************************************************************************
SigmaSoft Universal Parallel Interface Board
****************************************************************************/
#ifndef MAME_HEATHZENITH_SIGMASOFT_PARALLEL_PORT_H
#define MAME_HEATHZENITH_SIGMASOFT_PARALLEL_PORT_H
#pragma once
class sigmasoft_parallel_port : public device_t
{
public:
sigmasoft_parallel_port(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 ctrl_r_cb() { return m_ctrl_r.bind(); }
auto video_mem_r_cb() { return m_video_mem_r.bind(); }
auto video_mem_cb() { return m_video_mem_w.bind(); }
auto io_lo_cb() { return m_io_lo_addr.bind(); }
auto io_hi_cb() { return m_io_hi_addr.bind(); }
auto window_lo_cb() { return m_window_lo_addr.bind(); }
auto window_hi_cb() { return m_window_hi_addr.bind(); }
auto ctrl_cb() { return m_ctrl_w.bind(); }
protected:
virtual void device_start() override ATTR_COLD;
u8 video_mem_r();
void video_mem_w(u8 val);
void io_lo_addr_w(u8 val);
void io_hi_addr_w(u8 val);
void window_lo_addr_w(u8 val);
void window_hi_addr_w(u8 val);
void ctrl_w(u8 val);
u8 ctrl_r();
private:
// Reads
devcb_read8 m_ctrl_r;
devcb_read8 m_video_mem_r;
// Writes
devcb_write8 m_video_mem_w;
devcb_write8 m_io_lo_addr;
devcb_write8 m_io_hi_addr;
devcb_write8 m_window_lo_addr;
devcb_write8 m_window_hi_addr;
devcb_write8 m_ctrl_w;
};
DECLARE_DEVICE_TYPE(SIGMASOFT_PARALLEL_PORT, sigmasoft_parallel_port)
#endif // MAME_HEATHZENITH_SIGMASOFT_PARALLEL_PORT_H