mirror of
https://github.com/holub/mame
synced 2025-04-16 05:24:54 +03:00
bus/epson_qx, qx10.cpp: Added Epson QX-10 expansion bus. (#9241)
This commit is contained in:
parent
8f2247e1f2
commit
8b5307cee0
@ -3733,6 +3733,17 @@ if (BUSES["EPSON_SIO"]~=null) then
|
||||
}
|
||||
end
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/bus/epson_qx/option.h,BUSES["EPSON_QX"] = true
|
||||
---------------------------------------------------
|
||||
if (BUSES["EPSON_QX"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/bus/epson_qx/option.cpp",
|
||||
MAME_DIR .. "src/devices/bus/epson_qx/option.h",
|
||||
}
|
||||
end
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/bus/pce/pce_slot.h,BUSES["PCE"] = true
|
||||
|
@ -895,6 +895,7 @@ BUSES["ELECTRON_CART"] = true
|
||||
BUSES["ELECTRON"] = true
|
||||
BUSES["EP64"] = true
|
||||
BUSES["EPSON_SIO"] = true
|
||||
BUSES["EPSON_QX"] = true
|
||||
BUSES["FMT_SCSI"] = true
|
||||
BUSES["GAMATE"] = true
|
||||
BUSES["GAMEBOY"] = true
|
||||
|
210
src/devices/bus/epson_qx/option.cpp
Normal file
210
src/devices/bus/epson_qx/option.cpp
Normal file
@ -0,0 +1,210 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Brian Johnson
|
||||
/*******************************************************************
|
||||
*
|
||||
* Epson QX-10 Expansion emulation
|
||||
*
|
||||
*******************************************************************/
|
||||
#include "emu.h"
|
||||
#include "option.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(EPSON_QX_OPTION_BUS_SLOT, bus::epson_qx::option_slot_device, "epson_qx_option_slot", "QX-10 Option slot")
|
||||
DEFINE_DEVICE_TYPE(EPSON_QX_OPTION_BUS, bus::epson_qx::option_bus_device, "epson_qx_option_bus", "QX-10 Option Bus")
|
||||
|
||||
namespace bus::epson_qx {
|
||||
//**************************************************************************
|
||||
// EPSON SLOT DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// option_bus_slot_device - constructor
|
||||
//-------------------------------------------------
|
||||
option_slot_device::option_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, EPSON_QX_OPTION_BUS_SLOT, tag, owner, clock),
|
||||
device_single_card_slot_interface<device_option_expansion_interface>(mconfig, *this),
|
||||
m_bus(*this, finder_base::DUMMY_TAG),
|
||||
m_dmas_w_cb(*this),
|
||||
m_dmas_r_cb(*this),
|
||||
m_dmaf_w_cb(*this),
|
||||
m_dmaf_r_cb(*this),
|
||||
m_eopf_cb(*this),
|
||||
m_eops_cb(*this),
|
||||
m_slot(-1)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
void option_slot_device::device_start()
|
||||
{
|
||||
m_dmas_w_cb.resolve_safe();
|
||||
m_dmas_r_cb.resolve_safe(0xff);
|
||||
m_dmaf_w_cb.resolve();
|
||||
m_dmaf_r_cb.resolve();
|
||||
|
||||
m_eopf_cb.resolve_safe();
|
||||
m_eops_cb.resolve_safe();
|
||||
|
||||
device_option_expansion_interface *const intf(get_card_device());
|
||||
if (intf) {
|
||||
intf->set_option_bus(*m_bus, m_slot);
|
||||
}
|
||||
|
||||
m_bus->add_slot(*this);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(option_slot_device::eopf) { m_eopf_cb(state); }
|
||||
WRITE_LINE_MEMBER(option_slot_device::eops) { m_eops_cb(state); }
|
||||
|
||||
WRITE_LINE_MEMBER(option_slot_device::inth1_w) { (*m_bus).set_inth1_line(state, m_slot); }
|
||||
WRITE_LINE_MEMBER(option_slot_device::inth2_w) { (*m_bus).set_inth2_line(state, m_slot); }
|
||||
WRITE_LINE_MEMBER(option_slot_device::intl_w) { (*m_bus).set_intl_line(state, m_slot); }
|
||||
|
||||
WRITE_LINE_MEMBER(option_slot_device::drqf_w) { (*m_bus).set_drqf_line(state, m_slot); }
|
||||
WRITE_LINE_MEMBER(option_slot_device::drqs_w) { (*m_bus).set_drqs_line(state, m_slot); }
|
||||
|
||||
WRITE_LINE_MEMBER(option_slot_device::rdyf_w) { (*m_bus).set_rdyf_line(state, m_slot); }
|
||||
WRITE_LINE_MEMBER(option_slot_device::rdys_w) { (*m_bus).set_rdys_line(state, m_slot); }
|
||||
|
||||
//**************************************************************************
|
||||
// EPSON OPTION BUS DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// option_bus_device - constructor
|
||||
//-------------------------------------------------
|
||||
option_bus_device::option_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, EPSON_QX_OPTION_BUS, tag, owner, clock),
|
||||
m_iospace(*this, finder_base::DUMMY_TAG, -1),
|
||||
m_inth1_cb(*this),
|
||||
m_inth2_cb(*this),
|
||||
m_intl_cb(*this),
|
||||
m_drqf_cb(*this),
|
||||
m_drqs_cb(*this),
|
||||
m_rdyf_cb(*this),
|
||||
m_rdys_cb(*this),
|
||||
m_inth1(0),
|
||||
m_inth2(0),
|
||||
m_drqf(0),
|
||||
m_rdyf(0),
|
||||
m_rdys(0)
|
||||
{
|
||||
}
|
||||
|
||||
void option_bus_device::add_slot(option_slot_device &slot)
|
||||
{
|
||||
m_slot_list.push_back(&slot);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
void option_bus_device::device_start()
|
||||
{
|
||||
m_inth1_cb.resolve_safe();
|
||||
m_inth2_cb.resolve_safe();
|
||||
m_intl_cb.resolve_all_safe();
|
||||
m_drqf_cb.resolve_safe();
|
||||
m_drqs_cb.resolve_all_safe();
|
||||
m_rdyf_cb.resolve_safe();
|
||||
m_rdys_cb.resolve_safe();
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific startup
|
||||
//-------------------------------------------------
|
||||
void option_bus_device::device_reset()
|
||||
{
|
||||
m_inth1 = 0;
|
||||
m_inth2 = 0;
|
||||
m_drqf = 0;
|
||||
m_rdyf = 0;
|
||||
m_rdys = 0;
|
||||
}
|
||||
|
||||
void option_bus_device::dackf_w(uint8_t data)
|
||||
{
|
||||
for (int i = 0; i < m_slot_list.size(); ++i) {
|
||||
if (!m_slot_list[i]->m_dmaf_w_cb.isnull()) {
|
||||
m_slot_list[i]->m_dmaf_w_cb(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t option_bus_device::dackf_r()
|
||||
{
|
||||
uint8_t value = 0;
|
||||
bool found = false;
|
||||
for (int i = 0; i < m_slot_list.size(); ++i) {
|
||||
if (!m_slot_list[i]->m_dmaf_r_cb.isnull()) {
|
||||
found = true;
|
||||
value |= m_slot_list[i]->m_dmaf_r_cb();
|
||||
}
|
||||
}
|
||||
return (found ? value : 0xff);
|
||||
}
|
||||
|
||||
void option_bus_device::set_inth1_line(uint8_t state, uint8_t slot)
|
||||
{
|
||||
m_inth1 = state ? (m_inth1 | (1 << (slot & 0x07))) : (m_inth1 & ~(1 << (slot & 0x07)));
|
||||
m_inth1_cb(m_inth1 != 0);
|
||||
}
|
||||
|
||||
void option_bus_device::set_inth2_line(uint8_t state, uint8_t slot)
|
||||
{
|
||||
m_inth2 = state ? (m_inth2 | (1 << (slot & 0x07))) : (m_inth2 & ~(1 << (slot & 0x07)));
|
||||
m_inth2_cb(m_inth2 != 0);
|
||||
}
|
||||
|
||||
void option_bus_device::set_drqf_line(uint8_t state, uint8_t slot)
|
||||
{
|
||||
m_drqf = !state ? (m_drqf | (1 << (slot & 0x07))) : (m_drqf & ~(1 << (slot & 0x07)));
|
||||
m_drqf_cb(m_drqf == 0);
|
||||
}
|
||||
|
||||
void option_bus_device::set_rdyf_line(uint8_t state, uint8_t slot)
|
||||
{
|
||||
m_rdyf = !state ? (m_rdyf | (1 << (slot & 0x07))) : (m_rdyf & ~(1 << (slot & 0x07)));
|
||||
m_rdyf_cb(m_rdyf == 0);
|
||||
}
|
||||
|
||||
void option_bus_device::set_rdys_line(uint8_t state, uint8_t slot)
|
||||
{
|
||||
m_rdys = !state ? (m_rdys | (1 << (slot & 0x07))) : (m_rdys & ~(1 << (slot & 0x07)));
|
||||
m_rdys_cb(m_rdys == 0);
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// EPSON OPTION CARD INTERFACE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// option_device_expansion_interface - constructor
|
||||
//-------------------------------------------------
|
||||
device_option_expansion_interface::device_option_expansion_interface(const machine_config &mconfig, device_t &device) :
|
||||
device_interface(device, "qx_option_bus"),
|
||||
m_bus(nullptr),
|
||||
m_slot(-1)
|
||||
{
|
||||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
// interface_pre_start - device-specific pre startup
|
||||
//---------------------------------------------------
|
||||
void device_option_expansion_interface::interface_pre_start()
|
||||
{
|
||||
if (!m_bus || m_slot == -1)
|
||||
throw device_missing_dependencies();
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// SLOT_INTERFACE( option_bus_devices )
|
||||
//-------------------------------------------------
|
||||
|
||||
void option_bus_devices(device_slot_interface &device)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace bus::epson_qx
|
280
src/devices/bus/epson_qx/option.h
Normal file
280
src/devices/bus/epson_qx/option.h
Normal file
@ -0,0 +1,280 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Brian Johnson
|
||||
/*
|
||||
QX-10 Option bus
|
||||
|
||||
1 GND 2 GND
|
||||
3 DTB0 4 DTB1
|
||||
5 DTB2 6 DTB3
|
||||
7 DTB4 8 DTB5
|
||||
9 DTB6 10 DTB7
|
||||
11 -12V 12 -12V
|
||||
13 ADR0 14 ADR1
|
||||
15 ADR2 16 ADR3
|
||||
17 ADR4 18 ADR5
|
||||
19 ADR6 20 ADR7
|
||||
21 ADR8 22 ADR9
|
||||
23 ADR10 24 ADR11
|
||||
25 ADR12 26 ADR13
|
||||
27 ADR14 28 ADR15
|
||||
29 GND 30 GND
|
||||
31 CLK 32 GND
|
||||
33 /BSAK 34 /MEMX
|
||||
35 /IRD 36 /IWR
|
||||
37 /MRD 38 /MWR
|
||||
39 /RSIN 40 INTH1
|
||||
41 INTH2 42 INTL
|
||||
43 +5V 44 /RSET
|
||||
45 +5V 46 +5V
|
||||
47 /DRQF 48 /DRQS
|
||||
49 /RDYF 50 /RDYS
|
||||
51 /WAIT 52 /IWS
|
||||
53 /DAKF 54 /DAKS
|
||||
55 /EOPF 56 /EOPS
|
||||
57 +12V 58 +12V
|
||||
59 GND 60 GND
|
||||
|
||||
The INTH1 and INTH2 singals are the two hihg priority interrupts and are
|
||||
global to the entire option bus. The INTL signal is the low priority interrupt
|
||||
and is local to each of the 5 option slots.
|
||||
|
||||
5 4 3 2 1
|
||||
|---| |---| |---| |---| |---|
|
||||
| | | | | | | | | |
|
||||
| | | | | | | | | |
|
||||
| | | | | | | | | |
|
||||
| | | | | | | | | |
|
||||
| *-|--|-*-|--|-*-|--|-*-|--|-*-|--------IRQH1 (Master IR2)
|
||||
| | | | | | | | | |
|
||||
| *-|--|-*-|--|-*-|--|-*-|--|-*-|--------IRQH2 (Master IR3)
|
||||
| | | | | | | | | |
|
||||
| | | | | | | | | |
|
||||
| | | | | | | | | *-|--------IRQL (Slave IR1)
|
||||
| | | | | | | | | |
|
||||
| | | | | | | *-|--|---|--------IRQL (Slave IR3)
|
||||
| | | | | | | | | |
|
||||
| | | | | *-|--|---|--|---|--------IRQL (Slave IR4)
|
||||
| | | | | | | | | |
|
||||
| | | *-|--|---|--|---|--|---|--------IRQL (Slave IR6)
|
||||
| | | | | | | | | |
|
||||
| *-|--|---|--|---|--|---|--|---|--------IRQL (Slave IR7)
|
||||
| | | | | | | | | |
|
||||
| | | | | | | | | |
|
||||
| | | | | | | | | |
|
||||
| | | | | | | | | |
|
||||
|---| |---| |---| |---| |---|
|
||||
|
||||
The DREQ/DACK(F) signals are the high priorty DMA signals and are shared between all option slots.
|
||||
The DREQ/DACK(S) signals are the lower priority DMA signals and are local to each slot, with the
|
||||
exception of slot 5 which does not provide low priority DMA signals. The RDY/EOP(S) signals are
|
||||
also connected to all 5 options slots since the DREQ(S) signals are all connected to the same
|
||||
DMA controller.
|
||||
|
||||
5 4 3 2 1
|
||||
|---| |---| |---| |---| |---|
|
||||
| | | | | | | | | |
|
||||
| *-|--|-*-|--|-*-|--|-*-|--|-*-|--------DREQF (Master CH3)
|
||||
| *-|--|-*-|--|-*-|--|-*-|--|-*-|--------DACKF (Master Ch3)
|
||||
| | | | | | | | | |
|
||||
| *-|--|-*-|--|-*-|--|-*-|--|-*-|--------RDYF (Master RDY)
|
||||
| *-|--|-*-|--|-*-|--|-*-|--|-*-|--------EOPF (Master EOP)
|
||||
| | | | | | | | | |
|
||||
| | | | | | | | | *-|--------DREQS (Slave CH0)
|
||||
| | | | | | | | | *-|--------DACKS (Slave CH0)
|
||||
| | | | | | | | | |
|
||||
| | | | | | | *-|--|---|--------DREQS (Slave CH1)
|
||||
| | | | | | | *-|--|---|--------DACKS (Slave CH1)
|
||||
| | | | | | | | | |
|
||||
| | | | | *-|--|---|--|---|--------DREQS (Slave CH2)
|
||||
| | | | | *-|--|---|--|---|--------DACKS (Slave CH2)
|
||||
| | | | | | | | | |
|
||||
| | | *-|--|---|--|---|--|---|--------DREQS (Slave CH3)
|
||||
| | | *-|--|---|--|---|--|---|--------DACKS (Slave CH3)
|
||||
| | | | | | | | | |
|
||||
| *-|--|-*-|--|-*-|--|-*-|--|-*-|--------RDYS (Slave RDY)
|
||||
| *-|--|-*-|--|-*-|--|-*-|--|-*-|--------EOPS (Slave EOP)
|
||||
| | | | | | | | | |
|
||||
|---| |---| |---| |---| |---|
|
||||
|
||||
*/
|
||||
#ifndef MAME_BUS_EPSON_QX_BUS_H
|
||||
#define MAME_BUS_EPSON_QX_BUS_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace bus::epson_qx {
|
||||
|
||||
//**************************************************************************
|
||||
// FORWARD DECLARATIONS
|
||||
//**************************************************************************
|
||||
|
||||
class option_bus_device;
|
||||
class device_option_expansion_interface;
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
/* Epson Slot Device */
|
||||
|
||||
class option_slot_device : public device_t, public device_single_card_slot_interface<device_option_expansion_interface>
|
||||
{
|
||||
public:
|
||||
friend class option_bus_device;
|
||||
// construction/destruction
|
||||
template <typename T, typename U>
|
||||
option_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&bus_tag, int slot, U &&opts, const char *dflt)
|
||||
: option_slot_device(mconfig, tag, owner, bus_tag->clock())
|
||||
{
|
||||
option_reset();
|
||||
opts(*this);
|
||||
set_default_option(dflt);
|
||||
set_fixed(false);
|
||||
m_bus.set_tag(std::forward<T>(bus_tag));
|
||||
m_slot = slot;
|
||||
}
|
||||
option_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(inth1_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(inth2_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(intl_w);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(drqf_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(drqs_w);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(rdyf_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(rdys_w);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(eopf);
|
||||
DECLARE_WRITE_LINE_MEMBER(eops);
|
||||
|
||||
auto dmas_w_callback() { m_dmas_w_cb.bind(); }
|
||||
auto dmas_r_callback() { m_dmas_r_cb.bind(); }
|
||||
auto dmaf_w_callback() { m_dmaf_w_cb.bind(); }
|
||||
auto dmaf_r_callback() { m_dmaf_r_cb.bind(); }
|
||||
|
||||
auto in_eopf_callback() { return m_eopf_cb.bind(); }
|
||||
auto in_eops_callback() { return m_eops_cb.bind(); }
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
|
||||
// configuration
|
||||
required_device<option_bus_device> m_bus;
|
||||
devcb_write8 m_dmas_w_cb;
|
||||
devcb_read8 m_dmas_r_cb;
|
||||
devcb_write8 m_dmaf_w_cb;
|
||||
devcb_read8 m_dmaf_r_cb;
|
||||
|
||||
devcb_write_line m_eopf_cb;
|
||||
devcb_write_line m_eops_cb;;
|
||||
|
||||
int m_slot;
|
||||
};
|
||||
|
||||
|
||||
/* Epson Bus Device */
|
||||
|
||||
class option_bus_device : public device_t
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
option_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
template <typename T> void set_iospace(T &&tag, int spacenum) { m_iospace.set_tag(std::forward<T>(tag), spacenum); }
|
||||
void set_memview(memory_view::memory_view_entry &view) { m_view = &view; }
|
||||
|
||||
auto out_inth1_callback() { return m_inth1_cb.bind(); }
|
||||
auto out_inth2_callback() { return m_inth2_cb.bind(); }
|
||||
template <unsigned Slot> auto out_intl_callback() { return m_intl_cb[Slot].bind(); }
|
||||
|
||||
auto out_drqf_callback() { return m_drqf_cb.bind(); }
|
||||
template <unsigned Slot> auto out_drqs_callback() { return m_drqs_cb[Slot].bind(); }
|
||||
|
||||
auto out_rdyf_callback() { return m_rdyf_cb.bind(); }
|
||||
auto out_rdys_callback() { return m_rdys_cb.bind(); }
|
||||
|
||||
memory_view::memory_view_entry& memview() const { return *m_view; }
|
||||
address_space &iospace() const { return *m_iospace; }
|
||||
|
||||
void dackf_w(uint8_t data);
|
||||
uint8_t dackf_r();
|
||||
template <unsigned Slot> void dacks_w(uint8_t data) { (*this)[Slot]->m_dmas_w_cb(data); }
|
||||
template <unsigned Slot> uint8_t dacks_r() { return (*this)[Slot]->m_dmas_r_cb(); }
|
||||
|
||||
template <void (option_slot_device::*slot_callback)(int)> void slots_w(int state) {
|
||||
for (option_slot_device *slot : m_slot_list) {
|
||||
(slot->*slot_callback)(state);
|
||||
}
|
||||
}
|
||||
|
||||
void set_inth1_line(uint8_t state, uint8_t slot);
|
||||
void set_inth2_line(uint8_t state, uint8_t slot);
|
||||
void set_intl_line(uint8_t state, uint8_t slot) { m_intl_cb[slot](state); }
|
||||
void set_drqf_line(uint8_t state, uint8_t slot);
|
||||
void set_drqs_line(uint8_t state, uint8_t slot) { m_drqs_cb[slot](state); }
|
||||
void set_rdyf_line(uint8_t state, uint8_t slot);
|
||||
void set_rdys_line(uint8_t state, uint8_t slot);
|
||||
|
||||
void add_slot(option_slot_device &slot);
|
||||
option_slot_device* operator[](int index) const {assert(index < m_slot_list.size()); return m_slot_list[index]; }
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
required_address_space m_iospace;
|
||||
memory_view::memory_view_entry *m_view;
|
||||
|
||||
devcb_write_line m_inth1_cb;
|
||||
devcb_write_line m_inth2_cb;
|
||||
devcb_write_line::array<5> m_intl_cb;
|
||||
|
||||
devcb_write_line m_drqf_cb;
|
||||
devcb_write_line::array<4> m_drqs_cb;
|
||||
|
||||
devcb_write_line m_rdyf_cb;
|
||||
devcb_write_line m_rdys_cb;
|
||||
|
||||
std::vector<option_slot_device *> m_slot_list;
|
||||
|
||||
uint8_t m_inth1;
|
||||
uint8_t m_inth2;
|
||||
|
||||
uint8_t m_drqf;
|
||||
|
||||
uint8_t m_rdyf;
|
||||
uint8_t m_rdys;
|
||||
};
|
||||
|
||||
|
||||
/* Epson Option Card interface */
|
||||
class device_option_expansion_interface : public device_interface
|
||||
{
|
||||
public:
|
||||
void set_option_bus(option_bus_device &bus, int slot) { assert(!device().started()); m_bus = &bus; m_slot = slot; }
|
||||
|
||||
protected:
|
||||
device_option_expansion_interface(const machine_config &mconfig, device_t &device);
|
||||
|
||||
virtual void interface_pre_start() override;
|
||||
option_slot_device* get_slot() { return (*m_bus)[m_slot]; }
|
||||
|
||||
option_bus_device *m_bus;
|
||||
int m_slot;
|
||||
};
|
||||
|
||||
void option_bus_devices(device_slot_interface &device);
|
||||
|
||||
} // namespace bus::epson_qx
|
||||
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE_NS(EPSON_QX_OPTION_BUS_SLOT, bus::epson_qx, option_slot_device)
|
||||
DECLARE_DEVICE_TYPE_NS(EPSON_QX_OPTION_BUS, bus::epson_qx, option_bus_device)
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Mariusz Wojcieszek, Angelo Salese
|
||||
// copyright-holders:Mariusz Wojcieszek, Angelo Salese, Brian Johnson
|
||||
/***************************************************************************
|
||||
|
||||
QX-10
|
||||
@ -35,6 +35,7 @@
|
||||
#include "emu.h"
|
||||
|
||||
#include "bus/centronics/ctronics.h"
|
||||
#include "bus/epson_qx/option.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "imagedev/floppy.h"
|
||||
@ -85,13 +86,15 @@ public:
|
||||
m_rtc(*this, "rtc"),
|
||||
m_kbd(*this, "kbd"),
|
||||
m_centronics(*this, "centronics"),
|
||||
m_bus(*this, "bus"),
|
||||
m_speaker(*this, "speaker"),
|
||||
m_vram_bank(0),
|
||||
m_char_rom(*this, "chargen"),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_screen(*this, "screen"),
|
||||
m_ram(*this, RAM_TAG),
|
||||
m_palette(*this, "palette")
|
||||
m_palette(*this, "palette"),
|
||||
m_ram_view(*this, "ramview")
|
||||
{
|
||||
}
|
||||
|
||||
@ -168,6 +171,7 @@ private:
|
||||
required_device<mc146818_device> m_rtc;
|
||||
required_device<rs232_port_device> m_kbd;
|
||||
required_device<centronics_device> m_centronics;
|
||||
required_device<bus::epson_qx::option_bus_device> m_bus;
|
||||
required_device<speaker_sound_device> m_speaker;
|
||||
uint8_t m_vram_bank;
|
||||
//required_shared_ptr<uint8_t> m_video_ram;
|
||||
@ -197,6 +201,8 @@ private:
|
||||
|
||||
|
||||
/* memory */
|
||||
memory_view m_ram_view;
|
||||
int m_external_bank;
|
||||
int m_membank;
|
||||
int m_memprom;
|
||||
int m_memcmos;
|
||||
@ -323,7 +329,7 @@ void qx10_state::update_speaker()
|
||||
*/
|
||||
void qx10_state::update_memory_mapping()
|
||||
{
|
||||
int drambank = 0;
|
||||
int drambank = -1;
|
||||
|
||||
if (m_membank & 1)
|
||||
{
|
||||
@ -342,28 +348,45 @@ void qx10_state::update_memory_mapping()
|
||||
drambank = 3;
|
||||
}
|
||||
|
||||
if (!m_memprom)
|
||||
if (drambank >= 0 || !m_memprom || m_memcmos)
|
||||
{
|
||||
membank("bank1")->set_base(memregion("maincpu")->base());
|
||||
m_ram_view.select(0);
|
||||
if (!m_memprom)
|
||||
{
|
||||
membank("bank1")->set_base(memregion("maincpu")->base());
|
||||
}
|
||||
else
|
||||
{
|
||||
membank("bank1")->set_base(m_ram->pointer() + drambank*64*1024);
|
||||
}
|
||||
if (m_memcmos)
|
||||
{
|
||||
membank("bank2")->set_base(m_cmosram);
|
||||
}
|
||||
else
|
||||
{
|
||||
membank("bank2")->set_base(m_ram->pointer() + drambank*64*1024 + 32*1024);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
membank("bank1")->set_base(m_ram->pointer() + drambank*64*1024);
|
||||
}
|
||||
if (m_memcmos)
|
||||
{
|
||||
membank("bank2")->set_base(m_cmosram);
|
||||
}
|
||||
else
|
||||
{
|
||||
membank("bank2")->set_base(m_ram->pointer() + drambank*64*1024 + 32*1024);
|
||||
if (m_external_bank)
|
||||
{
|
||||
m_ram_view.select(1);;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ram_view.disable();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void qx10_state::qx10_18_w(uint8_t data)
|
||||
{
|
||||
m_membank = (data >> 4) & 0x0f;
|
||||
m_spkr_enable = (data >> 2) & 0x01;
|
||||
m_external_bank = (data >> 3) & 0x01;
|
||||
m_pit_1->write_gate0(data & 1);
|
||||
update_speaker();
|
||||
update_memory_mapping();
|
||||
@ -534,6 +557,7 @@ WRITE_LINE_MEMBER( qx10_state::tc_w )
|
||||
{
|
||||
/* floppy terminal count */
|
||||
m_fdc->tc_w(!state);
|
||||
m_bus->slots_w<&bus::epson_qx::option_slot_device::eopf>(state);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -661,8 +685,10 @@ void qx10_state::vram_bank_w(uint8_t data)
|
||||
void qx10_state::qx10_mem(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map(0x0000, 0x7fff).bankrw("bank1");
|
||||
map(0x8000, 0xdfff).bankrw("bank2");
|
||||
map(0x0000, 0xdfff).view(m_ram_view);
|
||||
m_ram_view[0](0x0000, 0x7fff).bankrw("bank1");
|
||||
m_ram_view[0](0x8000, 0xdfff).bankrw("bank2");
|
||||
m_ram_view[1](0x0000, 0xdfff).unmaprw();
|
||||
map(0xe000, 0xffff).ram();
|
||||
}
|
||||
|
||||
@ -688,7 +714,6 @@ void qx10_state::qx10_io(address_map &map)
|
||||
map(0x3c, 0x3d).rw(FUNC(qx10_state::mc146818_r), FUNC(qx10_state::mc146818_w));
|
||||
map(0x40, 0x4f).rw(m_dma_1, FUNC(am9517a_device::read), FUNC(am9517a_device::write));
|
||||
map(0x50, 0x5f).rw(m_dma_2, FUNC(am9517a_device::read), FUNC(am9517a_device::write));
|
||||
// map(0xfc, 0xfd) Multi-Font comms
|
||||
}
|
||||
|
||||
/* Input ports */
|
||||
@ -743,6 +768,7 @@ INPUT_PORTS_END
|
||||
|
||||
void qx10_state::machine_start()
|
||||
{
|
||||
m_bus->set_memview(m_ram_view[1]);
|
||||
}
|
||||
|
||||
void qx10_state::machine_reset()
|
||||
@ -755,6 +781,7 @@ void qx10_state::machine_reset()
|
||||
|
||||
m_zoom = 0;
|
||||
|
||||
m_external_bank = 0;
|
||||
m_memprom = 0;
|
||||
m_memcmos = 0;
|
||||
m_membank = 0;
|
||||
@ -965,6 +992,39 @@ void qx10_state::qx10(machine_config &config)
|
||||
/* internal ram */
|
||||
RAM(config, RAM_TAG).set_default_size("256K");
|
||||
|
||||
EPSON_QX_OPTION_BUS(config, m_bus, MAIN_CLK / 4);
|
||||
m_dma_1->out_iow_callback<2>().set(m_bus, FUNC(bus::epson_qx::option_bus_device::dackf_w));
|
||||
m_dma_1->in_ior_callback<2>().set(m_bus, FUNC(bus::epson_qx::option_bus_device::dackf_r));
|
||||
m_dma_2->out_iow_callback<0>().set(m_bus, FUNC(bus::epson_qx::option_bus_device::dacks_w<0>));
|
||||
m_dma_2->in_ior_callback<0>().set(m_bus, FUNC(bus::epson_qx::option_bus_device::dacks_r<0>));
|
||||
m_dma_2->out_iow_callback<1>().set(m_bus, FUNC(bus::epson_qx::option_bus_device::dacks_w<1>));
|
||||
m_dma_2->in_ior_callback<1>().set(m_bus, FUNC(bus::epson_qx::option_bus_device::dacks_r<1>));
|
||||
m_dma_2->out_iow_callback<2>().set(m_bus, FUNC(bus::epson_qx::option_bus_device::dacks_w<2>));
|
||||
m_dma_2->in_ior_callback<2>().set(m_bus, FUNC(bus::epson_qx::option_bus_device::dacks_r<2>));
|
||||
m_dma_2->out_iow_callback<3>().set(m_bus, FUNC(bus::epson_qx::option_bus_device::dacks_w<3>));
|
||||
m_dma_2->in_ior_callback<3>().set(m_bus, FUNC(bus::epson_qx::option_bus_device::dacks_r<3>));
|
||||
m_dma_2->out_eop_callback().set(m_bus, FUNC(bus::epson_qx::option_bus_device::slots_w<&bus::epson_qx::option_slot_device::eops>));
|
||||
m_bus->out_drqf_callback().set(m_dma_1, FUNC(am9517a_device::dreq2_w));
|
||||
m_bus->out_rdyf_callback().set(m_dma_1, FUNC(am9517a_device::ready_w));
|
||||
m_bus->out_drqs_callback<0>().set(m_dma_2, FUNC(am9517a_device::dreq0_w));
|
||||
m_bus->out_drqs_callback<1>().set(m_dma_2, FUNC(am9517a_device::dreq1_w));
|
||||
m_bus->out_drqs_callback<2>().set(m_dma_2, FUNC(am9517a_device::dreq2_w));
|
||||
m_bus->out_drqs_callback<3>().set(m_dma_2, FUNC(am9517a_device::dreq3_w));
|
||||
m_bus->out_rdys_callback().set(m_dma_2, FUNC(am9517a_device::ready_w));
|
||||
m_bus->out_inth1_callback().set(m_pic_m, FUNC(pic8259_device::ir2_w));
|
||||
m_bus->out_inth2_callback().set(m_pic_m, FUNC(pic8259_device::ir3_w));
|
||||
m_bus->out_intl_callback<0>().set(m_pic_s, FUNC(pic8259_device::ir1_w));
|
||||
m_bus->out_intl_callback<1>().set(m_pic_s, FUNC(pic8259_device::ir3_w));
|
||||
m_bus->out_intl_callback<2>().set(m_pic_s, FUNC(pic8259_device::ir4_w));
|
||||
m_bus->out_intl_callback<3>().set(m_pic_s, FUNC(pic8259_device::ir6_w));
|
||||
m_bus->out_intl_callback<4>().set(m_pic_s, FUNC(pic8259_device::ir7_w));
|
||||
m_bus->set_iospace(m_maincpu, AS_IO);
|
||||
EPSON_QX_OPTION_BUS_SLOT(config, "option1", m_bus, 0, bus::epson_qx::option_bus_devices, nullptr);
|
||||
EPSON_QX_OPTION_BUS_SLOT(config, "option2", m_bus, 1, bus::epson_qx::option_bus_devices, nullptr);
|
||||
EPSON_QX_OPTION_BUS_SLOT(config, "option3", m_bus, 2, bus::epson_qx::option_bus_devices, nullptr);
|
||||
EPSON_QX_OPTION_BUS_SLOT(config, "option4", m_bus, 3, bus::epson_qx::option_bus_devices, nullptr);
|
||||
EPSON_QX_OPTION_BUS_SLOT(config, "option5", m_bus, 4, bus::epson_qx::option_bus_devices, nullptr);
|
||||
|
||||
// software lists
|
||||
SOFTWARE_LIST(config, "flop_list").set_original("qx10_flop");
|
||||
|
||||
@ -979,12 +1039,6 @@ ROM_START( qx10 )
|
||||
ROM_SYSTEM_BIOS(1, "v003", "v0.03")
|
||||
ROMX_LOAD( "ipl003.bin", 0x0000, 0x0800, CRC(3cbc4008) SHA1(cc8c7d1aa0cca8f9753d40698b2dc6802fd5f890), ROM_BIOS(1))
|
||||
|
||||
/* This is probably the i8039 program ROM for the Q10MF Multifont card, and the actual font ROMs are missing (6 * HM43128) */
|
||||
/* The first part of this rom looks like code for an embedded controller?
|
||||
From 0300 on, is a keyboard lookup table */
|
||||
ROM_REGION( 0x0800, "i8039", 0 )
|
||||
ROM_LOAD( "m12020a.3e", 0x0000, 0x0800, CRC(fa27f333) SHA1(73d27084ca7b002d5f370220d8da6623a6e82132))
|
||||
|
||||
ROM_REGION( 0x1000, "chargen", 0 )
|
||||
// ROM_LOAD( "qge.2e", 0x0000, 0x0800, BAD_DUMP CRC(ed93cb81) SHA1(579e68bde3f4184ded7d89b72c6936824f48d10b)) //this one contains special characters only
|
||||
// ROM_LOAD( "qge.2e", 0x0000, 0x1000, BAD_DUMP CRC(eb31a2d5) SHA1(6dc581bf2854a07ae93b23b6dfc9c7abd3c0569e))
|
||||
|
Loading…
Reference in New Issue
Block a user