summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--scripts/src/bus.lua11
-rw-r--r--scripts/target/mame/mess.lua1
-rw-r--r--src/devices/bus/epson_qx/option.cpp210
-rw-r--r--src/devices/bus/epson_qx/option.h280
-rw-r--r--src/mame/drivers/qx10.cpp100
5 files changed, 579 insertions, 23 deletions
diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua
index b86f1073c08..8667c54788e 100644
--- a/scripts/src/bus.lua
+++ b/scripts/src/bus.lua
@@ -3735,6 +3735,17 @@ 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
---------------------------------------------------
if (BUSES["PCE"]~=null) then
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua
index 70815cf1b96..3e4fa07b2c9 100644
--- a/scripts/target/mame/mess.lua
+++ b/scripts/target/mame/mess.lua
@@ -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
diff --git a/src/devices/bus/epson_qx/option.cpp b/src/devices/bus/epson_qx/option.cpp
new file mode 100644
index 00000000000..0a6553d2f54
--- /dev/null
+++ b/src/devices/bus/epson_qx/option.cpp
@@ -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
diff --git a/src/devices/bus/epson_qx/option.h b/src/devices/bus/epson_qx/option.h
new file mode 100644
index 00000000000..0204e54f0f7
--- /dev/null
+++ b/src/devices/bus/epson_qx/option.h
@@ -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
diff --git a/src/mame/drivers/qx10.cpp b/src/mame/drivers/qx10.cpp
index 7d13a9c06d1..e68f362d892 100644
--- a/src/mame/drivers/qx10.cpp
+++ b/src/mame/drivers/qx10.cpp
@@ -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());
- }
- else
- {
- membank("bank1")->set_base(m_ram->pointer() + drambank*64*1024);
- }
- if (m_memcmos)
- {
- membank("bank2")->set_base(m_cmosram);
+ 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("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))