summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author angelosa <lordkale4@gmail.com>2025-08-17 18:22:29 +0200
committer angelosa <lordkale4@gmail.com>2025-08-17 18:23:45 +0200
commit100319ffe00d90f485e562d5b7731d3d1fee3e4a (patch)
tree0a7109221b68c9bec48a882a7c97ad5a55813bc8
parent3cdae25f45715928e8c651bd0a0569995ae61d7e (diff)
pc/teradrive.cpp: add handshake bits, add system inputs, add (very) temporary generic_cart_slot for testing TMSS behaviour
-rw-r--r--src/mame/pc/teradrive.cpp167
1 files changed, 125 insertions, 42 deletions
diff --git a/src/mame/pc/teradrive.cpp b/src/mame/pc/teradrive.cpp
index f2844210650..51b24b8f40b 100644
--- a/src/mame/pc/teradrive.cpp
+++ b/src/mame/pc/teradrive.cpp
@@ -39,6 +39,9 @@ TODO:
#include "emu.h"
+#include "bus/generic/slot.h"
+#include "bus/generic/carts.h"
+
#include "bus/isa/isa_cards.h"
#include "bus/pc_kbd/keyboards.h"
#include "bus/pc_kbd/pc_kbdc.h"
@@ -68,7 +71,10 @@ public:
template <typename T> void set_romdisk_tag(T &&tag) { m_romdisk.set_tag(std::forward<T>(tag)); }
auto tmss_bank_callback() { return m_tmss_bank_cb.bind(); }
+ auto reg_1163_read_callback() { return m_reg_1163_read_cb.bind(); }
+ auto reg_1163_write_callback() { return m_reg_1163_write_cb.bind(); }
auto reg_1164_callback() { return m_reg_1164_cb.bind(); }
+ auto system_in_callback() { return m_system_in_cb.bind(); }
protected:
virtual void device_start() override ATTR_COLD;
@@ -89,7 +95,10 @@ private:
u16 m_68k_address = 0;
devcb_write8 m_tmss_bank_cb;
+ devcb_read8 m_reg_1163_read_cb;
+ devcb_write8 m_reg_1163_write_cb;
devcb_write8 m_reg_1164_cb;
+ devcb_read8 m_system_in_cb;
};
DEFINE_DEVICE_TYPE(ISA16_IBM_79F2661, isa16_ibm_79f2661, "isa16_ibm_79f2661", "ISA16 IBM 79F2661 \"bus switch\"")
@@ -100,7 +109,10 @@ isa16_ibm_79f2661::isa16_ibm_79f2661(const machine_config &mconfig, const char *
, m_romdisk(*this, finder_base::DUMMY_TAG)
, m_rom_window_bank(*this, "rom_window_bank")
, m_tmss_bank_cb(*this)
+ , m_reg_1163_read_cb(*this, 0)
+ , m_reg_1163_write_cb(*this)
, m_reg_1164_cb(*this)
+ , m_system_in_cb(*this, 0)
{
}
@@ -117,6 +129,7 @@ void isa16_ibm_79f2661::device_reset()
m_reg_1163 = 0;
m_reg_1164 = 0;
m_68k_address = 0;
+ m_reg_1163_write_cb(0);
m_reg_1164_cb(0);
remap(AS_PROGRAM, 0, 0xfffff);
remap(AS_IO, 0, 0xffff);
@@ -137,13 +150,13 @@ void isa16_ibm_79f2661::remap(int space_id, offs_t start, offs_t end)
}
// +$1160 base
-// map(0x1160, 0x1160) romdisk bank * 0x2000, r/w
-// map(0x1161, 0x1161) <undefined>?
-// map(0x1162, 0x1162) romdisk segment start in ISA space (val & 0x1e | 0xc0)
-// map(0x1163, 0x1163) comms and misc handshake bits, partially reflected on 68k $ae0001 register
-// map(0x1164, 0x1164) boot control
-// map(0x1165, 0x1165) switches/bus timeout/TMSS unlock (r/o)
-// map(0x1166, 0x1167) 68k address space select & 0xffffe * 0x2000, r/w
+// map(0x1160, 0x1160) romdisk bank * 0x2000, r/w
+// map(0x1161, 0x1161) <undefined>?
+// map(0x1162, 0x1162) romdisk segment start in ISA space (val & 0x1e | 0xc0)
+// map(0x1163, 0x1163) comms and misc handshake bits, partially reflected on 68k $ae0001 register
+// map(0x1164, 0x1164) boot control
+// map(0x1165, 0x1165) switches/bus timeout/TMSS unlock (r/o)
+// map(0x1166, 0x1167) 68k address space select & 0xffffe * 0x2000, r/w
void isa16_ibm_79f2661::io_map(address_map &map)
{
map(0x00, 0x00).lrw8(
@@ -173,12 +186,20 @@ void isa16_ibm_79f2661::io_map(address_map &map)
remap(AS_PROGRAM, 0, 0xfffff);
})
);
+/*
+ * xx-- ---- 68k $ae0001 bits 3-2 (writes from this side)
+ * --xx ---- 68k $ae0001 bits 1-0 (reads from this side)
+ * ---- xx-- <unknown>
+ * ---- --x- Enable 286 ISA memory window (and disables TMSS from 68k)
+ * ---- ---x Enable auxiliary TMSS ROM (on 68k space?)
+ */
map(0x03, 0x03).lrw8(
NAME([this] (offs_t offset) {
- return m_reg_1163;
+ return (m_reg_1163 & 0xcf) | (m_reg_1163_read_cb() & 0x30);
}),
NAME([this] (offs_t offset, u8 data) {
m_reg_1163 = data;
+ m_reg_1163_write_cb(data);
})
);
/*
@@ -208,8 +229,8 @@ void isa16_ibm_79f2661::io_map(address_map &map)
* ---- ---x MD/PC switch (0) MD boot (1) PC boot
*/
map(0x05, 0x05).lr8(
- NAME([] (offs_t offset) {
- return 1 | 4;
+ NAME([this] (offs_t offset) {
+ return m_system_in_cb() & 5;
})
);
map(0x06, 0x07).lrw16(
@@ -236,10 +257,12 @@ public:
, m_ram(*this, RAM_TAG)
, m_isabus(*this, "isabus")
, m_speaker(*this, "speaker")
+ , m_system_in(*this, "SYSTEM_IN")
, m_md68kcpu(*this, "md68kcpu")
, m_mdscreen(*this, "mdscreen")
, m_tmss_bank(*this, "tmss_bank")
, m_tmss_view(*this, "tmss_view")
+ , m_md_cart(*this, "md_cart")
{ }
void teradrive(machine_config &config);
@@ -247,6 +270,7 @@ public:
protected:
void machine_start() override ATTR_COLD;
+ void machine_reset() override ATTR_COLD;
void x86_io(address_map &map) ATTR_COLD;
void x86_map(address_map &map) ATTR_COLD;
@@ -286,23 +310,31 @@ private:
u16 m_heartbeat = 0;
+ // bus switch semantics
+ required_ioport m_system_in;
+
static void romdisk_config(device_t *device);
void tmss_bank_w(u8 data);
+ u8 reg_1163_r();
+ void reg_1163_w(u8 data);
void reg_1164_w(u8 data);
+ u8 system_in_r();
// MD side
required_device<m68000_device> m_md68kcpu;
-// required_device<z80_device> m_mdz80cpu;
+// required_device<z80_device> m_mdz80cpu;
required_device<screen_device> m_mdscreen;
required_memory_bank m_tmss_bank;
memory_view m_tmss_view;
+ required_device<generic_slot_device> m_md_cart;
// TODO: main PC screen can also swap the VGA with this
// (roughly #5801 and #11343 league)
u32 md_screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
- u8 m_isa_address_bank;
+ u8 m_isa_address_bank = 0;
+ u8 m_68k_hs = 0;
};
void teradrive_state::x86_map(address_map &map)
@@ -341,37 +373,46 @@ u32 teradrive_state::md_screen_update(screen_device &screen, bitmap_rgb32 &bitma
void teradrive_state::md_68k_map(address_map &map)
{
map.unmap_value_high();
-// map(0x000000, 0x7fffff).view(m_cart_view);
+// map(0x000000, 0x7fffff).view(m_cart_view);
// when /CART pin is low
-// m_cart_view[0](0x000000, 0x3fffff).m(m_cart, FUNC(...::cart_map));
-// m_cart_view[0](0x000000, 0x003fff).view(m_tmss_view);
-// m_tmss_view[0](0x000000, 0x003fff).rom().region("tmss", 0);
-// m_cart_view[0](0x400000, 0x7fffff).m(m_exp, FUNC(...::expansion_map));
+// m_cart_view[0](0x000000, 0x3fffff).m(m_cart, FUNC(...::cart_map));
+// m_cart_view[0](0x000000, 0x003fff).view(m_tmss_view);
+// m_tmss_view[0](0x000000, 0x003fff).rom().region("tmss", 0);
+// m_cart_view[0](0x400000, 0x7fffff).m(m_exp, FUNC(...::expansion_map));
// /CART high (matters for MCD SRAM at very least)
-// m_cart_view[1](0x000000, 0x3fffff).m(m_exp, FUNC(...::expansion_map));
-// m_cart_view[1](0x400000, 0x7fffff).m(m_cart, FUNC(...::cart_map));
-// m_cart_view[1](0x400000, 0x403fff).view(m_tmss_view);
-// m_tmss_view[0](0x400000, 0x403fff).rom().region("tmss", 0);
+// m_cart_view[1](0x000000, 0x3fffff).m(m_exp, FUNC(...::expansion_map));
+// m_cart_view[1](0x400000, 0x7fffff).m(m_cart, FUNC(...::cart_map));
+// m_cart_view[1](0x400000, 0x403fff).view(m_tmss_view);
+// m_tmss_view[0](0x400000, 0x403fff).rom().region("tmss", 0);
+ map(0x000000, 0x3fffff).r(m_md_cart, FUNC(generic_slot_device::read_rom));
map(0x000000, 0x000fff).view(m_tmss_view);
m_tmss_view[0](0x000000, 0x000fff).bankr(m_tmss_bank);
-// map(0x800000, 0x9fffff) unmapped or 32X
-// map(0xa00000, 0xa07eff).mirror(0x8000) Z80 address space
-// map(0xa07f00, 0xa07fff).mirror(0x8000) Z80 VDP space (freezes machine if accessed from 68k)
-// map(0xa10000, 0xa100ff) I/O
-// map(0xa11000, 0xa110ff) memory mode register
-// map(0xa11100, 0xa111ff) Z80 BUSREQ/BUSACK
-// map(0xa11200, 0xa112ff) Z80 RESET
-// map(0xa11300, 0xa113ff) <open bus>
-
-// map(0xa11400, 0xa1dfff) <unmapped> (no DTACK generation, freezes machine without additional HW)
-// map(0xa12000, 0xa120ff).m(m_exp, FUNC(...::fdc_map));
-// map(0xa13000, 0xa130ff).m(m_cart, FUNC(...::time_map));
-// map(0xa14000, 0xa14003) TMSS lock
-// map(0xa15100, 0xa153ff) 32X registers if present, <unmapped> otherwise
-// map(0xae0000, 0xae0003) Teradrive bus switch registers
+// map(0x800000, 0x9fffff) unmapped or 32X
+// map(0xa00000, 0xa07eff).mirror(0x8000) Z80 address space
+// map(0xa07f00, 0xa07fff).mirror(0x8000) Z80 VDP space (freezes machine if accessed from 68k)
+// map(0xa10000, 0xa100ff) I/O
+// map(0xa11000, 0xa110ff) memory mode register
+// map(0xa11100, 0xa111ff) Z80 BUSREQ/BUSACK
+// map(0xa11200, 0xa112ff) Z80 RESET
+// map(0xa11300, 0xa113ff) <open bus>
+
+// map(0xa11400, 0xa1dfff) <unmapped> (no DTACK generation, freezes machine without additional HW)
+// map(0xa12000, 0xa120ff).m(m_exp, FUNC(...::fdc_map));
+// map(0xa13000, 0xa130ff).m(m_cart, FUNC(...::time_map));
+// map(0xa14000, 0xa14003) TMSS lock
+// map(0xa15100, 0xa153ff) 32X registers if present, <unmapped> otherwise
+// map(0xae0000, 0xae0003) Teradrive bus switch registers
+ map(0xae0001, 0xae0001).lrw8(
+ NAME([this] (offs_t offset) {
+ return m_68k_hs;
+ }),
+ NAME([this] (offs_t offset, u8 data) {
+ m_68k_hs = (data & 0xf3) | (m_68k_hs & 0x0c);
+ })
+ );
map(0xae0003, 0xae0003).lrw8(
NAME([this] (offs_t offset) {
return m_isa_address_bank;
@@ -386,13 +427,13 @@ void teradrive_state::md_68k_map(address_map &map)
// TODO: verify requiring swapped endianness
map(0xb00000, 0xbfffff).lrw16(
NAME([this] (offs_t offset, u16 mem_mask) {
- return m_isabus->mem16_swap_r(offset | (m_isa_address_bank * 0x8000), mem_mask);
+ return m_isabus->mem16_swap_r(offset | (m_isa_address_bank * 0x80000), mem_mask);
}),
NAME([this] (offs_t offset, u16 data, u16 mem_mask) {
- m_isabus->mem16_swap_w(offset | (m_isa_address_bank * 0x8000), data, mem_mask);
+ m_isabus->mem16_swap_w(offset | (m_isa_address_bank * 0x80000), data, mem_mask);
})
);
-// map(0xc00000, 0xdfffff) VDP and PSG (with mirrors and holes)
+// map(0xc00000, 0xdfffff) VDP and PSG (with mirrors and holes)
map(0xc00005, 0xc00005).lr8(NAME([this] (offs_t offset) {
return m_mdscreen->vblank() << 3;
}));
@@ -413,6 +454,17 @@ void teradrive_state::tmss_bank_w(u8 data)
m_tmss_bank->set_entry((data * 2) + 1);
}
+u8 teradrive_state::reg_1163_r()
+{
+ return (m_68k_hs & 3) << 4;
+}
+
+void teradrive_state::reg_1163_w(u8 data)
+{
+ m_68k_hs &= ~0x0c;
+ m_68k_hs = (data & 0xc0) >> 4;
+}
+
void teradrive_state::reg_1164_w(u8 data)
{
if (BIT(data, 0))
@@ -436,13 +488,23 @@ void teradrive_state::reg_1164_w(u8 data)
}
}
+u8 teradrive_state::system_in_r()
+{
+ return m_system_in->read();
+}
+
void teradrive_state::romdisk_config(device_t *device)
{
auto *state = device->subdevice<teradrive_state>(":");
isa16_ibm_79f2661 &bus_switch = *downcast<isa16_ibm_79f2661 *>(device);
bus_switch.set_romdisk_tag("romdisk");
bus_switch.tmss_bank_callback().set(*state, FUNC(teradrive_state::tmss_bank_w));
+ bus_switch.reg_1163_read_callback().set(*state, FUNC(teradrive_state::reg_1163_r));
+ bus_switch.reg_1163_write_callback().set(*state, FUNC(teradrive_state::reg_1163_w));
bus_switch.reg_1164_callback().set(*state, FUNC(teradrive_state::reg_1164_w));
+ // TODO: using set_ioport doesn't work, will try to map from bus_switch device anyway
+// bus_switch.system_in_callback().set_ioport("SYSTEM_IN");
+ bus_switch.system_in_callback().set(*state, FUNC(teradrive_state::system_in_r));
}
/*
@@ -451,11 +513,26 @@ void teradrive_state::romdisk_config(device_t *device)
*
*/
+static INPUT_PORTS_START( teradrive )
+ PORT_START("SYSTEM_IN")
+ PORT_DIPNAME( 0x01, 0x01, "Boot mode" )
+ PORT_DIPSETTING( 0x00, "MD boot" )
+ PORT_DIPSETTING( 0x01, "PC boot" )
+ PORT_DIPNAME( 0x04, 0x04, "Video mode" )
+ PORT_DIPSETTING( 0x00, "Video" ) // composite?
+ PORT_DIPSETTING( 0x04, "RGB" )
+INPUT_PORTS_END
+
void teradrive_state::machine_start()
{
m_tmss_bank->configure_entries(0, 0x200, memregion("tmss")->base(), 0x1000);
}
+void teradrive_state::machine_reset()
+{
+ m_68k_hs = 0;
+}
+
void teradrive_isa_cards(device_slot_interface &device)
{
device.option_add_internal("bus_switch", ISA16_IBM_79F2661);
@@ -471,6 +548,7 @@ void teradrive_state::at_softlists(machine_config &config)
// SOFTWARE_LIST(config, "photocd_list").set_compatible("photo_cd");
// TODO: MD portion
+ SOFTWARE_LIST(config, "cart_list").set_original("megadriv").set_filter("NTSC-J");
// TODO: Teradrive SW list
}
@@ -571,6 +649,12 @@ void teradrive_state::teradrive(machine_config &config)
// NOTE: PAL is 423x312
m_mdscreen->set_raw(md_master_xtal / 8, 427, 0, 320, 262, 0, 224);
m_mdscreen->set_screen_update(FUNC(teradrive_state::md_screen_update));
+
+ // TODO: vestigial
+ GENERIC_CARTSLOT(config, m_md_cart, generic_plain_slot, "megadriv_cart");
+ m_md_cart->set_width(GENERIC_ROM16_WIDTH);
+ // TODO: generic_cartslot has issues with softlisted endianness (use loose for now)
+ m_md_cart->set_endian(ENDIANNESS_BIG);
}
ROM_START( teradrive )
@@ -584,7 +668,6 @@ ROM_START( teradrive )
// MD 68k initial boot code, "TERA286 INITIALIZE" in header
// shows Sega logo + TMSS "produced by" + 1990 copyright at bottom if loaded thru megadrij
- // TODO: it's actually in romdisk space at $43000, remove me
ROM_REGION16_BE(0x200000, "tmss", ROMREGION_ERASEFF)
ROM_COPY("board6:romdisk", 0x00000, 0x0000, 0x200000 )
ROM_END
@@ -609,5 +692,5 @@ ROM_END
} // anonymous namespace
-COMP( 1991, teradrive, 0, 0, teradrive, 0, teradrive_state, empty_init, "Sega / International Business Machines", "Teradrive (Japan, Model 2)", MACHINE_NOT_WORKING )
-COMP( 1991, teradrive3, teradrive, 0, teradrive, 0, teradrive_state, empty_init, "Sega / International Business Machines", "Teradrive (Japan, Model 3)", MACHINE_NOT_WORKING )
+COMP( 1991, teradrive, 0, 0, teradrive, teradrive, teradrive_state, empty_init, "Sega / International Business Machines", "Teradrive (Japan, Model 2)", MACHINE_NOT_WORKING )
+COMP( 1991, teradrive3, teradrive, 0, teradrive, teradrive, teradrive_state, empty_init, "Sega / International Business Machines", "Teradrive (Japan, Model 3)", MACHINE_NOT_WORKING )