summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Olivier Galibert <galibert@pobox.com>2021-02-16 21:51:47 +0100
committer Olivier Galibert <galibert@pobox.com>2021-04-19 09:50:19 +0200
commitc037dfd82238537752e2078f52a3276badfbff83 (patch)
treecacfd418c9e97e4b87a5dccbe9c14980222d1944
parentccd815de1aa70c6bf86bb4b94fd4656aa8f779a5 (diff)
thomson: Turn the extensions into slot devices, modernize the floppies
-rw-r--r--scripts/src/bus.lua22
-rw-r--r--scripts/target/mame/arcade.lua1
-rw-r--r--src/devices/bus/bml3/bml3bus.h11
-rw-r--r--src/devices/bus/bml3/bml3mp1805.cpp90
-rw-r--r--src/devices/bus/bml3/bml3mp1805.h8
-rw-r--r--src/devices/bus/thomson/cd90_015.cpp120
-rw-r--r--src/devices/bus/thomson/cd90_015.h48
-rw-r--r--src/devices/bus/thomson/cd90_351.cpp495
-rw-r--r--src/devices/bus/thomson/cd90_351.h122
-rw-r--r--src/devices/bus/thomson/cd90_640.cpp91
-rw-r--r--src/devices/bus/thomson/cd90_640.h46
-rw-r--r--src/devices/bus/thomson/cq90_028.cpp76
-rw-r--r--src/devices/bus/thomson/cq90_028.h42
-rw-r--r--src/devices/bus/thomson/extension.cpp40
-rw-r--r--src/devices/bus/thomson/extension.h39
-rw-r--r--src/devices/bus/thomson/nanoreseau.cpp205
-rw-r--r--src/devices/bus/thomson/nanoreseau.h66
-rw-r--r--src/devices/machine/mc6843.cpp1493
-rw-r--r--src/devices/machine/mc6843.h230
-rw-r--r--src/devices/machine/wd_fdc.cpp2
-rw-r--r--src/lib/formats/all.cpp8
-rw-r--r--src/lib/formats/thom_dsk.cpp462
-rw-r--r--src/lib/formats/thom_dsk.h38
-rw-r--r--src/lib/formats/wd177x_dsk.cpp2
-rw-r--r--src/mame/drivers/thomson.cpp624
-rw-r--r--src/mame/includes/thomson.h524
-rw-r--r--src/mame/machine/thomflop.cpp1867
-rw-r--r--src/mame/machine/thomflop.h159
-rw-r--r--src/mame/machine/thomson.cpp482
-rw-r--r--src/mame/mame.lst1
-rw-r--r--src/mame/video/thomson.cpp56
31 files changed, 3203 insertions, 4267 deletions
diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua
index d31f046f3e7..34ffe693ee3 100644
--- a/scripts/src/bus.lua
+++ b/scripts/src/bus.lua
@@ -4493,3 +4493,25 @@ if (BUSES["SAMCOUPE_MOUSE_PORT"]~=null) then
MAME_DIR .. "src/devices/bus/samcoupe/mouse/mouse.h",
}
end
+
+---------------------------------------------------
+--
+--@src/devices/bus/thomson/extension.h,BUSES["THOMSON"] = true
+---------------------------------------------------
+
+if (BUSES["THOMSON"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/bus/thomson/extension.cpp",
+ MAME_DIR .. "src/devices/bus/thomson/extension.h",
+ MAME_DIR .. "src/devices/bus/thomson/cd90_015.cpp",
+ MAME_DIR .. "src/devices/bus/thomson/cd90_015.h",
+ MAME_DIR .. "src/devices/bus/thomson/cq90_028.cpp",
+ MAME_DIR .. "src/devices/bus/thomson/cq90_028.h",
+ MAME_DIR .. "src/devices/bus/thomson/cd90_351.cpp",
+ MAME_DIR .. "src/devices/bus/thomson/cd90_351.h",
+ MAME_DIR .. "src/devices/bus/thomson/cd90_640.cpp",
+ MAME_DIR .. "src/devices/bus/thomson/cd90_640.h",
+ MAME_DIR .. "src/devices/bus/thomson/nanoreseau.cpp",
+ MAME_DIR .. "src/devices/bus/thomson/nanoreseau.h",
+ }
+end
diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua
index d3c9c290125..cb392f5343d 100644
--- a/scripts/target/mame/arcade.lua
+++ b/scripts/target/mame/arcade.lua
@@ -843,6 +843,7 @@ BUSES["VECTREX"] = true
--BUSES["X68K"] = true
--BUSES["Z88"] = true
BUSES["ZORRO"] = true
+--BUSES["THOMSON"] = true
--------------------------------------------------
diff --git a/src/devices/bus/bml3/bml3bus.h b/src/devices/bus/bml3/bml3bus.h
index 6e17408aca3..b3c36ed9c70 100644
--- a/src/devices/bus/bml3/bml3bus.h
+++ b/src/devices/bus/bml3/bml3bus.h
@@ -133,12 +133,15 @@ protected:
address_space &space() { return m_bml3bus->space(); }
- void raise_slot_nmi() { m_bml3bus->set_nmi_line(ASSERT_LINE); }
- void lower_slot_nmi() { m_bml3bus->set_nmi_line(CLEAR_LINE); }
- void raise_slot_irq() { m_bml3bus->set_irq_line(ASSERT_LINE); }
- void lower_slot_irq() { m_bml3bus->set_irq_line(CLEAR_LINE); }
+ void raise_slot_nmi() { m_bml3bus->set_nmi_line(ASSERT_LINE); }
+ void lower_slot_nmi() { m_bml3bus->set_nmi_line(CLEAR_LINE); }
+ void raise_slot_irq() { m_bml3bus->set_irq_line(ASSERT_LINE); }
+ void lower_slot_irq() { m_bml3bus->set_irq_line(CLEAR_LINE); }
void raise_slot_firq() { m_bml3bus->set_firq_line(ASSERT_LINE); }
void lower_slot_firq() { m_bml3bus->set_firq_line(CLEAR_LINE); }
+ void nmi_w(int state) { m_bml3bus->set_nmi_line(state); }
+ void irq_w(int state) { m_bml3bus->set_irq_line(state); }
+ void firq_w(int state) { m_bml3bus->set_firq_line(state); }
device_bml3bus_card_interface(const machine_config &mconfig, device_t &device);
diff --git a/src/devices/bus/bml3/bml3mp1805.cpp b/src/devices/bus/bml3/bml3mp1805.cpp
index c5608351b07..68f99d3edd7 100644
--- a/src/devices/bus/bml3/bml3mp1805.cpp
+++ b/src/devices/bus/bml3/bml3mp1805.cpp
@@ -23,22 +23,6 @@
DEFINE_DEVICE_TYPE(BML3BUS_MP1805, bml3bus_mp1805_device, "bml3mp1805", "Hitachi MP-1805 Floppy Controller Card")
-static const floppy_interface bml3_mp1805_floppy_interface =
-{
- FLOPPY_STANDARD_3_SSDD,
- LEGACY_FLOPPY_OPTIONS_NAME(default),
- nullptr
-};
-
-WRITE_LINE_MEMBER( bml3bus_mp1805_device::bml3_mc6843_intrq_w )
-{
- if (state)
- {
- raise_slot_nmi();
- lower_slot_nmi();
- }
-}
-
#define MP1805_ROM_REGION "mp1805_rom"
ROM_START( mp1805 )
@@ -47,6 +31,11 @@ ROM_START( mp1805 )
ROM_LOAD( "mp1805.rom", 0xf800, 0x0800, BAD_DUMP CRC(b532d8d9) SHA1(6f1160356d5bf64b5926b1fdb60db414edf65f22))
ROM_END
+void bml3bus_mp1805_device::floppy_drives(device_slot_interface &device)
+{
+ device.option_add("mb_6890", FLOPPY_3_SSDD);
+}
+
/***************************************************************************
FUNCTION PROTOTYPES
@@ -58,12 +47,14 @@ ROM_END
void bml3bus_mp1805_device::device_add_mconfig(machine_config &config)
{
- MC6843(config, m_mc6843, 0);
- m_mc6843->set_floppy_drives(m_floppy[0], m_floppy[1], m_floppy[2], m_floppy[3]);
- m_mc6843->irq().set(FUNC(bml3bus_mp1805_device::bml3_mc6843_intrq_w));
-
- for (auto &floppy : m_floppy)
- LEGACY_FLOPPY(config, floppy, 0, &bml3_mp1805_floppy_interface);
+ MC6843(config, m_mc6843, 500000);
+ m_mc6843->force_ready();
+ m_mc6843->irq().set(FUNC(bml3bus_mp1805_device::nmi_w));
+
+ FLOPPY_CONNECTOR(config, m_floppy[0], floppy_drives, "mb_6890", floppy_image_device::default_floppy_formats).enable_sound(true);
+ FLOPPY_CONNECTOR(config, m_floppy[1], floppy_drives, nullptr, floppy_image_device::default_floppy_formats).enable_sound(true);
+ FLOPPY_CONNECTOR(config, m_floppy[2], floppy_drives, nullptr, floppy_image_device::default_floppy_formats).enable_sound(true);
+ FLOPPY_CONNECTOR(config, m_floppy[3], floppy_drives, nullptr, floppy_image_device::default_floppy_formats).enable_sound(true);
}
//-------------------------------------------------
@@ -88,33 +79,29 @@ void bml3bus_mp1805_device::bml3_mp1805_w(uint8_t data)
// MT ? ? ? D3 D2 D1 D0
// MT: 0=motor off, 1=motor on
// Dn: 1=select drive <n>
- int drive_select = data & 0x0f;
- int drive;
- // TODO: MESS UI for flipping disk? Note that D88 images are double-sided, but the physical drive is single-sided
- int side = 0;
- int motor = BIT(data, 7);
- switch (drive_select) {
- case 1:
- drive = 0;
- break;
- case 2:
- drive = 1;
- break;
- case 4:
- drive = 2;
- break;
- case 8:
- drive = 3;
- break;
- default:
- // TODO: what's the correct behaviour if more than one drive select bit is set? Or no bit set?
- drive = 0;
- break;
+
+ logerror("control_w %02x\n", data);
+ int prev, next;
+ for(prev = 0; prev != 4; prev++)
+ if(m_control & (1 << prev))
+ break;
+ m_control = data;
+ for(next = 0; next != 4; next++)
+ if(m_control & (1 << next))
+ break;
+
+ auto fprev = m_floppy[prev]->get_device();
+ auto fnext = m_floppy[next]->get_device();
+
+ if(fprev && fprev != fnext)
+ m_floppy[prev]->get_device()->mon_w(1);
+
+ if((m_control & 0x80) && fnext) {
+ logerror("motor on\n");
+ fnext->mon_w(0);
}
- m_mc6843->set_drive(drive);
- m_floppy[drive]->floppy_mon_w(motor);
- m_floppy[drive]->floppy_drive_set_ready_state(ASSERT_LINE, 0);
- m_mc6843->set_side(side);
+
+ m_mc6843->set_floppy(fnext);
}
@@ -125,7 +112,7 @@ void bml3bus_mp1805_device::bml3_mp1805_w(uint8_t data)
bml3bus_mp1805_device::bml3bus_mp1805_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, BML3BUS_MP1805, tag, owner, clock),
device_bml3bus_card_interface(mconfig, *this),
- m_floppy(*this, "floppy%u", 0U),
+ m_floppy(*this, "%u", 0U),
m_mc6843(*this, "mc6843"), m_rom(nullptr)
{
}
@@ -141,13 +128,16 @@ void bml3bus_mp1805_device::device_start()
// install into memory
address_space &space_prg = space();
- space_prg.install_readwrite_handler(0xff18, 0xff1f, read8sm_delegate(*m_mc6843, FUNC(mc6843_device::read)), write8sm_delegate(*m_mc6843, FUNC(mc6843_device::write)));
+ space_prg.install_device(0xff18, 0xff1f, *m_mc6843, &mc6843_device::map);
space_prg.install_readwrite_handler(0xff20, 0xff20, read8smo_delegate(*this, FUNC(bml3bus_mp1805_device::bml3_mp1805_r)), write8smo_delegate(*this, FUNC(bml3bus_mp1805_device::bml3_mp1805_w)));
// overwriting the main ROM (rather than using e.g. install_rom) should mean that bank switches for RAM expansion still work...
uint8_t *mainrom = device().machine().root_device().memregion("maincpu")->base();
memcpy(mainrom + 0xf800, m_rom + 0xf800, 0x800);
+
+ save_item(NAME(m_control));
}
void bml3bus_mp1805_device::device_reset()
{
+ m_control = 0;
}
diff --git a/src/devices/bus/bml3/bml3mp1805.h b/src/devices/bus/bml3/bml3mp1805.h
index 0c0a40f4fd2..ea5fafa8766 100644
--- a/src/devices/bus/bml3/bml3mp1805.h
+++ b/src/devices/bus/bml3/bml3mp1805.h
@@ -41,13 +41,15 @@ protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual const tiny_rom_entry *device_rom_region() const override;
- required_device_array<legacy_floppy_image_device, 4> m_floppy;
+ required_device_array<floppy_connector, 4> m_floppy;
required_device<mc6843_device> m_mc6843;
private:
- DECLARE_WRITE_LINE_MEMBER( bml3_mc6843_intrq_w );
-
uint8_t *m_rom;
+
+ uint8_t m_control;
+
+ static void floppy_drives(device_slot_interface &device);
};
// device type definition
diff --git a/src/devices/bus/thomson/cd90_015.cpp b/src/devices/bus/thomson/cd90_015.cpp
new file mode 100644
index 00000000000..8b37650cf86
--- /dev/null
+++ b/src/devices/bus/thomson/cd90_015.cpp
@@ -0,0 +1,120 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+// CD 90-015 - Floppy drive selectler built from a wd1770
+//
+// Handles up to two 5.25 dual-sided drives (DD 90-320)
+
+#include "emu.h"
+#include "cd90_015.h"
+#include "formats/thom_dsk.h"
+
+DEFINE_DEVICE_TYPE(CD90_015, cd90_015_device, "cd90_015", "Thomson CD90-015 floppy drive selectler")
+
+cd90_015_device::cd90_015_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, CD90_015, tag, owner, clock),
+ thomson_extension_interface(mconfig, *this),
+ m_fdc(*this, "fdc"),
+ m_floppy(*this, "%u", 0U),
+ m_rom(*this, "rom")
+{
+}
+
+ROM_START(cd90_015)
+ ROM_REGION( 0x7c0, "rom", 0 )
+ ROM_LOAD ( "cd90-015.rom", 0x000, 0x7c0, CRC(821d34c1) SHA1(31a6bb81baaeec5fc8de457c97264f9dfa92c18b) )
+ROM_END
+
+void cd90_015_device::rom_map(address_map &map)
+{
+ map(0x000, 0x7bf).rom().region(m_rom, 0);
+}
+
+void cd90_015_device::io_map(address_map &map)
+{
+ map(0, 7).m(m_fdc, FUNC(mc6843_device::map));
+ map(8, 9).rw(FUNC(cd90_015_device::motor_r), FUNC(cd90_015_device::select_w));
+}
+
+const tiny_rom_entry *cd90_015_device::device_rom_region() const
+{
+ return ROM_NAME(cd90_015);
+}
+
+void cd90_015_device::floppy_drives(device_slot_interface &device)
+{
+ device.option_add("dd90_015", FLOPPY_525_SD);
+}
+
+void cd90_015_device::floppy_formats(format_registration &fr)
+{
+ fr.add(FLOPPY_THOMSON_525_FORMAT);
+}
+
+void cd90_015_device::device_add_mconfig(machine_config &config)
+{
+ MC6843(config, m_fdc, 16_MHz_XTAL / 32); // Comes from the main board
+ m_fdc->force_ready();
+ FLOPPY_CONNECTOR(config, m_floppy[0], floppy_drives, "dd90_015", floppy_formats).enable_sound(true);
+ FLOPPY_CONNECTOR(config, m_floppy[1], floppy_drives, nullptr, floppy_formats).enable_sound(true);
+ FLOPPY_CONNECTOR(config, m_floppy[2], floppy_drives, nullptr, floppy_formats).enable_sound(true);
+ FLOPPY_CONNECTOR(config, m_floppy[3], floppy_drives, nullptr, floppy_formats).enable_sound(true);
+}
+
+void cd90_015_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ m_floppy[id]->get_device()->mon_w(1);
+}
+
+void cd90_015_device::device_start()
+{
+ for(int i=0; i != 4; i++)
+ m_motor_timer[i] = timer_alloc(i);
+ save_item(NAME(m_select));
+}
+
+void cd90_015_device::device_reset()
+{
+ m_select = 0;
+ for(int i=0; i != 4; i++) {
+ floppy_image_device *f = m_floppy[i]->get_device();
+ if(f)
+ f->mon_w(1);
+ }
+ m_fdc->set_floppy(nullptr);
+}
+
+void cd90_015_device::select_w(u8 data)
+{
+ u8 started = (~m_select) & data;
+ m_select = data & 0xf;
+
+ for(int i = 0; i != 5; i++)
+ if(m_select & (1 << i)) {
+ m_fdc->set_floppy(m_floppy[i]->get_device());
+ goto found;
+ }
+ m_fdc->set_floppy(nullptr);
+
+ found:
+ for(int i = 0; i != 4; i++)
+ if(started & (1 << i)) {
+ if(m_floppy[i]->get_device()) {
+ m_floppy[i]->get_device()->mon_w(0);
+ m_motor_timer[i]->adjust(attotime::from_seconds(5));
+ }
+ }
+
+ logerror("select_w %x\n", m_select);
+}
+
+u8 cd90_015_device::motor_r()
+{
+ u8 res = 0xf;
+ for(int i=0; i != 4; i++)
+ if(m_floppy[i]->get_device() && !m_floppy[i]->get_device()->mon_r())
+ res &= ~(1 << i);
+ if(!machine().side_effects_disabled())
+ logerror("motor_r %x\n", res);
+ return res;
+}
diff --git a/src/devices/bus/thomson/cd90_015.h b/src/devices/bus/thomson/cd90_015.h
new file mode 100644
index 00000000000..7d2c963f7f6
--- /dev/null
+++ b/src/devices/bus/thomson/cd90_015.h
@@ -0,0 +1,48 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+// CD 90-015 - Floppy drive controller built from a hd 46503s aka hd6843 aka mc6843
+//
+// Handles up to four 5.25 single-sided drives (DD 90-015)
+
+#ifndef MAME_BUS_THOMSON_CD90_015_H
+#define MAME_BUS_THOMSON_CD90_015_H
+
+#include "extension.h"
+#include "imagedev/floppy.h"
+#include "machine/mc6843.h"
+
+class cd90_015_device : public device_t, public thomson_extension_interface
+{
+public:
+ cd90_015_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
+ virtual ~cd90_015_device() = default;
+
+ virtual void rom_map(address_map &map) override;
+ virtual void io_map(address_map &map) override;
+
+protected:
+ virtual const tiny_rom_entry *device_rom_region() const override;
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+
+private:
+ required_device<mc6843_device> m_fdc;
+ required_device_array<floppy_connector, 4> m_floppy;
+ required_memory_region m_rom;
+
+ emu_timer *m_motor_timer[4];
+ u8 m_select;
+
+ void select_w(u8 data);
+ u8 motor_r();
+
+ static void floppy_formats(format_registration &fr);
+ static void floppy_drives(device_slot_interface &device);
+};
+
+DECLARE_DEVICE_TYPE(CD90_015, cd90_015_device)
+
+#endif
diff --git a/src/devices/bus/thomson/cd90_351.cpp b/src/devices/bus/thomson/cd90_351.cpp
new file mode 100644
index 00000000000..e57d15db8d0
--- /dev/null
+++ b/src/devices/bus/thomson/cd90_351.cpp
@@ -0,0 +1,495 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+
+// CD 90-351 - Custom floppy drive controller (THMFC1)
+//
+// Handles up to two 3.5 dual-sided drives (DD 90-352)
+// or up to two 2.8 dual-sided QDD drivers (QD 90-280)
+
+
+#include "emu.h"
+#include "cd90_351.h"
+#include "formats/thom_dsk.h"
+
+DEFINE_DEVICE_TYPE(CD90_351, cd90_351_device, "cd90_351", "Thomson CD90-351 floppy drive controller")
+
+cd90_351_device::cd90_351_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, CD90_351, tag, owner, 16000000),
+ thomson_extension_interface(mconfig, *this),
+ m_floppy(*this, "%u", 0U),
+ m_rom(*this, "rom"),
+ m_rom_bank(*this, "rom_bank")
+{
+}
+
+ROM_START(cd90_351)
+ // Rom has been dumped from the system, so the unaccessible ranges are
+ // missing (and probably totally unimportant)
+
+ ROM_REGION( 0x2000, "rom", 0 )
+ ROM_LOAD ( "cd-351-0.rom", 0x0000, 0x7c0, CRC(2c0159fd) SHA1(bab5395ed8bc7c06f9897897f836054e6546e8e8) )
+ ROM_LOAD ( "cd-351-1.rom", 0x0800, 0x7c0, CRC(8e58d159) SHA1(dcf992c96e7556b2faee6bacd3f744e56998e6ea) )
+ ROM_LOAD ( "cd-351-2.rom", 0x1000, 0x7c0, CRC(c9228b60) SHA1(179e10107d5be91e684069dee80f94847b83201f) )
+ ROM_LOAD ( "cd-351-3.rom", 0x1800, 0x7c0, CRC(3ca8e5dc) SHA1(7118636fb5c597c78c2fce17b02aed5e4ba38635) )
+ROM_END
+
+void cd90_351_device::rom_map(address_map &map)
+{
+ map(0x000, 0x7bf).bankr(m_rom_bank);
+}
+
+void cd90_351_device::io_map(address_map &map)
+{
+ map(0, 0).rw(FUNC(cd90_351_device::stat0_r), FUNC(cd90_351_device::cmd0_w));
+ map(1, 1).rw(FUNC(cd90_351_device::stat1_r), FUNC(cd90_351_device::cmd1_w));
+ map(2, 2).w(FUNC(cd90_351_device::cmd2_w));
+ map(3, 3).rw(FUNC(cd90_351_device::rdata_r), FUNC(cd90_351_device::wdata_w));
+ map(4, 4).w(FUNC(cd90_351_device::wclk_w));
+ map(5, 5).w(FUNC(cd90_351_device::wsect_w));
+ map(6, 6).w(FUNC(cd90_351_device::wtrck_w));
+ map(7, 7).w(FUNC(cd90_351_device::wcell_w));
+ map(8, 8).w(FUNC(cd90_351_device::bank_w));
+}
+
+const tiny_rom_entry *cd90_351_device::device_rom_region() const
+{
+ return ROM_NAME(cd90_351);
+}
+
+void cd90_351_device::floppy_drives(device_slot_interface &device)
+{
+ device.option_add("dd90_352", FLOPPY_35_DD);
+ // device.option_add("qd90_280", FLOPPY_28_QDD);
+}
+
+void cd90_351_device::floppy_formats(format_registration &fr)
+{
+ fr.add_pc_formats();
+ fr.add(FLOPPY_THOMSON_35_FORMAT);
+}
+
+void cd90_351_device::device_add_mconfig(machine_config &config)
+{
+ FLOPPY_CONNECTOR(config, m_floppy[0], floppy_drives, "dd90_352", floppy_formats).enable_sound(true);
+ FLOPPY_CONNECTOR(config, m_floppy[1], floppy_drives, nullptr, floppy_formats).enable_sound(true);
+}
+
+void cd90_351_device::device_start()
+{
+ m_rom_bank->configure_entries(0, 4, m_rom->base(), 0x800);
+ m_timer_motoroff = timer_alloc(ID_MOTOROFF);
+
+ save_item(NAME(m_cmd0));
+ save_item(NAME(m_cmd1));
+ save_item(NAME(m_cmd2));
+ save_item(NAME(m_stat0));
+ save_item(NAME(m_data));
+ save_item(NAME(m_clk));
+ save_item(NAME(m_sect));
+ save_item(NAME(m_trck));
+ save_item(NAME(m_cell));
+ save_item(NAME(m_last_sync));
+ save_item(NAME(m_window_start));
+ save_item(NAME(m_shift_reg));
+ save_item(NAME(m_crc));
+ save_item(NAME(m_bit_counter));
+ save_item(NAME(m_data_reg));
+ save_item(NAME(m_data_separator_phase));
+}
+
+void cd90_351_device::device_reset()
+{
+ m_rom_bank->set_entry(0);
+
+ m_cmd0 = 0;
+ m_cmd1 = 0;
+ m_cmd2 = 0;
+ m_stat0 = S0_FREE;
+ m_data = 0;
+ m_clk = 0;
+ m_sect = 0;
+ m_trck = 0;
+ m_cell = 0;
+ m_last_sync = 0;
+ m_window_start = 0;
+ m_shift_reg = 0;
+ m_crc = 0;
+ m_bit_counter = 0;
+ m_data_reg = 0;
+ m_data_separator_phase = false;
+ m_state = S_IDLE;
+ m_cur_floppy = nullptr;
+}
+
+void cd90_351_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ switch(id) {
+ case ID_MOTOROFF:
+ logerror("motor off\n");
+ if(m_cur_floppy)
+ m_cur_floppy->mon_w(1);
+ break;
+ }
+}
+
+void cd90_351_device::device_post_load()
+{
+ if(m_cmd2 & C2_DRS0)
+ m_cur_floppy = m_floppy[0]->get_device();
+ else if(m_cmd2 & C2_DRS1)
+ m_cur_floppy = m_floppy[1]->get_device();
+ else
+ m_cur_floppy = nullptr;
+}
+
+void cd90_351_device::cmd0_w(u8 data)
+{
+ sync();
+
+ static const char *const mode[4] = { "reset", "wsect", "rhead", "rsect" };
+ m_cmd0 = data;
+ logerror("cmd0_w %02x, code=%s, ensyn=%d nomck=%d wgc=%d mode=%s\n", m_cmd1,
+ m_cmd0 & C0_FM ? "fm" : "mfm",
+ m_cmd0 & C0_ENSYN ? 1 : 0,
+ m_cmd0 & C0_NOMCK ? 1 : 0,
+ m_cmd0 & C0_WGC ? 1 : 0,
+ mode[m_cmd0 & 3]);
+
+ if(m_stat0 & S0_FREE)
+ switch(m_cmd0 & 3) {
+ case 0:
+ break;
+ case 1:
+ logerror("wsect\n");
+ exit(0);
+ case 2:
+ logerror("rhead\n");
+ exit(0);
+ case 3:
+ logerror("read_sector start h=%d t=%2d s=%2d sz=%d\n",
+ m_cmd1 & C1_SIDE ? 1 : 0,
+ m_trck,
+ m_sect,
+ 128 << ((m_cmd1 >> 5) & 3));
+ m_state = S_WAIT_HEADER_SYNC;
+ m_stat0 &= ~S0_FREE;
+ m_window_start = m_last_sync;
+ break;
+ }
+}
+
+void cd90_351_device::cmd1_w(u8 data)
+{
+ sync();
+
+ m_cmd1 = data;
+ logerror("cmd1_w %02x, sector=(size=%d, side=%d) precomp=%d sync_only_when_ready=%s\n", m_cmd1,
+ 128 << ((m_cmd1 >> 5) & 3),
+ m_cmd1 & C1_SIDE ? 1 : 0,
+ (m_cmd1 >> 1) & 7,
+ m_cmd1 & C1_DSYRD ? "on" : "off");
+}
+
+void cd90_351_device::cmd2_w(u8 data)
+{
+ sync();
+
+ u8 prev = m_cmd2;
+
+ m_cmd2 = data;
+ logerror("cmd2_w %02x, side=%d dir=%d step=%d motor=%s sel=%c%c\n", m_cmd2,
+ m_cmd2 & C2_SISELB ? 1 : 0,
+ m_cmd2 & C2_DIRECB ? 1 : 0,
+ m_cmd2 & C2_STEP ? 1 : 0,
+ m_cmd2 & C2_MTON ? "on" : "off",
+ m_cmd2 & C2_DRS1 ? 'b' : '-',
+ m_cmd2 & C2_DRS0 ? 'a' : '-');
+
+ if(m_cmd2 & C2_DRS0)
+ m_cur_floppy = m_floppy[0]->get_device();
+ else if(m_cmd2 & C2_DRS1)
+ m_cur_floppy = m_floppy[1]->get_device();
+ else
+ m_cur_floppy = nullptr;
+
+ if(m_cur_floppy) {
+ if((prev & C2_MTON) && !(m_cmd2 & C2_MTON))
+ m_timer_motoroff->adjust(attotime::from_seconds(2));
+ if(m_cmd2 & C2_MTON) {
+ m_cur_floppy->mon_w(0);
+ m_timer_motoroff->adjust(attotime::never);
+ }
+ m_cur_floppy->ss_w(m_cmd2 & C2_SISELB ? 0 : 1);
+ m_cur_floppy->dir_w(m_cmd2 & C2_DIRECB ? 0 : 1);
+ m_cur_floppy->stp_w(m_cmd2 & C2_STEP ? 0 : 1);
+ }
+}
+
+void cd90_351_device::wdata_w(u8 data)
+{
+ m_data = data;
+ m_stat0 &= ~(S0_BYTE | S0_DREQ);
+ logerror("wdata_w %02x\n", data);
+}
+
+void cd90_351_device::wclk_w(u8 data)
+{
+ sync();
+
+ m_clk = data;
+ logerror("wclk_w %02x\n", data);
+}
+
+void cd90_351_device::wsect_w(u8 data)
+{
+ sync();
+
+ m_sect = data;
+ logerror("wsect_w %02x\n", data);
+}
+
+void cd90_351_device::wtrck_w(u8 data)
+{
+ sync();
+
+ m_trck = data;
+ logerror("wtrck_w %02x\n", data);
+}
+
+void cd90_351_device::wcell_w(u8 data)
+{
+ sync();
+
+ m_cell = data;
+ logerror("wcell_w %02x\n", data);
+}
+
+u8 cd90_351_device::stat0_r()
+{
+ if(!machine().side_effects_disabled()) {
+ sync();
+ static int ps = -1;
+ if(m_stat0 != ps)
+ logerror("stat0_r %02x -%s%s%s%s%s%s\n", m_stat0,
+ m_stat0 & S0_BYTE ? " byte" : "",
+ m_stat0 & S0_END ? " end" : "",
+ m_stat0 & S0_FREE ? " free" : "",
+ m_stat0 & S0_CRCER ? " crcer" : "",
+ m_stat0 & S0_DREQ ? " dreq" : "",
+ m_stat0 & S0_SYNC ? " sync" : "");
+ ps = m_stat0;
+ }
+ return m_stat0;
+}
+
+u8 cd90_351_device::stat1_r()
+{
+ u8 res = 0;
+ if(m_cur_floppy) {
+ if(m_cur_floppy->idx_r())
+ res |= S1_INDX;
+ if(!m_cur_floppy->dskchg_r())
+ res |= S1_DKCH;
+ if(!m_cur_floppy->mon_r())
+ res |= S1_MTON;
+ if(!m_cur_floppy->trk00_r())
+ res |= S1_TRK0;
+ if(!m_cur_floppy->wpt_r())
+ res |= S1_WPRT;
+ if(!m_cur_floppy->ready_r())
+ res |= S1_RDY;
+ }
+
+ if(!machine().side_effects_disabled())
+ logerror("stat1_r %02x -%s%s%s%s%s%s\n", res,
+ res & S1_INDX ? " index" : "",
+ res & S1_DKCH ? " dskchg" : "",
+ res & S1_MTON ? " mton" : "",
+ res & S1_TRK0 ? " trk0" : "",
+ res & S1_WPRT ? " wprt" : "",
+ res & S1_RDY ? " ready" : "");
+ return res;
+}
+
+u8 cd90_351_device::rdata_r()
+{
+ if(!machine().side_effects_disabled())
+ m_stat0 &= ~(S0_BYTE | S0_DREQ);
+ return m_data;
+}
+
+void cd90_351_device::bank_w(u8 data)
+{
+ logerror("bank_w %d\n", data & 3);
+ m_rom_bank->set_entry(data & 3);
+}
+
+u64 cd90_351_device::time_to_cycles(const attotime &tm) const
+{
+ return tm.as_ticks(clock());
+}
+
+attotime cd90_351_device::cycles_to_time(u64 cycles) const
+{
+ return attotime::from_ticks(cycles, clock());
+}
+
+bool cd90_351_device::read_one_bit(u64 limit, u64 &next_flux_change)
+{
+ while(next_flux_change <= m_last_sync) {
+ attotime flux = m_cur_floppy ? m_cur_floppy->get_next_transition(cycles_to_time(m_last_sync+1)) : attotime::never;
+ next_flux_change = flux.is_never() ? u64(-1) : time_to_cycles(flux);
+ }
+
+ u64 window_end = m_window_start + (m_cell & 0x7f);
+ if(window_end > limit)
+ return true;
+
+ int bit = next_flux_change < window_end;
+ if(bit && (m_cmd0 & C0_NOMCK))
+ m_window_start = next_flux_change + ((m_cell & 0x7f) >> 1);
+ else
+ m_window_start = window_end;
+
+ m_last_sync = window_end;
+
+ m_shift_reg = (m_shift_reg << 1) | bit;
+ m_bit_counter++;
+ if(m_data_separator_phase) {
+ m_data_reg = (m_data_reg << 1) | bit;
+ if((m_crc ^ (bit ? 0x8000 : 0x0000)) & 0x8000)
+ m_crc = (m_crc << 1) ^ 0x1021;
+ else
+ m_crc = m_crc << 1;
+ }
+
+ m_data_separator_phase = !m_data_separator_phase;
+ return false;
+}
+
+u8 cd90_351_device::clk_bits() const
+{
+ return
+ (m_shift_reg & 0x8000 ? 0x80 : 0x00) |
+ (m_shift_reg & 0x2000 ? 0x40 : 0x00) |
+ (m_shift_reg & 0x0800 ? 0x20 : 0x00) |
+ (m_shift_reg & 0x0200 ? 0x10 : 0x00) |
+ (m_shift_reg & 0x0080 ? 0x08 : 0x00) |
+ (m_shift_reg & 0x0020 ? 0x04 : 0x00) |
+ (m_shift_reg & 0x0008 ? 0x02 : 0x00) |
+ (m_shift_reg & 0x0002 ? 0x01 : 0x00);
+}
+
+
+void cd90_351_device::sync()
+{
+ u64 next_sync = machine().time().as_ticks(clock());
+ u64 next_flux_change = 0;
+ while(m_last_sync < next_sync)
+ switch(m_state) {
+ case S_IDLE:
+ m_last_sync = next_sync;
+ break;
+
+ case S_WAIT_HEADER_SYNC: {
+ if(read_one_bit(next_sync, next_flux_change))
+ return;
+ if(m_shift_reg == 0xaaaa) {
+ m_crc = 0xffff;
+ m_data_separator_phase = false;
+ }
+ if(m_data_reg == m_data && clk_bits() == m_clk) {
+ m_bit_counter = 0;
+ m_state = S_VERIFY_HEADER;
+ }
+ break;
+ }
+
+ case S_VERIFY_HEADER: {
+ if(read_one_bit(next_sync, next_flux_change))
+ return;
+ if(m_bit_counter & 0xf)
+ break;
+ bool valid = true;
+ switch(m_bit_counter >> 4) {
+ case 1:
+ case 2:
+ valid = m_data_reg == m_data && clk_bits() == m_clk;
+ break;
+ case 3:
+ valid = m_data_reg == 0xfe;
+ break;
+ case 4:
+ valid = m_data_reg == m_trck;
+ break;
+ case 5:
+ valid = (m_data_reg & 1) == (m_cmd1 & C1_SIDE ? 1 : 0);
+ break;
+ case 6:
+ valid = m_data_reg == m_sect;
+ break;
+ case 7:
+ valid = (m_data_reg & 3) == ((m_cmd1 >> 5) & 3);
+ break;
+ // 8 skipped
+ case 9:
+ valid = m_crc == 0;
+ m_bit_counter = 0;
+ m_state = S_SKIP_GAP;
+ break;
+ }
+ if(!valid)
+ m_state = S_WAIT_HEADER_SYNC;
+ break;
+ }
+
+ case S_SKIP_GAP:
+ if(read_one_bit(next_sync, next_flux_change))
+ return;
+ if(m_bit_counter == 27 << 4) {
+ m_bit_counter = 0;
+ m_state = S_WAIT_SECTOR_SYNC;
+ }
+ break;
+
+
+ case S_WAIT_SECTOR_SYNC: {
+ if(read_one_bit(next_sync, next_flux_change))
+ return;
+ if(m_shift_reg == 0xaaaa) {
+ m_crc = 0xffff;
+ m_data_separator_phase = false;
+ }
+ if(m_data_reg == m_data && clk_bits() == m_clk) {
+ m_bit_counter = 0;
+ m_data = m_data_reg;
+ m_stat0 |= S0_DREQ;
+ m_state = S_READ_SECTOR;
+ }
+ if(m_bit_counter == 42 << 4)
+ m_state = S_WAIT_HEADER_SYNC;
+ break;
+ }
+
+ case S_READ_SECTOR:
+ if(read_one_bit(next_sync, next_flux_change))
+ return;
+ if(m_bit_counter != 16)
+ break;
+ if(m_stat0 & (S0_BYTE|S0_DREQ)) {
+ logerror("read_sector end\n");
+ if(m_crc)
+ m_stat0 |= S0_CRCER;
+ m_stat0 &= ~S0_BYTE;
+ m_stat0 |= S0_FREE;
+ m_cmd0 &= ~3;
+ m_state = S_IDLE;
+ break;
+ }
+ m_stat0 |= S0_BYTE;
+ m_data = m_data_reg;
+ m_bit_counter = 0;
+ break;
+ }
+}
diff --git a/src/devices/bus/thomson/cd90_351.h b/src/devices/bus/thomson/cd90_351.h
new file mode 100644
index 00000000000..0d5957ad203
--- /dev/null
+++ b/src/devices/bus/thomson/cd90_351.h
@@ -0,0 +1,122 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+// CD 90-351 - Custom floppy drive controller (THMFC1)
+//
+// Handles up to two 3.5 dual-sided drives (DD 90-352)
+// or up to two 2.8 dual-sided QDD drivers (QD 90-280)
+
+#ifndef MAME_BUS_THOMSON_CD90_351_H
+#define MAME_BUS_THOMSON_CD90_351_H
+
+#include "extension.h"
+#include "imagedev/floppy.h"
+
+class cd90_351_device : public device_t, public thomson_extension_interface
+{
+public:
+ cd90_351_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 16000000);
+ virtual ~cd90_351_device() = default;
+
+ virtual void rom_map(address_map &map) override;
+ virtual void io_map(address_map &map) override;
+
+protected:
+ virtual const tiny_rom_entry *device_rom_region() const override;
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+ virtual void device_post_load() override;
+
+private:
+ enum {
+ ID_MOTOROFF = 0,
+ };
+
+ enum {
+ S0_BYTE = 0x80,
+ S0_END = 0x10,
+ S0_FREE = 0x08,
+ S0_CRCER = 0x04,
+ S0_DREQ = 0x02,
+ S0_SYNC = 0x01,
+
+ S1_INDX = 0x40,
+ S1_DKCH = 0x20,
+ S1_MTON = 0x10,
+ S1_TRK0 = 0x08,
+ S1_WPRT = 0x04,
+ S1_RDY = 0x02,
+
+ C0_FM = 0x20,
+ C0_ENSYN = 0x10,
+ C0_NOMCK = 0x08,
+ C0_WGC = 0x04,
+
+ C1_SIDE = 0x10,
+ C1_DSYRD = 0x01,
+
+ C2_SISELB = 0x40,
+ C2_DIRECB = 0x20,
+ C2_STEP = 0x10,
+ C2_MTON = 0x04,
+ C2_DRS1 = 0x02,
+ C2_DRS0 = 0x01,
+ };
+
+ enum {
+ S_IDLE,
+ S_WAIT_HEADER_SYNC,
+ S_VERIFY_HEADER,
+ S_SKIP_GAP,
+ S_WAIT_SECTOR_SYNC,
+ S_READ_SECTOR,
+ };
+
+ required_device_array<floppy_connector, 2> m_floppy;
+ required_memory_region m_rom;
+ memory_bank_creator m_rom_bank;
+ floppy_image_device *m_cur_floppy;
+ emu_timer *m_timer_motoroff;
+
+ u64 m_last_sync, m_window_start;
+ int m_state;
+
+ u16 m_shift_reg, m_crc, m_bit_counter;
+ u8 m_data_reg;
+
+ u8 m_cmd0, m_cmd1, m_cmd2, m_stat0;
+ u8 m_data, m_clk, m_sect, m_trck, m_cell;
+
+ bool m_data_separator_phase;
+
+ static void floppy_formats(format_registration &fr);
+ static void floppy_drives(device_slot_interface &device);
+
+ u8 clk_bits() const;
+
+ void cmd0_w(u8 data);
+ void cmd1_w(u8 data);
+ void cmd2_w(u8 data);
+ void wdata_w(u8 data);
+ void wclk_w(u8 data);
+ void wsect_w(u8 data);
+ void wtrck_w(u8 data);
+ void wcell_w(u8 data);
+ void bank_w(u8 data);
+
+ u8 stat0_r();
+ u8 stat1_r();
+ u8 rdata_r();
+
+ u64 time_to_cycles(const attotime &tm) const;
+ attotime cycles_to_time(u64 cycles) const;
+
+ void sync();
+ bool read_one_bit(u64 limit, u64 &next_flux_change);
+};
+
+DECLARE_DEVICE_TYPE(CD90_351, cd90_351_device)
+
+#endif
diff --git a/src/devices/bus/thomson/cd90_640.cpp b/src/devices/bus/thomson/cd90_640.cpp
new file mode 100644
index 00000000000..4cae4efb97a
--- /dev/null
+++ b/src/devices/bus/thomson/cd90_640.cpp
@@ -0,0 +1,91 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+// CD 90-640 - Floppy drive controller built from a wd1770
+//
+// Handles up to two 5.25 dual-sided drives (DD 90-320)
+
+#include "emu.h"
+#include "cd90_640.h"
+#include "formats/thom_dsk.h"
+
+DEFINE_DEVICE_TYPE(CD90_640, cd90_640_device, "cd90_640", "Thomson CD90-640 floppy drive controller")
+
+cd90_640_device::cd90_640_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, CD90_640, tag, owner, clock),
+ thomson_extension_interface(mconfig, *this),
+ m_fdc(*this, "fdc"),
+ m_floppy(*this, "%u", 0U),
+ m_rom(*this, "rom")
+{
+}
+
+ROM_START(cd90_640)
+ ROM_REGION( 0x7c0, "rom", 0 )
+ ROM_LOAD ( "cd90-640.rom", 0x000, 0x7c0, CRC(5114c0a5) SHA1(5c72566c22d8160ef0c75959e1863a1309bbbe49) )
+ROM_END
+
+void cd90_640_device::rom_map(address_map &map)
+{
+ map(0x000, 0x7bf).rom().region(m_rom, 0);
+}
+
+void cd90_640_device::io_map(address_map &map)
+{
+ map(0, 3).rw(m_fdc, FUNC(wd1770_device::read), FUNC(wd1770_device::write));
+ map(8, 8).rw(FUNC(cd90_640_device::control_r), FUNC(cd90_640_device::control_w));
+}
+
+const tiny_rom_entry *cd90_640_device::device_rom_region() const
+{
+ return ROM_NAME(cd90_640);
+}
+
+void cd90_640_device::floppy_drives(device_slot_interface &device)
+{
+ device.option_add("dd90_640", FLOPPY_525_DD);
+}
+
+void cd90_640_device::floppy_formats(format_registration &fr)
+{
+ fr.add(FLOPPY_THOMSON_525_FORMAT);
+}
+
+void cd90_640_device::device_add_mconfig(machine_config &config)
+{
+ WD1770(config, m_fdc, 8_MHz_XTAL);
+ FLOPPY_CONNECTOR(config, m_floppy[0], floppy_drives, "dd90_640", floppy_formats).enable_sound(true);
+ FLOPPY_CONNECTOR(config, m_floppy[1], floppy_drives, nullptr, floppy_formats).enable_sound(true);
+}
+
+void cd90_640_device::device_start()
+{
+ save_item(NAME(m_control));
+}
+
+void cd90_640_device::device_reset()
+{
+ m_control = 0;
+ m_fdc->set_floppy(nullptr);
+ m_fdc->dden_w(0);
+}
+
+void cd90_640_device::control_w(u8 data)
+{
+ m_control = data;
+ floppy_image_device *floppy = nullptr;
+ if(m_control & 2)
+ floppy = m_floppy[0]->get_device();
+ else if(m_control & 4)
+ floppy = m_floppy[1]->get_device();
+ if(floppy)
+ floppy->ss_w(m_control & 1);
+ m_fdc->set_floppy(floppy);
+ m_fdc->dden_w(m_control & 0x80 ? 1 : 0);
+ logerror("control %02x\n", m_control);
+}
+
+u8 cd90_640_device::control_r()
+{
+ return m_control;
+}
diff --git a/src/devices/bus/thomson/cd90_640.h b/src/devices/bus/thomson/cd90_640.h
new file mode 100644
index 00000000000..5598a71546d
--- /dev/null
+++ b/src/devices/bus/thomson/cd90_640.h
@@ -0,0 +1,46 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+// CD 90-640 - Floppy drive controller built from a wd1770
+//
+// Handles up to two 5.25 dual-sided drives (DD 90-320)
+
+#ifndef MAME_BUS_THOMSON_CD90_640_H
+#define MAME_BUS_THOMSON_CD90_640_H
+
+#include "extension.h"
+#include "imagedev/floppy.h"
+#include "machine/wd_fdc.h"
+
+class cd90_640_device : public device_t, public thomson_extension_interface
+{
+public:
+ cd90_640_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
+ virtual ~cd90_640_device() = default;
+
+ virtual void rom_map(address_map &map) override;
+ virtual void io_map(address_map &map) override;
+
+protected:
+ virtual const tiny_rom_entry *device_rom_region() const override;
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ required_device<wd1770_device> m_fdc;
+ required_device_array<floppy_connector, 2> m_floppy;
+ required_memory_region m_rom;
+
+ u8 m_control;
+
+ void control_w(u8 data);
+ u8 control_r();
+
+ static void floppy_formats(format_registration &fr);
+ static void floppy_drives(device_slot_interface &device);
+};
+
+DECLARE_DEVICE_TYPE(CD90_640, cd90_640_device)
+
+#endif
diff --git a/src/devices/bus/thomson/cq90_028.cpp b/src/devices/bus/thomson/cq90_028.cpp
new file mode 100644
index 00000000000..fd14c5302f7
--- /dev/null
+++ b/src/devices/bus/thomson/cq90_028.cpp
@@ -0,0 +1,76 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+// CQ 90-028 - QDD drive controller built from a motorola 6852 (serial chip)
+//
+// Handles n? QDD drives (QD 90-128)
+
+// Nonfunctional, essentially because we have no container for the QDD
+// (it's not a floppy, the closest equivalent would be a digital tape)
+
+#include "emu.h"
+#include "cq90_028.h"
+
+DEFINE_DEVICE_TYPE(CQ90_028, cq90_028_device, "cq90_028", "Thomson CQ90-028 QDD controller")
+
+cq90_028_device::cq90_028_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, CQ90_028, tag, owner, clock),
+ thomson_extension_interface(mconfig, *this),
+ m_serial(*this, "serial"),
+ m_rom(*this, "rom")
+{
+}
+
+ROM_START(cq90_028)
+ ROM_REGION( 0x7c0, "rom", 0 )
+ ROM_LOAD ( "cq90-028.rom", 0x000, 0x7c0, CRC(ca4dba3d) SHA1(949c1f777c892da62c242215d79757d61e71e62b) )
+ROM_END
+
+void cq90_028_device::rom_map(address_map &map)
+{
+ map(0x000, 0x7bf).rom().region(m_rom, 0);
+}
+
+void cq90_028_device::io_map(address_map &map)
+{
+ map(0x0, 0x1).rw(m_serial, FUNC(mc6852_device::read), FUNC(mc6852_device::write));
+ map(0x8, 0x8).rw(FUNC(cq90_028_device::status_r), FUNC(cq90_028_device::drive_w));
+ map(0xc, 0xc).w(FUNC(cq90_028_device::motor_w));
+}
+
+const tiny_rom_entry *cq90_028_device::device_rom_region() const
+{
+ return ROM_NAME(cq90_028);
+}
+
+void cq90_028_device::device_add_mconfig(machine_config &config)
+{
+ MC6852(config, m_serial, 16_MHz_XTAL / 16); // Comes from the main board
+ // Base tx/rx clock is 101564Hz
+ // There's probably a pll in the gate array
+}
+
+void cq90_028_device::device_start()
+{
+}
+
+void cq90_028_device::device_reset()
+{
+}
+
+void cq90_028_device::drive_w(u8 data)
+{
+ logerror("drive_w %02x\n", data);
+}
+
+void cq90_028_device::motor_w(u8 data)
+{
+ logerror("motor_w %02x\n", data);
+}
+
+u8 cq90_028_device::status_r()
+{
+ // 40 = disk absent
+ // 80 = index pulse
+ return 0x40;
+}
diff --git a/src/devices/bus/thomson/cq90_028.h b/src/devices/bus/thomson/cq90_028.h
new file mode 100644
index 00000000000..d0a44448e38
--- /dev/null
+++ b/src/devices/bus/thomson/cq90_028.h
@@ -0,0 +1,42 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+// CQ 90-028 - QDD drive controller built from a motorola 6852 (serial chip)
+//
+// Handles n? QDD drives (QD 90-128)
+
+#ifndef MAME_BUS_THOMSON_CQ90_028_H
+#define MAME_BUS_THOMSON_CQ90_028_H
+
+#include "extension.h"
+#include "machine/mc6852.h"
+
+class cq90_028_device : public device_t, public thomson_extension_interface
+{
+public:
+ cq90_028_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
+ virtual ~cq90_028_device() = default;
+
+ static constexpr feature_type unemulated_features() { return feature::DISK; }
+
+ virtual void rom_map(address_map &map) override;
+ virtual void io_map(address_map &map) override;
+
+protected:
+ virtual const tiny_rom_entry *device_rom_region() const override;
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ required_device<mc6852_device> m_serial;
+ required_memory_region m_rom;
+
+ void drive_w(u8 data);
+ void motor_w(u8 data);
+ u8 status_r();
+};
+
+DECLARE_DEVICE_TYPE(CQ90_028, cq90_028_device)
+
+#endif
diff --git a/src/devices/bus/thomson/extension.cpp b/src/devices/bus/thomson/extension.cpp
new file mode 100644
index 00000000000..12462b9898a
--- /dev/null
+++ b/src/devices/bus/thomson/extension.cpp
@@ -0,0 +1,40 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+// Generic Thomson TO*/MO* extension slot
+
+
+#include "emu.h"
+#include "extension.h"
+
+DEFINE_DEVICE_TYPE(THOMSON_EXTENSION, thomson_extension_device, "thomson_extension", "Thomson TO*/MO* extension port")
+
+thomson_extension_device::thomson_extension_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, THOMSON_EXTENSION, tag, owner, clock),
+ device_single_card_slot_interface<thomson_extension_interface>(mconfig, *this)
+{
+}
+
+void thomson_extension_device::rom_map(address_space_installer &space, offs_t start, offs_t end)
+{
+ auto dev = get_card_device();
+ if(dev)
+ space.install_device(start, end, *dev, &thomson_extension_interface::rom_map);
+}
+
+void thomson_extension_device::io_map(address_space_installer &space, offs_t start, offs_t end)
+{
+ auto dev = get_card_device();
+ if(dev)
+ space.install_device(start, end, *dev, &thomson_extension_interface::io_map);
+}
+
+void thomson_extension_device::device_start()
+{
+}
+
+thomson_extension_interface::thomson_extension_interface(const machine_config &mconfig, device_t &device) :
+ device_interface(device, "extension")
+{
+}
+
diff --git a/src/devices/bus/thomson/extension.h b/src/devices/bus/thomson/extension.h
new file mode 100644
index 00000000000..bbe9db92915
--- /dev/null
+++ b/src/devices/bus/thomson/extension.h
@@ -0,0 +1,39 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+// Generic Thomson TO*/MO* extension slot
+
+#ifndef MAME_BUS_THOMSON_EXTENSION_H
+#define MAME_BUS_THOMSON_EXTENSION_H
+
+class thomson_extension_interface : public device_interface
+{
+public:
+ thomson_extension_interface(const machine_config &mconfig, device_t &device);
+ virtual ~thomson_extension_interface() = default;
+
+ // 0x7c0 window at e000 on TO* and a000 on MO*
+ virtual void rom_map(address_map &map) = 0;
+
+ // 0x10 window at e7d0 on TO* and a7e0 on MO*
+ virtual void io_map(address_map &map) = 0;
+};
+
+
+
+class thomson_extension_device : public device_t, public device_single_card_slot_interface<thomson_extension_interface>
+{
+public:
+ thomson_extension_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
+ virtual ~thomson_extension_device() = default;
+
+ void rom_map(address_space_installer &space, offs_t start, offs_t end);
+ void io_map(address_space_installer &space, offs_t start, offs_t end);
+
+protected:
+ virtual void device_start() override;
+};
+
+DECLARE_DEVICE_TYPE(THOMSON_EXTENSION, thomson_extension_device)
+
+#endif
diff --git a/src/devices/bus/thomson/nanoreseau.cpp b/src/devices/bus/thomson/nanoreseau.cpp
new file mode 100644
index 00000000000..51f11c65761
--- /dev/null
+++ b/src/devices/bus/thomson/nanoreseau.cpp
@@ -0,0 +1,205 @@
+// license:BSD-3-Clause
+// copyright-holders:Antoine Mine, Olivier Galibert
+
+// The "Nanoreseau" was a proprietary networking for MO/TO Thomson
+// computers using rs-485. A PC is supposed to be used as a network
+// head.
+
+#include "emu.h"
+#include "nanoreseau.h"
+
+DEFINE_DEVICE_TYPE(NANORESEAU_TO, nanoreseau_to_device, "nanoreseau_to", "Nanoreseau controller (TO rom)")
+DEFINE_DEVICE_TYPE(NANORESEAU_MO, nanoreseau_mo_device, "nanoreseau_mo", "Nanoreseau controller (MO rom)")
+
+ nanoreseau_device::nanoreseau_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool no_id) :
+ device_t(mconfig, type, tag, owner, clock),
+ thomson_extension_interface(mconfig, *this),
+ m_mc6854(*this, "mc6854"),
+ m_rom(*this, "rom"),
+ m_id(*this, "id"),
+ m_no_id(no_id)
+{
+}
+
+nanoreseau_to_device::nanoreseau_to_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, bool no_id) :
+ nanoreseau_device(mconfig, NANORESEAU_TO, tag, owner, clock)
+{
+}
+
+nanoreseau_mo_device::nanoreseau_mo_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, bool no_id) :
+ nanoreseau_device(mconfig, NANORESEAU_MO, tag, owner, clock)
+{
+}
+
+ROM_START(nanoreseau_to)
+ ROM_REGION( 0x7c0, "rom", 0 )
+ ROM_LOAD ( "nano7.rom", 0x000, 0x7c0, CRC(42a1d1a6) SHA1(973209f4baa5e81bf7885c0602949e064bac7862) )
+ROM_END
+
+ROM_START(nanoreseau_mo)
+ ROM_REGION( 0x7c0, "rom", 0 )
+ ROM_LOAD ( "nano5.rom", 0x000, 0x7c0, CRC(2f756868) SHA1(b5b7cb6d12493d849330b6b5628efd1a83a4bbf5) )
+ROM_END
+
+static INPUT_PORTS_START(nanoreseau_config)
+ PORT_START("id")
+ PORT_CONFNAME(0x1f, 0x01, "Network ID")
+ PORT_CONFSETTING(0x00, "0 (Master)")
+ PORT_CONFSETTING(0x01, "1")
+ PORT_CONFSETTING(0x02, "2")
+ PORT_CONFSETTING(0x03, "3")
+ PORT_CONFSETTING(0x04, "4")
+ PORT_CONFSETTING(0x05, "5")
+ PORT_CONFSETTING(0x06, "6")
+ PORT_CONFSETTING(0x07, "7")
+ PORT_CONFSETTING(0x08, "8")
+ PORT_CONFSETTING(0x09, "9")
+ PORT_CONFSETTING(0x0a, "10")
+ PORT_CONFSETTING(0x0b, "11")
+ PORT_CONFSETTING(0x0c, "12")
+ PORT_CONFSETTING(0x0d, "13")
+ PORT_CONFSETTING(0x0e, "14")
+ PORT_CONFSETTING(0x0f, "15")
+ PORT_CONFSETTING(0x10, "16")
+ PORT_CONFSETTING(0x11, "17")
+ PORT_CONFSETTING(0x12, "18")
+ PORT_CONFSETTING(0x13, "19")
+ PORT_CONFSETTING(0x14, "20")
+ PORT_CONFSETTING(0x15, "21")
+ PORT_CONFSETTING(0x16, "22")
+ PORT_CONFSETTING(0x17, "23")
+ PORT_CONFSETTING(0x18, "24")
+ PORT_CONFSETTING(0x19, "25")
+ PORT_CONFSETTING(0x1a, "26")
+ PORT_CONFSETTING(0x1b, "27")
+ PORT_CONFSETTING(0x1c, "28")
+ PORT_CONFSETTING(0x1d, "29")
+ PORT_CONFSETTING(0x1e, "30")
+ PORT_CONFSETTING(0x1f, "31")
+INPUT_PORTS_END
+
+void nanoreseau_device::rom_map(address_map &map)
+{
+ map(0x000, 0x7bf).rom().region(m_rom, 0);
+}
+
+void nanoreseau_device::io_map(address_map &map)
+{
+ map(0, 3).rw(m_mc6854, FUNC(mc6854_device::read), FUNC(mc6854_device::write));
+ if(!m_no_id)
+ map(8, 8).r(FUNC(nanoreseau_device::id_r));
+}
+
+const tiny_rom_entry *nanoreseau_to_device::device_rom_region() const
+{
+ return ROM_NAME(nanoreseau_to);
+}
+
+const tiny_rom_entry *nanoreseau_mo_device::device_rom_region() const
+{
+ return ROM_NAME(nanoreseau_mo);
+}
+
+void nanoreseau_device::device_add_mconfig(machine_config &config)
+{
+ MC6854(config, m_mc6854);
+ m_mc6854->set_out_frame_callback(FUNC(nanoreseau_device::got_frame));
+}
+
+void nanoreseau_device::device_start()
+{
+ m_timer = timer_alloc(0);
+ save_item(NAME(m_answer_step));
+}
+
+void nanoreseau_device::device_reset()
+{
+ m_answer_step = 4;
+ m_mc6854->set_cts(0);
+ m_mc6854->set_cts(1);
+}
+
+ioport_constructor nanoreseau_device::device_input_ports() const
+{
+ return m_no_id ? nullptr : INPUT_PORTS_NAME(nanoreseau_config);
+}
+
+/*********************** Network ************************/
+
+/* The network extension is built as an external floppy controller.
+ It uses the same ROM and I/O space, and so, it is natural to have the
+ toplevel network emulation here!
+*/
+
+/* NOTE: This is work in progress!
+ For the moment, only hand-checks works: the TO7 can take the line, then
+ perform a DKBOOT request. We do not have the server emulated yet, so,
+ no way to answer the request.
+*/
+
+/* consigne DKBOOT
+
+ MO5 BASIC
+ $00 $00 $01 $00 $00 $00 $00 $00 $00 $00 $01 $00<$41 $00 $FF $20
+ $3D $4C $01 $60 $20 $3C $4F $01 $05 $20 $3F $9C $19 $25 $03 $11
+ $93 $15 $10 $25 $32 $8A $7E $FF $E1 $FD $E9 $41>$00 $00 $00 $00
+ $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00
+
+ TO7/70 BASIC
+ $00 $00 $01 $00 $00 $00 $00 $00 $00 $00 $02 $00<$20 $42 $41 $53
+ $49 $43 $20 $4D $49 $43 $52 $4F $53 $4F $46 $54 $20 $31 $2E $30
+ $04 $00 $00 $00 $00 $00 $60 $FF $37 $9B $37 $9C>$00 $00 $00 $00
+ $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00
+
+ TO7 BASIC
+ $00 $00 $01 $00 $00 $00 $00 $00 $00 $00 $00 $00<$20 $42 $41 $53
+ $49 $43 $20 $4D $49 $43 $52 $4F $53 $4F $46 $54 $20 $31 $2E $30
+ $04 $00 $00 $00 $00 $00 $60 $FF $37 $9B $37 $9C>$00 $00 $00 $00
+ $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00
+
+ TO7 LOGO
+ $00 $00 $01 $00 $00 $00 $00 $00 $00 $00 $00 $00<$00 $00 $00 $00
+ $00 $20 $4C $4F $47 $4F $04 $00 $00 $00 $00 $00 $00 $00 $00 $00
+ $00 $00 $00 $00 $00 $00 $AA $FF $01 $16 $00 $C8>$00 $00 $00 $00
+ $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00
+
+
+*/
+
+void nanoreseau_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ m_answer_step ++;
+ m_mc6854->set_cts(m_answer_step & 1);
+ if(m_answer_step < 4)
+ m_timer->adjust(attotime::from_usec(100));
+}
+
+void nanoreseau_device::got_frame(uint8_t *data, int length)
+{
+ std::string frame = util::string_format("%s: frame", machine().time().to_string());
+ for(int i = 0; i < length; i++)
+ frame += util::string_format(" %02x", data[i]);
+ logerror("%s\n", frame);
+
+ if(data[1] == 0xff) {
+ logerror("frame: %d phones %d\n", data[2], data[0]);
+ m_answer_step = 0;
+ m_timer->adjust(attotime::from_usec(100));
+ m_mc6854->set_cts(0);
+
+ } else if (!data[1]) {
+ char name[33];
+ memcpy(name, data + 12, 32);
+ name[32] = 0;
+ for(int i=0; i<32; i++)
+ if(name[i] < 32 || name[i] >= 127)
+ name[i]='.';
+ logerror("DKBOOT system %s appli %s\n", data[10] == 0 ? "TO7" : data[10] == 1 ? "MO5" : data[10] == 2 ? "TO7/70" : "?", name);
+ }
+}
+
+u8 nanoreseau_device::id_r()
+{
+ // network ID of the computer
+ return m_id->read();
+}
diff --git a/src/devices/bus/thomson/nanoreseau.h b/src/devices/bus/thomson/nanoreseau.h
new file mode 100644
index 00000000000..b50f8618556
--- /dev/null
+++ b/src/devices/bus/thomson/nanoreseau.h
@@ -0,0 +1,66 @@
+// license:BSD-3-Clause
+// copyright-holders:Antoine Mine, Olivier Galibert
+
+// The "Nanoreseau" was a proprietary networking for MO/TO Thomson
+// computers using rs-485. A PC is supposed to be used as a network
+// head.
+
+#ifndef MAME_BUS_THOMSON_NANORESEAU_H
+#define MAME_BUS_THOMSON_NANORESEAU_H
+
+#include "extension.h"
+#include "machine/mc6854.h"
+
+class nanoreseau_device : public device_t, public thomson_extension_interface
+{
+public:
+ nanoreseau_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool no_id = false);
+ virtual ~nanoreseau_device() = default;
+
+ virtual void rom_map(address_map &map) override;
+ virtual void io_map(address_map &map) override;
+
+protected:
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual ioport_constructor device_input_ports() const override;
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+
+private:
+ required_device<mc6854_device> m_mc6854;
+ required_memory_region m_rom;
+ required_ioport m_id;
+ bool m_no_id;
+
+ emu_timer *m_timer;
+ int m_answer_step;
+
+ void got_frame(uint8_t *data, int length);
+ u8 id_r();
+};
+
+class nanoreseau_mo_device : public nanoreseau_device
+{
+public:
+ nanoreseau_mo_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0, bool no_id = false);
+ virtual ~nanoreseau_mo_device() = default;
+
+protected:
+ virtual const tiny_rom_entry *device_rom_region() const override;
+};
+
+class nanoreseau_to_device : public nanoreseau_device
+{
+public:
+ nanoreseau_to_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0, bool no_id = false);
+ virtual ~nanoreseau_to_device() = default;
+
+protected:
+ virtual const tiny_rom_entry *device_rom_region() const override;
+};
+
+DECLARE_DEVICE_TYPE(NANORESEAU_MO, nanoreseau_mo_device)
+DECLARE_DEVICE_TYPE(NANORESEAU_TO, nanoreseau_to_device)
+
+#endif
diff --git a/src/devices/machine/mc6843.cpp b/src/devices/machine/mc6843.cpp
index 74945094b40..caf637c2eb3 100644
--- a/src/devices/machine/mc6843.cpp
+++ b/src/devices/machine/mc6843.cpp
@@ -1,835 +1,942 @@
// license:BSD-3-Clause
-// copyright-holders:Antoine Mine
-/**********************************************************************
-
- Copyright (C) Antoine Mine' 2007
-
- Motorola 6843 Floppy Disk Controller emulation.
-
-**********************************************************************/
-
-/*
- Main MC 6843 features are:
- - single density floppies
- - IBM 3740 compatible
- - DMA-able
- - high-level commands (including multi-sector read/write)
-
- CLONES: HD 46503S seems to be a clone of MC 6843
-
- BUGS
- The driver was designed with Thomson computer emulation in mind
- (CD 90-015 5"1/4 floppy controller) and works in this context.
- It might work in other contexts but has currently shortcomings:
- - DMA is not emulated
- - Free-Format Read is not emulated
- - Free-Format Write only supports track formatting, in a specific
- format (FWF=1, Thomson-like sector formats)
- - very rough timing: basically, there is a fixed delay between
- a command request (CMR write) and its response (first byte
- available, seek complete, etc.); there is no delay between
- read / write
- */
+// copyright-holders:Olivier Galibert
+// Not implemented for lack of test cases: FFR
#include "emu.h"
#include "mc6843.h"
-//#define VERBOSE 1
-#include "logmacro.h"
-
-
-/******************* parameters ******************/
-
-/* macro-command numbers */
-#define CMD_STZ 0x2 /* seek track zero */
-#define CMD_SEK 0x3 /* seek */
-#define CMD_SSR 0x4 /* single sector read */
-#define CMD_SSW 0x5 /* single sector write */
-#define CMD_RCR 0x6 /* read CRC */
-#define CMD_SWD 0x7 /* single sector write with delete data mark */
-#define CMD_MSW 0xd /* multiple sector write */
-#define CMD_MSR 0xc /* multiple sector read */
-#define CMD_FFW 0xb /* free format write */
-#define CMD_FFR 0xa /* free format read */
-
-/* coarse delays */
-#define DELAY_SEEK attotime::from_usec( 100 ) /* track seek time */
-#define DELAY_ADDR attotime::from_usec( 100 ) /* search-address time */
-#define DELAY_CRC attotime::from_usec( 64 ) /* read crc time */
-
-
-
-static const char *const mc6843_cmd[16] =
-{
- "---", "---", "STZ", "SEK", "SSR", "SSW", "RCR", "SWD",
- "---", "---", "FFR", "FFW", "MSR", "MSW", "---", "---",
-};
-
-
-
-
DEFINE_DEVICE_TYPE(MC6843, mc6843_device, "mc6843", "Motorola MC6843 FDC")
mc6843_device::mc6843_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, MC6843, tag, owner, clock),
- m_floppy(*this, {finder_base::DUMMY_TAG, finder_base::DUMMY_TAG, finder_base::DUMMY_TAG, finder_base::DUMMY_TAG}),
- m_write_irq(*this),
- m_CTAR(0),
- m_CMR(0),
- m_ISR(0),
- m_SUR(0),
- m_STRA(0),
- m_STRB(0),
- m_SAR(0),
- m_GCR(0),
- m_CCR(0),
- m_LTAR(0),
- m_drive(0),
- m_side(0),
- m_data_size(0),
- m_data_idx(0),
- m_data_id(0),
- m_index_pulse(0),
- m_crc_wait(0),
- m_timer_cont(nullptr)
-{
- for (auto & elem : m_data)
- {
- elem = 0;
- }
+ m_irq(*this),
+ m_force_ready(false)
+{
}
-//-------------------------------------------------
-// device_start - device-specific startup
-//-------------------------------------------------
-
void mc6843_device::device_start()
{
- m_write_irq.resolve_safe();
-
- m_timer_cont = timer_alloc(TIMER_CONT);
-
- save_item(NAME(m_CTAR));
- save_item(NAME(m_CMR));
- save_item(NAME(m_ISR));
- save_item(NAME(m_SUR));
- save_item(NAME(m_STRA));
- save_item(NAME(m_STRB));
- save_item(NAME(m_SAR));
- save_item(NAME(m_GCR));
- save_item(NAME(m_CCR));
- save_item(NAME(m_LTAR));
- save_item(NAME(m_drive));
- save_item(NAME(m_side));
- save_item(NAME(m_data));
- save_item(NAME(m_data_size));
- save_item(NAME(m_data_idx));
- save_item(NAME(m_data_id));
- save_item(NAME(m_crc_wait));
-}
-
-//-------------------------------------------------
-// device_reset - device-specific reset
-//-------------------------------------------------
+ m_irq.resolve_safe();
+ m_timer = timer_alloc(0);
+ m_floppy = nullptr;
+
+ m_dir = 0x00;
+ m_dor = 0x00;
+ m_ctar = 0x00;
+ m_sur = 0x00;
+ m_cmr = 0x00;
+ m_gcr = 0x00;
+ m_ccr = 0x00;
+ m_ltar = 0x00;
+
+ save_item(NAME(m_dir));
+ save_item(NAME(m_dor));
+ save_item(NAME(m_ctar));
+ save_item(NAME(m_cmr));
+ save_item(NAME(m_isr));
+ save_item(NAME(m_sur));
+ save_item(NAME(m_stra));
+ save_item(NAME(m_sar));
+ save_item(NAME(m_strb));
+ save_item(NAME(m_gcr));
+ save_item(NAME(m_ccr));
+ save_item(NAME(m_ltar));
+ save_item(NAME(m_state));
+ save_item(NAME(m_step_count));
+ save_item(NAME(m_head_loaded));
+ save_item(NAME(m_dir_loaded));
+ save_item(NAME(m_dor_loaded));
+ save_item(NAME(m_dor_needed));
+ save_item(NAME(m_idam_turns));
+}
void mc6843_device::device_reset()
{
- LOG (( "mc6843 reset\n" ));
+ m_state = S_IDLE;
+ m_cur_live.state = L_IDLE;
+ m_cur_live.tm = attotime::never;
- /* setup/reset floppy drive */
- for (auto &img : m_floppy)
- {
- if (img.found())
- {
- img->floppy_mon_w(CLEAR_LINE);
- img->floppy_drive_set_ready_state(FLOPPY_DRIVE_READY, 0 );
- img->floppy_drive_set_rpm( 300. );
- }
- }
+ m_step_count = 0;
+ m_head_loaded = false;
- /* reset registers */
- m_CMR &= 0xf0; /* zero only command */
- m_ISR = 0;
- m_STRA &= 0x5c;
- m_SAR = 0;
- m_STRB &= 0x20;
- status_update( );
-
- m_data_size = 0;
- m_data_idx = 0;
- m_crc_wait = 0;
- m_timer_cont->adjust( attotime::never );
-}
-
-/************************** floppy interface ****************************/
+ m_dir_loaded = false;
+ m_dor_loaded = false;
+ m_dor_needed = false;
+ m_idam_turns = 0;
+ m_cmr &= 0xf0;
+ m_isr = 0x00;
+ m_stra = 0x00;
+ m_sar = 0x00;
+ m_strb = 0x00;
+}
-legacy_floppy_image_device* mc6843_device::floppy_image( )
+void mc6843_device::map(address_map &map)
{
- assert(m_floppy[m_drive].found());
- return m_floppy[m_drive].target();
+ map(0, 0).rw(FUNC(mc6843_device::dir_r), FUNC(mc6843_device::dor_w));
+ map(1, 1).rw(FUNC(mc6843_device::ctar_r), FUNC(mc6843_device::ctar_w));
+ map(2, 2).rw(FUNC(mc6843_device::isr_r), FUNC(mc6843_device::cmr_w));
+ map(3, 3).rw(FUNC(mc6843_device::stra_r), FUNC(mc6843_device::sur_w));
+ map(4, 4).rw(FUNC(mc6843_device::strb_r), FUNC(mc6843_device::sar_w));
+ map(5, 5).w (FUNC(mc6843_device::gcr_w));
+ map(6, 6).w (FUNC(mc6843_device::ccr_w));
+ map(7, 7).w (FUNC(mc6843_device::ltar_w));
}
-
-void mc6843_device::set_drive( int drive )
+void mc6843_device::set_floppy(floppy_image_device *floppy)
{
- m_drive = drive;
-}
+ if(m_floppy == floppy)
+ return;
+ int prev_ready = m_floppy ? m_floppy->ready_r() : 1;
+ if(m_floppy) {
+ m_floppy->setup_index_pulse_cb(floppy_image_device::index_pulse_cb());
+ m_floppy->setup_ready_cb(floppy_image_device::ready_cb());
+ }
-void mc6843_device::set_side( int side )
-{
- m_side = side;
-}
+ m_floppy = floppy;
+ logerror("floppy %s\n", m_floppy ? m_floppy->tag() : "-");
+ int next_ready = m_floppy ? m_floppy->ready_r() : 1;
-/* called after ISR or STRB has changed */
-void mc6843_device::status_update( )
-{
- int irq = 0;
+ if(m_floppy) {
+ m_floppy->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(&mc6843_device::index_callback, this));
+ m_floppy->setup_ready_cb(floppy_image_device::ready_cb(&mc6843_device::ready_callback, this));
+ }
- /* ISR3 */
- if ( (m_CMR & 0x40) || ! m_STRB )
- m_ISR &= ~8;
- else
- m_ISR |= 8;
+ if(prev_ready != next_ready)
+ ready_callback(m_floppy, next_ready);
+}
- /* interrupts */
- if ( m_ISR & 4 )
- irq = 1; /* unmaskable */
- if ( ! (m_CMR & 0x80) )
- {
- /* maskable */
- if ( m_ISR & ~4 )
- irq = 1;
+u8 mc6843_device::dir_r()
+{
+ if(!machine().side_effects_disabled()) {
+ m_dir_loaded = false;
+ logerror("dir_r %02x\n", m_dir);
}
-
- m_write_irq( irq );
- LOG( "status_update: irq=%i (CMR=%02X, ISR=%02X)\n", irq, m_CMR, m_ISR );
+ return m_dir;
}
+void mc6843_device::dor_w(u8 data)
+{
+ m_dor = data;
+ m_dor_loaded = true;
+ logerror("dor_w %02x\n", m_dor);
+}
-void mc6843_device::set_index_pulse( int index_pulse )
+u8 mc6843_device::ctar_r()
{
- m_index_pulse = index_pulse;
+ if(!machine().side_effects_disabled())
+ logerror("ctar_r %02x\n", m_ctar);
+ return m_ctar;
}
+void mc6843_device::ctar_w(u8 data)
+{
+ m_ctar = data;
+ logerror("ctar_w %02x\n", m_ctar);
+}
-/* called at end of command */
-void mc6843_device::cmd_end( )
+void mc6843_device::isr_raise(u8 flag)
{
- int cmd = m_CMR & 0x0f;
+ m_isr |= flag;
+}
- if ( ( cmd == CMD_STZ ) || ( cmd == CMD_SEK ) )
- {
- m_ISR |= 0x02; /* set Settling Time Complete */
- }
- else
- {
- m_ISR |= 0x01; /* set Macro Command Complete */
+u8 mc6843_device::isr_r()
+{
+ u8 res = m_isr;
+ if(!machine().side_effects_disabled()) {
+ logerror("isr_r %02x\n", m_isr);
+ m_isr &= 0x8;
}
- m_STRA &= ~0x80; /* clear Busy */
- m_CMR &= 0xf0; /* clear command */
- status_update( );
+ return res;
}
-
-
-/* Seek Track Zero bottom half */
-void mc6843_device::finish_STZ( )
+void mc6843_device::cmr_w(u8 data)
{
- legacy_floppy_image_device* img = floppy_image( );
- int i;
-
- /* seek to track zero */
- for ( i=0; i<83; i++ )
- {
- if (img->floppy_tk00_r() == CLEAR_LINE)
- break;
- img->floppy_drive_seek( -1 );
+ static const char *cmds[0x10] = {
+ "nop", "?1",
+ "stz", "sek", "ssr", "ssw", "rcr", "swd",
+ "?8", "?9",
+ "ffr", "ffw", "msr", "msw",
+ "?e", "?f"
+ };
+
+ if(m_stra & SA_BUSY) {
+ if((data & 0xf) == 0 && (m_cmr & 0xf) == C_FFW) {
+ m_stra &= ~SA_BUSY;
+ live_abort();
+ m_state = S_IDLE;
+ } else {
+ logerror("cmr_w %02x - dropped busy\n", data);
+ return;
+ }
}
- LOG( "%f mc6843_finish_STZ: actual=%i\n", machine().time().as_double(), img->floppy_drive_get_current_track() );
-
- /* update state */
- m_CTAR = 0;
- m_GCR = 0;
- m_SAR = 0;
- m_STRB |= img->floppy_tk00_r() << 4;
-
- cmd_end( );
+ m_cmr = data;
+ logerror("cmr_w %02x - isr=%s isr3=%s %s fwf=%d %s\n", m_cmr,
+ m_cmr & 0x80 ? "off" : "on",
+ m_cmr & 0x40 ? "off" : "on",
+ m_cmr & 0x20 ? "dma" : "pio",
+ m_cmr & 0x10 ? 1 : 0,
+ cmds[m_cmr & 0xf]);
+ command_start();
}
-
-
-/* Seek bottom half */
-void mc6843_device::finish_SEK( )
+u8 mc6843_device::stra_r()
{
- legacy_floppy_image_device* img = floppy_image( );
+ u8 res = m_stra;
+ if(m_floppy) {
+ if(m_floppy->idx_r())
+ res |= SA_IDX;
+ if(m_floppy->wpt_r())
+ res |= SA_WPT;
+ if(!m_floppy->trk00_r())
+ res |= SA_TRK0;
+ }
+ if(is_ready())
+ res |= SA_RDY;
- /* seek to track */
- // TODO: not sure how CTAR bit 7 is handled here, but this is the safest approach for now
- img->floppy_drive_seek( m_GCR - (m_CTAR & 0x7F) );
+ switch(m_cmr & 0xf) {
+ case C_SSR: case C_MSR: case C_FFR:
+ if(m_dir_loaded)
+ res |= SA_DTR;
+ break;
+ case C_SSW: case C_SWD: case C_MSW: case C_FFW:
+ if(!m_dor_loaded && m_dor_needed)
+ res |= SA_DTR;
+ break;
+ }
- LOG( "%f mc6843_finish_SEK: from %i to %i (actual=%i)\n", machine().time().as_double(), (m_CTAR & 0x7F), m_GCR, img->floppy_drive_get_current_track() );
+ if(!machine().side_effects_disabled()) {
+ static int prev = -1;
+ if(prev != res) {
+ logerror("stra_r %02x -%s%s%s%s%s%s%s%s\n", res,
+ res & SA_BUSY ? " busy" : "",
+ res & SA_IDX ? " idx" : "",
+ res & SA_TNEQ ? " tneq" : "",
+ res & SA_WPT ? " wpt" : "",
+ res & SA_TRK0 ? " trk0" : "",
+ res & SA_RDY ? " rdy" : "",
+ res & SA_DDM ? " ddm" : "",
+ res & SA_DTR ? " dtr" : "");
+ prev = res;
+ }
+ }
+ return res;
+}
- /* update state */
- m_CTAR = m_GCR;
- m_SAR = 0;
- cmd_end( );
+void mc6843_device::sur_w(u8 data)
+{
+ m_sur = data;
+ logerror("sur_w %02x\n", m_sur);
}
+u8 mc6843_device::strb_r()
+{
+ if(!machine().side_effects_disabled()) {
+ logerror("strb_r %02x -%s%s%s%s%s%s%s%s\n", m_strb,
+ m_strb & SB_HERR ? " herr" : "",
+ m_strb & SB_WERR ? " werr" : "",
+ m_strb & SB_FI ? " fi" : "",
+ m_strb & SB_SERR ? " serr" : "",
+ m_strb & SB_SAERR ? " saerr" : "",
+ m_strb & SB_DMERR ? " dmerr" : "",
+ m_strb & SB_CRC ? " crc" : "",
+ m_strb & SB_DTERR ? " dterr" : "");
+ }
+ return m_strb;
+}
+void mc6843_device::sar_w(u8 data)
+{
+ m_sar = data & 0x1f;
+ logerror("sar_w %02x\n", m_sar);
+}
-/* preamble to all sector read / write commands, returns 1 if found */
-int mc6843_device::address_search( chrn_id* id )
+void mc6843_device::gcr_w(u8 data)
{
- legacy_floppy_image_device* img = floppy_image( );
- int r = 0;
+ m_gcr = data & 0x7f;
+ logerror("gcr_w %02x\n", m_gcr);
+}
- while ( 1 )
- {
- if ( ( ! img->floppy_drive_get_next_id( m_side, id ) ) || ( id->flags & ID_FLAG_CRC_ERROR_IN_ID_FIELD ) || ( id->N != 0 ) )
- {
- /* read address error */
- LOG( "%f mc6843_address_search: get_next_id failed\n", machine().time().as_double() );
- m_STRB |= 0x0a; /* set CRC error & Sector Address Undetected */
- cmd_end( );
- return 0;
- }
+void mc6843_device::ccr_w(u8 data)
+{
+ m_ccr = data & 3;
+ logerror("ccr_w %02x\n", m_ccr);
+}
- if ( id->C != m_LTAR )
- {
- /* track mismatch */
- LOG( "%f mc6843_address_search: track mismatch: logical=%i real=%i\n", machine().time().as_double(), m_LTAR, id->C );
- m_data[0] = id->C; /* make the track number available to the CPU */
- m_STRA |= 0x20; /* set Track Not Equal */
- cmd_end( );
- return 0;
- }
+void mc6843_device::ltar_w(u8 data)
+{
+ m_ltar = data & 0x7f;
+ logerror("ltar_w %02x\n", m_ltar);
+}
- if ( id->R == m_SAR )
- {
- /* found! */
- LOG( "%f mc6843_address_search: sector %i found on track %i\n", machine().time().as_double(), id->R, id->C );
- if ( ! (m_CMR & 0x20) )
- {
- m_ISR |= 0x04; /* if no DMA, set Status Sense */
+void mc6843_device::index_callback(floppy_image_device *floppy, int state)
+{
+ if(state) {
+ live_sync();
+ logerror("idam %d\n", m_idam_turns);
+ if(m_idam_turns) {
+ m_idam_turns --;
+ if(!m_idam_turns) {
+ live_abort();
+ m_state = S_IDAM_NOT_FOUND;
}
- return 1;
}
+ run(false, false, true);
+ }
+}
- if ( img->floppy_drive_get_flag_state( FLOPPY_DRIVE_INDEX ) )
- {
- r++;
- if ( r >= 4 )
- {
- /* time-out after 3 full revolutions */
- LOG( "%f mc6843_address_search: no sector %i found after 3 revolutions\n", machine().time().as_double(), m_SAR );
- m_STRB |= 0x08; /* set Sector Address Undetected */
- cmd_end( );
- return 0;
- }
- }
+void mc6843_device::ready_callback(floppy_image_device *floppy, int state)
+{
+ if(state) {
+ live_sync();
+ run(false, true, false);
}
+}
- //return 0; /* unreachable */
+void mc6843_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ live_sync();
+ run(true, false, false);
}
+void mc6843_device::command_start()
+{
+ assert(m_state == S_IDLE);
+ switch(m_cmr & 0xf) {
+
+ case C_STZ:
+ logerror("Seek to track 0\n");
+ if(m_floppy)
+ m_floppy->dir_w(1);
+ m_stra |= SA_BUSY;
+ m_step_count = 82;
+ m_state = S_STZ_STEP;
+ break;
+ case C_SEK:
+ logerror("Seek from track %d to %d\n", m_ctar, m_gcr);
+ if(m_gcr > m_ctar) {
+ if(m_floppy)
+ m_floppy->dir_w(0);
+ m_step_count = m_gcr - m_ctar;
+ } else {
+ if(m_floppy)
+ m_floppy->dir_w(1);
+ m_step_count = m_ctar - m_gcr;
+ }
+ m_stra |= SA_BUSY;
+ if(!m_step_count) {
+ m_state = S_SEEK_HEAD_SETTLING;
+ delay(4096 * (m_sur & 15));
+ } else
+ m_state = S_SEEK_STEP;
+ break;
-/* preamble specific to read commands (adds extra checks) */
-int mc6843_device::address_search_read( chrn_id* id )
-{
- if ( ! address_search( id ) )
- return 0;
+ case C_SSR: case C_RCR: case C_SSW: case C_SWD: case C_MSR: case C_MSW:
+ m_stra |= SA_BUSY;
+ m_stra &= ~(SA_DDM|SA_TNEQ);
+ m_state = S_SRW_WAIT_READY;
+ break;
- if ( id->flags & ID_FLAG_CRC_ERROR_IN_DATA_FIELD )
- {
- LOG( "%f mc6843_address_search_read: data CRC error\n", machine().time().as_double() );
- m_STRB |= 0x06; /* set CRC error & Data Mark Undetected */
- cmd_end( );
- return 0;
- }
+ case C_FFW:
+ m_stra |= SA_BUSY;
+ m_state = S_FFW_WAIT_READY;
+ m_dor_needed = true;
+ break;
+
+ case 0x0:
+ case 0x1:
+ case 0x8:
+ case 0x9:
+ case 0xe:
+ case 0xf:
+ break;
- if ( id->flags & ID_FLAG_DELETED_DATA )
- {
- LOG( "%f mc6843_address_search_read: deleted data\n", machine().time().as_double() );
- m_STRA |= 0x02; /* set Delete Data Mark Detected */
+ default:
+ fatalerror("Unsupported command\n");
}
- return 1;
+ run(false, false, false);
}
+void mc6843_device::delay(int cycles)
+{
+ // A delay of zero freezes the fdc, it's expected
+ if(cycles) {
+ m_timer->adjust(attotime::from_ticks(cycles, clock()));
+ }
+}
+bool mc6843_device::is_ready() const
+{
+ return m_force_ready || (m_floppy && !m_floppy->ready_r());
+}
-/* Read CRC bottom half */
-void mc6843_device::finish_RCR( )
+void mc6843_device::run(bool timeout, bool ready, bool index)
{
- chrn_id id;
- if ( ! address_search_read( &id ) )
- return;
- cmd_end( );
-}
+ for(;;) {
+ if(m_cur_live.state != L_IDLE) {
+ live_run();
+ if(m_cur_live.state != L_IDLE)
+ return;
+ }
+ switch(m_state) {
+ case S_IDLE:
+ return;
+ case S_STZ_STEP:
+ if(m_floppy && !m_floppy->trk00_r()) {
+ m_floppy->stp_w(0);
+ m_floppy->stp_w(1);
+ }
+ m_step_count --;
+ m_state = S_STZ_STEP_WAIT;
+ delay(1024 * (m_sur >> 4));
+ return;
+
+ case S_STZ_STEP_WAIT:
+ if(!timeout)
+ return;
+ if(m_step_count)
+ m_state = S_STZ_STEP;
+ else {
+ m_ctar = m_gcr = 0;
+ m_state = S_STZ_HEAD_SETTLING;
+ delay(4096 * (m_sur & 15));
+ return;
+ }
+ break;
-/* Single / Multiple Sector Read bottom half */
-void mc6843_device::cont_SR( )
-{
- chrn_id id;
- legacy_floppy_image_device* img = floppy_image( );
+ case S_STZ_HEAD_SETTLING:
+ if(!timeout)
+ return;
+ m_head_loaded = true;
+ m_stra &= ~SA_BUSY;
+ m_state = S_IDLE;
+ isr_raise(I_SCE);
+ return;
+
+ case S_SEEK_STEP:
+ if(m_floppy) {
+ m_floppy->stp_w(0);
+ m_floppy->stp_w(1);
+ }
+ m_step_count --;
+ m_state = S_SEEK_STEP_WAIT;
+ delay(1024 * (m_sur >> 4));
+ return;
+
+ case S_SEEK_STEP_WAIT:
+ if(!timeout)
+ return;
+ if(m_step_count)
+ m_state = S_SEEK_STEP;
+ else {
+ m_ctar = m_gcr;
+ m_state = S_SEEK_HEAD_SETTLING;
+ delay(4096 * (m_sur & 15));
+ return;
+ }
+ break;
- /* sector seek */
- if ( ! address_search_read( &id ) )
- return;
+ case S_SEEK_HEAD_SETTLING:
+ if(!timeout)
+ return;
+ m_head_loaded = true;
+ m_stra &= ~SA_BUSY;
+ m_state = S_IDLE;
+ isr_raise(I_SCE);
+ return;
+
+ case S_SRW_WAIT_READY:
+ if(!is_ready())
+ return;
+ if(!m_head_loaded) {
+ m_state = S_SRW_HEAD_SETTLING;
+ delay(4096 * (m_sur & 15));
+ return;
+ } else
+ m_state = S_SRW_START;
+ break;
+
+ case S_SRW_HEAD_SETTLING:
+ if(timeout) {
+ m_head_loaded = true;
+ m_state = S_SRW_START;
+ }
+ break;
- /* sector read */
- img->floppy_drive_read_sector_data( m_side, id.data_id, m_data, 128 );
- m_data_idx = 0;
- m_data_size = 128;
- m_STRA |= 0x01; /* set Data Transfer Request */
- status_update( );
+ case S_SRW_START:
+ m_idam_turns = 3;
+ live_start(L_IDAM_SEARCH);
+ return;
+
+ case S_FFW_WAIT_READY:
+ if(!is_ready())
+ return;
+ if(!m_head_loaded) {
+ m_state = S_FFW_HEAD_SETTLING;
+ delay(4096 * (m_sur & 15));
+ return;
+ } else
+ m_state = S_FFW_START;
+ break;
+
+ case S_FFW_HEAD_SETTLING:
+ if(timeout) {
+ m_head_loaded = true;
+ m_state = S_FFW_START;
+ }
+ break;
+
+ case S_FFW_START:
+ live_start(L_FFW_BYTE);
+ return;
+
+ case S_IDAM_BAD_TRACK:
+ m_dir = m_cur_live.data_reg;
+ m_stra |= SA_TNEQ;
+ m_stra &= ~SA_BUSY;
+ m_state = S_IDLE;
+ isr_raise(I_RWCE);
+ return;
+
+ case S_IDAM_BAD_CRC:
+ m_strb |= SB_CRC | SB_SAERR;
+ m_stra &= ~SA_BUSY;
+ m_state = S_IDLE;
+ isr_raise(I_RWCE | I_STRB);
+ return;
+
+ case S_IDAM_FOUND:
+ if(m_cmr & 0x20)
+ isr_raise(I_SSR);
+ if((m_cmr & 0xf) == C_SSR || (m_cmr & 0xf) == C_MSR || (m_cmr & 0xf) == C_RCR)
+ live_start(L_DAM_SEARCH);
+
+ else {
+ m_dor_needed = true;
+ live_start(L_DAM_WAIT);
+ }
+ return;
+
+ case S_IDAM_NOT_FOUND:
+ m_stra &= ~SA_BUSY;
+ m_strb |= SB_SAERR;
+ m_state = S_IDLE;
+ isr_raise(I_RWCE | I_STRB);
+ logerror("not found\n");
+ return;
+
+ case S_DAM_NOT_FOUND:
+ m_strb |= SB_DMERR;
+ m_stra &= ~SA_BUSY;
+ m_state = S_IDLE;
+ isr_raise(I_RWCE | I_STRB);
+ return;
+
+ case S_DAM_BAD_CRC:
+ m_strb |= SB_CRC;
+ m_stra &= ~SA_BUSY;
+ m_state = S_IDLE;
+ isr_raise(I_RWCE | I_STRB);
+ return;
+
+ case S_DAM_DONE:
+ m_dor_needed = false;
+ if((m_cmr & 0xf) == C_MSR || (m_cmr & 0xf) == C_MSW) {
+ m_sar = (m_sar + 1) & 0x1f;
+ m_gcr = (m_gcr - 1) & 0x7f;
+ if(m_gcr != 0x7f) {
+ m_state = S_SRW_START;
+ break;
+ }
+ }
+ m_stra &= ~SA_BUSY;
+ m_state = S_IDLE;
+ isr_raise(I_RWCE);
+ return;
+ }
+ }
}
-void mc6843_device::finish_SR( )
+void mc6843_device::live_start(int state, bool start_writing)
{
- m_crc_wait = 0;
- cmd_end( );
+ m_cur_live.tm = machine().time();
+ m_cur_live.state = state;
+ m_cur_live.next_state = -1;
+ m_cur_live.shift_reg = 0;
+ m_cur_live.crc = 0xffff;
+ m_cur_live.bit_counter = 0;
+ m_cur_live.data_separator_phase = false;
+ m_cur_live.data_reg = 0;
+
+ m_cur_live.pll.reset(m_cur_live.tm);
+ m_cur_live.pll.set_clock(attotime::from_ticks(2, clock()));
+ if(start_writing)
+ m_cur_live.pll.start_writing(machine().time());
+
+ m_checkpoint_live = m_cur_live;
+
+ live_run();
}
-/* Single / Multiple Sector Write bottom half */
-void mc6843_device::cont_SW( )
+void mc6843_device::checkpoint()
{
- chrn_id id;
-
- /* sector seek */
- if ( ! address_search( &id ) )
- return;
-
- /* setup sector write buffer */
- m_data_idx = 0;
- m_data_size = 128;
- m_STRA |= 0x01; /* set Data Transfer Request */
- m_data_id = id.data_id; /* for subsequent write sector command */
- status_update( );
+ m_cur_live.pll.commit(m_floppy, m_cur_live.tm);
+ m_checkpoint_live = m_cur_live;
}
+void mc6843_device::rollback()
+{
+ m_cur_live = m_checkpoint_live;
+}
+void mc6843_device::live_delay(int state)
+{
+ m_cur_live.next_state = state;
+ m_timer->adjust(m_cur_live.tm - machine().time());
+}
-/* bottom halves, called to continue / finish a command after some delay */
-void mc6843_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+void mc6843_device::live_sync()
{
- switch (id)
- {
- case TIMER_CONT:
- {
- int cmd = m_CMR & 0x0f;
-
- LOG( "%f mc6843_cont: timer called for cmd=%s(%i)\n", machine().time().as_double(), mc6843_cmd[cmd], cmd );
-
- m_timer_cont->adjust( attotime::never );
-
- switch ( cmd )
- {
- case CMD_STZ: finish_STZ( ); break;
- case CMD_SEK: finish_SEK( ); break;
- case CMD_SSR:
- case CMD_MSR:
- if ( m_crc_wait )
- finish_SR( );
- else
- cont_SR( );
- break;
- case CMD_SSW: cont_SW( ); break;
- case CMD_RCR: finish_RCR( ); break;
- case CMD_SWD: cont_SW( ); break;
- case CMD_MSW: cont_SW( ); break;
- }
+ if(m_cur_live.state != L_IDLE && !m_cur_live.tm.is_never()) {
+ if(m_cur_live.tm > machine().time()) {
+ if(0)
+ logerror("%s: Rolling back and replaying (%s)\n", machine().time().to_string(), m_cur_live.tm.to_string());
+ rollback();
+ live_run(machine().time());
+ m_cur_live.pll.commit(m_floppy, m_cur_live.tm);
+ } else {
+ if(0)
+ logerror("%s: Committing (%s)\n", machine().time().to_string(), m_cur_live.tm.to_string());
+ m_cur_live.pll.commit(m_floppy, m_cur_live.tm);
+ if(m_cur_live.next_state != -1) {
+ m_cur_live.state = m_cur_live.next_state;
+ m_cur_live.next_state = -1;
}
- break;
-
- default:
- break;
+ if(m_cur_live.state == L_IDLE) {
+ m_cur_live.pll.stop_writing(m_floppy, m_cur_live.tm);
+ m_cur_live.tm = attotime::never;
+ }
+ }
+ m_cur_live.next_state = -1;
+ checkpoint();
}
}
+void mc6843_device::live_abort()
+{
+ if(!m_cur_live.tm.is_never() && m_cur_live.tm > machine().time()) {
+ rollback();
+ live_run(machine().time());
+ }
+ m_cur_live.pll.stop_writing(m_floppy, m_cur_live.tm);
+ m_cur_live.tm = attotime::never;
+ m_cur_live.state = L_IDLE;
+ m_cur_live.next_state = -1;
+}
-/************************** CPU interface ****************************/
-
-
+bool mc6843_device::read_one_bit(const attotime &limit)
+{
+ int bit = m_cur_live.pll.get_next_bit(m_cur_live.tm, m_floppy, limit);
+ if(bit < 0)
+ return true;
+ m_cur_live.shift_reg = (m_cur_live.shift_reg << 1) | bit;
+ m_cur_live.bit_counter++;
+ if(m_cur_live.data_separator_phase) {
+ m_cur_live.data_reg = (m_cur_live.data_reg << 1) | bit;
+ if((m_cur_live.crc ^ (bit ? 0x8000 : 0x0000)) & 0x8000)
+ m_cur_live.crc = (m_cur_live.crc << 1) ^ 0x1021;
+ else
+ m_cur_live.crc = m_cur_live.crc << 1;
+ }
+ m_cur_live.data_separator_phase = !m_cur_live.data_separator_phase;
+ return false;
+}
-uint8_t mc6843_device::read(offs_t offset)
+bool mc6843_device::write_one_bit(const attotime &limit)
{
- uint8_t data = 0;
+ bool bit = m_cur_live.shift_reg & 0x8000;
+ if(m_cur_live.pll.write_next_bit(bit, m_cur_live.tm, m_floppy, limit))
+ return true;
+ if(m_cur_live.bit_counter & 1) {
+ if((m_cur_live.crc ^ (bit ? 0x8000 : 0x0000)) & 0x8000)
+ m_cur_live.crc = (m_cur_live.crc << 1) ^ 0x1021;
+ else
+ m_cur_live.crc = m_cur_live.crc << 1;
+ }
+ m_cur_live.shift_reg = m_cur_live.shift_reg << 1;
+ m_cur_live.bit_counter--;
+ return false;
+}
- switch ( offset ) {
- case 0: /* Data Input Register (DIR) */
- {
- int cmd = m_CMR & 0x0f;
+void mc6843_device::live_run(attotime limit)
+{
+ if(m_cur_live.state == L_IDLE || m_cur_live.next_state != -1)
+ return;
- if (machine().side_effects_disabled())
- {
- data = m_data[0];
- break;
+ if(limit == attotime::never) {
+ if(m_floppy)
+ limit = m_floppy->time_next_index();
+ if(limit == attotime::never) {
+ // Happens when there's no disk or if the wd is not
+ // connected to a drive, hence no index pulse. Force a
+ // sync from time to time in that case, so that the main
+ // cpu timeout isn't too painful. Avoids looping into
+ // infinity looking for data too.
+
+ limit = machine().time() + attotime::from_msec(1);
+ m_timer->adjust(attotime::from_msec(1));
}
+ }
- LOG( "%f %s mc6843_r: data input cmd=%s(%i), pos=%i/%i, GCR=%i, ",
- machine().time().as_double(), machine().describe_context(),
- mc6843_cmd[cmd], cmd, m_data_idx,
- m_data_size, m_GCR );
-
- if ( cmd == CMD_SSR || cmd == CMD_MSR )
- {
- /* sector read */
- assert( m_data_size > 0 );
- assert( m_data_idx < m_data_size );
- assert( m_data_idx < sizeof(m_data) );
- data = m_data[ m_data_idx ];
- m_data_idx++;
-
- if ( m_data_idx >= m_data_size )
- {
- /* end of sector read */
-
- m_STRA &= ~0x01; /* clear Data Transfer Request */
-
- if ( cmd == CMD_MSR )
- {
- /* schedule next sector in multiple sector read */
- m_GCR--;
- m_SAR++;
- if ( m_GCR == 0xff )
- {
- m_crc_wait = 1;
- m_timer_cont->adjust( DELAY_CRC );
- }
- else if ( m_SAR > 26 )
-
- {
- m_STRB |= 0x08; /* set Sector Address Undetected */
- m_crc_wait = 1;
- m_timer_cont->adjust( DELAY_CRC );
- }
- else
- {
- m_timer_cont->adjust( DELAY_ADDR );
- }
- }
- else
- {
- m_crc_wait = 1;
- m_timer_cont->adjust( DELAY_CRC );
- }
+ for(;;) {
+ switch(m_cur_live.state) {
+ case L_IDAM_SEARCH:
+ if(read_one_bit(limit))
+ return;
+
+ if(0)
+ logerror("%s: shift = %04x data=%02x c=%d\n", m_cur_live.tm.to_string(), m_cur_live.shift_reg,
+ (m_cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) |
+ (m_cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) |
+ (m_cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) |
+ (m_cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) |
+ (m_cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) |
+ (m_cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) |
+ (m_cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) |
+ (m_cur_live.shift_reg & 0x0001 ? 0x01 : 0x00),
+ m_cur_live.bit_counter);
+
+ if(m_cur_live.shift_reg == 0xf57e) {
+ m_cur_live.crc = 0xef21;
+ m_cur_live.data_separator_phase = false;
+ m_cur_live.bit_counter = 0;
+ m_cur_live.state = L_IDAM_CHECK_TRACK;
}
- }
- else if ( cmd == 0 )
- {
- data = m_data[0];
- }
- else
- {
- /* XXX TODO: other read modes */
- data = m_data[0];
- logerror( "%s mc6843 read in unsupported command mode %i\n", machine().describe_context(), cmd );
- }
-
- LOG( "data=%02X\n", data );
+ break;
- break;
- }
+ case L_IDAM_CHECK_TRACK:
+ if(read_one_bit(limit))
+ return;
- case 1: /* Current-Track Address Register (CTAR) */
- data = m_CTAR;
- if (machine().side_effects_disabled())
- break;
- LOG( "%f %s mc6843_r: read CTAR %i (actual=%i)\n",
- machine().time().as_double(), machine().describe_context(), data,
- floppy_image()->floppy_drive_get_current_track());
- break;
+ if(m_cur_live.bit_counter == 16) {
+ logerror("%s IDAM track %d\n", m_cur_live.tm.to_string(), m_cur_live.data_reg);
+ if(m_cur_live.data_reg != m_ltar) {
+ m_state = S_IDAM_BAD_TRACK;
+ live_delay(L_IDLE);
+ return;
- case 2: /* Interrupt Status Register (ISR) */
- data = m_ISR;
- if (machine().side_effects_disabled())
+ } else
+ m_cur_live.state = L_IDAM_CHECK_SECTOR;
+ }
break;
- LOG( "%f %s mc6843_r: read ISR %02X: cmd=%scomplete settle=%scomplete sense-rq=%i STRB=%i\n",
- machine().time().as_double(), machine().describe_context(), data,
- (data & 1) ? "" : "not-" , (data & 2) ? "" : "not-",
- (data >> 2) & 1, (data >> 3) & 1 );
-
- /* reset */
- m_ISR &= 8; /* keep STRB */
- status_update( );
- break;
- case 3: /* Status Register A (STRA) */
- {
- /* update */
- legacy_floppy_image_device* img = floppy_image( );
- int flag = img->floppy_drive_get_flag_state( FLOPPY_DRIVE_READY);
- data = m_STRA & 0xa3;
- if ( flag & FLOPPY_DRIVE_READY )
- data |= 0x04;
+ case L_IDAM_CHECK_SECTOR:
+ if(read_one_bit(limit))
+ return;
- data |= !img->floppy_tk00_r() << 3;
- data |= !img->floppy_wpt_r() << 4;
+ if(m_cur_live.bit_counter == 48) {
+ logerror("%s IDAM sector %d\n", m_cur_live.tm.to_string(), m_cur_live.data_reg);
+ if(m_cur_live.data_reg != m_sar)
+ m_cur_live.state = L_IDAM_SEARCH;
+ else
+ m_cur_live.state = L_IDAM_CHECK_CRC;
+ }
+ break;
- if ( m_index_pulse )
- data |= 0x40;
+ case L_IDAM_CHECK_CRC:
+ if(read_one_bit(limit))
+ return;
- if (machine().side_effects_disabled())
+ if(m_cur_live.bit_counter == 96) {
+ logerror("IDAM crc remainder %04x\n", m_cur_live.crc);
+ if(m_cur_live.crc)
+ m_state = S_IDAM_BAD_CRC;
+ else
+ m_state = S_IDAM_FOUND;
+ live_delay(L_IDLE);
+ return;
+ }
break;
- m_STRA = data;
- LOG( "%f %s mc6843_r: read STRA %02X: data-rq=%i del-dta=%i ready=%i t0=%i wp=%i trk-dif=%i idx=%i busy=%i\n",
- machine().time().as_double(), machine().describe_context(), data,
- data & 1, (data >> 1) & 1, (data >> 2) & 1, (data >> 3) & 1,
- (data >> 4) & 1, (data >> 5) & 1, (data >> 6) & 1, (data >> 7) & 1 );
- break;
- }
-
- case 4: /* Status Register B (STRB) */
- data = m_STRB;
- if (machine().side_effects_disabled())
+ case L_DAM_SEARCH:
+ if(read_one_bit(limit))
+ return;
+
+ if(m_cur_live.shift_reg == 0xf56a || m_cur_live.shift_reg == 0xf56f) {
+ m_cur_live.data_separator_phase = false;
+ m_cur_live.bit_counter = 0;
+ logerror("DAM mark %02x\n", m_cur_live.data_reg);
+ if(m_cur_live.shift_reg == 0xf56f) {
+ logerror("DAM found\n");
+ m_cur_live.crc = 0xbf84;
+ m_cur_live.state = L_DAM_READ;
+ } else {
+ logerror("DDAM found\n");
+ m_cur_live.crc = 0x8fe7;
+ live_delay(L_DAM_DELETED);
+ return;
+ }
+ }
break;
- LOG( "%f %s mc6843_r: read STRB %02X: data-err=%i CRC-err=%i dta--mrk-err=%i sect-mrk-err=%i seek-err=%i fi=%i wr-err=%i hard-err=%i\n",
- machine().time().as_double(), machine().describe_context(), data,
- data & 1, (data >> 1) & 1, (data >> 2) & 1, (data >> 3) & 1,
- (data >> 4) & 1, (data >> 5) & 1, (data >> 6) & 1, (data >> 7) & 1 );
-
- /* (partial) reset */
- m_STRB &= ~0xfb;
- status_update( );
- break;
- case 7: /* Logical-Track Address Register (LTAR) */
- data = m_LTAR;
- if (machine().side_effects_disabled())
+ case L_DAM_DELETED:
+ m_stra |= SA_DDM;
+ m_cur_live.state = L_DAM_READ;
break;
- LOG( "%f %s mc6843_r: read LTAR %i (actual=%i)\n",
- machine().time().as_double(), machine().describe_context(), data,
- floppy_image()->floppy_drive_get_current_track());
- break;
- default:
- logerror( "%s mc6843 invalid read offset %i\n", machine().describe_context(), offset );
- }
+ case L_DAM_READ:
+ if(read_one_bit(limit))
+ return;
- return data;
-}
-
-void mc6843_device::write(offs_t offset, uint8_t data)
-{
- switch ( offset ) {
- case 0: /* Data Output Register (DOR) */
- {
- int cmd = m_CMR & 0x0f;
- int FWF = (m_CMR >> 4) & 1;
-
- LOG( "%f %s mc6843_w: data output cmd=%s(%i), pos=%i/%i, GCR=%i, data=%02X\n",
- machine().time().as_double(), machine().describe_context(),
- mc6843_cmd[cmd], cmd, m_data_idx,
- m_data_size, m_GCR, data );
-
- if ( cmd == CMD_SSW || cmd == CMD_MSW || cmd == CMD_SWD )
- {
- /* sector write */
- assert( m_data_size > 0 );
- assert( m_data_idx < m_data_size );
- assert( m_data_idx < sizeof(m_data) );
- m_data[ m_data_idx ] = data;
- m_data_idx++;
- if ( m_data_idx >= m_data_size )
- {
- /* end of sector write */
- legacy_floppy_image_device* img = floppy_image( );
-
- LOG( "%f %s mc6843_w: write sector %i\n", machine().time().as_double(), machine().describe_context(), m_data_id );
-
- img->floppy_drive_write_sector_data(
- m_side, m_data_id,
- m_data, m_data_size,
- (cmd == CMD_SWD) ? ID_FLAG_DELETED_DATA : 0 );
-
- m_STRA &= ~0x01; /* clear Data Transfer Request */
-
- if ( cmd == CMD_MSW )
- {
- m_GCR--;
- m_SAR++;
- if ( m_GCR == 0xff )
- {
- cmd_end( );
- }
- else if ( m_SAR > 26 )
-
- {
- m_STRB |= 0x08; /* set Sector Address Undetected */
- cmd_end( );
- }
- else
- {
- m_timer_cont->adjust( DELAY_ADDR );
- }
- }
- else
- {
- cmd_end( );
- }
+ if(!(m_cur_live.bit_counter & 0xf)) {
+ live_delay(L_DAM_READ_BYTE);
+ return;
}
- }
- else if ( (cmd == CMD_FFW) && FWF )
- {
- /* assume we are formatting */
- uint8_t nibble;
- nibble =
- (data & 0x01) |
- ((data & 0x04) >> 1 )|
- ((data & 0x10) >> 2 )|
- ((data & 0x40) >> 3 );
-
- assert( m_data_idx < sizeof(m_data) );
-
- m_data[m_data_idx / 2] =
- (m_data[m_data_idx / 2] << 4) | nibble;
-
- if ( (m_data_idx == 0) && (m_data[0] == 0xfe ) )
- {
- /* address mark detected */
- m_data_idx = 2;
- }
- else if ( m_data_idx == 9 )
- {
- /* address id field complete */
- if ( (m_data[2] == 0) && (m_data[4] == 0) )
- {
- /* valid address id field */
- legacy_floppy_image_device* img = floppy_image( );
- uint8_t track = m_data[1];
- uint8_t sector = m_data[3];
- uint8_t filler = 0xe5; /* standard Thomson filler */
- LOG( "%f %s mc6843_w: address id detected track=%i sector=%i\n", machine().time().as_double(), machine().describe_context(), track, sector);
- img->floppy_drive_format_sector( m_side, sector, track, 0, sector, 0, filler );
- m_data_idx = 0;
+ break;
+
+ case L_DAM_READ_BYTE: {
+ int byte = m_cur_live.bit_counter >> 4;
+ logerror("byte %02x = %02x crc %04x\n", byte, m_cur_live.data_reg, m_cur_live.crc);
+ if(byte <= 128) {
+ if((m_cmr & 0xf) != C_RCR) {
+ if(m_dir_loaded)
+ m_strb |= SB_DTERR;
+ m_dir_loaded = true;
}
+ m_dir = m_cur_live.data_reg;
+ } else if(byte == 130) {
+ if(m_cur_live.crc)
+ m_state = S_DAM_BAD_CRC;
else
- {
- /* abort */
- m_data_idx = 0;
- }
- }
- else if ( m_data_idx > 0 )
- {
- /* accumulate address id field */
- m_data_idx++;
+ m_state = S_DAM_DONE;
+ m_cur_live.state = L_IDLE;
+ return;
}
- }
- else if ( cmd == 0 )
- {
- /* nothing */
- }
- else
- {
- /* XXX TODO: other write modes */
- logerror( "%s mc6843 write %02X in unsupported command mode %i (FWF=%i)\n", machine().describe_context(), data, cmd, FWF );
- }
- break;
- }
-
- case 1: /* Current-Track Address Register (CTAR) */
- m_CTAR = data;
- LOG( "%f %s mc6843_w: set CTAR to %i %02X (actual=%i) \n",
- machine().time().as_double(), machine().describe_context(), m_CTAR, data,
- floppy_image()->floppy_drive_get_current_track());
- break;
-
- case 2: /* Command Register (CMR) */
- {
- int cmd = data & 15;
-
- LOG( "%f %s mc6843_w: set CMR to $%02X: cmd=%s(%i) FWF=%i DMA=%i ISR3-intr=%i fun-intr=%i\n",
- machine().time().as_double(), machine().describe_context(),
- data, mc6843_cmd[cmd], cmd, (data >> 4) & 1, (data >> 5) & 1,
- (data >> 6) & 1, (data >> 7) & 1 );
-
- /* sanitize state */
- m_STRA &= ~0x81; /* clear Busy & Data Transfer Request */
- m_data_idx = 0;
- m_data_size = 0;
-
- /* commands are initiated by updating some flags and scheduling
- a bottom-half (mc6843_cont) after some delay */
-
- switch (cmd)
- {
- case CMD_SSW:
- case CMD_SSR:
- case CMD_SWD:
- case CMD_RCR:
- case CMD_MSR:
- case CMD_MSW:
- m_STRA |= 0x80; /* set Busy */
- m_STRA &= ~0x22; /* clear Track Not Equal & Delete Data Mark Detected */
- m_STRB &= ~0x04; /* clear Data Mark Undetected */
- m_timer_cont->adjust( DELAY_ADDR );
- break;
- case CMD_STZ:
- case CMD_SEK:
- m_STRA |= 0x80; /* set Busy */
- m_timer_cont->adjust( DELAY_SEEK );
- break;
- case CMD_FFW:
- case CMD_FFR:
- m_data_idx = 0;
- m_STRA |= 0x01; /* set Data Transfer Request */
+ m_cur_live.state = L_DAM_READ;
break;
}
- m_CMR = data;
- status_update( );
- break;
- }
-
- case 3: /* Set-Up Register (SUR) */
- m_SUR = data;
+ case L_DAM_WAIT:
+ if(read_one_bit(limit))
+ return;
- /* assume CLK freq = 1MHz (IBM 3740 compatibility) */
- LOG( "%f %s mc6843_w: set SUR to $%02X: head settling time=%fms, track-to-track seek time=%f\n",
- machine().time().as_double(), machine().describe_context(),
- data, 4.096 * (data & 15), 1.024 * ((data >> 4) & 15) );
- break;
+ if(m_cur_live.bit_counter == 11*16) {
+ m_cur_live.bit_counter = (6+1+128+2)*16;
+ live_delay(L_DAM_WRITE_BYTE);
+ return;
+ }
+ break;
- case 4: /* Sector Address Register (SAR) */
- m_SAR = data & 0x1f;
- LOG( "%f %s mc6843_w: set SAR to %i (%02X)\n", machine().time().as_double(), machine().describe_context(), m_SAR, data );
- break;
+ case L_DAM_WRITE:
+ if(write_one_bit(limit))
+ return;
+ if(!(m_cur_live.bit_counter & 0xf)) {
+ live_delay(L_DAM_WRITE_BYTE);
+ return;
+ }
+ break;
- case 5: /* General Count Register (GCR) */
- m_GCR = data & 0x7f;
- LOG( "%f %s mc6843_w: set GCR to %i (%02X)\n", machine().time().as_double(), machine().describe_context(), m_GCR, data );
- break;
+ case L_DAM_WRITE_BYTE: {
+ int byte = (6+1+128+2) - (m_cur_live.bit_counter >> 4);
+ if(!byte) {
+ m_cur_live.pll.start_writing(m_cur_live.tm);
+ m_cur_live.shift_reg = 0xaaaa;
- case 6: /* CRC Control Register (CCR) */
- m_CCR = data & 3;
- LOG( "%f %s mc6843_w: set CCR to %02X: CRC=%s shift=%i\n",
- machine().time().as_double(), machine().describe_context(), data,
- (data & 1) ? "enabled" : "disabled", (data >> 1) & 1 );
- break;
+ } else if(byte <= 5) {
+ m_cur_live.shift_reg = 0xaaaa;
- case 7: /* Logical-Track Address Register (LTAR) */
- m_LTAR = data & 0x7f;
- LOG( "%f %s mc6843_w: set LTAR to %i %02X (actual=%i)\n",
- machine().time().as_double(), machine().describe_context(), m_LTAR, data,
- floppy_image()->floppy_drive_get_current_track());
- break;
+ } else if(byte <= 6) {
+ m_cur_live.crc = 0xffff;
+ if((m_cmr & 0xf) == C_SWD)
+ m_cur_live.shift_reg = 0xf56a;
+ else
+ m_cur_live.shift_reg = 0xf56f;
+
+ } else if(byte <= 134) {
+ if(!m_dor_loaded)
+ m_strb |= SB_DTERR;
+ m_dor_loaded = false;
+ if(byte == 128)
+ m_dor_needed = false;
+ m_cur_live.shift_reg = 0xaaaa |
+ (m_dor & 0x80 ? 1<<14 : 0) |
+ (m_dor & 0x40 ? 1<<12 : 0) |
+ (m_dor & 0x20 ? 1<<10 : 0) |
+ (m_dor & 0x10 ? 1<< 8 : 0) |
+ (m_dor & 0x08 ? 1<< 6 : 0) |
+ (m_dor & 0x04 ? 1<< 4 : 0) |
+ (m_dor & 0x02 ? 1<< 2 : 0) |
+ (m_dor & 0x01 ? 1 : 0);
+
+ } else if(byte <= 136) {
+ m_cur_live.shift_reg = 0xaaaa |
+ (m_cur_live.crc & 0x8000 ? 1<<14 : 0) |
+ (m_cur_live.crc & 0x4000 ? 1<<12 : 0) |
+ (m_cur_live.crc & 0x2000 ? 1<<10 : 0) |
+ (m_cur_live.crc & 0x1000 ? 1<< 8 : 0) |
+ (m_cur_live.crc & 0x0800 ? 1<< 6 : 0) |
+ (m_cur_live.crc & 0x0400 ? 1<< 4 : 0) |
+ (m_cur_live.crc & 0x0200 ? 1<< 2 : 0) |
+ (m_cur_live.crc & 0x0100 ? 1 : 0);
+
+ } else if(byte <= 137) {
+ m_cur_live.shift_reg = 0xffff;
+
+ } else {
+ m_state = S_DAM_DONE;
+ m_cur_live.state = L_IDLE;
+ m_cur_live.pll.stop_writing(m_floppy, m_cur_live.tm);
+ return;
+ }
+ m_cur_live.state = L_DAM_WRITE;
+ break;
+ }
+
+ case L_FFW_BYTE:
+ if(!m_dor_loaded)
+ m_strb |= SB_DTERR;
+ m_dor_loaded = false;
+ logerror("write %02x\n", m_dor);
+ if(m_cmr & 0x10) {
+ m_cur_live.shift_reg = m_dor << 8;
+ m_cur_live.bit_counter = 8;
+
+ } else {
+ m_cur_live.shift_reg = 0xaaaa |
+ (m_dor & 0x80 ? 1<<14 : 0) |
+ (m_dor & 0x40 ? 1<<12 : 0) |
+ (m_dor & 0x20 ? 1<<10 : 0) |
+ (m_dor & 0x10 ? 1<< 8 : 0) |
+ (m_dor & 0x08 ? 1<< 6 : 0) |
+ (m_dor & 0x04 ? 1<< 4 : 0) |
+ (m_dor & 0x02 ? 1<< 2 : 0) |
+ (m_dor & 0x01 ? 1 : 0);
+ m_cur_live.bit_counter = 16;
+ }
+ m_cur_live.state = L_FFW_WRITE;
+ break;
- default:
- logerror( "%s mc6843 invalid write offset %i (data=$%02X)\n", machine().describe_context(), offset, data );
+ case L_FFW_WRITE:
+ if(write_one_bit(limit))
+ return;
+ if(m_cur_live.bit_counter == 0) {
+ live_delay(L_FFW_BYTE);
+ return;
+ }
+ break;
+ }
}
}
diff --git a/src/devices/machine/mc6843.h b/src/devices/machine/mc6843.h
index 488b4671026..03482d79375 100644
--- a/src/devices/machine/mc6843.h
+++ b/src/devices/machine/mc6843.h
@@ -1,43 +1,30 @@
// license:BSD-3-Clause
-// copyright-holders:Antoine Mine
-/**********************************************************************
+// copyright-holders:Olivier Galibert
- Copyright (C) Antoine Mine' 2007
-
- Motorola 6843 Floppy Disk Controller emulation.
-
-**********************************************************************/
+// Motorola 6843 floppy drive controller
+//
+// The Hitachi HD46503S, HD6843 and HD68A43 seem identical
#ifndef MAME_MACHINE_MC6843_H
#define MAME_MACHINE_MC6843_H
#pragma once
-#include "imagedev/flopdrv.h"
-
+#include "imagedev/floppy.h"
+#include "fdc_pll.h"
class mc6843_device : public device_t
{
public:
mc6843_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- template<int Id, typename T> void set_floppy_drive(T &&tag) { m_floppy[Id].set_tag(std::forward<T>(tag)); }
- template<typename T, typename U, typename V, typename W> void set_floppy_drives(T &&tag0, U &&tag1, V &&tag2, W &&tag3)
- {
- m_floppy[0].set_tag(std::forward<T>(tag0));
- m_floppy[1].set_tag(std::forward<U>(tag1));
- m_floppy[2].set_tag(std::forward<V>(tag2));
- m_floppy[3].set_tag(std::forward<W>(tag3));
- }
+ void force_ready() { m_force_ready = true; }
- auto irq() { return m_write_irq.bind(); }
+ auto irq() { return m_irq.bind(); }
- uint8_t read(offs_t offset);
- void write(offs_t offset, uint8_t data);
+ void set_floppy(floppy_image_device *floppy);
- void set_drive(int drive);
- void set_side(int side);
- void set_index_pulse(int index_pulse);
+ void map(address_map &map);
protected:
// device-level overrides
@@ -46,52 +33,163 @@ protected:
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
private:
- enum
- {
- TIMER_CONT
+ // Status flags
+ enum {
+ SA_BUSY = 0x80,
+ SA_IDX = 0x40,
+ SA_TNEQ = 0x20,
+ SA_WPT = 0x10,
+ SA_TRK0 = 0x08,
+ SA_RDY = 0x04,
+ SA_DDM = 0x02,
+ SA_DTR = 0x01,
+
+ SB_HERR = 0x80,
+ SB_WERR = 0x40,
+ SB_FI = 0x20,
+ SB_SERR = 0x10,
+ SB_SAERR = 0x08,
+ SB_DMERR = 0x04,
+ SB_CRC = 0x02,
+ SB_DTERR = 0x01,
+
+ I_STRB = 0x08,
+ I_SSR = 0x04,
+ I_SCE = 0x02,
+ I_RWCE = 0x01,
+
+ C_STZ = 0x2,
+ C_SEK = 0x3,
+ C_SSR = 0x4,
+ C_SSW = 0x5,
+ C_RCR = 0x6,
+ C_SWD = 0x7,
+ C_FFR = 0xa,
+ C_FFW = 0xb,
+ C_MSR = 0xc,
+ C_MSW = 0xd,
+ };
+
+ enum {
+ S_IDLE,
+
+ S_STZ_STEP,
+ S_STZ_STEP_WAIT,
+ S_STZ_HEAD_SETTLING,
+
+ S_SEEK_STEP,
+ S_SEEK_STEP_WAIT,
+ S_SEEK_HEAD_SETTLING,
+
+ S_SRW_WAIT_READY,
+ S_SRW_HEAD_SETTLING,
+ S_SRW_START,
+
+ S_FFW_WAIT_READY,
+ S_FFW_HEAD_SETTLING,
+ S_FFW_START,
+
+ S_IDAM_BAD_TRACK,
+ S_IDAM_BAD_CRC,
+ S_IDAM_FOUND,
+ S_IDAM_NOT_FOUND,
+
+ S_DAM_NOT_FOUND,
+ S_DAM_BAD_CRC,
+ S_DAM_DONE,
+ };
+
+ enum {
+ L_IDLE,
+
+ L_IDAM_SEARCH,
+ L_IDAM_CHECK_TRACK,
+ L_IDAM_CHECK_SECTOR,
+ L_IDAM_CHECK_CRC,
+
+ L_DAM_SEARCH,
+ L_DAM_DELETED,
+ L_DAM_READ,
+ L_DAM_READ_BYTE,
+
+ L_DAM_WAIT,
+ L_DAM_WRITE,
+ L_DAM_WRITE_BYTE,
+
+ L_FFW_BYTE,
+ L_FFW_WRITE,
};
- optional_device_array<legacy_floppy_image_device, 4> m_floppy;
-
- devcb_write_line m_write_irq;
-
- /* registers */
- uint8_t m_CTAR; /* current track */
- uint8_t m_CMR; /* command */
- uint8_t m_ISR; /* interrupt status */
- uint8_t m_SUR; /* set-up */
- uint8_t m_STRA; /* status */
- uint8_t m_STRB; /* status */
- uint8_t m_SAR; /* sector address */
- uint8_t m_GCR; /* general count */
- uint8_t m_CCR; /* CRC control */
- uint8_t m_LTAR; /* logical address track (=track destination) */
-
- /* internal state */
- uint8_t m_drive;
- uint8_t m_side;
- uint8_t m_data[128]; /* sector buffer */
- uint32_t m_data_size; /* size of data */
- uint32_t m_data_idx; /* current read/write position in data */
- uint32_t m_data_id; /* chrd_id for sector write */
- uint8_t m_index_pulse;
- uint8_t m_crc_wait;
-
- /* trigger delayed actions (bottom halves) */
- emu_timer* m_timer_cont;
-
- legacy_floppy_image_device* floppy_image();
- void status_update();
- void cmd_end();
- void finish_STZ();
- void finish_SEK();
- int address_search(chrn_id* id);
- int address_search_read(chrn_id* id);
- void finish_RCR();
- void cont_SR();
- void finish_SR();
- void cont_SW();
+ struct live_info {
+ attotime tm;
+ fdc_pll_t pll;
+ int state, next_state;
+ u16 shift_reg;
+ u16 crc;
+ int bit_counter;
+ bool data_separator_phase, data_bit_context;
+ uint8_t data_reg;
+ };
+ devcb_write_line m_irq;
+ bool m_force_ready;
+
+ emu_timer *m_timer;
+ floppy_image_device *m_floppy;
+
+ live_info m_cur_live, m_checkpoint_live;
+
+ int m_state;
+
+ bool m_head_loaded, m_dir_loaded, m_dor_loaded, m_dor_needed;
+
+ u8 m_dir;
+ u8 m_dor;
+ u8 m_ctar;
+ u8 m_cmr;
+ u8 m_isr;
+ u8 m_sur;
+ u8 m_stra;
+ u8 m_sar;
+ u8 m_strb;
+ u8 m_gcr;
+ u8 m_ccr;
+ u8 m_ltar;
+
+ u8 m_step_count;
+ u8 m_idam_turns;
+
+ u8 dir_r();
+ void dor_w(u8 data);
+ u8 ctar_r();
+ void ctar_w(u8 data);
+ u8 isr_r();
+ void cmr_w(u8 data);
+ u8 stra_r();
+ void sur_w(u8 data);
+ u8 strb_r();
+ void sar_w(u8 data);
+ void gcr_w(u8 data);
+ void ccr_w(u8 data);
+ void ltar_w(u8 data);
+
+ void index_callback(floppy_image_device *floppy, int state);
+ void ready_callback(floppy_image_device *floppy, int state);
+
+ void command_start();
+ void run(bool timeout, bool ready, bool index);
+ void isr_raise(u8 flag);
+ void delay(int);
+ void live_start(int state, bool start_writing = false);
+ void checkpoint();
+ void rollback();
+ void live_delay(int state);
+ void live_sync();
+ void live_abort();
+ bool read_one_bit(const attotime &limit);
+ bool write_one_bit(const attotime &limit);
+ void live_run(attotime limit = attotime::never);
+ bool is_ready() const;
};
DECLARE_DEVICE_TYPE(MC6843, mc6843_device)
diff --git a/src/devices/machine/wd_fdc.cpp b/src/devices/machine/wd_fdc.cpp
index c7c5d5a7f00..d32626b5f03 100644
--- a/src/devices/machine/wd_fdc.cpp
+++ b/src/devices/machine/wd_fdc.cpp
@@ -23,7 +23,7 @@
#define LOG_LIVE (1U << 13) // Live states
#define LOG_FUNC (1U << 14) // Function calls
-#define VERBOSE (LOG_GENERAL)
+#define VERBOSE (LOG_DESC)
//#define LOG_OUTPUT_STREAM std::cout
#include "logmacro.h"
diff --git a/src/lib/formats/all.cpp b/src/lib/formats/all.cpp
index 345487e970d..5c3ee523508 100644
--- a/src/lib/formats/all.cpp
+++ b/src/lib/formats/all.cpp
@@ -589,6 +589,10 @@
#include "thom_cas.h"
#endif
+#ifdef HAS_FORMATS_THOM_DSK
+#include "thom_dsk.h"
+#endif
+
#ifdef HAS_FORMATS_TI99_DSK
#include "ti99_dsk.h"
#endif
@@ -1202,6 +1206,10 @@ void mame_formats_full_list(mame_formats_enumerator &en)
en.add(to7_cassette_formats); // thom_cas.h
en.add(mo5_cassette_formats); // thom_cas.h
#endif
+#ifdef HAS_FORMATS_THOM_DSK
+ en.add(FLOPPY_THOMSON_525_FORMAT); // thom_dsk.h
+ en.add(FLOPPY_THOMSON_35_FORMAT); // thom_dsk.h
+#endif
en.category("Texas Instruments");
#ifdef HAS_FORMATS_TI99_DSK
diff --git a/src/lib/formats/thom_dsk.cpp b/src/lib/formats/thom_dsk.cpp
index d525641c29f..b1b34e987c2 100644
--- a/src/lib/formats/thom_dsk.cpp
+++ b/src/lib/formats/thom_dsk.cpp
@@ -1,444 +1,86 @@
// license:BSD-3-Clause
-// copyright-holders:Antoine Mine
-/*********************************************************************
+// copyright-holders:Olivier Galibert
- formats/thom_dsk.c
-
- Thomson disk images
-
- Based on work of Antoine Mine'
-
-*********************************************************************/
-
-#include <cstring>
-#include <cassert>
#include "thom_dsk.h"
-#include "basicdsk.h"
-
-static const int sap_magic_num = 0xB3; /* simple XOR crypt */
-
-
-static const char sap_header[] =
- "\001SYSTEME D'ARCHIVAGE PUKALL S.A.P. "
- "(c) Alexandre PUKALL Avril 1998";
-
-static const uint16_t sap_crc[] =
+thomson_525_format::thomson_525_format() : wd177x_format(formats)
{
- 0x0000, 0x1081, 0x2102, 0x3183, 0x4204, 0x5285, 0x6306, 0x7387,
- 0x8408, 0x9489, 0xa50a, 0xb58b, 0xc60c, 0xd68d, 0xe70e, 0xf78f,
-};
-
-struct sap_dsk_tag
-{
- int tracks;
- int sector_size;
- int sector_pos[80][16]; /* remember sector position in file */
-};
-
-static uint16_t thom_sap_crc( uint8_t* data, int size )
-{
- int i;
- uint16_t crc = 0xffff, crc2;
- for ( i = 0; i < size; i++ )
- {
- crc2 = ( crc >> 4 ) ^ sap_crc[ ( crc ^ data[i] ) & 15 ];
- crc = ( crc2 >> 4 ) ^ sap_crc[ ( crc2 ^ (data[i] >> 4) ) & 15 ];
- }
- return crc;
}
-static struct sap_dsk_tag *get_tag(floppy_image_legacy *floppy)
+const char *thomson_525_format::name() const
{
- struct sap_dsk_tag *tag;
- tag = (sap_dsk_tag *)floppy_tag(floppy);
- return tag;
+ return "thomson_525";
}
-
-static FLOPPY_IDENTIFY(sap_dsk_identify)
-{
- char header[0x100];
- floppy_image_read(floppy, header, 0, sizeof(sap_header));
- if (!memcmp( header, sap_header, sizeof(sap_header) ) )
- {
- *vote= 100;
- } else {
- *vote = 0;
- }
- return FLOPPY_ERROR_SUCCESS;
-}
-static int sap_get_heads_per_disk(floppy_image_legacy *floppy)
+const char *thomson_525_format::description() const
{
- return 1;
+ return "Thomson 5.25 disk image";
}
-static int sap_get_tracks_per_disk(floppy_image_legacy *floppy)
+const char *thomson_525_format::extensions() const
{
- return get_tag(floppy)->tracks;
+ return "fd";
}
-
-static floperr_t get_offset(floppy_image_legacy *floppy, int head, int track, int sector, bool sector_is_index, uint64_t *offset)
-{
- uint64_t offs;
- struct sap_dsk_tag *tag = get_tag(floppy);
- /* translate the sector to a raw sector */
- if (!sector_is_index)
+const thomson_525_format::format thomson_525_format::formats[] = {
{
- sector -= 1;
- }
- /* check to see if we are out of range */
- if ((head < 0) || (head >= 1) || (track < 0) || (track >=tag->tracks)
- || (sector < 0) || (sector >= 16))
- return FLOPPY_ERROR_SEEKERROR;
-
- offs = tag->sector_pos[track][sector];
- if (offs <= 0 )
- return FLOPPY_ERROR_SEEKERROR;
-
- if (offset)
- *offset = offs;
- return FLOPPY_ERROR_SUCCESS;
-}
-
-
-
-static floperr_t internal_sap_read_sector(floppy_image_legacy *floppy, int head, int track, int sector, bool sector_is_index, void *buffer, size_t buflen)
-{
- uint64_t offset;
- floperr_t err;
- int i;
- uint8_t *buf;
- err = get_offset(floppy, head, track, sector, sector_is_index, &offset);
- if (err)
- return err;
-
- floppy_image_read(floppy, buffer, offset+4, buflen);
- buf = (uint8_t*)buffer;
- for (i=0;i<buflen;i++) {
- buf[i] ^= sap_magic_num;
- }
- return FLOPPY_ERROR_SUCCESS;
-}
-
-
-
-static floperr_t internal_sap_write_sector(floppy_image_legacy *floppy, int head, int track, int sector, bool sector_is_index, const void *buffer, size_t buflen, int ddam)
-{
- uint64_t offset;
- floperr_t err;
- uint8_t buf[256+6];
- uint16_t crc;
- int i;
- err = get_offset(floppy, head, track, sector, sector_is_index, &offset);
- if (err)
- return err;
-
- /* buf = 4-byte header + sector + 2-byte CRC */
- floppy_image_read(floppy, buf, offset, 4);
- for (i=0;i<buflen;i++) {
- buf[i+4] = ((uint8_t*)buffer)[i];
- }
- crc = thom_sap_crc( buf, buflen+4 );
- buf[buflen+4] = crc >> 8;
- buf[buflen+5] = crc & 0xff;
- for (i=0;i<buflen;i++) {
- buf[i+4] ^= sap_magic_num;
- }
- floppy_image_write(floppy, buf, offset, buflen+6);
-
- return FLOPPY_ERROR_SUCCESS;
-}
-
-
-static floperr_t sap_read_sector(floppy_image_legacy *floppy, int head, int track, int sector, void *buffer, size_t buflen)
-{
- return internal_sap_read_sector(floppy, head, track, sector, false, buffer, buflen);
-}
+ floppy_image::FF_525, floppy_image::SSSD, floppy_image::FM,
+ 4000,
+ 16, 40, 1,
+ 128, {},
+ 1, {},
+ 17, 22, 12
+ },
+ {
+ floppy_image::FF_525, floppy_image::SSDD, floppy_image::MFM,
+ 2000,
+ 16, 40, 1,
+ 256, {},
+ 1, {},
+ 31, 22, 44
+ },
+ {}
+};
-static floperr_t sap_write_sector(floppy_image_legacy *floppy, int head, int track, int sector, const void *buffer, size_t buflen, int ddam)
-{
- return internal_sap_write_sector(floppy, head, track, sector, false, buffer, buflen, ddam);
-}
-static floperr_t sap_read_indexed_sector(floppy_image_legacy *floppy, int head, int track, int sector, void *buffer, size_t buflen)
+thomson_35_format::thomson_35_format() : wd177x_format(formats)
{
- return internal_sap_read_sector(floppy, head, track, sector, true, buffer, buflen);
}
-static floperr_t sap_write_indexed_sector(floppy_image_legacy *floppy, int head, int track, int sector, const void *buffer, size_t buflen, int ddam)
+const char *thomson_35_format::name() const
{
- return internal_sap_write_sector(floppy, head, track, sector, true, buffer, buflen, ddam);
+ return "thomson_35";
}
-static floperr_t sap_get_sector_length(floppy_image_legacy *floppy, int head, int track, int sector, uint32_t *sector_length)
+const char *thomson_35_format::description() const
{
- floperr_t err;
- err = get_offset(floppy, head, track, sector, false, nullptr);
- if (err)
- return err;
-
- if (sector_length) {
- *sector_length = get_tag(floppy)->sector_size;
- }
- return FLOPPY_ERROR_SUCCESS;
+ return "Thomson 3.5 disk image";
}
-
-
-static floperr_t sap_get_indexed_sector_info(floppy_image_legacy *floppy, int head, int track, int sector_index, int *cylinder, int *side, int *sector, uint32_t *sector_length, unsigned long *flags)
+const char *thomson_35_format::extensions() const
{
- floperr_t err;
- uint8_t header[4];
- uint64_t offset = 0;
- sector_index += 1;
- err = get_offset(floppy, head, track, sector_index, false, &offset);
-
- floppy_image_read(floppy, header, offset, 4);
- if (cylinder)
- *cylinder = header[2];
- if (side)
- *side = head;
- if (sector)
- *sector = header[3];
- if (sector_length)
- *sector_length = get_tag(floppy)->sector_size;
- if (flags)
- /* TODO: read DAM or DDAM and determine flags */
- *flags = 0;
- return err;
+ return "fd";
}
-static floperr_t sap_post_format(floppy_image_legacy *floppy, util::option_resolution *params)
-{
- int track,sector;
- int pos;
- uint8_t buf[256], header[4];
- struct sap_dsk_tag *tag;
- tag = (struct sap_dsk_tag *) floppy_create_tag(floppy, sizeof(struct sap_dsk_tag));
-
- /* default options */
- if ( !tag->tracks )
- {
- tag->tracks = 80;
- tag->sector_size = 256;
- }
-
- /* create SAP file header */
- floppy_image_write( floppy, sap_header, 0, 66 );
-
- for ( track = 0; track < 80; track++ )
- for ( sector = 0; sector < 16; sector++ )
- tag->sector_pos[track][sector] = 0;
-
- /* create all sectors with valid header and CRC */
- memset(buf, 0xe5, 256);
- pos = 0x42;
- header[0] = (tag->sector_size==128) ? 1 : 0;
- header[1] = 0;
- for ( track = 0, pos = 0x42; track < tag->tracks; track++ )
- for ( sector = 0; sector < 16; sector++, pos += tag->sector_size + 6 ) {
- tag->sector_pos[track][sector] = pos;
- header[2] = track;
- header[3] = sector + 1;
- floppy_image_write(floppy, header, pos, 4);
- sap_write_indexed_sector( floppy, 0, track, sector, buf, tag->sector_size, 0 );
- }
-
- return FLOPPY_ERROR_SUCCESS;
-}
-
-
-static FLOPPY_CONSTRUCT(sap_dsk_construct)
-{
- struct FloppyCallbacks *callbacks;
- struct sap_dsk_tag *tag;
- int j;
- uint8_t fmt;
- tag = (struct sap_dsk_tag *) floppy_create_tag(floppy, sizeof(struct sap_dsk_tag));
- if (!tag)
- return FLOPPY_ERROR_OUTOFMEMORY;
-
- /* guess format */
- floppy_image_read(floppy, &fmt, 0x42, 1);
- if ( fmt==1 ) tag->sector_size = 128; else tag->sector_size = 256;
-
- /* start with an empty offset table */
- tag->tracks = 0;
- for ( int i = 0; i < 80; i++ )
- for ( j = 0; j < 16; j++ )
- tag->sector_pos[i][j] = 0;
-
- /* count tracks & fill sector offset table */
- for ( uint64_t i = 0x42; i+4 < floppy_image_size(floppy); i += tag->sector_size + 6 ) // CRC 2 bytes + 4 bytes sector header
+const thomson_35_format::format thomson_35_format::formats[] = {
{
- uint8_t sector, track;
- floppy_image_read(floppy, &track, i+2, 1);
- floppy_image_read(floppy, &sector, i+3, 1);
- if ( track >= 80 || sector < 1 || sector > 16 ) continue;
- if ( track > tag->tracks ) tag->tracks = track+1;
- tag->sector_pos[track][sector-1] = i;
- }
- callbacks = floppy_callbacks(floppy);
- callbacks->read_sector = sap_read_sector;
- callbacks->write_sector = sap_write_sector;
- callbacks->read_indexed_sector = sap_read_indexed_sector;
- callbacks->write_indexed_sector = sap_write_indexed_sector;
- callbacks->get_sector_length = sap_get_sector_length;
- callbacks->get_heads_per_disk = sap_get_heads_per_disk;
- callbacks->get_tracks_per_disk = sap_get_tracks_per_disk;
- callbacks->get_indexed_sector_info = sap_get_indexed_sector_info;
- callbacks->post_format = sap_post_format;
-
- return FLOPPY_ERROR_SUCCESS;
-}
-
-static FLOPPY_IDENTIFY(qdd_dsk_identify)
-{
- *vote = (floppy_image_size(floppy) == (51200)) ? 100 : 0;
- return FLOPPY_ERROR_SUCCESS;
-}
-
-/* fixed interlacing map for QDDs */
-static int thom_qdd_map[400];
-
-static int qdd_translate_sector(floppy_image_legacy *floppy, int sector)
-{
- return thom_qdd_map[sector-1];
-}
-
-static void thom_qdd_compute_map ( void )
-{
- /* this map is hardcoded in the QDD BIOS */
- static const int p[6][4] =
- {
- { 20, 2, 14, 8 }, { 21, 19, 13, 7 },
- { 22, 18, 12, 6 }, { 23, 17, 11, 5 },
- { 24, 16, 10, 4 }, { 1, 15, 9, 3 }
- };
- static const int q[4] = { 0, 8, 4, 12 };
- int t, s;
- for ( t = 0; t < 24; t++ )
+ floppy_image::FF_35, floppy_image::SSDD, floppy_image::MFM,
+ 2000,
+ 16, 80, 1,
+ 256, {},
+ 1, {},
+ 31, 22, 44
+ },
{
- for ( s = 0; s < 16; s++ )
- {
- thom_qdd_map[ t*16 + s ] = p[ t/4 ][ s%4 ] * 16 + (s/4) + 4*(t%4);
- }
- }
- for ( s = 0; s < 16; s++ )
- {
- thom_qdd_map[ 24*16 + s ] = q[ s%4 ] + (s/4);
- }
-}
-
-static FLOPPY_CONSTRUCT(qdd_dsk_construct)
-{
- struct basicdsk_geometry geometry;
-
- thom_qdd_compute_map();
-
- memset(&geometry, 0, sizeof(geometry));
- geometry.heads = 1;
- geometry.first_sector_id = 1;
- geometry.sector_length = 128;
- geometry.tracks = 1;
- geometry.sectors = 400;
- geometry.translate_sector = qdd_translate_sector;
- return basicdsk_construct(floppy, &geometry);
-}
-
-
-/* ----------------------------------------------------------------------- */
-
-
-static floperr_t fd_identify(floppy_image_legacy *floppy, int *vote, int tracks, int sector_size)
-{
- uint64_t expected_size;
- expected_size = sector_size;
- expected_size *= tracks;
- expected_size *= 16; /* secetors */
- *vote = (floppy_image_size(floppy) == expected_size) ? 100 : 50;
- return FLOPPY_ERROR_SUCCESS;
-}
-
-static floperr_t fd_construct(floppy_image_legacy *floppy, int tracks, int sector_size)
-{
- struct basicdsk_geometry geometry;
- memset(&geometry, 0, sizeof(geometry));
- geometry.heads = 1;
- geometry.first_sector_id = 1;
- geometry.sector_length = sector_size;
- geometry.tracks = tracks;
- geometry.sectors = 16;
- return basicdsk_construct(floppy, &geometry);
-}
-
-
-static FLOPPY_IDENTIFY(fd_80_256_identify)
-{
- return fd_identify(floppy, vote, 80, 256);
-}
-
-static FLOPPY_CONSTRUCT(fd_80_256_construct)
-{
- return fd_construct(floppy, 80, 256);
-}
-
-static FLOPPY_IDENTIFY(fd_40_256_identify)
-{
- return fd_identify(floppy, vote, 40, 256);
-}
-
-static FLOPPY_CONSTRUCT(fd_40_256_construct)
-{
- return fd_construct(floppy, 40, 256);
-}
-
-static FLOPPY_IDENTIFY(fd_80_128_identify)
-{
- return fd_identify(floppy, vote, 80, 128);
-}
-
-static FLOPPY_CONSTRUCT(fd_80_128_construct)
-{
- return fd_construct(floppy, 80, 128);
-}
-
-static FLOPPY_IDENTIFY(fd_40_128_identify)
-{
- return fd_identify(floppy, vote, 40, 128);
-}
-
-static FLOPPY_CONSTRUCT(fd_40_128_construct)
-{
- return fd_construct(floppy, 40, 128);
-}
-
-
-/* ----------------------------------------------------------------------- */
-
-LEGACY_FLOPPY_OPTIONS_START(thomson)
-
-LEGACY_FLOPPY_OPTION(fdmfm2, "fd", "Thomson FD (MFM) 80 tracks disk image (3\"1/2 DD)",
- fd_80_256_identify, fd_80_256_construct, nullptr, nullptr)
-
-// Note: no way to distinguish between FD files for 5"1/4 DD and 3"1/2 SD actually, as they have the same size
-// however, we expect 3"1/2 SD to be rather rare, so, we simply put it after 5"1/4 DD
-
-LEGACY_FLOPPY_OPTION(fdmfm, "fd", "Thomson FD (MFM) 40 tracks disk image (5\"1/4 DD)",
- fd_40_256_identify, fd_40_256_construct, nullptr, nullptr)
-
-LEGACY_FLOPPY_OPTION(fd2, "fd", "Thomson FD (FM) 80 tracks disk image (3\"1/2 SD)",
- fd_80_128_identify, fd_80_128_construct, nullptr, nullptr)
-
-LEGACY_FLOPPY_OPTION(fd, "fd", "Thomson FD (FM) 40 tracks disk image (5\"1/4 SD)",
- fd_40_128_identify, fd_40_128_construct, nullptr, nullptr)
-
-LEGACY_FLOPPY_OPTION(sap,"sap", "Thomson SAP floppy disk image",
- sap_dsk_identify, sap_dsk_construct, nullptr, nullptr)
-
-LEGACY_FLOPPY_OPTION(qdd,"qd", "Thomson QDD floppy disk image (2\"8 SD)",
- qdd_dsk_identify, qdd_dsk_construct, nullptr, nullptr)
+ floppy_image::FF_35, floppy_image::DSDD, floppy_image::MFM,
+ 2000,
+ 16, 80, 2,
+ 256, {},
+ 1, {},
+ 31, 22, 44
+ },
+ {}
+};
-LEGACY_FLOPPY_OPTIONS_END
+const floppy_format_type FLOPPY_THOMSON_525_FORMAT = &floppy_image_format_creator<thomson_525_format>;
+const floppy_format_type FLOPPY_THOMSON_35_FORMAT = &floppy_image_format_creator<thomson_35_format>;
diff --git a/src/lib/formats/thom_dsk.h b/src/lib/formats/thom_dsk.h
index 24bf68f3b38..3d8fd504084 100644
--- a/src/lib/formats/thom_dsk.h
+++ b/src/lib/formats/thom_dsk.h
@@ -1,18 +1,40 @@
// license:BSD-3-Clause
-// copyright-holders:Miodrag Milanovic
+// copyright-holders:Olivier Galibert
#ifndef MAME_FORMATS_THOM_DSK_H
#define MAME_FORMATS_THOM_DSK_H
#pragma once
-#include "flopimg.h"
+#include "wd177x_dsk.h"
-/* recognized image formats:
- - .fd one-side 5"1/4 (single and double density), 3"1/2
- - .qd one-side QDD
- - .sap one-side double-density 5"1/4, 3"1/2
-*/
+class thomson_525_format : public wd177x_format
+{
+public:
+ thomson_525_format();
-LEGACY_FLOPPY_OPTIONS_EXTERN(thomson);
+ virtual const char *name() const override;
+ virtual const char *description() const override;
+ virtual const char *extensions() const override;
+
+private:
+ static const format formats[];
+};
+
+class thomson_35_format : public wd177x_format
+{
+public:
+ thomson_35_format();
+
+ virtual const char *name() const override;
+ virtual const char *description() const override;
+ virtual const char *extensions() const override;
+
+private:
+ static const format formats[];
+};
+
+
+extern const floppy_format_type FLOPPY_THOMSON_525_FORMAT;
+extern const floppy_format_type FLOPPY_THOMSON_35_FORMAT;
#endif // MAME_FORMATS_THOM_DSK_H
diff --git a/src/lib/formats/wd177x_dsk.cpp b/src/lib/formats/wd177x_dsk.cpp
index 3d314e12383..5dbc140a80a 100644
--- a/src/lib/formats/wd177x_dsk.cpp
+++ b/src/lib/formats/wd177x_dsk.cpp
@@ -438,7 +438,7 @@ void wd177x_format::check_compatibility(floppy_image *image, std::vector<int> &c
break;
}
int ns = 0;
- for(int j = 0; j < 256 && j < sectors.size(); j++)
+ for(int j=0; j<int(sectors.size()); j++)
if(!sectors[j].empty()) {
int sid;
if(tf.sector_base_id == -1) {
diff --git a/src/mame/drivers/thomson.cpp b/src/mame/drivers/thomson.cpp
index 3603e491ff6..97c3519da09 100644
--- a/src/mame/drivers/thomson.cpp
+++ b/src/mame/drivers/thomson.cpp
@@ -81,6 +81,11 @@
#include "bus/centronics/ctronics.h"
#include "bus/rs232/rs232.h"
+#include "bus/thomson/cd90_015.h"
+#include "bus/thomson/cq90_028.h"
+#include "bus/thomson/cd90_351.h"
+#include "bus/thomson/cd90_640.h"
+#include "bus/thomson/nanoreseau.h"
#include "imagedev/flopdrv.h"
#include "machine/6821pia.h"
#include "machine/clock.h"
@@ -285,7 +290,7 @@ boot floppy.
. DD 90-352 3"1/2 floppy drives
- alternate QDD floppy drive extension
. CQ 90-028 floppy controller, based on a Motorola 6852 SSDA
- . QD 90-028 quickdrive 2"8 (QDD), only one drive, signe side
+ . QD 90-028 quickdrive 2"8 (QDD), only one drive, single side
- speech synthesis extension: based on a Philips / Signetics MEA 8000
(cannot be used with the MODEM)
- MIDIPAK MIDI extension, uses a EF 6850 ACIA
@@ -315,11 +320,9 @@ void thomson_state::to7_map(address_map &map)
map(0x4000, 0x5fff).bankr(THOM_VRAM_BANK).w(FUNC(thomson_state::to7_vram_w));
map(0x6000, 0x7fff).bankrw(THOM_BASE_BANK); /* 1 * 8 KB */
map(0x8000, 0xdfff).bankrw(THOM_RAM_BANK); /* 16 or 24 KB (for extension) */
- map(0xe000, 0xe7bf).bankr(THOM_FLOP_BANK);
map(0xe7c0, 0xe7c7).rw(m_mc6846, FUNC(mc6846_device::read), FUNC(mc6846_device::write));
map(0xe7c8, 0xe7cb).rw("pia_0", FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt));
map(0xe7cc, 0xe7cf).rw("pia_1", FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt));
- map(0xe7d0, 0xe7df).rw(FUNC(thomson_state::to7_floppy_r), FUNC(thomson_state::to7_floppy_w));
map(0xe7e0, 0xe7e3).rw("to7_io:pia_2", FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt));
map(0xe7e8, 0xe7eb).rw("acia", FUNC(mos6551_device::read), FUNC(mos6551_device::write));
map(0xe7f2, 0xe7f3).rw(FUNC(thomson_state::to7_midi_r), FUNC(thomson_state::to7_midi_w));
@@ -342,57 +345,6 @@ void thomson_state::to7_map(address_map &map)
/* ------------ ROMS ------------ */
-/* external floppy controllers */
-#define ROM_FLOPPY \
- /* no controller */ \
- ROM_REGION( 0x800, "floppy_none", 0 ) \
- ROM_FILL( 0, 0x800, 0x39 ) \
- /* CD 90-015 (5"1/4) */ \
- ROM_REGION( 0x800, "floppy_cd90_015", 0 ) \
- ROM_LOAD ( "cd90-015.rom", 0x000, 0x7c0, \
- CRC(821d34c1) \
- SHA1(31a6bb81baaeec5fc8de457c97264f9dfa92c18b) ) \
- /* CD 90-640 (5"1/4) */ \
- ROM_REGION( 0x800, "floppy_cd90_640", 0 ) \
- ROM_LOAD ( "cd90-640.rom", 0x000, 0x7c0, \
- CRC(5114c0a5) \
- SHA1(5c72566c22d8160ef0c75959e1863a1309bbbe49) ) \
- /* CD 90-351 (3"1/2) */ \
- ROM_REGION( 0x2000, "floppy_cd90_351", 0 ) \
- ROM_LOAD ( "cd-351-0.rom", 0x0000, 0x7c0, \
- CRC(2c0159fd) \
- SHA1(bab5395ed8bc7c06f9897897f836054e6546e8e8) ) \
- ROM_LOAD ( "cd-351-1.rom", 0x0800, 0x7c0, \
- CRC(8e58d159) \
- SHA1(dcf992c96e7556b2faee6bacd3f744e56998e6ea) ) \
- ROM_LOAD ( "cd-351-2.rom", 0x1000, 0x7c0, \
- CRC(c9228b60) \
- SHA1(179e10107d5be91e684069dee80f94847b83201f) ) \
- ROM_LOAD ( "cd-351-3.rom", 0x1800, 0x7c0, \
- CRC(3ca8e5dc) \
- SHA1(7118636fb5c597c78c2fce17b02aed5e4ba38635) ) \
- /* CQ 90-028 (2"8, aka QDD) */ \
- ROM_REGION( 0x800, "floppy_cq90_028", 0 ) \
- ROM_LOAD ( "cq90-028.rom", 0x000, 0x7c0, \
- CRC(ca4dba3d) \
- SHA1(949c1f777c892da62c242215d79757d61e71e62b) )
-
-/* external floppy / network controller: 9 banks */
-#define ROM_FLOPPY5 \
- ROM_FLOPPY \
- ROM_REGION( 0x800, "floppy_nano", 0 ) \
- ROM_LOAD ( "nano5.rom", 0x000, 0x7c0, \
- CRC(2f756868) \
- SHA1(b5b7cb6d12493d849330b6b5628efd1a83a4bbf5) )
-
-#define ROM_FLOPPY7 \
- ROM_FLOPPY \
- ROM_REGION( 0x800, "floppy_nano", 0 ) \
- ROM_LOAD ( "nano7.rom", 0x000, 0x7c0, \
- CRC(42a1d1a6) \
- SHA1(973209f4baa5e81bf7885c0602949e064bac7862) )
-
-
ROM_START ( to7 )
ROM_REGION ( 0x10000, "maincpu", 0 )
ROM_LOAD ( "to7.rom", 0xe800, 0x1800,
@@ -401,8 +353,6 @@ ROM_START ( to7 )
ROM_REGION ( 0x10000, "cartridge", 0 )
ROM_FILL ( 0x00000, 0x10000, 0x39 )
-
- ROM_FLOPPY7
ROM_END
ROM_START ( t9000 )
@@ -413,8 +363,6 @@ ROM_START ( t9000 )
ROM_REGION ( 0x10000, "cartridge", 0 )
ROM_FILL ( 0x00000, 0x10000, 0x39 )
-
- ROM_FLOPPY7
ROM_END
@@ -453,54 +401,6 @@ static INPUT_PORTS_START ( to7_mconfig )
INPUT_PORTS_END
-static INPUT_PORTS_START ( to7_fconfig )
- PORT_START ( "fconfig" )
-
- PORT_CONFNAME ( 0x07, 0x03, "Floppy (reset)" )
- PORT_CONFSETTING ( 0x00, DEF_STR ( None ) )
- PORT_CONFSETTING ( 0x01, "CD 90-015 (5\"1/4 SD)" )
- PORT_CONFSETTING ( 0x02, "CD 90-640 (5\"1/4 DD)" )
- PORT_CONFSETTING ( 0x03, "CD 90-351 (3\"1/2)" )
- PORT_CONFSETTING ( 0x04, "CQ 90-028 (2\"8 QDD)" )
- PORT_CONFSETTING ( 0x05, "Network" )
-
- PORT_CONFNAME ( 0xf8, 0x08, "Network ID" )
- PORT_CONFSETTING ( 0x00, "0 (Master)" )
- PORT_CONFSETTING ( 0x08, "1" )
- PORT_CONFSETTING ( 0x10, "2" )
- PORT_CONFSETTING ( 0x18, "3" )
- PORT_CONFSETTING ( 0x20, "4" )
- PORT_CONFSETTING ( 0x28, "5" )
- PORT_CONFSETTING ( 0x30, "6" )
- PORT_CONFSETTING ( 0x38, "7" )
- PORT_CONFSETTING ( 0x40, "8" )
- PORT_CONFSETTING ( 0x48, "9" )
- PORT_CONFSETTING ( 0x50, "10" )
- PORT_CONFSETTING ( 0x58, "11" )
- PORT_CONFSETTING ( 0x60, "12" )
- PORT_CONFSETTING ( 0x68, "13" )
- PORT_CONFSETTING ( 0x70, "14" )
- PORT_CONFSETTING ( 0x78, "15" )
- PORT_CONFSETTING ( 0x80, "16" )
- PORT_CONFSETTING ( 0x88, "17" )
- PORT_CONFSETTING ( 0x90, "18" )
- PORT_CONFSETTING ( 0x98, "19" )
- PORT_CONFSETTING ( 0xa0, "20" )
- PORT_CONFSETTING ( 0xa8, "21" )
- PORT_CONFSETTING ( 0xb0, "22" )
- PORT_CONFSETTING ( 0xb8, "23" )
- PORT_CONFSETTING ( 0xc0, "24" )
- PORT_CONFSETTING ( 0xc8, "25" )
- PORT_CONFSETTING ( 0xd0, "26" )
- PORT_CONFSETTING ( 0xd8, "27" )
- PORT_CONFSETTING ( 0xe0, "28" )
- PORT_CONFSETTING ( 0xe8, "29" )
- PORT_CONFSETTING ( 0xf0, "30" )
- PORT_CONFSETTING ( 0xf8, "31" )
-
-INPUT_PORTS_END
-
-
static INPUT_PORTS_START ( to7_keyboard )
PORT_START ( "keyboard.0" )
KEY ( 0, "Shift", LSHIFT ) PORT_CODE ( KEYCODE_RSHIFT ) PORT_CHAR(UCHAR_SHIFT_1)
@@ -580,7 +480,6 @@ static INPUT_PORTS_START ( to7 )
PORT_INCLUDE ( thom_game_port )
PORT_INCLUDE ( to7_keyboard )
PORT_INCLUDE ( to7_config )
- PORT_INCLUDE ( to7_fconfig )
PORT_INCLUDE ( to7_vconfig )
PORT_INCLUDE ( to7_mconfig )
INPUT_PORTS_END
@@ -589,51 +488,9 @@ static INPUT_PORTS_START ( t9000 )
PORT_INCLUDE ( to7 )
INPUT_PORTS_END
-WRITE_LINE_MEMBER( thomson_state::fdc_index_0_w )
-{
- thomson_index_callback(0, state);
-}
-
-WRITE_LINE_MEMBER( thomson_state::fdc_index_1_w )
-{
- thomson_index_callback(1, state);
-}
-
-WRITE_LINE_MEMBER( thomson_state::fdc_index_2_w )
-{
- thomson_index_callback(2, state);
-}
-
-WRITE_LINE_MEMBER( thomson_state::fdc_index_3_w )
-{
- thomson_index_callback(3, state);
-}
-
-static const floppy_interface thomson_floppy_interface =
-{
- FLOPPY_STANDARD_5_25_DSHD,
- LEGACY_FLOPPY_OPTIONS_NAME(thomson),
- "thom_flop"
-};
-
-void thomson_state::cd90_640_formats(format_registration &fr)
-{
- fr.add_mfm_containers();
- fr.add(FLOPPY_CD90_640_FORMAT);
-}
-
-static void cd90_640_floppies(device_slot_interface &device)
-{
- device.option_add("sssd", FLOPPY_525_SSSD);
- device.option_add("sd", FLOPPY_525_SD);
- device.option_add("ssdd", FLOPPY_525_SSDD);
- device.option_add("dd", FLOPPY_525_DD);
-}
-
-
/* ------------ driver ------------ */
-void thomson_state::to7_base(machine_config &config)
+void thomson_state::to7_base(machine_config &config, bool is_mo)
{
MCFG_MACHINE_START_OVERRIDE( thomson_state, to7 )
MCFG_MACHINE_RESET_OVERRIDE( thomson_state, to7 )
@@ -671,33 +528,16 @@ void thomson_state::to7_base(machine_config &config)
m_cassette->set_default_state(CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED);
m_cassette->set_interface("to_cass");
-/* floppy */
- CQ90_028(config, m_to7qdd, 0);
-
- THMFC1(config, m_thmfc, 16_MHz_XTAL);
- m_thmfc->floppy_active_cb().set(FUNC(thomson_state::thom_floppy_active));
-
- MC6843(config, m_mc6843, 16_MHz_XTAL / 16 / 2);
- m_mc6843->set_floppy_drives(m_floppy_image[0], m_floppy_image[1], m_floppy_image[2], m_floppy_image[3]);
-
- LEGACY_FLOPPY(config, m_floppy_image[0], 0, &thomson_floppy_interface);
- m_floppy_image[0]->out_idx_cb().set(FUNC(thomson_state::fdc_index_0_w));
- LEGACY_FLOPPY(config, m_floppy_image[1], 0, &thomson_floppy_interface);
- m_floppy_image[1]->out_idx_cb().set(FUNC(thomson_state::fdc_index_1_w));
- LEGACY_FLOPPY(config, m_floppy_image[2], 0, &thomson_floppy_interface);
- m_floppy_image[2]->out_idx_cb().set(FUNC(thomson_state::fdc_index_2_w));
- LEGACY_FLOPPY(config, m_floppy_image[3], 0, &thomson_floppy_interface);
- m_floppy_image[3]->out_idx_cb().set(FUNC(thomson_state::fdc_index_3_w));
-
- WD2793(config, m_wd2793_fdc, 16_MHz_XTAL / 16);
- FLOPPY_CONNECTOR(config, "wd2793:0", cd90_640_floppies, "dd", thomson_state::cd90_640_formats);
- FLOPPY_CONNECTOR(config, "wd2793:1", cd90_640_floppies, "dd", thomson_state::cd90_640_formats);
-
-
-/* network */
- MC6854(config, m_mc6854);
- m_mc6854->set_out_frame_callback(FUNC(thomson_state::to7_network_got_frame));
-
+/* extension port */
+ THOMSON_EXTENSION(config, m_extension);
+ m_extension->option_add("cd90_015", CD90_015);
+ m_extension->option_add("cq90_028", CQ90_028);
+ m_extension->option_add("cd90_351", CD90_351);
+ m_extension->option_add("cd90_640", CD90_640);
+ if(is_mo)
+ m_extension->option_add("nanoreseau", NANORESEAU_MO);
+ else
+ m_extension->option_add("nanoreseau", NANORESEAU_TO);
/* pia */
PIA6821(config, m_pia_sys, 0);
@@ -759,7 +599,7 @@ void thomson_state::to7_base(machine_config &config)
void thomson_state::to7(machine_config &config)
{
- to7_base(config);
+ to7_base(config, false);
/* timer */
MC6846(config, m_mc6846, 16_MHz_XTAL / 16);
@@ -837,11 +677,9 @@ void thomson_state::to770_map(address_map &map)
map(0x4000, 0x5fff).bankr(THOM_VRAM_BANK).w(FUNC(thomson_state::to770_vram_w));
map(0x6000, 0x9fff).bankrw(THOM_BASE_BANK); /* 16 KB */
map(0xa000, 0xdfff).bankrw(THOM_RAM_BANK); /* 6 * 16 KB */
- map(0xe000, 0xe7bf).bankr(THOM_FLOP_BANK);
map(0xe7c0, 0xe7c7).rw(m_mc6846, FUNC(mc6846_device::read), FUNC(mc6846_device::write));
map(0xe7c8, 0xe7cb).rw("pia_0", FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt));
map(0xe7cc, 0xe7cf).rw("pia_1", FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt));
- map(0xe7d0, 0xe7df).rw(FUNC(thomson_state::to7_floppy_r), FUNC(thomson_state::to7_floppy_w));
map(0xe7e0, 0xe7e3).rw("to7_io:pia_2", FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt));
map(0xe7e4, 0xe7e7).rw(FUNC(thomson_state::to770_gatearray_r), FUNC(thomson_state::to770_gatearray_w));
map(0xe7e8, 0xe7eb).rw("acia", FUNC(mos6551_device::read), FUNC(mos6551_device::write));
@@ -873,8 +711,6 @@ ROM_START ( to770 )
ROM_REGION ( 0x10000, "cartridge", 0 )
ROM_FILL ( 0x00000, 0x10000, 0x39 )
-
- ROM_FLOPPY7
ROM_END
ROM_START ( to770a )
@@ -885,8 +721,6 @@ ROM_START ( to770a )
ROM_REGION ( 0x10000, "cartridge", 0 )
ROM_FILL ( 0x00000, 0x10000, 0x39 )
-
- ROM_FLOPPY7
ROM_END
@@ -1034,22 +868,20 @@ Differences include:
**********************************************************************/
-void thomson_state::mo5_map(address_map &map)
+void mo5_state::mo5_map(address_map &map)
{
- map(0x0000, 0x1fff).bankr(THOM_VRAM_BANK).w(FUNC(thomson_state::to770_vram_w));
+ map(0x0000, 0x1fff).bankr(THOM_VRAM_BANK).w(FUNC(mo5_state::to770_vram_w));
map(0x2000, 0x9fff).bankrw(THOM_BASE_BANK);
- map(0xa000, 0xa7bf).bankr(THOM_FLOP_BANK);
map(0xa7c0, 0xa7c3).rw("pia_0", FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt));
- map(0xa7cb, 0xa7cb).w(FUNC(thomson_state::mo5_ext_w));
+ map(0xa7cb, 0xa7cb).w(FUNC(mo5_state::mo5_ext_w));
map(0xa7cc, 0xa7cf).rw("pia_1", FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt));
- map(0xa7d0, 0xa7df).rw(FUNC(thomson_state::to7_floppy_r), FUNC(thomson_state::to7_floppy_w));
map(0xa7e0, 0xa7e3).rw("to7_io:pia_2", FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt));
- map(0xa7e4, 0xa7e7).rw(FUNC(thomson_state::mo5_gatearray_r), FUNC(thomson_state::mo5_gatearray_w));
+ map(0xa7e4, 0xa7e7).rw(FUNC(mo5_state::mo5_gatearray_r), FUNC(mo5_state::mo5_gatearray_w));
map(0xa7e8, 0xa7eb).rw("acia", FUNC(mos6551_device::read), FUNC(mos6551_device::write));
- map(0xa7f2, 0xa7f3).rw(FUNC(thomson_state::to7_midi_r), FUNC(thomson_state::to7_midi_w));
+ map(0xa7f2, 0xa7f3).rw(FUNC(mo5_state::to7_midi_r), FUNC(mo5_state::to7_midi_w));
map(0xa7fe, 0xa7ff).rw(m_mea8000, FUNC(mea8000_device::read), FUNC(mea8000_device::write));
- map(0xb000, 0xefff).bankr(THOM_CART_BANK).w(FUNC(thomson_state::mo5_cartridge_w));
+ map(0xb000, 0xefff).bankr(THOM_CART_BANK).w(FUNC(mo5_state::mo5_cartridge_w));
map(0xf000, 0xffff).rom(); /* system bios */
/* 0x10000 - 0x1ffff: 16 KB integrated BASIC / 64 KB external cartridge */
@@ -1078,8 +910,6 @@ ROM_START ( mo5 )
ROM_REGION ( 0x10000, "cartridge", 0 )
ROM_FILL( 0x00000, 0x10000, 0x39 )
-
- ROM_FLOPPY5
ROM_END
ROM_START ( mo5e )
@@ -1093,8 +923,6 @@ ROM_START ( mo5e )
ROM_REGION ( 0x10000, "cartridge", 0 )
ROM_FILL( 0x00000, 0x10000, 0x39 )
-
- ROM_FLOPPY5
ROM_END
@@ -1138,28 +966,28 @@ INPUT_PORTS_END
/* ------------ driver ------------ */
-void thomson_state::mo5(machine_config &config)
+void mo5_state::mo5(machine_config &config)
{
- to7_base(config);
- MCFG_MACHINE_START_OVERRIDE( thomson_state, mo5 )
- MCFG_MACHINE_RESET_OVERRIDE( thomson_state, mo5 )
+ to7_base(config, true);
+ MCFG_MACHINE_START_OVERRIDE( mo5_state, mo5 )
+ MCFG_MACHINE_RESET_OVERRIDE( mo5_state, mo5 )
- m_maincpu->set_addrmap(AS_PROGRAM, &thomson_state::mo5_map);
+ m_maincpu->set_addrmap(AS_PROGRAM, &mo5_state::mo5_map);
m_cassette->set_formats(mo5_cassette_formats);
m_cassette->set_interface("mo_cass");
- subdevice<palette_device>("palette")->set_init(FUNC(thomson_state::mo5_palette));
+ subdevice<palette_device>("palette")->set_init(FUNC(mo5_state::mo5_palette));
- m_pia_sys->readpa_handler().set(FUNC(thomson_state::mo5_sys_porta_in));
- m_pia_sys->readpb_handler().set(FUNC(thomson_state::mo5_sys_portb_in));
- m_pia_sys->writepa_handler().set(FUNC(thomson_state::mo5_sys_porta_out));
+ m_pia_sys->readpa_handler().set(FUNC(mo5_state::mo5_sys_porta_in));
+ m_pia_sys->readpb_handler().set(FUNC(mo5_state::mo5_sys_portb_in));
+ m_pia_sys->writepa_handler().set(FUNC(mo5_state::mo5_sys_porta_out));
m_pia_sys->writepb_handler().set("buzzer", FUNC(dac_bit_interface::data_w));
- m_pia_sys->ca2_handler().set(FUNC(thomson_state::mo5_set_cassette_motor));
+ m_pia_sys->ca2_handler().set(FUNC(mo5_state::mo5_set_cassette_motor));
m_pia_sys->cb2_handler().set_nop();
m_pia_sys->irqb_handler().set("mainirq", FUNC(input_merger_device::in_w<1>)); // WARNING: differs from TO7 !
- GENERIC_CARTSLOT(config.replace(), "cartslot", generic_plain_slot, "mo_cart", "m5,rom").set_device_load(FUNC(thomson_state::mo5_cartridge));
+ GENERIC_CARTSLOT(config.replace(), "cartslot", generic_plain_slot, "mo_cart", "m5,rom").set_device_load(FUNC(mo5_state::mo5_cartridge));
config.device_remove("to7_cart_list");
config.device_remove("to7_cass_list");
@@ -1175,15 +1003,15 @@ void thomson_state::mo5(machine_config &config)
m_ram->set_default_size("112K");
}
-void thomson_state::mo5e(machine_config &config)
+void mo5_state::mo5e(machine_config &config)
{
mo5(config);
}
-COMP( 1984, mo5, 0, 0, mo5, mo5, thomson_state, empty_init, "Thomson", "MO5", 0 )
+COMP( 1984, mo5, 0, 0, mo5, mo5, mo5_state, empty_init, "Thomson", "MO5", 0 )
-COMP( 1986, mo5e, mo5, 0, mo5e, mo5e, thomson_state, empty_init, "Thomson", "MO5E", 0 )
+COMP( 1986, mo5e, mo5, 0, mo5e, mo5e, mo5_state, empty_init, "Thomson", "MO5E", 0 )
/********************************* TO9 *******************************
@@ -1258,26 +1086,24 @@ It was replaced quickly with the improved TO9+.
**********************************************************************/
-void thomson_state::to9_map(address_map &map)
+void to9_state::to9_map(address_map &map)
{
- map(0x0000, 0x3fff).bankr(THOM_CART_BANK).w(FUNC(thomson_state::to9_cartridge_w));/* 4 * 16 KB */
- map(0x4000, 0x5fff).bankr(THOM_VRAM_BANK).w(FUNC(thomson_state::to770_vram_w));
+ map(0x0000, 0x3fff).bankr(THOM_CART_BANK).w(FUNC(to9_state::to9_cartridge_w));/* 4 * 16 KB */
+ map(0x4000, 0x5fff).bankr(THOM_VRAM_BANK).w(FUNC(to9_state::to770_vram_w));
map(0x6000, 0x9fff).bankrw(THOM_BASE_BANK); /* 16 KB */
map(0xa000, 0xdfff).bankrw(THOM_RAM_BANK); /* 10 * 16 KB */
- map(0xe000, 0xe7bf).bankr(THOM_FLOP_BANK);
map(0xe7c0, 0xe7c7).rw(m_mc6846, FUNC(mc6846_device::read), FUNC(mc6846_device::write));
map(0xe7c8, 0xe7cb).rw("pia_0", FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt));
map(0xe7cc, 0xe7cf).rw("pia_1", FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt));
- map(0xe7d0, 0xe7d9).rw(FUNC(thomson_state::to9_floppy_r), FUNC(thomson_state::to9_floppy_w));
- map(0xe7da, 0xe7dd).rw(FUNC(thomson_state::to9_vreg_r), FUNC(thomson_state::to9_vreg_w));
- map(0xe7de, 0xe7df).rw(FUNC(thomson_state::to9_kbd_r), FUNC(thomson_state::to9_kbd_w));
- map(0xe7e4, 0xe7e7).rw(FUNC(thomson_state::to9_gatearray_r), FUNC(thomson_state::to9_gatearray_w));
+ map(0xe7da, 0xe7dd).rw(FUNC(to9_state::to9_vreg_r), FUNC(to9_state::to9_vreg_w));
+ map(0xe7de, 0xe7df).rw(FUNC(to9_state::to9_kbd_r), FUNC(to9_state::to9_kbd_w));
+ map(0xe7e4, 0xe7e7).rw(FUNC(to9_state::to9_gatearray_r), FUNC(to9_state::to9_gatearray_w));
map(0xe7e8, 0xe7eb).rw("acia", FUNC(mos6551_device::read), FUNC(mos6551_device::write));
-/* map(0xe7f0, 0xe7f7).rw(FUNC(thomson_state::to9_ieee_r), FUNC(thomson_state::to9_ieee_w )); */
- map(0xe7f2, 0xe7f3).rw(FUNC(thomson_state::to7_midi_r), FUNC(thomson_state::to7_midi_w));
+/* map(0xe7f0, 0xe7f7).rw(FUNC(to9_state::to9_ieee_r), FUNC(to9_state::to9_ieee_w )); */
+ map(0xe7f2, 0xe7f3).rw(FUNC(to9_state::to7_midi_r), FUNC(to9_state::to7_midi_w));
map(0xe7f8, 0xe7fb).rw("pia_3", FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt));
- map(0xe7fe, 0xe7ff).rw(FUNC(thomson_state::to7_modem_mea8000_r), FUNC(thomson_state::to7_modem_mea8000_w));
+ map(0xe7fe, 0xe7ff).rw(FUNC(to9_state::to7_modem_mea8000_r), FUNC(to9_state::to7_modem_mea8000_w));
map(0xe800, 0xffff).rom(); /* system bios */
/* 0x10000 - 0x1ffff: 64 KB external ROM cartridge */
@@ -1335,8 +1161,6 @@ ROM_START ( to9 )
ROM_REGION ( 0x10000, "cartridge", 0 )
ROM_FILL( 0x00000, 0x10000, 0x39 )
-
- ROM_FLOPPY7
ROM_END
@@ -1435,92 +1259,44 @@ static INPUT_PORTS_START ( to9_keyboard )
KEY ( 7, "> <", BACKSLASH2 ) PORT_CHAR('>') PORT_CHAR('<')
INPUT_PORTS_END
-static INPUT_PORTS_START ( to9_fconfig )
- PORT_START ( "fconfig" )
-
- PORT_CONFNAME ( 0x07, 0x00, "External floppy (reset)" )
- PORT_CONFSETTING ( 0x00, "No external" )
- PORT_CONFSETTING ( 0x01, "CD 90-015 (5\"1/4 SD)" )
- PORT_CONFSETTING ( 0x02, "CD 90-640 (5\"1/4 DD)" )
- PORT_CONFSETTING ( 0x03, "CD 90-351 (3\"1/2)" )
- PORT_CONFSETTING ( 0x04, "CQ 90-028 (2\"8 QDD)" )
- PORT_CONFSETTING ( 0x05, "Network" )
-
- PORT_CONFNAME ( 0xf8, 0x08, "Network ID" )
- PORT_CONFSETTING ( 0x00, "0 (Master)" )
- PORT_CONFSETTING ( 0x08, "1" )
- PORT_CONFSETTING ( 0x10, "2" )
- PORT_CONFSETTING ( 0x18, "3" )
- PORT_CONFSETTING ( 0x20, "4" )
- PORT_CONFSETTING ( 0x28, "5" )
- PORT_CONFSETTING ( 0x30, "6" )
- PORT_CONFSETTING ( 0x38, "7" )
- PORT_CONFSETTING ( 0x40, "8" )
- PORT_CONFSETTING ( 0x48, "9" )
- PORT_CONFSETTING ( 0x50, "10" )
- PORT_CONFSETTING ( 0x58, "11" )
- PORT_CONFSETTING ( 0x60, "12" )
- PORT_CONFSETTING ( 0x68, "13" )
- PORT_CONFSETTING ( 0x70, "14" )
- PORT_CONFSETTING ( 0x78, "15" )
- PORT_CONFSETTING ( 0x80, "16" )
- PORT_CONFSETTING ( 0x88, "17" )
- PORT_CONFSETTING ( 0x90, "18" )
- PORT_CONFSETTING ( 0x98, "19" )
- PORT_CONFSETTING ( 0xa0, "20" )
- PORT_CONFSETTING ( 0xa8, "21" )
- PORT_CONFSETTING ( 0xb0, "22" )
- PORT_CONFSETTING ( 0xb8, "23" )
- PORT_CONFSETTING ( 0xc0, "24" )
- PORT_CONFSETTING ( 0xc8, "25" )
- PORT_CONFSETTING ( 0xd0, "26" )
- PORT_CONFSETTING ( 0xd8, "27" )
- PORT_CONFSETTING ( 0xe0, "28" )
- PORT_CONFSETTING ( 0xe8, "29" )
- PORT_CONFSETTING ( 0xf0, "30" )
- PORT_CONFSETTING ( 0xf8, "31" )
-
-INPUT_PORTS_END
-
static INPUT_PORTS_START ( to9 )
PORT_INCLUDE ( thom_lightpen )
PORT_INCLUDE ( thom_game_port )
PORT_INCLUDE ( to9_keyboard )
PORT_INCLUDE ( to7_config )
- PORT_INCLUDE ( to9_fconfig )
PORT_INCLUDE ( to7_vconfig )
PORT_INCLUDE ( to7_mconfig )
INPUT_PORTS_END
/* ------------ driver ------------ */
-void thomson_state::to9(machine_config &config)
+void to9_state::to9(machine_config &config)
{
to7(config);
- MCFG_MACHINE_START_OVERRIDE( thomson_state, to9 )
- MCFG_MACHINE_RESET_OVERRIDE( thomson_state, to9 )
+ MCFG_MACHINE_START_OVERRIDE( to9_state, to9 )
+ MCFG_MACHINE_RESET_OVERRIDE( to9_state, to9 )
- m_maincpu->set_addrmap(AS_PROGRAM, &thomson_state::to9_map);
+ m_maincpu->set_addrmap(AS_PROGRAM, &to9_state::to9_map);
- m_pia_sys->readpa_handler().set(FUNC(thomson_state::to9_sys_porta_in));
+ m_pia_sys->readpa_handler().set(FUNC(to9_state::to9_sys_porta_in));
m_pia_sys->readpb_handler().set_constant(0);
- m_pia_sys->writepa_handler().set(FUNC(thomson_state::to9_sys_porta_out));
- m_pia_sys->writepb_handler().set(FUNC(thomson_state::to9_sys_portb_out));
+ m_pia_sys->writepa_handler().set(FUNC(to9_state::to9_sys_porta_out));
+ m_pia_sys->writepb_handler().set(FUNC(to9_state::to9_sys_portb_out));
m_pia_sys->cb2_handler().set_nop();
m_pia_sys->irqa_handler().set_nop();
- m_mc6846->out_port().set(FUNC(thomson_state::to9_timer_port_out));
+ m_mc6846->out_port().set(FUNC(to9_state::to9_timer_port_out));
CENTRONICS(config, m_centronics, centronics_devices, "printer");
- m_centronics->busy_handler().set(FUNC(thomson_state::write_centronics_busy));
+ m_centronics->busy_handler().set(FUNC(to9_state::write_centronics_busy));
/* internal ram */
m_ram->set_default_size("192K").set_extra_options("128K");
}
-COMP( 1985, to9, 0, 0, to9, to9, thomson_state, empty_init, "Thomson", "TO9", MACHINE_IMPERFECT_COLORS )
+COMP( 1985, to9, 0, 0, to9, to9, to9_state, empty_init, "Thomson", "TO9", MACHINE_IMPERFECT_COLORS )
/******************************** TO8 ********************************
@@ -1586,27 +1362,25 @@ The TO8D is simply a TO8 with an integrated 3"1/2 floppy drive.
**********************************************************************/
-void thomson_state::to8_map(address_map &map)
+void to9_state::to8_map(address_map &map)
{
- map(0x0000, 0x3fff).bankr(THOM_CART_BANK).w(FUNC(thomson_state::to8_cartridge_w)); /* 4 * 16 KB */
- map(0x4000, 0x5fff).bankr(THOM_VRAM_BANK).w(FUNC(thomson_state::to770_vram_w));
- map(0x6000, 0x7fff).bankr(TO8_SYS_LO).w(FUNC(thomson_state::to8_sys_lo_w));
- map(0x8000, 0x9fff).bankr(TO8_SYS_HI).w(FUNC(thomson_state::to8_sys_hi_w));
- map(0xa000, 0xbfff).bankr(TO8_DATA_LO).w(FUNC(thomson_state::to8_data_lo_w));
- map(0xc000, 0xdfff).bankr(TO8_DATA_HI).w(FUNC(thomson_state::to8_data_hi_w));
- map(0xe000, 0xe7bf).bankr(THOM_FLOP_BANK); /* 2 * 2 KB */
+ map(0x0000, 0x3fff).bankr(THOM_CART_BANK).w(FUNC(to9_state::to8_cartridge_w)); /* 4 * 16 KB */
+ map(0x4000, 0x5fff).bankr(THOM_VRAM_BANK).w(FUNC(to9_state::to770_vram_w));
+ map(0x6000, 0x7fff).bankr(TO8_SYS_LO).w(FUNC(to9_state::to8_sys_lo_w));
+ map(0x8000, 0x9fff).bankr(TO8_SYS_HI).w(FUNC(to9_state::to8_sys_hi_w));
+ map(0xa000, 0xbfff).bankr(TO8_DATA_LO).w(FUNC(to9_state::to8_data_lo_w));
+ map(0xc000, 0xdfff).bankr(TO8_DATA_HI).w(FUNC(to9_state::to8_data_hi_w));
map(0xe7c0, 0xe7c7).rw(m_mc6846, FUNC(mc6846_device::read), FUNC(mc6846_device::write));
map(0xe7c8, 0xe7cb).rw("pia_0", FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt));
map(0xe7cc, 0xe7cf).rw("pia_1", FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt));
- map(0xe7d0, 0xe7d9).rw(FUNC(thomson_state::to8_floppy_r), FUNC(thomson_state::to8_floppy_w));
- map(0xe7da, 0xe7dd).rw(FUNC(thomson_state::to8_vreg_r), FUNC(thomson_state::to8_vreg_w));
- map(0xe7e4, 0xe7e7).rw(FUNC(thomson_state::to8_gatearray_r), FUNC(thomson_state::to8_gatearray_w));
+ map(0xe7da, 0xe7dd).rw(FUNC(to9_state::to8_vreg_r), FUNC(to9_state::to8_vreg_w));
+ map(0xe7e4, 0xe7e7).rw(FUNC(to9_state::to8_gatearray_r), FUNC(to9_state::to8_gatearray_w));
map(0xe7e8, 0xe7eb).rw("acia", FUNC(mos6551_device::read), FUNC(mos6551_device::write));
-/* map(0xe7f0, 0xe7f7).rw(FUNC(thomson_state::to9_ieee_r), FUNC(thomson_state::to9_ieee_w )); */
- map(0xe7f2, 0xe7f3).rw(FUNC(thomson_state::to7_midi_r), FUNC(thomson_state::to7_midi_w));
+/* map(0xe7f0, 0xe7f7).rw(FUNC(to9_state::to9_ieee_r), FUNC(to9_state::to9_ieee_w )); */
+ map(0xe7f2, 0xe7f3).rw(FUNC(to9_state::to7_midi_r), FUNC(to9_state::to7_midi_w));
map(0xe7f8, 0xe7fb).rw("pia_3", FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt));
- map(0xe7fe, 0xe7ff).rw(FUNC(thomson_state::to7_modem_mea8000_r), FUNC(thomson_state::to7_modem_mea8000_w));
+ map(0xe7fe, 0xe7ff).rw(FUNC(to9_state::to7_modem_mea8000_r), FUNC(to9_state::to7_modem_mea8000_w));
map(0xe800, 0xffff).bankr(TO8_BIOS_BANK); /* 2 * 6 KB */
/* 0x10000 - 0x1ffff: 64 KB external ROM cartridge */
@@ -1648,8 +1422,6 @@ ROM_START ( to8 )
ROM_REGION ( 0x10000, "cartridge", 0 )
ROM_FILL( 0x00000, 0x10000, 0x39 )
-
- ROM_FLOPPY7
ROM_END
ROM_START ( to8d )
@@ -1679,8 +1451,6 @@ ROM_START ( to8d )
ROM_REGION ( 0x10000, "cartridge", 0 )
ROM_FILL( 0x00000, 0x10000, 0x39 )
-
- ROM_FLOPPY7
ROM_END
@@ -1705,7 +1475,6 @@ static INPUT_PORTS_START ( to8 )
PORT_INCLUDE ( thom_game_port )
PORT_INCLUDE ( to9_keyboard )
PORT_INCLUDE ( to8_config )
- PORT_INCLUDE ( to9_fconfig )
PORT_INCLUDE ( to7_vconfig )
PORT_INCLUDE ( to7_mconfig )
INPUT_PORTS_END
@@ -1717,29 +1486,29 @@ INPUT_PORTS_END
/* ------------ driver ------------ */
-void thomson_state::to8(machine_config &config)
+void to9_state::to8(machine_config &config)
{
to7(config);
- MCFG_MACHINE_START_OVERRIDE( thomson_state, to8 )
- MCFG_MACHINE_RESET_OVERRIDE( thomson_state, to8 )
+ MCFG_MACHINE_START_OVERRIDE( to9_state, to8 )
+ MCFG_MACHINE_RESET_OVERRIDE( to9_state, to8 )
- m_maincpu->set_addrmap(AS_PROGRAM, &thomson_state::to8_map);
+ m_maincpu->set_addrmap(AS_PROGRAM, &to9_state::to8_map);
//MC6804(config, "kbdmcu", 11_MHz_XTAL);
- m_pia_sys->readpa_handler().set(FUNC(thomson_state::to8_sys_porta_in));
+ m_pia_sys->readpa_handler().set(FUNC(to9_state::to8_sys_porta_in));
m_pia_sys->readpb_handler().set_constant(0);
- m_pia_sys->writepa_handler().set(FUNC(thomson_state::to9_sys_porta_out));
- m_pia_sys->writepb_handler().set(FUNC(thomson_state::to8_sys_portb_out));
+ m_pia_sys->writepa_handler().set(FUNC(to9_state::to9_sys_porta_out));
+ m_pia_sys->writepb_handler().set(FUNC(to9_state::to8_sys_portb_out));
m_pia_sys->cb2_handler().set_nop();
m_pia_sys->irqa_handler().set_nop();
CENTRONICS(config, m_centronics, centronics_devices, "printer");
- m_centronics->busy_handler().set(FUNC(thomson_state::write_centronics_busy));
+ m_centronics->busy_handler().set(FUNC(to9_state::write_centronics_busy));
- m_mc6846->out_port().set(FUNC(thomson_state::to8_timer_port_out));
- m_mc6846->in_port().set(FUNC(thomson_state::to8_timer_port_in));
- m_mc6846->cp2().set(FUNC(thomson_state::to8_timer_cp2_out));
+ m_mc6846->out_port().set(FUNC(to9_state::to8_timer_port_out));
+ m_mc6846->in_port().set(FUNC(to9_state::to8_timer_port_in));
+ m_mc6846->cp2().set(FUNC(to9_state::to8_timer_cp2_out));
/* internal ram */
m_ram->set_default_size("512K").set_extra_options("256K");
@@ -1750,15 +1519,15 @@ void thomson_state::to8(machine_config &config)
SOFTWARE_LIST(config.replace(), "to7_qd_list").set_compatible("to7_qd");
}
-void thomson_state::to8d(machine_config &config)
+void to9_state::to8d(machine_config &config)
{
to8(config);
}
-COMP( 1986, to8, 0, 0, to8, to8, thomson_state, empty_init, "Thomson", "TO8", 0 )
+COMP( 1986, to8, 0, 0, to8, to8, to9_state, empty_init, "Thomson", "TO8", 0 )
-COMP( 1987, to8d, to8, 0, to8d, to8d, thomson_state, empty_init, "Thomson", "TO8D", 0 )
+COMP( 1987, to8d, to8, 0, to8d, to8d, to9_state, empty_init, "Thomson", "TO8D", 0 )
/******************************** TO9+ *******************************
@@ -1798,28 +1567,26 @@ The differences with the TO8 are:
**********************************************************************/
-void thomson_state::to9p_map(address_map &map)
+void to9_state::to9p_map(address_map &map)
{
- map(0x0000, 0x3fff).bankr(THOM_CART_BANK).w(FUNC(thomson_state::to8_cartridge_w)); /* 4 * 16 KB */
- map(0x4000, 0x5fff).bankr(THOM_VRAM_BANK).w(FUNC(thomson_state::to770_vram_w));
- map(0x6000, 0x7fff).bankr(TO8_SYS_LO).w(FUNC(thomson_state::to8_sys_lo_w));
- map(0x8000, 0x9fff).bankr(TO8_SYS_HI).w(FUNC(thomson_state::to8_sys_hi_w));
- map(0xa000, 0xbfff).bankr(TO8_DATA_LO).w(FUNC(thomson_state::to8_data_lo_w));
- map(0xc000, 0xdfff).bankr(TO8_DATA_HI).w(FUNC(thomson_state::to8_data_hi_w));
- map(0xe000, 0xe7bf).bankr(THOM_FLOP_BANK); /* 2 * 2 KB */
+ map(0x0000, 0x3fff).bankr(THOM_CART_BANK).w(FUNC(to9_state::to8_cartridge_w)); /* 4 * 16 KB */
+ map(0x4000, 0x5fff).bankr(THOM_VRAM_BANK).w(FUNC(to9_state::to770_vram_w));
+ map(0x6000, 0x7fff).bankr(TO8_SYS_LO).w(FUNC(to9_state::to8_sys_lo_w));
+ map(0x8000, 0x9fff).bankr(TO8_SYS_HI).w(FUNC(to9_state::to8_sys_hi_w));
+ map(0xa000, 0xbfff).bankr(TO8_DATA_LO).w(FUNC(to9_state::to8_data_lo_w));
+ map(0xc000, 0xdfff).bankr(TO8_DATA_HI).w(FUNC(to9_state::to8_data_hi_w));
map(0xe7c0, 0xe7c7).rw(m_mc6846, FUNC(mc6846_device::read), FUNC(mc6846_device::write));
map(0xe7c8, 0xe7cb).rw("pia_0", FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt));
map(0xe7cc, 0xe7cf).rw("pia_1", FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt));
- map(0xe7d0, 0xe7d9).rw(FUNC(thomson_state::to8_floppy_r), FUNC(thomson_state::to8_floppy_w));
- map(0xe7da, 0xe7dd).rw(FUNC(thomson_state::to8_vreg_r), FUNC(thomson_state::to8_vreg_w));
- map(0xe7de, 0xe7df).rw(FUNC(thomson_state::to9_kbd_r), FUNC(thomson_state::to9_kbd_w));
- map(0xe7e4, 0xe7e7).rw(FUNC(thomson_state::to8_gatearray_r), FUNC(thomson_state::to8_gatearray_w));
+ map(0xe7da, 0xe7dd).rw(FUNC(to9_state::to8_vreg_r), FUNC(to9_state::to8_vreg_w));
+ map(0xe7de, 0xe7df).rw(FUNC(to9_state::to9_kbd_r), FUNC(to9_state::to9_kbd_w));
+ map(0xe7e4, 0xe7e7).rw(FUNC(to9_state::to8_gatearray_r), FUNC(to9_state::to8_gatearray_w));
map(0xe7e8, 0xe7eb).rw("acia", FUNC(mos6551_device::read), FUNC(mos6551_device::write));
-/* map(0xe7f0, 0xe7f7).rw(FUNC(thomson_state::to9_ieee_r), FUNC(thomson_state::to9_ieee_w )); */
- map(0xe7f2, 0xe7f3).rw(FUNC(thomson_state::to7_midi_r), FUNC(thomson_state::to7_midi_w));
+/* map(0xe7f0, 0xe7f7).rw(FUNC(to9_state::to9_ieee_r), FUNC(to9_state::to9_ieee_w )); */
+ map(0xe7f2, 0xe7f3).rw(FUNC(to9_state::to7_midi_r), FUNC(to9_state::to7_midi_w));
map(0xe7f8, 0xe7fb).rw("pia_3", FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt));
- map(0xe7fe, 0xe7ff).rw(FUNC(thomson_state::to7_modem_mea8000_r), FUNC(thomson_state::to7_modem_mea8000_w));
+ map(0xe7fe, 0xe7ff).rw(FUNC(to9_state::to7_modem_mea8000_r), FUNC(to9_state::to7_modem_mea8000_w));
map(0xe800, 0xffff).bankr(TO8_BIOS_BANK); /* 2 * 6 KB */
/* 0x10000 - 0x1ffff: 64 KB external ROM cartridge */
@@ -1861,8 +1628,6 @@ ROM_START ( to9p )
ROM_REGION ( 0x10000, "cartridge", 0 )
ROM_FILL( 0x00000, 0x10000, 0x39 )
-
- ROM_FLOPPY7
ROM_END
@@ -1873,35 +1638,34 @@ static INPUT_PORTS_START ( to9p )
PORT_INCLUDE ( thom_game_port )
PORT_INCLUDE ( to9_keyboard )
PORT_INCLUDE ( to7_config )
- PORT_INCLUDE ( to9_fconfig )
PORT_INCLUDE ( to7_vconfig )
PORT_INCLUDE ( to7_mconfig )
INPUT_PORTS_END
/* ------------ driver ------------ */
-void thomson_state::to9p(machine_config &config)
+void to9_state::to9p(machine_config &config)
{
to7(config);
- MCFG_MACHINE_START_OVERRIDE( thomson_state, to9p )
- MCFG_MACHINE_RESET_OVERRIDE( thomson_state, to9p )
+ MCFG_MACHINE_START_OVERRIDE( to9_state, to9p )
+ MCFG_MACHINE_RESET_OVERRIDE( to9_state, to9p )
- m_maincpu->set_addrmap(AS_PROGRAM, &thomson_state::to9p_map);
+ m_maincpu->set_addrmap(AS_PROGRAM, &to9_state::to9p_map);
- m_pia_sys->readpa_handler().set(FUNC(thomson_state::to8_sys_porta_in));
+ m_pia_sys->readpa_handler().set(FUNC(to9_state::to8_sys_porta_in));
m_pia_sys->readpb_handler().set_constant(0);
- m_pia_sys->writepa_handler().set(FUNC(thomson_state::to9_sys_porta_out));
- m_pia_sys->writepb_handler().set(FUNC(thomson_state::to8_sys_portb_out));
+ m_pia_sys->writepa_handler().set(FUNC(to9_state::to9_sys_porta_out));
+ m_pia_sys->writepb_handler().set(FUNC(to9_state::to8_sys_portb_out));
m_pia_sys->cb2_handler().set_nop();
m_pia_sys->irqa_handler().set_nop();
m_pia_sys->irqb_handler().set("mainfirq", FUNC(input_merger_device::in_w<1>));
CENTRONICS(config, m_centronics, centronics_devices, "printer");
- m_centronics->busy_handler().set(FUNC(thomson_state::write_centronics_busy));
+ m_centronics->busy_handler().set(FUNC(to9_state::write_centronics_busy));
- m_mc6846->out_port().set(FUNC(thomson_state::to9p_timer_port_out));
- m_mc6846->in_port().set(FUNC(thomson_state::to9p_timer_port_in));
- m_mc6846->cp2().set(FUNC(thomson_state::to8_timer_cp2_out));
+ m_mc6846->out_port().set(FUNC(to9_state::to9p_timer_port_out));
+ m_mc6846->in_port().set(FUNC(to9_state::to9p_timer_port_in));
+ m_mc6846->cp2().set(FUNC(to9_state::to8_timer_cp2_out));
/* internal ram */
m_ram->set_default_size("512K");
@@ -1912,7 +1676,7 @@ void thomson_state::to9p(machine_config &config)
SOFTWARE_LIST(config.replace(), "to7_qd_list").set_compatible("to7_qd");
}
-COMP( 1986, to9p, 0, 0, to9p, to9p, thomson_state, empty_init, "Thomson", "TO9+", 0 )
+COMP( 1986, to9p, 0, 0, to9p, to9p, to9_state, empty_init, "Thomson", "TO9+", 0 )
@@ -1974,27 +1738,25 @@ a PC XT.
**********************************************************************/
-void thomson_state::mo6_map(address_map &map)
+void mo6_state::mo6_map(address_map &map)
{
- map(0x0000, 0x1fff).bankr(THOM_VRAM_BANK).w(FUNC(thomson_state::to770_vram_w));
- map(0x2000, 0x3fff).bankr(TO8_SYS_LO).w(FUNC(thomson_state::to8_sys_lo_w));
- map(0x4000, 0x5fff).bankr(TO8_SYS_HI).w(FUNC(thomson_state::to8_sys_hi_w));
- map(0x6000, 0x7fff).bankr(TO8_DATA_LO).w(FUNC(thomson_state::to8_data_lo_w));
- map(0x8000, 0x9fff).bankr(TO8_DATA_HI).w(FUNC(thomson_state::to8_data_hi_w));
- map(0xa000, 0xa7bf).bankr(THOM_FLOP_BANK);
+ map(0x0000, 0x1fff).bankr(THOM_VRAM_BANK).w(FUNC(mo6_state::to770_vram_w));
+ map(0x2000, 0x3fff).bankr(TO8_SYS_LO).w(FUNC(mo6_state::to8_sys_lo_w));
+ map(0x4000, 0x5fff).bankr(TO8_SYS_HI).w(FUNC(mo6_state::to8_sys_hi_w));
+ map(0x6000, 0x7fff).bankr(TO8_DATA_LO).w(FUNC(mo6_state::to8_data_lo_w));
+ map(0x8000, 0x9fff).bankr(TO8_DATA_HI).w(FUNC(mo6_state::to8_data_hi_w));
map(0xa7c0, 0xa7c3).rw("pia_0", FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt));
- map(0xa7cb, 0xa7cb).w(FUNC(thomson_state::mo6_ext_w));
+ map(0xa7cb, 0xa7cb).w(FUNC(mo6_state::mo6_ext_w));
map(0xa7cc, 0xa7cf).rw("pia_1", FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt));
- map(0xa7d0, 0xa7d9).rw(FUNC(thomson_state::to7_floppy_r), FUNC(thomson_state::to7_floppy_w));
- map(0xa7da, 0xa7dd).rw(FUNC(thomson_state::mo6_vreg_r), FUNC(thomson_state::mo6_vreg_w));
- map(0xa7e4, 0xa7e7).rw(FUNC(thomson_state::mo6_gatearray_r), FUNC(thomson_state::mo6_gatearray_w));
+ map(0xa7da, 0xa7dd).rw(FUNC(mo6_state::mo6_vreg_r), FUNC(mo6_state::mo6_vreg_w));
+ map(0xa7e4, 0xa7e7).rw(FUNC(mo6_state::mo6_gatearray_r), FUNC(mo6_state::mo6_gatearray_w));
map(0xa7e8, 0xa7eb).rw("acia", FUNC(mos6551_device::read), FUNC(mos6551_device::write));
-/* map(0xa7f0, 0xa7f7).rw(FUNC(thomson_state::to9_ieee_r), FUNC(homson_state::to9_ieee_w));*/
- map(0xa7f2, 0xa7f3).rw(FUNC(thomson_state::to7_midi_r), FUNC(thomson_state::to7_midi_w));
+/* map(0xa7f0, 0xa7f7).rw(FUNC(mo6_state::to9_ieee_r), FUNC(homson_state::to9_ieee_w));*/
+ map(0xa7f2, 0xa7f3).rw(FUNC(mo6_state::to7_midi_r), FUNC(mo6_state::to7_midi_w));
map(0xa7fe, 0xa7ff).rw(m_mea8000, FUNC(mea8000_device::read), FUNC(mea8000_device::write));
- map(0xb000, 0xbfff).bankr(MO6_CART_LO).w(FUNC(thomson_state::mo6_cartridge_w));
- map(0xc000, 0xefff).bankr(MO6_CART_HI).w(FUNC(thomson_state::mo6_cartridge_w));
+ map(0xb000, 0xbfff).bankr(MO6_CART_LO).w(FUNC(mo6_state::mo6_cartridge_w));
+ map(0xc000, 0xefff).bankr(MO6_CART_HI).w(FUNC(mo6_state::mo6_cartridge_w));
map(0xf000, 0xffff).bankr(TO8_BIOS_BANK);
/* 0x10000 - 0x1ffff: 64 KB external ROM cartridge */
@@ -2035,8 +1797,6 @@ ROM_START ( mo6 )
ROM_REGION ( 0x10000, "cartridge", 0 )
ROM_FILL ( 0x00000, 0x10000, 0x39 )
-
- ROM_FLOPPY5
ROM_END
ROM_START ( pro128 )
@@ -2066,8 +1826,6 @@ ROM_START ( pro128 )
ROM_REGION ( 0x10000, "cartridge", 0 )
ROM_FILL ( 0x00000, 0x10000, 0x39 )
-
- ROM_FLOPPY5
ROM_END
@@ -2211,7 +1969,6 @@ static INPUT_PORTS_START ( mo6 )
PORT_INCLUDE ( thom_game_port )
PORT_INCLUDE ( mo6_keyboard )
PORT_INCLUDE ( to7_config )
- PORT_INCLUDE ( to7_fconfig )
PORT_INCLUDE ( to7_vconfig )
INPUT_PORTS_END
@@ -2220,42 +1977,41 @@ static INPUT_PORTS_START ( pro128 )
PORT_INCLUDE ( thom_game_port )
PORT_INCLUDE ( pro128_keyboard )
PORT_INCLUDE ( to7_config )
- PORT_INCLUDE ( to7_fconfig )
PORT_INCLUDE ( to7_vconfig )
INPUT_PORTS_END
/* ------------ driver ------------ */
-void thomson_state::mo6(machine_config &config)
+void mo6_state::mo6(machine_config &config)
{
- to7_base(config);
- MCFG_MACHINE_START_OVERRIDE( thomson_state, mo6 )
- MCFG_MACHINE_RESET_OVERRIDE( thomson_state, mo6 )
+ to7_base(config, true);
+ MCFG_MACHINE_START_OVERRIDE( mo6_state, mo6 )
+ MCFG_MACHINE_RESET_OVERRIDE( mo6_state, mo6 )
- m_maincpu->set_addrmap(AS_PROGRAM, &thomson_state::mo6_map);
+ m_maincpu->set_addrmap(AS_PROGRAM, &mo6_state::mo6_map);
m_cassette->set_formats(mo5_cassette_formats);
m_cassette->set_interface("mo_cass");
- m_pia_sys->readpa_handler().set(FUNC(thomson_state::mo6_sys_porta_in));
- m_pia_sys->readpb_handler().set(FUNC(thomson_state::mo6_sys_portb_in));
- m_pia_sys->writepa_handler().set(FUNC(thomson_state::mo6_sys_porta_out));
+ m_pia_sys->readpa_handler().set(FUNC(mo6_state::mo6_sys_porta_in));
+ m_pia_sys->readpb_handler().set(FUNC(mo6_state::mo6_sys_portb_in));
+ m_pia_sys->writepa_handler().set(FUNC(mo6_state::mo6_sys_porta_out));
m_pia_sys->writepb_handler().set("buzzer", FUNC(dac_bit_interface::data_w));
- m_pia_sys->ca2_handler().set(FUNC(thomson_state::mo5_set_cassette_motor));
- m_pia_sys->cb2_handler().set(FUNC(thomson_state::mo6_sys_cb2_out));
+ m_pia_sys->ca2_handler().set(FUNC(mo6_state::mo5_set_cassette_motor));
+ m_pia_sys->cb2_handler().set(FUNC(mo6_state::mo6_sys_cb2_out));
m_pia_sys->irqb_handler().set("mainirq", FUNC(input_merger_device::in_w<1>)); // differs from TO
- m_pia_game->writepa_handler().set(FUNC(thomson_state::mo6_game_porta_out));
- m_pia_game->cb2_handler().set(FUNC(thomson_state::mo6_game_cb2_out));
+ m_pia_game->writepa_handler().set(FUNC(mo6_state::mo6_game_porta_out));
+ m_pia_game->cb2_handler().set(FUNC(mo6_state::mo6_game_cb2_out));
CENTRONICS(config, m_centronics, centronics_devices, "printer");
- m_centronics->busy_handler().set(FUNC(thomson_state::write_centronics_busy));
+ m_centronics->busy_handler().set(FUNC(mo6_state::write_centronics_busy));
OUTPUT_LATCH(config, m_cent_data_out);
m_centronics->set_output_latch(*m_cent_data_out);
- GENERIC_CARTSLOT(config.replace(), "cartslot", generic_plain_slot, "mo_cart", "m5,rom").set_device_load(FUNC(thomson_state::mo5_cartridge));
+ GENERIC_CARTSLOT(config.replace(), "cartslot", generic_plain_slot, "mo_cart", "m5,rom").set_device_load(FUNC(mo6_state::mo5_cartridge));
/* internal ram */
m_ram->set_default_size("128K");
@@ -2274,7 +2030,7 @@ void thomson_state::mo6(machine_config &config)
SOFTWARE_LIST(config, "mo5_qd_list").set_compatible("mo5_qd");
}
-void thomson_state::pro128(machine_config &config)
+void mo6_state::pro128(machine_config &config)
{
mo6(config);
config.device_remove("mo6_cass_list");
@@ -2290,9 +2046,9 @@ void thomson_state::pro128(machine_config &config)
SOFTWARE_LIST(config, "p128_flop_list").set_original("pro128_flop");
}
-COMP( 1986, mo6, 0, 0, mo6, mo6, thomson_state, empty_init, "Thomson", "MO6", 0 )
+COMP( 1986, mo6, 0, 0, mo6, mo6, mo6_state, empty_init, "Thomson", "MO6", 0 )
-COMP( 1986, pro128, mo6, 0, pro128, pro128, thomson_state, empty_init, "Olivetti / Thomson", "Prodest PC 128", 0 )
+COMP( 1986, pro128, mo6, 0, pro128, pro128, mo6_state, empty_init, "Olivetti / Thomson", "Prodest PC 128", 0 )
@@ -2325,31 +2081,31 @@ Here are the differences between the MO6 and MO5NR:
**********************************************************************/
-void thomson_state::mo5nr_map(address_map &map)
+void mo5nr_state::mo5nr_map(address_map &map)
{
- map(0x0000, 0x1fff).bankr(THOM_VRAM_BANK).w(FUNC(thomson_state::to770_vram_w));
- map(0x2000, 0x3fff).bankr(TO8_SYS_LO).w(FUNC(thomson_state::to8_sys_lo_w));
- map(0x4000, 0x5fff).bankr(TO8_SYS_HI).w(FUNC(thomson_state::to8_sys_hi_w));
- map(0x6000, 0x7fff).bankr(TO8_DATA_LO).w(FUNC(thomson_state::to8_data_lo_w));
- map(0x8000, 0x9fff).bankr(TO8_DATA_HI).w(FUNC(thomson_state::to8_data_hi_w));
- map(0xa000, 0xa7bf).bankr(THOM_FLOP_BANK);
+ map(0x0000, 0x1fff).bankr(THOM_VRAM_BANK).w(FUNC(mo5nr_state::to770_vram_w));
+ map(0x2000, 0x3fff).bankr(TO8_SYS_LO).w(FUNC(mo5nr_state::to8_sys_lo_w));
+ map(0x4000, 0x5fff).bankr(TO8_SYS_HI).w(FUNC(mo5nr_state::to8_sys_hi_w));
+ map(0x6000, 0x7fff).bankr(TO8_DATA_LO).w(FUNC(mo5nr_state::to8_data_lo_w));
+ map(0x8000, 0x9fff).bankr(TO8_DATA_HI).w(FUNC(mo5nr_state::to8_data_hi_w));
+ map(0xa000, 0xa7ff).view(m_extension_view);
map(0xa7c0, 0xa7c3).rw("pia_0", FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt));
- map(0xa7cb, 0xa7cb).w(FUNC(thomson_state::mo6_ext_w));
+ map(0xa7cb, 0xa7cb).w(FUNC(mo5nr_state::mo6_ext_w));
map(0xa7cc, 0xa7cf).rw("pia_1", FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt));
- map(0xa7d0, 0xa7d9).rw(FUNC(thomson_state::mo5nr_net_r), FUNC(thomson_state::mo5nr_net_w));
- map(0xa7da, 0xa7dd).rw(FUNC(thomson_state::mo6_vreg_r), FUNC(thomson_state::mo6_vreg_w));
+ m_extension_view[1](0xa7d8, 0xa7d9).r(FUNC(mo5nr_state::id_r));
+ map(0xa7da, 0xa7dd).rw(FUNC(mo5nr_state::mo6_vreg_r), FUNC(mo5nr_state::mo6_vreg_w));
map(0xa7e1, 0xa7e1).r("cent_data_in", FUNC(input_buffer_device::read));
map(0xa7e1, 0xa7e1).w(m_cent_data_out, FUNC(output_latch_device::write));
- map(0xa7e3, 0xa7e3).rw(FUNC(thomson_state::mo5nr_prn_r), FUNC(thomson_state::mo5nr_prn_w));
- map(0xa7e4, 0xa7e7).rw(FUNC(thomson_state::mo6_gatearray_r), FUNC(thomson_state::mo6_gatearray_w));
+ map(0xa7e3, 0xa7e3).rw(FUNC(mo5nr_state::mo5nr_prn_r), FUNC(mo5nr_state::mo5nr_prn_w));
+ map(0xa7e4, 0xa7e7).rw(FUNC(mo5nr_state::mo6_gatearray_r), FUNC(mo5nr_state::mo6_gatearray_w));
map(0xa7e8, 0xa7eb).rw("acia", FUNC(mos6551_device::read), FUNC(mos6551_device::write));
-/* map(0xa7f0, 0xa7f7).rw(FUNC(thomson_state::to9_ieee_r), FUNC(homson_state::to9_ieee_w));*/
- map(0xa7f2, 0xa7f3).rw(FUNC(thomson_state::to7_midi_r), FUNC(thomson_state::to7_midi_w));
+/* map(0xa7f0, 0xa7f7).rw(FUNC(mo5nr_state::to9_ieee_r), FUNC(homson_state::to9_ieee_w));*/
+ map(0xa7f2, 0xa7f3).rw(FUNC(mo5nr_state::to7_midi_r), FUNC(mo5nr_state::to7_midi_w));
map(0xa7f8, 0xa7fb).rw("pia_3", FUNC(pia6821_device::read_alt), FUNC(pia6821_device::write_alt));
map(0xa7fe, 0xa7ff).rw(m_mea8000, FUNC(mea8000_device::read), FUNC(mea8000_device::write));
- map(0xb000, 0xbfff).bankr(MO6_CART_LO).w(FUNC(thomson_state::mo6_cartridge_w));
- map(0xc000, 0xefff).bankr(MO6_CART_HI).w(FUNC(thomson_state::mo6_cartridge_w));
+ map(0xb000, 0xbfff).bankr(MO6_CART_LO).w(FUNC(mo5nr_state::mo6_cartridge_w));
+ map(0xc000, 0xefff).bankr(MO6_CART_HI).w(FUNC(mo5nr_state::mo6_cartridge_w));
map(0xf000, 0xffff).bankr(TO8_BIOS_BANK);
/* 0x10000 - 0x1ffff: 64 KB external ROM cartridge */
@@ -2390,8 +2146,6 @@ ROM_START ( mo5nr )
ROM_REGION ( 0x10000, "cartridge", 0 )
ROM_FILL ( 0x00000, 0x10000, 0x39 ) /* TODO: network ROM */
-
- ROM_FLOPPY5
ROM_END
@@ -2485,44 +2239,84 @@ static INPUT_PORTS_START ( mo5nr )
PORT_INCLUDE ( thom_game_port )
PORT_INCLUDE ( mo5nr_keyboard )
PORT_INCLUDE ( to7_config )
- PORT_INCLUDE ( to7_fconfig )
PORT_INCLUDE ( to7_vconfig )
+
+ PORT_START ( "nanoreseau_config" )
+ PORT_DIPNAME(0x01, 0x01, "Extension selection") PORT_DIPLOCATION("SW03:1")
+ PORT_DIPSETTING(0x00, "Extension port")
+ PORT_DIPSETTING(0x01, "Internal networking")
+
+ PORT_DIPNAME(0x3e, 0x02, "Network ID") PORT_DIPLOCATION("SW03:2,3,4,5,6")
+ PORT_DIPSETTING(0x00, "0 (Master)")
+ PORT_DIPSETTING(0x02, "1")
+ PORT_DIPSETTING(0x04, "2")
+ PORT_DIPSETTING(0x06, "3")
+ PORT_DIPSETTING(0x08, "4")
+ PORT_DIPSETTING(0x0a, "5")
+ PORT_DIPSETTING(0x0c, "6")
+ PORT_DIPSETTING(0x0e, "7")
+ PORT_DIPSETTING(0x10, "8")
+ PORT_DIPSETTING(0x12, "9")
+ PORT_DIPSETTING(0x14, "10")
+ PORT_DIPSETTING(0x16, "11")
+ PORT_DIPSETTING(0x18, "12")
+ PORT_DIPSETTING(0x1a, "13")
+ PORT_DIPSETTING(0x1c, "14")
+ PORT_DIPSETTING(0x1e, "15")
+ PORT_DIPSETTING(0x20, "16")
+ PORT_DIPSETTING(0x22, "17")
+ PORT_DIPSETTING(0x24, "18")
+ PORT_DIPSETTING(0x26, "19")
+ PORT_DIPSETTING(0x28, "20")
+ PORT_DIPSETTING(0x2a, "21")
+ PORT_DIPSETTING(0x2c, "22")
+ PORT_DIPSETTING(0x2e, "23")
+ PORT_DIPSETTING(0x30, "24")
+ PORT_DIPSETTING(0x32, "25")
+ PORT_DIPSETTING(0x34, "26")
+ PORT_DIPSETTING(0x36, "27")
+ PORT_DIPSETTING(0x38, "28")
+ PORT_DIPSETTING(0x3a, "29")
+ PORT_DIPSETTING(0x3c, "30")
+ PORT_DIPSETTING(0x3e, "31")
INPUT_PORTS_END
/* ------------ driver ------------ */
-void thomson_state::mo5nr(machine_config &config)
+void mo5nr_state::mo5nr(machine_config &config)
{
- to7_base(config);
- MCFG_MACHINE_START_OVERRIDE( thomson_state, mo5nr )
- MCFG_MACHINE_RESET_OVERRIDE( thomson_state, mo5nr )
+ to7_base(config, true);
+ MCFG_MACHINE_START_OVERRIDE( mo5nr_state, mo5nr )
+ MCFG_MACHINE_RESET_OVERRIDE( mo5nr_state, mo5nr )
- m_maincpu->set_addrmap(AS_PROGRAM, &thomson_state::mo5nr_map);
+ m_maincpu->set_addrmap(AS_PROGRAM, &mo5nr_state::mo5nr_map);
m_cassette->set_formats(mo5_cassette_formats);
m_cassette->set_interface("mo_cass");
- m_pia_sys->readpa_handler().set(FUNC(thomson_state::mo6_sys_porta_in));
- m_pia_sys->readpb_handler().set(FUNC(thomson_state::mo5nr_sys_portb_in));
- m_pia_sys->writepa_handler().set(FUNC(thomson_state::mo5nr_sys_porta_out));
+ m_pia_sys->readpa_handler().set(FUNC(mo5nr_state::mo6_sys_porta_in));
+ m_pia_sys->readpb_handler().set(FUNC(mo5nr_state::mo5nr_sys_portb_in));
+ m_pia_sys->writepa_handler().set(FUNC(mo5nr_state::mo5nr_sys_porta_out));
m_pia_sys->writepb_handler().set("buzzer", FUNC(dac_bit_interface::data_w));
- m_pia_sys->ca2_handler().set(FUNC(thomson_state::mo5_set_cassette_motor));
- m_pia_sys->cb2_handler().set(FUNC(thomson_state::mo6_sys_cb2_out));
+ m_pia_sys->ca2_handler().set(FUNC(mo5nr_state::mo5_set_cassette_motor));
+ m_pia_sys->cb2_handler().set(FUNC(mo5nr_state::mo6_sys_cb2_out));
m_pia_sys->irqb_handler().set("mainirq", FUNC(input_merger_device::in_w<1>)); // differs from TO
- m_pia_game->writepa_handler().set(FUNC(thomson_state::mo6_game_porta_out));
+ m_pia_game->writepa_handler().set(FUNC(mo5nr_state::mo6_game_porta_out));
CENTRONICS(config, m_centronics, centronics_devices, "printer");
m_centronics->set_data_input_buffer("cent_data_in");
- m_centronics->busy_handler().set(FUNC(thomson_state::write_centronics_busy));
+ m_centronics->busy_handler().set(FUNC(mo5nr_state::write_centronics_busy));
INPUT_BUFFER(config, "cent_data_in");
OUTPUT_LATCH(config, m_cent_data_out);
m_centronics->set_output_latch(*m_cent_data_out);
- GENERIC_CARTSLOT(config.replace(), "cartslot", generic_plain_slot, "mo_cart", "m5,rom").set_device_load(FUNC(thomson_state::mo5_cartridge));
+ GENERIC_CARTSLOT(config.replace(), "cartslot", generic_plain_slot, "mo_cart", "m5,rom").set_device_load(FUNC(mo5nr_state::mo5_cartridge));
+
+ NANORESEAU_MO(config, m_nanoreseau, 0, true);
/* internal ram */
m_ram->set_default_size("128K");
@@ -2541,4 +2335,4 @@ void thomson_state::mo5nr(machine_config &config)
SOFTWARE_LIST(config, "mo5_qd_list").set_compatible("mo5_qd");
}
-COMP( 1986, mo5nr, 0, 0, mo5nr, mo5nr, thomson_state, empty_init, "Thomson", "MO5 NR", 0 )
+COMP( 1986, mo5nr, 0, 0, mo5nr, mo5nr, mo5nr_state, empty_init, "Thomson", "MO5 NR", 0 )
diff --git a/src/mame/includes/thomson.h b/src/mame/includes/thomson.h
index 9541dd12e4a..2e55288714b 100644
--- a/src/mame/includes/thomson.h
+++ b/src/mame/includes/thomson.h
@@ -17,20 +17,18 @@
#include "formats/thom_cas.h"
#include "formats/thom_dsk.h"
#include "imagedev/cassette.h"
-#include "imagedev/floppy.h"
#include "machine/6821pia.h"
#include "machine/6850acia.h"
#include "machine/input_merger.h"
#include "machine/mc6843.h"
#include "machine/mc6846.h"
#include "machine/mc6846.h"
-#include "machine/mc6854.h"
#include "machine/mos6551.h"
#include "machine/ram.h"
-#include "machine/thomflop.h"
-#include "machine/wd_fdc.h"
#include "sound/dac.h"
#include "sound/mea8000.h"
+#include "bus/thomson/extension.h"
+#include "bus/thomson/nanoreseau.h"
#include "bus/centronics/ctronics.h"
#include "bus/generic/slot.h"
@@ -55,7 +53,6 @@
/* bank-switching */
#define THOM_CART_BANK "bank2" /* cartridge ROM */
#define THOM_RAM_BANK "bank3" /* data RAM */
-#define THOM_FLOP_BANK "bank4" /* external floppy controller ROM */
#define THOM_BASE_BANK "bank5" /* system RAM */
/* bank-switching */
@@ -104,7 +101,6 @@ class thomson_state : public driver_device
public:
thomson_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
- m_mc6854(*this, "mc6854"),
m_maincpu(*this, "maincpu"),
m_cassette(*this, "cassette"),
m_dac(*this, "dac"),
@@ -117,10 +113,10 @@ public:
m_ram(*this, RAM_TAG),
m_mc6846(*this, "mc6846"),
m_mc6843(*this, "mc6843"),
- m_wd2793_fdc(*this, "wd2793"),
m_screen(*this, "screen"),
m_mainirq(*this, "mainirq"),
m_mainfirq(*this, "mainfirq"),
+ m_extension(*this, "extension"),
m_io_game_port_directions(*this, "game_port_directions"),
m_io_game_port_buttons(*this, "game_port_buttons"),
m_io_mouse_x(*this, "mouse_x"),
@@ -132,54 +128,30 @@ public:
m_io_config(*this, "config"),
m_io_vconfig(*this, "vconfig"),
m_io_mconfig(*this, "mconfig"),
- m_io_fconfig(*this, "fconfig"),
m_io_keyboard(*this, "keyboard.%u", 0),
m_vrambank(*this, THOM_VRAM_BANK),
m_cartbank(*this, THOM_CART_BANK),
m_rambank(*this, THOM_RAM_BANK),
- m_flopbank(*this, THOM_FLOP_BANK),
m_basebank(*this, THOM_BASE_BANK),
- m_syslobank(*this, TO8_SYS_LO),
- m_syshibank(*this, TO8_SYS_HI),
- m_datalobank(*this, TO8_DATA_LO),
- m_datahibank(*this, TO8_DATA_HI),
- m_biosbank(*this, TO8_BIOS_BANK),
- m_cartlobank(*this, MO6_CART_LO),
- m_carthibank(*this, MO6_CART_HI),
m_cart_rom(*this, "cartridge"),
- m_to7qdd(*this, "to7qdd"),
- m_thmfc(*this, "thmfc"),
- m_floppy_led(*this, "floppy"),
- m_floppy_image(*this, "floppy%u", 0U),
m_caps_led(*this, "led0")
{
}
- void to9(machine_config &config);
- void to7_base(machine_config &config);
+ void to7_base(machine_config &config, bool is_mo);
void to7(machine_config &config);
- void mo5e(machine_config &config);
void to770a(machine_config &config);
void t9000(machine_config &config);
- void to8(machine_config &config);
- void pro128(machine_config &config);
- void mo6(machine_config &config);
- void mo5(machine_config &config);
- void to9p(machine_config &config);
- void mo5nr(machine_config &config);
void to770(machine_config &config);
- void to8d(machine_config &config);
void to770_scandraw_16( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
void mo5_scandraw_16( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
void mo5alt_scandraw_16( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
- void to9_scandraw_16( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
void bitmap4_scandraw_16( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
void bitmap4alt_scandraw_16( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
void bitmap4althalf_scandraw_16( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
void bitmap16_scandraw_16( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
void mode80_scandraw_16( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
- void mode80_to9_scandraw_16( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
void page1_scandraw_16( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
void page2_scandraw_16( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
void overlay_scandraw_16( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
@@ -189,31 +161,31 @@ public:
void to770_scandraw_8( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
void mo5_scandraw_8( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
void mo5alt_scandraw_8( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
- void to9_scandraw_8( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
void bitmap4_scandraw_8( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
void bitmap4alt_scandraw_8( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
void bitmap4althalf_scandraw_8( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
void bitmap16_scandraw_8( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
void mode80_scandraw_8( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
- void mode80_to9_scandraw_8( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
void page1_scandraw_8( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
void page2_scandraw_8( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
void overlay_scandraw_8( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
void overlayhalf_scandraw_8( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
void overlay3_scandraw_8( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
void bitmap16alt_scandraw_8( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
+ void to9_scandraw_16( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
+ void mode80_to9_scandraw_16( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
+ void to9_scandraw_8( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
+ void mode80_to9_scandraw_8( uint8_t* vram, uint16_t* dst, uint16_t* pal, int org, int len );
protected:
- virtual void video_start() override;
+ emu_timer* m_mo5_periodic_timer;
+ uint8_t m_mo5_reg_cart; /* 0xa7cb bank switch */
-private:
- static void cd90_640_formats(format_registration &fr);
+ virtual void video_start() override;
DECLARE_DEVICE_IMAGE_LOAD_MEMBER( to7_cartridge );
- DECLARE_DEVICE_IMAGE_LOAD_MEMBER( mo5_cartridge );
DECLARE_WRITE_LINE_MEMBER( to7_set_cassette_motor );
- DECLARE_WRITE_LINE_MEMBER( mo5_set_cassette_motor );
DECLARE_WRITE_LINE_MEMBER( thom_dev_irq_0 );
void to7_cartridge_w(offs_t offset, uint8_t data);
uint8_t to7_cartridge_r(offs_t offset);
@@ -249,102 +221,12 @@ private:
DECLARE_MACHINE_RESET( to770 );
DECLARE_MACHINE_START( to770 );
void to7_lightpen_cb( int step );
- void mo5_lightpen_cb( int step );
- TIMER_CALLBACK_MEMBER( mo5_periodic_cb );
- void mo5_sys_porta_out(uint8_t data);
- uint8_t mo5_sys_porta_in();
- uint8_t mo5_sys_portb_in();
- uint8_t mo5_gatearray_r(offs_t offset);
- void mo5_gatearray_w(offs_t offset, uint8_t data);
- void mo5_update_cart_bank_postload();
- void mo5_cartridge_w(offs_t offset, uint8_t data);
- uint8_t mo5_cartridge_r(offs_t offset);
- void mo5_ext_w(uint8_t data);
- DECLARE_MACHINE_RESET( mo5 );
- DECLARE_MACHINE_START( mo5 );
- void to9_ieee_w(offs_t offset, uint8_t data);
- uint8_t to9_ieee_r(offs_t offset);
- uint8_t to9_gatearray_r(offs_t offset);
- void to9_gatearray_w(offs_t offset, uint8_t data);
- uint8_t to9_vreg_r(offs_t offset);
- void to9_vreg_w(offs_t offset, uint8_t data);
- void to9_update_cart_bank_postload();
- void to9_cartridge_w(offs_t offset, uint8_t data);
- uint8_t to9_cartridge_r(offs_t offset);
- void to9_update_ram_bank_postload();
- uint8_t to9_kbd_r(offs_t offset);
- void to9_kbd_w(offs_t offset, uint8_t data);
- TIMER_CALLBACK_MEMBER( to9_kbd_timer_cb );
- uint8_t to9_sys_porta_in();
- void to9_sys_porta_out(uint8_t data);
- void to9_sys_portb_out(uint8_t data);
- void to9_timer_port_out(uint8_t data);
- DECLARE_MACHINE_RESET( to9 );
- DECLARE_MACHINE_START( to9 );
- TIMER_CALLBACK_MEMBER( to8_kbd_timer_cb );
- void to8_update_floppy_bank_postload();
- void to8_update_ram_bank_postload();
- void to8_update_cart_bank_postload();
- void to8_cartridge_w(offs_t offset, uint8_t data);
- uint8_t to8_cartridge_r(offs_t offset);
- uint8_t to8_floppy_r(offs_t offset);
- void to8_floppy_w(offs_t offset, uint8_t data);
- uint8_t to8_gatearray_r(offs_t offset);
- void to8_gatearray_w(offs_t offset, uint8_t data);
- uint8_t to8_vreg_r(offs_t offset);
- void to8_vreg_w(offs_t offset, uint8_t data);
- uint8_t to8_sys_porta_in();
- void to8_sys_portb_out(uint8_t data);
- uint8_t to8_timer_port_in();
- void to8_timer_port_out(uint8_t data);
- DECLARE_WRITE_LINE_MEMBER( to8_timer_cp2_out );
- void to8_lightpen_cb( int step );
- DECLARE_MACHINE_RESET( to8 );
- DECLARE_MACHINE_START( to8 );
- uint8_t to9p_timer_port_in();
- void to9p_timer_port_out(uint8_t data);
- DECLARE_MACHINE_RESET( to9p );
- DECLARE_MACHINE_START( to9p );
- void mo6_update_ram_bank_postload();
- void mo6_update_cart_bank_postload();
- void mo6_cartridge_w(offs_t offset, uint8_t data);
- uint8_t mo6_cartridge_r(offs_t offset);
- void mo6_ext_w(uint8_t data);
- DECLARE_WRITE_LINE_MEMBER( mo6_centronics_busy );
- void mo6_game_porta_out(uint8_t data);
- DECLARE_WRITE_LINE_MEMBER( mo6_game_cb2_out );
- TIMER_CALLBACK_MEMBER( mo6_game_update_cb );
- uint8_t mo6_sys_porta_in();
- uint8_t mo6_sys_portb_in();
- void mo6_sys_porta_out(uint8_t data);
- DECLARE_WRITE_LINE_MEMBER( mo6_sys_cb2_out );
- uint8_t mo6_gatearray_r(offs_t offset);
- void mo6_gatearray_w(offs_t offset, uint8_t data);
- uint8_t mo6_vreg_r(offs_t offset);
- void mo6_vreg_w(offs_t offset, uint8_t data);
- DECLARE_MACHINE_RESET( mo6 );
- DECLARE_MACHINE_START( mo6 );
- uint8_t mo5nr_net_r(offs_t offset);
- void mo5nr_net_w(offs_t offset, uint8_t data);
- uint8_t mo5nr_prn_r();
- void mo5nr_prn_w(uint8_t data);
- uint8_t mo5nr_sys_portb_in();
- void mo5nr_sys_porta_out(uint8_t data);
- DECLARE_MACHINE_RESET( mo5nr );
- DECLARE_MACHINE_START( mo5nr );
TIMER_CALLBACK_MEMBER( thom_lightpen_step );
TIMER_CALLBACK_MEMBER( thom_scanline_start );
uint32_t screen_update_thom(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void to7_vram_w(offs_t offset, uint8_t data);
void to770_vram_w(offs_t offset, uint8_t data);
- void to8_sys_lo_w(offs_t offset, uint8_t data);
- void to8_sys_hi_w(offs_t offset, uint8_t data);
- void to8_data_lo_w(offs_t offset, uint8_t data);
- void to8_data_hi_w(offs_t offset, uint8_t data);
- void to8_vcart_w(offs_t offset, uint8_t data);
- void mo6_vcart_lo_w(offs_t offset, uint8_t data);
- void mo6_vcart_hi_w(offs_t offset, uint8_t data);
TIMER_CALLBACK_MEMBER( thom_set_init );
DECLARE_WRITE_LINE_MEMBER(thom_vblank);
@@ -357,37 +239,13 @@ private:
TIMER_CALLBACK_MEMBER( ans3 );
TIMER_CALLBACK_MEMBER( ans2 );
TIMER_CALLBACK_MEMBER( ans );
- uint8_t to7_network_r(offs_t offset);
- void to7_network_w(offs_t offset, uint8_t data);
- uint8_t to7_floppy_r(offs_t offset);
- void to7_floppy_w(offs_t offset, uint8_t data);
- uint8_t to9_floppy_r(offs_t offset);
- void to9_floppy_w(offs_t offset, uint8_t data);
- WRITE_LINE_MEMBER( fdc_index_0_w);
- WRITE_LINE_MEMBER( fdc_index_1_w);
- WRITE_LINE_MEMBER( fdc_index_2_w);
- WRITE_LINE_MEMBER( fdc_index_3_w);
- void thomson_index_callback(int index, int state);
void thom_palette(palette_device &palette);
- void mo5_palette(palette_device &palette);
-
- optional_device<mc6854_device> m_mc6854;
-
- DECLARE_WRITE_LINE_MEMBER(write_centronics_busy);
int m_centronics_busy;
int m_centronics_perror;
- void to7_network_got_frame(uint8_t *data, int length);
-
- void mo5_map(address_map &map);
- void mo5nr_map(address_map &map);
- void mo6_map(address_map &map);
void to7_map(address_map &map);
void to770_map(address_map &map);
- void to8_map(address_map &map);
- void to9_map(address_map &map);
- void to9p_map(address_map &map);
required_device<cpu_device> m_maincpu;
required_device<cassette_image_device> m_cassette;
@@ -401,10 +259,10 @@ private:
required_device<ram_device> m_ram;
optional_device<mc6846_device> m_mc6846;
optional_device<mc6843_device> m_mc6843;
- required_device<wd2793_device> m_wd2793_fdc;
required_device<screen_device> m_screen;
required_device<input_merger_device> m_mainirq;
required_device<input_merger_device> m_mainfirq;
+ required_device<thomson_extension_device> m_extension;
required_ioport m_io_game_port_directions;
required_ioport m_io_game_port_buttons;
required_ioport m_io_mouse_x;
@@ -416,34 +274,19 @@ private:
required_ioport m_io_config;
required_ioport m_io_vconfig;
optional_ioport m_io_mconfig;
- required_ioport m_io_fconfig;
required_ioport_array<10> m_io_keyboard;
required_memory_bank m_vrambank;
optional_memory_bank m_cartbank;
optional_memory_bank m_rambank;
- required_memory_bank m_flopbank;
required_memory_bank m_basebank;
- required_memory_bank m_syslobank;
- optional_memory_bank m_syshibank;
- optional_memory_bank m_datalobank;
- optional_memory_bank m_datahibank;
- optional_memory_bank m_biosbank;
- optional_memory_bank m_cartlobank;
- optional_memory_bank m_carthibank;
required_region_ptr<uint8_t> m_cart_rom;
- required_device<cq90_028_device> m_to7qdd;
- required_device<thmfc1_device> m_thmfc;
- output_finder<> m_floppy_led;
- required_device_array<legacy_floppy_image_device, 4> m_floppy_image;
-
output_finder<> m_caps_led;
/* bank logging and optimisations */
int m_old_cart_bank;
int m_old_cart_bank_was_read_only;
int m_old_ram_bank;
- int m_old_floppy_bank;
/* buffer storing demodulated bits, only for k7 and with speed hack */
uint32_t m_to7_k7_bitsize;
uint8_t* m_to7_k7_bits;
@@ -457,43 +300,6 @@ private:
emu_timer* m_to7_game_timer;
uint8_t m_to7_game_sound;
uint8_t m_to7_game_mute;
- emu_timer* m_mo5_periodic_timer;
- uint8_t m_mo5_reg_cart; /* 0xa7cb bank switch */
- uint8_t m_to9_palette_data[32];
- uint8_t m_to9_palette_idx;
- uint8_t m_to9_soft_bank;
- uint8_t m_to9_kbd_parity; /* 0=even, 1=odd, 2=no parity */
- uint8_t m_to9_kbd_intr; /* interrupt mode */
- uint8_t m_to9_kbd_in; /* data from keyboard */
- uint8_t m_to9_kbd_status; /* status */
- uint8_t m_to9_kbd_overrun; /* character lost */
- uint8_t m_to9_kbd_periph; /* peripheral mode */
- uint8_t m_to9_kbd_byte_count; /* byte-count in peripheral mode */
- uint16_t m_to9_mouse_x;
- uint16_t m_to9_mouse_y;
- uint8_t m_to9_kbd_last_key; /* for key repetition */
- uint16_t m_to9_kbd_key_count;
- uint8_t m_to9_kbd_caps; /* caps-lock */
- uint8_t m_to9_kbd_pad; /* keypad outputs special codes */
- emu_timer* m_to9_kbd_timer;
- uint8_t m_to8_kbd_ack; /* 1 = cpu inits / accepts transfers */
- uint16_t m_to8_kbd_data; /* data to transmit */
- uint16_t m_to8_kbd_step; /* transmission automaton state */
- uint8_t m_to8_kbd_last_key; /* last key (for repetition) */
- uint32_t m_to8_kbd_key_count; /* keypress time (for repetition) */
- uint8_t m_to8_kbd_caps; /* caps lock */
- emu_timer* m_to8_kbd_timer; /* bit-send */
- emu_timer* m_to8_kbd_signal; /* signal from CPU */
- uint8_t m_to8_data_vpage;
- uint8_t m_to8_cart_vpage;
- uint8_t m_to8_reg_ram;
- uint8_t m_to8_reg_cart;
- uint8_t m_to8_reg_sys1;
- uint8_t m_to8_reg_sys2;
- uint8_t m_to8_lightpen_intr;
- uint8_t m_to8_soft_select;
- uint8_t m_to8_soft_bank;
- uint8_t m_to8_bios_bank;
/* We allow choosing dynamically:
- the border size
@@ -516,7 +322,7 @@ private:
/* called thom_lightpen_nb times */
emu_timer *m_thom_lightpen_timer;
/* lightpen callback function to call from timer */
- void (thomson_state::*m_thom_lightpen_cb)(int step);
+ std::function<void (int)> m_thom_lightpen_cb;
uint8_t* m_thom_vram; /* pointer to video memory */
emu_timer* m_thom_scanline_timer; /* scan-line update */
uint16_t m_thom_last_pal[16]; /* palette at last scanline start */
@@ -546,19 +352,10 @@ private:
bool m_thom_vstate_dirty;
bool m_thom_vstate_last_dirty;
uint32_t m_thom_mode_point;
- uint32_t m_thom_floppy_wcount;
- uint32_t m_thom_floppy_rcount;
emu_timer *m_thom_init_timer;
void (thomson_state::*m_thom_init_cb)( int init );
- uint8_t m_to7_controller_type;
- uint8_t m_to7_floppy_bank;
- uint8_t m_to7_5p14_select;
- uint8_t m_to7_5p14sd_select;
-
int to7_get_cassette();
- int mo5_get_cassette();
- void mo5_set_cassette( int data );
void thom_irq_reset();
void to7_update_cart_bank();
void to7_set_init( int init );
@@ -571,8 +368,190 @@ private:
void to7_midi_reset();
void to7_midi_init();
void to770_update_ram_bank();
+
+ TIMER_CALLBACK_MEMBER( mo5_periodic_cb );
+ int mo5_get_cassette();
+ void mo5_set_cassette( int data );
void mo5_init_timer();
+
+ bool update_screen_size();
+ unsigned thom_video_elapsed();
+ struct thom_vsignal thom_get_vsignal();
+ void thom_get_lightpen_pos( int*x, int* y );
+ struct thom_vsignal thom_get_lightpen_vsignal( int xdec, int ydec, int xdec2 );
+ void thom_set_lightpen_callback( int nb );
+ int thom_mode_is_hires( int mode );
+ void thom_border_changed();
+ void thom_gplinfo_changed();
+ void thom_set_border_color( unsigned index );
+ void thom_set_palette( unsigned index, uint16_t color );
+ void thom_set_video_mode( unsigned mode );
+ void thom_set_video_page( unsigned page );
+ void thom_set_mode_point( int point );
+ unsigned to7_lightpen_gpl( int decx, int decy );
+ void thom_configure_palette( double gamma, const uint16_t* pal, palette_device& palette );
+
+ DECLARE_WRITE_LINE_MEMBER( mo5_set_cassette_motor );
+ DECLARE_DEVICE_IMAGE_LOAD_MEMBER( mo5_cartridge );
+};
+
+class mo5_state : public thomson_state
+{
+public:
+ mo5_state(const machine_config &mconfig, device_type type, const char *tag) :
+ thomson_state(mconfig, type, tag)
+ {
+ }
+
+ void mo5(machine_config &config);
+ void mo5e(machine_config &config);
+
+protected:
+ void mo5_lightpen_cb( int step );
+ void mo5_sys_porta_out(uint8_t data);
+ uint8_t mo5_sys_porta_in();
+ uint8_t mo5_sys_portb_in();
+ uint8_t mo5_gatearray_r(offs_t offset);
+ void mo5_gatearray_w(offs_t offset, uint8_t data);
+ void mo5_update_cart_bank_postload();
+ void mo5_cartridge_w(offs_t offset, uint8_t data);
+ uint8_t mo5_cartridge_r(offs_t offset);
+ void mo5_ext_w(uint8_t data);
+ DECLARE_MACHINE_RESET( mo5 );
+ DECLARE_MACHINE_START( mo5 );
+
+ void mo5_palette(palette_device &palette);
+
+ void mo5_map(address_map &map);
+
void mo5_update_cart_bank();
+};
+
+class to9_state : public thomson_state
+{
+public:
+ to9_state(const machine_config &mconfig, device_type type, const char *tag) :
+ thomson_state(mconfig, type, tag),
+ m_syslobank(*this, TO8_SYS_LO),
+ m_syshibank(*this, TO8_SYS_HI),
+ m_datalobank(*this, TO8_DATA_LO),
+ m_datahibank(*this, TO8_DATA_HI),
+ m_biosbank(*this, TO8_BIOS_BANK)
+ {
+ }
+
+ void to8(machine_config &config);
+ void to8d(machine_config &config);
+ void to9(machine_config &config);
+ void to9p(machine_config &config);
+
+protected:
+ required_memory_bank m_syslobank;
+ optional_memory_bank m_syshibank;
+ optional_memory_bank m_datalobank;
+ optional_memory_bank m_datahibank;
+ optional_memory_bank m_biosbank;
+
+ uint8_t m_to8_kbd_ack; /* 1 = cpu inits / accepts transfers */
+ uint16_t m_to8_kbd_data; /* data to transmit */
+ uint16_t m_to8_kbd_step; /* transmission automaton state */
+ uint8_t m_to8_kbd_last_key; /* last key (for repetition) */
+ uint32_t m_to8_kbd_key_count; /* keypress time (for repetition) */
+ uint8_t m_to8_kbd_caps; /* caps lock */
+ emu_timer* m_to8_kbd_timer; /* bit-send */
+ emu_timer* m_to8_kbd_signal; /* signal from CPU */
+ uint8_t m_to8_data_vpage;
+ uint8_t m_to8_cart_vpage;
+ uint8_t m_to8_reg_ram;
+ uint8_t m_to8_reg_cart;
+ uint8_t m_to8_reg_sys1;
+ uint8_t m_to8_reg_sys2;
+ uint8_t m_to8_lightpen_intr;
+ uint8_t m_to8_soft_select;
+ uint8_t m_to8_soft_bank;
+ uint8_t m_to8_bios_bank;
+
+ TIMER_CALLBACK_MEMBER( to8_kbd_timer_cb );
+ void to8_update_ram_bank_postload();
+ void to8_update_cart_bank_postload();
+ void to8_cartridge_w(offs_t offset, uint8_t data);
+ uint8_t to8_cartridge_r(offs_t offset);
+ uint8_t to8_gatearray_r(offs_t offset);
+ void to8_gatearray_w(offs_t offset, uint8_t data);
+ uint8_t to8_vreg_r(offs_t offset);
+ void to8_vreg_w(offs_t offset, uint8_t data);
+ uint8_t to8_sys_porta_in();
+ void to8_sys_portb_out(uint8_t data);
+ uint8_t to8_timer_port_in();
+ void to8_timer_port_out(uint8_t data);
+ DECLARE_WRITE_LINE_MEMBER( to8_timer_cp2_out );
+ void to8_lightpen_cb( int step );
+ DECLARE_MACHINE_RESET( to8 );
+ DECLARE_MACHINE_START( to8 );
+
+ DECLARE_WRITE_LINE_MEMBER(write_centronics_busy);
+
+ void to8_sys_lo_w(offs_t offset, uint8_t data);
+ void to8_sys_hi_w(offs_t offset, uint8_t data);
+ void to8_data_lo_w(offs_t offset, uint8_t data);
+ void to8_data_hi_w(offs_t offset, uint8_t data);
+ void to8_vcart_w(offs_t offset, uint8_t data);
+
+ int to8_kbd_ktest();
+ int to8_kbd_get_key();
+ void to8_kbd_timer_func();
+ void to8_kbd_set_ack( int data );
+ void to8_kbd_reset();
+ void to8_kbd_init();
+ void to8_update_ram_bank();
+ void to8_update_cart_bank();
+
+ void to9_ieee_w(offs_t offset, uint8_t data);
+ uint8_t to9_ieee_r(offs_t offset);
+ uint8_t to9_gatearray_r(offs_t offset);
+ void to9_gatearray_w(offs_t offset, uint8_t data);
+ uint8_t to9_vreg_r(offs_t offset);
+ void to9_vreg_w(offs_t offset, uint8_t data);
+ void to9_update_cart_bank_postload();
+ void to9_cartridge_w(offs_t offset, uint8_t data);
+ uint8_t to9_cartridge_r(offs_t offset);
+ void to9_update_ram_bank_postload();
+ uint8_t to9_kbd_r(offs_t offset);
+ void to9_kbd_w(offs_t offset, uint8_t data);
+ TIMER_CALLBACK_MEMBER( to9_kbd_timer_cb );
+ uint8_t to9_sys_porta_in();
+ void to9_sys_porta_out(uint8_t data);
+ void to9_sys_portb_out(uint8_t data);
+ void to9_timer_port_out(uint8_t data);
+ DECLARE_MACHINE_RESET( to9 );
+ DECLARE_MACHINE_START( to9 );
+ uint8_t to9p_timer_port_in();
+ void to9p_timer_port_out(uint8_t data);
+ DECLARE_MACHINE_RESET( to9p );
+ DECLARE_MACHINE_START( to9p );
+
+ void to8_map(address_map &map);
+ void to9_map(address_map &map);
+ void to9p_map(address_map &map);
+
+ uint8_t m_to9_palette_data[32];
+ uint8_t m_to9_palette_idx;
+ uint8_t m_to9_soft_bank;
+ uint8_t m_to9_kbd_parity; /* 0=even, 1=odd, 2=no parity */
+ uint8_t m_to9_kbd_intr; /* interrupt mode */
+ uint8_t m_to9_kbd_in; /* data from keyboard */
+ uint8_t m_to9_kbd_status; /* status */
+ uint8_t m_to9_kbd_overrun; /* character lost */
+ uint8_t m_to9_kbd_periph; /* peripheral mode */
+ uint8_t m_to9_kbd_byte_count; /* byte-count in peripheral mode */
+ uint16_t m_to9_mouse_x;
+ uint16_t m_to9_mouse_y;
+ uint8_t m_to9_kbd_last_key; /* for key repetition */
+ uint16_t m_to9_kbd_key_count;
+ uint8_t m_to9_kbd_caps; /* caps-lock */
+ uint8_t m_to9_kbd_pad; /* keypad outputs special codes */
+ emu_timer* m_to9_kbd_timer;
+
void to9_set_video_mode( uint8_t data, int style );
void to9_palette_init();
void to9_update_cart_bank();
@@ -583,53 +562,88 @@ private:
int to9_kbd_get_key();
void to9_kbd_reset();
void to9_kbd_init();
- int to8_kbd_ktest();
- int to8_kbd_get_key();
- void to8_kbd_timer_func();
- void to8_kbd_set_ack( int data );
- void to8_kbd_reset();
- void to8_kbd_init();
- void to8_update_floppy_bank();
- void to8_update_ram_bank();
- void to8_update_cart_bank();
- void to8_floppy_init();
- void to8_floppy_reset();
+};
+
+class mo6_state : public to9_state
+{
+public:
+ mo6_state(const machine_config &mconfig, device_type type, const char *tag) :
+ to9_state(mconfig, type, tag),
+ m_cartlobank(*this, MO6_CART_LO),
+ m_carthibank(*this, MO6_CART_HI)
+ {
+ }
+
+ void mo6(machine_config &config);
+ void pro128(machine_config &config);
+
+ DECLARE_MACHINE_RESET( mo6 );
+ DECLARE_MACHINE_START( mo6 );
+
+protected:
+ optional_memory_bank m_cartlobank;
+ optional_memory_bank m_carthibank;
+
+ void mo6_update_ram_bank_postload();
+ void mo6_update_cart_bank_postload();
+ void mo6_cartridge_w(offs_t offset, uint8_t data);
+ uint8_t mo6_cartridge_r(offs_t offset);
+ void mo6_ext_w(uint8_t data);
+ DECLARE_WRITE_LINE_MEMBER( mo6_centronics_busy );
+ void mo6_game_porta_out(uint8_t data);
+ DECLARE_WRITE_LINE_MEMBER( mo6_game_cb2_out );
+ TIMER_CALLBACK_MEMBER( mo6_game_update_cb );
+ uint8_t mo6_sys_porta_in();
+ uint8_t mo6_sys_portb_in();
+ void mo6_sys_porta_out(uint8_t data);
+ DECLARE_WRITE_LINE_MEMBER( mo6_sys_cb2_out );
+ uint8_t mo6_gatearray_r(offs_t offset);
+ void mo6_gatearray_w(offs_t offset, uint8_t data);
+ uint8_t mo6_vreg_r(offs_t offset);
+ void mo6_vreg_w(offs_t offset, uint8_t data);
+ void mo6_vcart_lo_w(offs_t offset, uint8_t data);
+ void mo6_vcart_hi_w(offs_t offset, uint8_t data);
+ void mo6_map(address_map &map);
void mo6_update_ram_bank();
void mo6_update_cart_bank();
void mo6_game_init();
void mo6_game_reset();
+};
+
+class mo5nr_state : public mo6_state
+{
+public:
+ mo5nr_state(const machine_config &mconfig, device_type type, const char *tag) :
+ mo6_state(mconfig, type, tag),
+ m_nanoreseau(*this, "nanoreseau"),
+ m_nanoreseau_config(*this, "nanoreseau_config"),
+ m_extension_view(*this, "extension_view")
+ {
+ }
+
+ void mo5nr(machine_config &config);
+
+ DECLARE_MACHINE_RESET( mo5nr );
+ DECLARE_MACHINE_START( mo5nr );
+
+protected:
+ required_device<nanoreseau_device> m_nanoreseau;
+ required_ioport m_nanoreseau_config;
+ memory_view m_extension_view;
+
+ void mo5nr_map(address_map &map);
+
void mo5nr_game_init();
void mo5nr_game_reset();
- bool update_screen_size();
- unsigned thom_video_elapsed();
- struct thom_vsignal thom_get_vsignal();
- void thom_get_lightpen_pos( int*x, int* y );
- struct thom_vsignal thom_get_lightpen_vsignal( int xdec, int ydec, int xdec2 );
- void thom_set_lightpen_callback( int nb );
- int thom_mode_is_hires( int mode );
- void thom_border_changed();
- void thom_gplinfo_changed();
- void thom_set_border_color( unsigned index );
- void thom_set_palette( unsigned index, uint16_t color );
- void thom_set_video_mode( unsigned mode );
- void thom_set_video_page( unsigned page );
- void thom_set_mode_point( int point );
- void thom_floppy_active( int write );
- unsigned to7_lightpen_gpl( int decx, int decy );
- void thom_configure_palette( double gamma, const uint16_t* pal, palette_device& palette );
+ uint8_t id_r();
- void to7_5p14_reset();
- void to7_5p14_init();
- void to7_5p14_index_pulse_callback( int state );
- void to7_5p14sd_reset();
- void to7_5p14sd_init();
- void to7_network_init();
- void to7_network_reset();
- void to7_floppy_init();
- void to7_floppy_reset();
- void to9_floppy_init(void* int_base);
- void to9_floppy_reset();
+ uint8_t mo5nr_net_r(offs_t offset);
+ void mo5nr_net_w(offs_t offset, uint8_t data);
+ uint8_t mo5nr_prn_r();
+ void mo5nr_prn_w(uint8_t data);
+ uint8_t mo5nr_sys_portb_in();
+ void mo5nr_sys_porta_out(uint8_t data);
};
/*----------- defined in video/thomson.cpp -----------*/
diff --git a/src/mame/machine/thomflop.cpp b/src/mame/machine/thomflop.cpp
deleted file mode 100644
index 2179377c8b5..00000000000
--- a/src/mame/machine/thomflop.cpp
+++ /dev/null
@@ -1,1867 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Antoine Mine
-/**********************************************************************
-
- Copyright (C) Antoine Mine' 2006
-
- Thomson 8-bit computers
-
-**********************************************************************/
-
-#include "emu.h"
-#include "includes/thomson.h"
-
-
-#define VERBOSE 0 /* 0, 1 or 2 */
-
-#define PRINT(x) osd_printf_info x
-
-#define LOG(x) do { if (VERBOSE > 0) logerror x; } while (0)
-#define VLOG(x) do { if (VERBOSE > 1) logerror x; } while (0)
-
-
-
-
-/******************* 3''1/2 & 5''1/4 disk format ********************/
-
-/*
- single density sector format:
-
- data bytes
-
- id field 00 6 byte synchro
- FE 1 id field mark
- 1 track
- 1 side
- 1 sector
- 00 1 log sector size (0->128, 1->256, 2->512,...)
- 2 CRC (unemulated)
- FF 12 spaces
- data field 00 6 bytes synchro
- FB 1 data field mark
- E5 128 actual data (set to E5 when formatting)
- 2 CRC (unemulated)
- FF 22 ? spaces
-
-
-
- double density sector format:
-
- data bytes
-
- id field 00 12 bit synchro
- A1 3 byte synchro
- FE 1 id field mark
- 1 track
- 1 side
- 1 sector
- 01 1 log sector size (0->128, 1->256, 2->512,...)
- 2 CRC (unemulated)
- 4E/F7 22 spaces
- data field 00 12 bit synchro
- A1 3 bytes synchro
- FB 1 data field mark
- E5 256 actual data (set to E5 when formatting)
- 2 CRC (unemulated)
- 4E/F7 74 ? spaces
-
- => at most 392 bytes / sector
- => at most 6272 bytes / track
-
- Notes:
- - the BIOS puts 4E bytes as spaces after id and data fields
- - some protected games expect F7 bytes (instead of 4E) after id fields
-*/
-
-#define THOM_SIZE_ID 32
-#define THOM_SIZE_DATA_LO (128+80)
-#define THOM_SIZE_DATA_HI (256+80)
-#define THOM_SIZE_SYNCHRO 12
-
-
-// build an identifier, with header & space
-int thomson_legacy_floppy_interface::floppy_make_addr(chrn_id id, uint8_t *dst, int sector_size)
-{
- if ( sector_size == 128 )
- {
- // single density
- memset( dst, 0x00, 6 ); // synchro bytes
- dst[ 7 ] = 0xfe; // address field mark
- dst[ 8 ] = id.C;
- dst[ 9 ] = id.H;
- dst[ 10 ] = id.N;
- dst[ 11 ] = id.R;
- dst[ 12 ] = 0; // TODO: CRC
- dst[ 13 ] = 0; // TODO: CRC
- memset( dst + 14, 0xff, 12 ); // end mark
- return 36;
- }
- else
- {
- // double density
- memset( dst, 0xa1, 3 ); // synchro bytes
- dst[ 3 ] = 0xfe; // address field mark
- dst[ 4 ] = id.C;
- dst[ 5 ] = id.H;
- dst[ 6 ] = id.N;
- dst[ 7 ] = id.R;
- dst[ 8 ] = 0; // TODO: CRC
- dst[ 9 ] = 0; // TODO: CRC
- memset( dst + 10, 0xf7, 22 ); // end mark
- return 32;
- }
-}
-
-
-
-// build a sector, with header & space
-int thomson_legacy_floppy_interface::floppy_make_sector(legacy_floppy_image_device *img, chrn_id id, uint8_t *dst, int sector_size)
-{
- if ( sector_size == 128 )
- {
- // single density
- memset( dst, 0x00, 6 ); // synchro bytes
- dst[ 6 ] = 0xfb; // data field mark
- img->floppy_drive_read_sector_data
- ( id.H, id.data_id, dst + 7, sector_size );
- dst[ sector_size + 7 ] = 0; // TODO: CRC
- dst[ sector_size + 8 ] = 0; // TODO: CRC
- memset( dst + sector_size + 9, 0xff, 22 ); // end mark
- return sector_size + 31;
- }
- else
- {
- // double density
- memset( dst, 0xa1, 3 ); // synchro bytes
- dst[ 3 ] = 0xfb; // data field mark
- img->floppy_drive_read_sector_data
- ( id.H, id.data_id, dst + 4, sector_size );
- dst[ sector_size + 4 ] = 0; // TODO: CRC
- dst[ sector_size + 5 ] = 0; // TODO: CRC
- memset( dst + sector_size + 6, 0xF7, 74 ); // end mark
- return sector_size + 80;
- }
-}
-
-
-
-// build a whole track
-int thomson_legacy_floppy_interface::floppy_make_track(legacy_floppy_image_device *img, uint8_t *dst, int sector_size, int side)
-{
- uint8_t space = ( sector_size == 128 ) ? 0xff : 0;
- uint8_t *org = dst;
- chrn_id id;
- int nb;
-
- // go to start of track
- while ( ! img->floppy_drive_get_flag_state( FLOPPY_DRIVE_INDEX ) )
- {
- if ( ! img->floppy_drive_get_next_id( side, &id ) )
- return 0;
- }
-
- // for each sector...
- for ( nb = 0; nb < 16; nb++ )
- {
- if ( ! img->floppy_drive_get_next_id( side, &id ) )
- break;
-
- memset( dst, space, THOM_SIZE_SYNCHRO ); dst += THOM_SIZE_SYNCHRO;
- dst += floppy_make_addr( id, dst, sector_size );
- memset( dst, space, THOM_SIZE_SYNCHRO ); dst += THOM_SIZE_SYNCHRO;
- dst += floppy_make_sector( img, id, dst, sector_size );
-
- if ( img->floppy_drive_get_flag_state( FLOPPY_DRIVE_INDEX ) )
- break;
- }
- return dst - org;
-}
-
-
-
-/******************* QDD disk format ********************/
-
-/*
- sector format:
-
- data bytes
-
- id field 16 17 synchro
- A5 1 id field mark
- 1 sector (1-400) hi byte
- 1 sector (1-400) low byte
- 1 check-sum (sum modulo 256 of 3 last bytes)
-
- data field 16 10 synchro
- 5A 1 data field mark
- FF 128 actual data (set to FF when formatting)
- 1 check-sum (sum modulo 256 of 129 last bytes)
-
-
- there are 400 sectors numbered from 1
-*/
-
-#define THOM_QDD_SYNCH_DISK 100
-#define THOM_QDD_SYNCH_ADDR 17
-#define THOM_QDD_SYNCH_DATA 10
-
-#define THOM_QDD_SIZE_ID ( 4 + THOM_QDD_SYNCH_ADDR )
-#define THOM_QDD_SIZE_DATA ( 130 + THOM_QDD_SYNCH_DATA )
-
-
-// build an identifier, with header
-int thomson_legacy_floppy_interface::qdd_make_addr(int sector, uint8_t *dst)
-{
- dst[ 0 ] = 0xa5;
- dst[ 1 ] = sector >> 8;
- dst[ 2 ] = sector & 0xff;
- dst[ 3 ] = dst[ 0 ] + dst[ 1 ] + dst[ 2 ];
- return 4;
-}
-
-
-
-// build a sector, with header
-int thomson_legacy_floppy_interface::qdd_make_sector(legacy_floppy_image_device *img, int sector, uint8_t *dst)
-{
- int i;
- dst[ 0 ] = 0x5a;
- img->floppy_drive_read_sector_data ( 0, sector, dst + 1, 128 );
- dst[ 129 ] = 0;
- for ( i = 0; i < 129; i++ )
- dst[ 129 ] += dst[ i ];
- return 130;
-}
-
-
-
-// build a whole disk
-int thomson_legacy_floppy_interface::qdd_make_disk(legacy_floppy_image_device *img, uint8_t *dst)
-{
- uint8_t* org = dst;
- int i;
-
- memset( dst, 0x16, THOM_QDD_SYNCH_DISK ); dst += THOM_QDD_SYNCH_DISK;
-
- for ( i = 1; i <= 400; i++ )
- {
- memset( dst, 0x16, THOM_QDD_SYNCH_ADDR ); dst += THOM_QDD_SYNCH_ADDR;
- dst += qdd_make_addr( i, dst );
- memset( dst, 0x16, THOM_QDD_SYNCH_DATA ); dst += THOM_QDD_SYNCH_DATA;
- dst += qdd_make_sector( img, i, dst );
- }
-
- memset( dst, 0x16, THOM_QDD_SYNCH_DISK ); dst += THOM_QDD_SYNCH_DISK;
-
- return dst - org;
-}
-
-
-
-/*********************** CD 90-640 controller ************************/
-
-/* 5''1/4 two-sided double-density
- used in TO7, TO7/70, MO5 computers
- based on a WD2793 (or lower ?) chip
-*/
-
-
-
-uint8_t thomson_state::to7_5p14_r(offs_t offset)
-{
- if ( offset < 4 )
- return m_wd2793_fdc->read(offset);
- else if ( offset == 8 )
- return m_to7_5p14_select;
- else
- logerror ( "%s: to7_5p14_r: invalid read offset %i\n", machine().describe_context(), offset );
- return 0;
-}
-
-
-
-void thomson_state::to7_5p14_w(offs_t offset, uint8_t data)
-{
- if ( offset < 4 )
- m_wd2793_fdc->write(offset, data);
- else if ( offset == 8 )
- {
- // drive select
- floppy_image_device *floppy = nullptr;
-
- if (BIT(data, 1)) floppy = m_wd2793_fdc->subdevice<floppy_connector>("0")->get_device();
- if (BIT(data, 2)) floppy = m_wd2793_fdc->subdevice<floppy_connector>("1")->get_device();
-
- m_wd2793_fdc->set_floppy(floppy);
-
- if (floppy)
- {
- thom_floppy_active( 0 );
- floppy->mon_w(0);
- floppy->ss_w(BIT(data, 0));
- }
- }
- else
- {
- logerror("%s: to7_5p14_w: invalid write offset %i (data=$%02X)\n",
- machine().describe_context(), offset, data );
- }
-}
-
-
-
-void thomson_state::to7_5p14_reset()
-{
- logerror("%s: to7_5p14_reset: CD 90-640 controller\n", machine().describe_context());
- m_wd2793_fdc->reset();
-}
-
-
-
-void thomson_state::to7_5p14_init()
-{
- logerror("%s: to7_5p14_init: CD 90-640 controller\n", machine().describe_context());
- save_item(NAME(m_to7_5p14_select));
-}
-
-
-
-/*********************** CD 90-015 controller ************************/
-
-/* 5''1/4 one-sided single-density (up to 4 one-sided drives)
- used in TO7, TO7/70, MO5 computers
- based on HD 46503 S chip, but we actually use a MC 6843 instead
- (seems they are clone)
-*/
-
-
-
-uint8_t thomson_state::to7_5p14sd_r(offs_t offset)
-{
- if ( offset < 8 )
- return m_mc6843->read(offset);
- else if ( offset >= 8 && offset <= 9 )
- return m_to7_5p14sd_select;
- else
- logerror ( "%f $%04x to7_5p14sd_r: invalid read offset %i\n", machine().time().as_double(), m_maincpu->pc(), offset );
- return 0;
-}
-
-
-
-void thomson_state::to7_5p14sd_w(offs_t offset, uint8_t data)
-{
- if ( offset < 8 )
- m_mc6843->write(offset, data);
- else if ( offset >= 8 && offset <= 9 )
- {
- // drive select
- int drive = -1, side = 0;
-
- if ( data & 1 )
- {
- drive = 0;
- side = 0;
- }
- else if ( data & 2 )
- {
- drive = 1;
- side = 1;
- }
- else if ( data & 4 )
- {
- drive = 2;
- side = 0;
- }
- else if ( data & 8 )
- {
- drive = 3;
- side = 1;
- }
-
- m_to7_5p14sd_select = data;
-
- if ( drive != -1 )
- {
- thom_floppy_active( 0 );
- m_mc6843->set_drive( drive );
- m_mc6843->set_side( side );
- LOG(( "%f $%04x to7_5p14sd_w: $%02X set drive=%i side=%i\n",
- machine().time().as_double(), m_maincpu->pc(), data, drive, side ));
- }
- }
- else
- logerror ( "%f $%04x to7_5p14sd_w: invalid write offset %i (data=$%02X)\n",
- machine().time().as_double(), m_maincpu->pc(), offset, data );
-}
-
-void thomson_state::to7_5p14_index_pulse_callback( int state )
-{
- m_mc6843->set_index_pulse( state );
-}
-
-void thomson_state::to7_5p14sd_reset()
-{
- LOG(( "to7_5p14sd_reset: CD 90-015 controller\n" ));
- for (auto &img : m_floppy_image)
- {
- img->floppy_drive_set_ready_state( FLOPPY_DRIVE_READY, 0 );
- img->floppy_drive_set_rpm( 300. );
- img->floppy_drive_seek( - img->floppy_drive_get_current_track() );
- }
-}
-
-
-void thomson_state::to7_5p14sd_init()
-{
- LOG(( "to7_5p14sd_init: CD 90-015 controller\n" ));
- save_item(NAME(m_to7_5p14sd_select));
-}
-
-
-/*********************** CQ 90-028 controller ************************/
-
-/* QDD 2''8 controller
- used in TO7, TO7/70, MO5 computers
- it is based on a MC6852 SSDA
-
- Note: the MC6852 is only partially emulated, most features are not used in
- the controller and are ignored.
-*/
-
-
-
-// MC6852 status
-enum : uint8_t
-{
- QDD_S_RDA = 0x01, // receiver data available
- QDD_S_TDRA = 0x02, // transitter data register available
- QDD_S_NDCD = 0x04, // data carrier detect, negated (unused)
- QDD_S_NCTS = 0x08, // clear-to-send, negated write-protect
- QDD_S_TUF = 0x10, // transmitter underflow (unused)
- QDD_S_OVR = 0x20, // receiver overrun (unused)
- QDD_S_PE = 0x40, // receiver parity error (unused)
- QDD_S_IRQ = 0x80, // interrupt request
- QDD_S_ERR = (QDD_S_TUF | QDD_S_OVR | QDD_S_PE | QDD_S_NDCD | QDD_S_NCTS)
-};
-
-
-// MC6852 control
-enum : uint8_t
-{
- QDD_C1_RIE = 0x20, // interrupt on reveive
- QDD_C1_TIE = 0x10, // interrupt on transmit
- QDD_C1_CLRSYNC = 0x08, // clear receiver sync char (unused)
- QDD_C1_STRIPSYNC = 0x04, // strips sync from received (unused)
- QDD_C1_TRESET = 0x02, // transmitter reset
- QDD_C1_RRESET = 0x01, // receiver reset
- QDD_C2_EIE = 0x80, // interrupt on error
- QDD_C2_TSYNC = 0x40, // underflow = ff if 0 / sync if 1 (unused)
- QDD_C2_BLEN = 0x04, // transfer byte length (unused)
- QDD_C3_CLRTUF = 0x08, // clear underflow
- QDD_C3_CLRCTS = 0x04, // clear CTS
- QDD_C3_SYNCLEN = 0x02, // sync byte length (unused)
- QDD_C3_SYNCMODE = 0x01 // external / internal sync mode (unused)
-};
-
-
-// a track is actually the whole disk = 400 128-byte sectors + headers
-#define QDD_MAXBUF ( THOM_QDD_SIZE_ID + THOM_QDD_SIZE_DATA ) * 512
-
-
-DEFINE_DEVICE_TYPE(CQ90_028, cq90_028_device, "cq90_028", "Thomson CQ 90-028 Quick Disk Controller")
-
-cq90_028_device::cq90_028_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, CQ90_028, tag, owner, clock)
- , thomson_legacy_floppy_interface(mconfig, *this)
- , m_qdd_image(*this, "^floppy0")
-{
-}
-
-
-void cq90_028_device::index_pulse_cb(int state)
-{
- m_index_pulse = state;
-
- if ( state )
- {
- // rewind to disk start
- m_data_idx = 0;
- m_start_idx = 0;
- m_data_size = 0;
- }
-
- VLOG(( "%f to7_qdd_pulse_cb: state=%i\n", machine().time().as_double(), state ));
-}
-
-
-// update MC6852 status register
-void cq90_028_device::stat_update()
-{
- // byte-ready
- m_status |= QDD_S_RDA | QDD_S_TDRA;
- if ( !m_drive )
- m_status |= QDD_S_PE;
-
- // write-protect
- if (m_qdd_image->floppy_wpt_r() == CLEAR_LINE)
- m_status |= QDD_S_NCTS;
-
- // sticky reset conditions
- if ( m_ctrl1 & QDD_C1_RRESET )
- m_status &= ~(QDD_S_PE | QDD_S_RDA | QDD_S_OVR);
- if ( m_ctrl1 & QDD_C1_TRESET )
- m_status &= ~(QDD_S_TDRA | QDD_S_TUF);
-
- // irq update
- if ( ( (m_ctrl1 & QDD_C1_RIE) && !(m_status & QDD_S_RDA ) ) ||
- ( (m_ctrl1 & QDD_C1_TIE) && !(m_status & QDD_S_TDRA) ) ||
- ( (m_ctrl2 & QDD_C2_EIE) && !(m_status & QDD_S_ERR ) ) )
- m_status &= ~QDD_S_IRQ;
-
- if ( ( (m_ctrl1 & QDD_C1_RIE) && (m_status & QDD_S_RDA ) ) ||
- ( (m_ctrl1 & QDD_C1_TIE) && (m_status & QDD_S_TDRA) ) ||
- ( (m_ctrl2 & QDD_C2_EIE) && (m_status & QDD_S_ERR ) ) )
- m_status |= QDD_S_IRQ;
-}
-
-
-
-uint8_t cq90_028_device::qdd_read_byte()
-{
- uint8_t data;
-
- // rebuild disk if needed
- if ( !m_data_size )
- {
- m_data_size = qdd_make_disk( m_qdd_image.target(), &m_data[0] );
- assert( m_data_idx < QDD_MAXBUF );
- }
-
- if ( m_data_idx >= m_data_size )
- data = 0;
- else
- data = m_data[ m_data_idx ];
-
- VLOG(( "%f %s to7_qdd_read_byte: RDATA off=%i/%i data=$%02X\n",
- machine().time().as_double(), machine().describe_context(),
- m_data_idx, m_data_size, data ));
-
- m_data_idx++;
- m_start_idx = m_data_idx;
-
- return data;
-}
-
-
-
-/* This is quite complex: bytes are written one at a time by the CPU and we
- must detect the following patterns:
- * CPU write id field and data field => format
- * CPU write data field after it has read an id field => sector write
- */
-void cq90_028_device::qdd_write_byte(uint8_t data)
-{
- // rebuild disk if needed
- if ( !m_data_size )
- {
- m_data_size = qdd_make_disk( m_qdd_image.target(), &m_data[0] );
- assert( m_data_idx < QDD_MAXBUF );
- }
-
- if ( ( m_start_idx != m_data_idx || // field in construction
- data==0xA5 || data==0x5A ) && // first byte of tentative field
- m_data_idx < m_data_size )
- {
- // this is the first byte of the field
- if ( m_start_idx == m_data_idx )
- m_data_crc = 0;
-
- // accumulate bytes
- m_data[ m_data_idx ] = data;
- m_data_idx++;
-
- VLOG (( "%f %s to7_qdd_write_byte: got $%02X offs=%i-%i\n",
- machine().time().as_double(), machine().describe_context(), data,
- m_start_idx, m_data_idx ));
-
- // end of tentative id field
- if ( m_data_idx == m_start_idx + 4 &&
- m_data[ m_start_idx ] == 0xA5 &&
- m_data[ m_start_idx + 3 ] == m_data_crc )
- {
- // got an id field => format
- int sector = (int) m_data[ m_start_idx + 1 ] * 256 + (int) m_data[ m_start_idx + 2 ];
- uint8_t filler = 0xff;
-
- LOG(( "%f %s to7_qdd_write_byte: got id field for sector=%i\n",
- machine().time().as_double(), machine().describe_context(), sector ));
-
- m_qdd_image->floppy_drive_format_sector(
- 0, sector, 0, 0, sector, 128, filler );
- //thom_floppy_active( 1 );
- m_start_idx = m_data_idx;
- }
-
- // end of tentative data field
- else if ( m_data_idx == m_start_idx + 130 &&
- m_data[ m_start_idx ] == 0x5A &&
- m_data[ m_start_idx + 129 ] == m_data_crc )
- {
- int i;
-
- // look backwards for previous id field
- for ( i = m_start_idx - 3; i >= 0; i-- )
- {
- if ( m_data[ i ] == 0xA5 &&
- ( ( m_data[ i ] + m_data[ i + 1 ] +
- m_data[ i + 2 ] ) & 0xff
- ) == m_data[ i + 3 ] )
- break;
- }
-
- if ( i >= 0 )
- {
- // got an id & a data field => write
- int sector = (int) m_data[ i + 1 ] * 256 + (int) m_data[ i + 2 ];
-
- LOG(( "%f %s to7_qdd_write_byte: goto data field for sector=%i\n",
- machine().time().as_double(), machine().describe_context(), sector ));
-
- m_qdd_image->floppy_drive_write_sector_data( 0, sector, &m_data[ m_start_idx + 1 ], 128, 0 );
- //thom_floppy_active( 1 );
- }
-
- m_start_idx = m_data_idx;
- }
-
- else m_data_crc += data;
- }
-}
-
-
-
-uint8_t cq90_028_device::qdd_r(offs_t offset)
-{
- switch ( offset )
- {
- case 0: // MC6852 status
- stat_update();
- VLOG(( "%f %s to7_qdd_r: STAT=$%02X irq=%i pe=%i ovr=%i und=%i tr=%i rd=%i ncts=%i\n",
- machine().time().as_double(), machine().describe_context(), m_status,
- m_status & QDD_S_IRQ ? 1 : 0,
- m_status & QDD_S_PE ? 1 : 0,
- m_status & QDD_S_OVR ? 1 : 0,
- m_status & QDD_S_TUF ? 1 : 0,
- m_status & QDD_S_TDRA ? 1 : 0,
- m_status & QDD_S_RDA ? 1 : 0,
- m_status & QDD_S_NCTS ? 1 : 0 ));
- return m_status;
-
- case 1: // MC6852 data input => read byte from disk
- m_status &= ~(QDD_S_RDA | QDD_S_PE | QDD_S_OVR);
- stat_update();
- return qdd_read_byte();
-
- case 8: // floppy status
- {
- uint8_t data = 0;
- device_image_interface* img = m_qdd_image.target();
- if ( ! img->exists() )
- data |= 0x40; // disk present
- if ( m_index_pulse )
- data |= 0x80; // disk start
- VLOG(( "%f %s to7_qdd_r: STATUS8 $%02X\n", machine().time().as_double(), machine().describe_context(), data ));
- return data;
- }
-
- default:
- logerror ( "%f %s to7_qdd_r: invalid read offset %i\n", machine().time().as_double(), machine().describe_context(), offset );
- return 0;
- }
-}
-
-
-
-void cq90_028_device::qdd_w(offs_t offset, uint8_t data)
-{
- switch ( offset )
- {
- case 0: // MC6852 control 1
- // reset
- if ( data & QDD_C1_RRESET )
- m_status &= ~(QDD_S_PE | QDD_S_RDA | QDD_S_OVR);
- if ( data & QDD_C1_TRESET )
- m_status &= ~(QDD_S_TDRA | QDD_S_TUF);
-
- m_ctrl1 = ( data & ~(QDD_C1_RRESET | QDD_C1_TRESET) ) |( data & (QDD_C1_RRESET | QDD_C1_TRESET) & m_ctrl1 );
- stat_update();
- VLOG(( "%f %s to7_qdd_w: CTRL1=$%02X reset=%c%c %s%sirq=%c%c\n",
- machine().time().as_double(), machine().describe_context(), data,
- data & QDD_C1_RRESET ? 'r' : '-', data & QDD_C1_TRESET ? 't' : '-',
- data & QDD_C1_STRIPSYNC ? "strip-sync " : "",
- data & QDD_C1_CLRSYNC ? "clear-sync " : "",
- data & QDD_C1_RIE ? 'r' : '-',
- data & QDD_C1_TIE ? 't' : '-' ));
- break;
-
- case 1:
- switch ( m_ctrl1 >> 6 )
- {
- case 0: // MC6852 control 2
- {
-#if 0
- // most of these are unused now
- static const int bit[8] = { 6, 6, 7, 8, 7, 7, 8, 8 };
- static const int par[8] = { 2, 1, 0, 0, 2, 1, 2, 1 };
- static const char *const parname[3] = { "none", "odd", "even" };
- int bits, parity;
- bits = bit[ (data >> 3) & 7 ];
- parity = par[ (data >> 3) & 7 ];
- stat_update();
- VLOG(( "%f %s to7_qdd_w: CTRL2=$%02X bits=%i par=%s blen=%i under=%s%s\n",
- machine().time().as_double(), machine().describe_context(), data,
- bits, parname[ parity ], data & QDD_C2_BLEN ? 1 : 2,
- data & QDD_C2_TSYNC ? "sync" : "ff",
- data & QDD_C2_EIE ? "irq-err" : "" ));
-#endif
- m_ctrl2 = data;
- break;
- }
-
- case 1: // MC6852 control 3
- m_ctrl3 = data;
- // reset just once each write, not sticky
- if ( data & QDD_C3_CLRTUF )
- m_status &= ~QDD_S_TUF;
- if ( data & QDD_C3_CLRCTS )
- m_status &= ~QDD_S_NCTS;
- stat_update();
- VLOG(( "%f %s to7_qdd_w: CTRL3=$%02X %s%ssync-len=%i sync-mode=%s\n",
- machine().time().as_double(), machine().describe_context(), data,
- data & QDD_C3_CLRTUF ? "clr-tuf " : "",
- data & QDD_C3_CLRCTS ? "clr-cts " : "",
- data & QDD_C3_SYNCLEN ? 1 : 2,
- data & QDD_C3_SYNCMODE ? "ext" : "int" ));
- break;
-
- case 2: // MC6852 sync code => write byte to disk
- qdd_write_byte( data );
- break;
-
- case 3: // MC6852 data out => does not seem to be used
- VLOG(( "%f %s to7_qdd_w: ignored WDATA=$%02X\n", machine().time().as_double(), machine().describe_context(), data ));
- break;
-
- }
- break;
-
- case 8: // set drive
- m_drive = data;
- VLOG(( "%f %s to7_qdd_w: DRIVE=$%02X\n", machine().time().as_double(), machine().describe_context(), data ));
- break;
-
- case 12: // motor pulse ?
- //thom_floppy_active( 0 );
- VLOG(( "%f %s to7_qdd_w: MOTOR=$%02X\n", machine().time().as_double(), machine().describe_context(), data ));
- break;
-
- default:
- logerror ( "%f %s to7_qdd_w: invalid write offset %i (data=$%02X)\n", machine().time().as_double(), machine().describe_context(), offset, data );
- }
-}
-
-
-
-void cq90_028_device::qdd_reset()
-{
- LOG(( "to7_qdd_reset: CQ 90-028 controller\n" ));
-
- m_qdd_image->floppy_drive_set_ready_state( FLOPPY_DRIVE_READY, 0 );
-
- m_qdd_image->floppy_mon_w(CLEAR_LINE);
-
- // pulse each time the whole-disk spiraling track ends
- // at 90us per byte read, the disk can be read in 6s
- m_qdd_image->floppy_drive_set_rpm( 60. / 6. );
-
- m_ctrl1 |= QDD_C1_TRESET | QDD_C1_RRESET; // reset
- m_ctrl2 &= 0x7c; // clear EIE, PC2-PC1
- m_ctrl3 &= 0xfe; // internal sync
- m_drive = 0;
- stat_update();
-}
-
-
-
-void cq90_028_device::device_start()
-{
- m_data = make_unique_clear<uint8_t[]>(QDD_MAXBUF);
-
- save_item(NAME(m_status));
- save_item(NAME(m_ctrl1));
- save_item(NAME(m_ctrl2));
- save_item(NAME(m_ctrl3));
- save_item(NAME(m_drive));
- save_item(NAME(m_data_idx));
- save_item(NAME(m_start_idx));
- save_item(NAME(m_data_size));
- save_item(NAME(m_data_crc));
- save_item(NAME(m_index_pulse));
- save_pointer(NAME(m_data), QDD_MAXBUF);
-}
-
-
-
-/********************** THMFC1 controller *************************/
-
-/* custom Thomson Gate-array for 3''1/2, 5''1/4 (double density only) & QDD
- */
-
-
-// STAT0 flags
-enum : uint8_t
-{
- STAT0_SYNCHRO = 0x01, // bit clock synchronized
- STAT0_BYTE_READY_OP = 0x02, // byte ready (high-level operation)
- STAT0_CRC_ERROR = 0x04,
- STAT0_FINISHED = 0x08,
- STAT0_FINISHING = 0x10, // (unemulated)
- STAT0_BYTE_READY_POL = 0x80 // polling mode
-};
-
-/*#define THOM_MAXBUF (THOM_SIZE_ID+THOM_SIZE_DATA_HI+2*THOM_SIZE_SYNCHRO)*17*/
-#define THOM_MAXBUF ( THOM_QDD_SIZE_ID + THOM_QDD_SIZE_DATA ) * 512
-
-
-DEFINE_DEVICE_TYPE(THMFC1, thmfc1_device, "thmfc1", "Thomson THMFC1 floppy controller")
-
-ALLOW_SAVE_TYPE(thmfc1_device::thmfc1_op);
-
-thmfc1_device::thmfc1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, THMFC1, tag, owner, clock)
- , thomson_legacy_floppy_interface(mconfig, *this)
- , m_floppy_image(*this, "^floppy%u", 0U)
- , m_floppy_active_cb(*this)
- , m_op(OP_RESET)
- , m_sector(0)
- , m_sector_id(0)
- , m_track(0)
- , m_side(0)
- , m_drive(0)
- , m_sector_size(0)
- , m_formatting(0)
- , m_ipl(0)
- , m_wsync(0)
- , m_motor_on(0)
- , m_data_idx(0)
- , m_data_size(0)
- , m_data_finish(0)
- , m_data_raw_idx(0)
- , m_data_raw_size(0)
- , m_data_crc(0)
- , m_stat0(0)
- , m_floppy_cmd(nullptr)
-{
-}
-
-
-void thmfc1_device::device_resolve_objects()
-{
- m_floppy_active_cb.resolve_safe();
-}
-
-
-legacy_floppy_image_device *thmfc1_device::get_floppy_image()
-{
- return m_floppy_image[m_drive].target();
-}
-
-
-
-bool thmfc1_device::floppy_is_qdd( legacy_floppy_image_device *image ) const
-{
- if (!image) return false;
- if (!image->exists()) return false;
- return image->length() == 51200; // idf QDD
-}
-
-
-
-void thmfc1_device::index_pulse_cb( int index, int state )
-{
- legacy_floppy_image_device *const image = m_floppy_image[index];
-
- if ( image != get_floppy_image())
- return;
-
- if ( floppy_is_qdd(image) )
- {
- // pulse each time the whole-disk spiraling track ends
- image->floppy_drive_set_rpm( 16.92f /* 423/25 */ );
- m_ipl = state;
- if ( state )
- {
- m_data_raw_size = 0;
- m_data_raw_idx = 0;
- m_data_idx = 0;
- }
- }
- else
- {
- image->floppy_drive_set_rpm( 300. );
- m_ipl = state;
- if ( state )
- m_data_raw_idx = 0;
- }
-
- VLOG(( "%f thmfc_floppy_index_pulse_cb: state=%i\n", machine().time().as_double(), state ));
-}
-
-
-
-int thmfc1_device::floppy_find_sector( chrn_id* dst )
-{
- legacy_floppy_image_device *const img = get_floppy_image();
- chrn_id id;
- int r = 0;
-
- // scan track, try 4 revolutions
- while ( r < 4 )
- {
- if ( img->floppy_drive_get_next_id( m_side, &id ) )
- {
- if ( id.C == m_track &&
- id.R == m_sector &&
- (128 << id.N) == m_sector_size
- /* check side ? id.H == m_side */ )
- {
- if ( dst )
- memcpy( dst, &id, sizeof( chrn_id ) );
- m_stat0 = STAT0_BYTE_READY_POL;
- LOG (( "thmfc_floppy_find_sector: sector found C=%i H=%i R=%i N=%i\n", id.C, id.H, id.R, id.N ));
- return 1;
- }
- }
-
- if ( img->floppy_drive_get_flag_state( FLOPPY_DRIVE_INDEX ) )
- r++;
- }
-
- m_stat0 = STAT0_CRC_ERROR | STAT0_FINISHED;
- LOG (( "thmfc_floppy_find_sector: sector not found drive=%s track=%i sector=%i\n", img->tag(), m_track, m_sector ));
- return 0;
-}
-
-
-
-// complete command (by read, write, or timeout)
-void thmfc1_device::floppy_cmd_complete()
-{
- LOG (( "%f thmfc_floppy_cmd_complete_cb: cmd=%i off=%i/%i/%i\n",
- machine().time().as_double(), m_op, m_data_idx,
- m_data_finish - 1, m_data_size - 1 ));
-
- if ( m_op == OP_WRITE_SECT )
- {
- legacy_floppy_image_device *const img = get_floppy_image();
- img->floppy_drive_write_sector_data( m_side, m_sector_id, &m_data[3], m_data_size - 3, 0 );
- m_floppy_active_cb( 1 );
- }
- m_op = OP_RESET;
- m_stat0 |= STAT0_FINISHED;
- m_data_idx = 0;
- m_data_size = 0;
- m_floppy_cmd->adjust(attotime::never);
-}
-
-
-
-TIMER_CALLBACK_MEMBER( thmfc1_device::floppy_cmd_complete_cb )
-{
- floppy_cmd_complete();
-}
-
-
-
-// intelligent read: show just one field, skip header
-uint8_t thmfc1_device::floppy_read_byte()
-{
- uint8_t data = m_data[ m_data_idx ];
-
- VLOG(( "%f %s thmfc_floppy_read_byte: off=%i/%i/%i data=$%02X\n",
- machine().time().as_double(), machine().describe_context(),
- m_data_idx, m_data_finish - 1, m_data_size - 1,
- data ));
-
- if ( m_data_idx >= m_data_size - 1 )
- floppy_cmd_complete();
- else
- m_data_idx++;
-
- if ( m_data_idx >= m_data_finish )
- m_stat0 |= STAT0_FINISHED;
-
- return data;
-}
-
-
-
-// dumb read: show whole track with field headers and gaps
-uint8_t thmfc1_device::floppy_raw_read_byte()
-{
- uint8_t data;
-
- // rebuild track if needed
- if ( ! m_data_raw_size )
- {
- if ( floppy_is_qdd(get_floppy_image()))
- // QDD: track = whole disk
- m_data_raw_size = qdd_make_disk ( get_floppy_image(), &m_data[0] );
- else
- {
- m_data_raw_idx = 0;
- m_data_raw_size = floppy_make_track( get_floppy_image(), &m_data[0],
- m_sector_size, m_side );
- }
- assert( m_data_raw_size < THOM_MAXBUF );
- }
-
- if ( m_data_raw_idx >= m_data_raw_size )
- data = 0;
- else
- data = m_data[ m_data_raw_idx ];
-
- VLOG(( "%f %s thmfc_floppy_raw_read_byte: off=%i/%i data=$%02X\n",
- machine().time().as_double(), machine().describe_context(),
- m_data_raw_idx, m_data_raw_size, data ));
-
- m_data_raw_idx++;
-
- return data;
-}
-
-
-
-// QDD writing / formating
-void thmfc1_device::floppy_qdd_write_byte( uint8_t data )
-{
- int i;
-
- if ( m_formatting &&
- ( m_data_idx || data==0xA5 || data==0x5A ) &&
- m_data_raw_idx < THOM_MAXBUF )
- {
- if ( ! m_data_raw_size )
- {
- m_data_raw_size = qdd_make_disk ( get_floppy_image(), &m_data[0] );
- assert( m_data_raw_size < THOM_MAXBUF );
- }
-
- // accumulate bytes to form a field
- m_data[ m_data_raw_idx ] = data;
- m_data_raw_idx++;
-
- if ( ! m_data_idx )
- {
- // start
- m_data_crc = 0;
- m_data_idx = m_data_raw_idx;
- }
-
- VLOG (( "%f %s thmfc_floppy_qdd_write_byte: $%02X offs=%i-%i\n",
- machine().time().as_double(), machine().describe_context(), data,
- m_data_idx, m_data_raw_idx ));
-
- if ( m_data_raw_idx == m_data_idx + 3 &&
- m_data[ m_data_idx - 1 ] == 0xA5 &&
- m_data[ m_data_idx + 2 ] == m_data_crc )
- {
- // got an id field => format
- int sector = (int) m_data[ m_data_idx ] * 256 + (int) m_data[ m_data_idx + 1 ];
- uint8_t filler = 0xff;
-
- LOG(( "%f %s thmfc_floppy_qdd_write_byte: id field, sector=%i\n", machine().time().as_double(), machine().describe_context(), sector ));
-
- get_floppy_image()->floppy_drive_format_sector( 0, sector, 0, 0, sector, 128, filler );
- m_floppy_active_cb( 1 );
- m_data_idx = 0;
- }
-
- else if ( m_data_raw_idx == m_data_idx + 129 &&
- m_data[ m_data_idx - 1 ] == 0x5A &&
- m_data[ m_data_idx + 128 ] == m_data_crc )
- {
- // look backwards for previous id field
- for ( i = m_data_idx - 4; i >= 0; i-- )
- {
- if ( m_data[ i ] == 0xA5 &&
- ( ( m_data[ i ] + m_data[ i + 1 ] +
- m_data[ i + 2 ] ) & 0xff
- ) == m_data[ i + 3 ] )
- break;
- }
-
- if ( i >= 0 )
- {
- // got an id & a data field => write
- legacy_floppy_image_device * img = get_floppy_image();
- int sector = (int) m_data[ i + 1 ] * 256 +
- (int) m_data[ i + 2 ];
-
- LOG(( "%f %s thmfc_floppy_qdd_write_byte: data field, sector=%i\n",
- machine().time().as_double(), machine().describe_context(), sector ));
-
- img->floppy_drive_write_sector_data( 0, sector, &m_data[m_data_idx], 128, 0 );
- m_floppy_active_cb( 1 );
- }
-
- m_data_idx = 0;
-
- }
- else
- m_data_crc += data;
- }
- else
- {
- m_data_raw_idx++;
- VLOG (( "%f %s thmfc_floppy_qdd_write_byte: ignored $%02X\n", machine().time().as_double(), machine().describe_context(), data ));
- }
-
-}
-
-
-
-// intelligent writing
-void thmfc1_device::floppy_write_byte( uint8_t data )
-{
- VLOG (( "%f %s thmfc_floppy_write_byte: off=%i/%i data=$%02X\n",
- machine().time().as_double(), machine().describe_context(),
- m_data_idx, m_data_size - 1, data ));
-
- m_data_raw_size = 0;
- m_data[ m_data_idx ] = data;
- if ( m_data_idx >= m_data_size - 1 )
- floppy_cmd_complete();
- else
- m_data_idx++;
-}
-
-// intelligent formatting
-void thmfc1_device::floppy_format_byte( uint8_t data )
-{
- VLOG (( "%f %s thmfc_floppy_format_byte: $%02X\n", machine().time().as_double(), machine().describe_context(), data ));
-
- m_data_raw_size = 0;
-
- // accumulate bytes to form an id field
- if ( m_data_idx || data==0xA1 )
- {
- static const uint8_t header[] = { 0xa1, 0xa1, 0xa1, 0xfe };
- m_data[ m_data_idx ] = data;
- m_data_idx++;
- if ( m_data_idx > 11 )
- {
- if ( !memcmp ( &m_data[0], header, sizeof( header ) ) )
- {
- // got id field => format
- legacy_floppy_image_device * img = get_floppy_image();
- uint8_t track = m_data[4];
- uint8_t side = m_data[5];
- uint8_t sector = m_data[6];
- uint8_t length = m_data[7]; // actually, log length
- uint8_t filler = 0xe5; // standard Thomson filler
-
- chrn_id id;
- if ( floppy_find_sector( &id ) )
- {
- img->floppy_drive_format_sector( side, m_sector_id, track, m_side, sector, length, filler );
- m_floppy_active_cb( 1 );
- }
- }
-
- m_data_idx = 0;
- }
-
- }
-}
-
-
-
-uint8_t thmfc1_device::floppy_r(offs_t offset)
-{
- switch ( offset )
- {
- case 0: // STAT0
- m_stat0 ^= STAT0_SYNCHRO | STAT0_BYTE_READY_POL;
- VLOG(( "%f %s thmfc_floppy_r: STAT0=$%02X\n", machine().time().as_double(), machine().describe_context(), m_stat0 ));
- return m_stat0;
-
- case 1: // STAT1
- {
- uint8_t data = 0;
- legacy_floppy_image_device * img = get_floppy_image();
- int flags = img->floppy_drive_get_flag_state(-1 );
- if ( floppy_is_qdd(img) )
- {
- if ( ! img->exists() )
- data |= 0x40; // disk present
- if ( ! m_ipl )
- data |= 0x02; // disk start
- data |= 0x08; // connected
- }
- else
- {
- if ( m_ipl )
- data |= 0x40;
- if ( img->exists() )
- data |= 0x20; // disk change (?)
-
- data |= !img->floppy_tk00_r() << 3;
-
- if ( flags & FLOPPY_DRIVE_READY )
- data |= 0x02;
- }
- if (!m_motor_on)
- data |= 0x10;
- if (!img->floppy_wpt_r())
- data |= 0x04;
- VLOG(( "%f %s thmfc_floppy_r: STAT1=$%02X\n", machine().time().as_double(), machine().describe_context(), data ));
- return data;
- }
-
- case 3: // RDATA
-
- if ( m_op == OP_READ_SECT || m_op == OP_READ_ADDR )
- return floppy_read_byte();
- else
- return floppy_raw_read_byte();
-
- case 6:
- return 0;
-
- case 8:
- {
- // undocumented => emulate TO7 QDD controller ?
- uint8_t data = m_ipl << 7;
- VLOG(( "%f %s thmfc_floppy_r: STAT8=$%02X\n", machine().time().as_double(), machine().describe_context(), data ));
- return data;
- }
-
- default:
- logerror ( "%f %s thmfc_floppy_r: invalid read offset %i\n", machine().time().as_double(), machine().describe_context(), offset );
- return 0;
- }
-}
-
-
-
-void thmfc1_device::floppy_w(offs_t offset, uint8_t data)
-{
- switch ( offset ) {
- case 0: // CMD0
- {
- int wsync = (data >> 4) & 1;
- int qdd = floppy_is_qdd(get_floppy_image());
- chrn_id id;
- m_formatting = (data >> 2) & 1;
- LOG (( "%f %s thmfc_floppy_w: CMD0=$%02X dens=%s wsync=%i dsync=%i fmt=%i op=%i\n",
- machine().time().as_double(), machine().describe_context(), data,
- (BIT(data, 5) ? "FM" : "MFM"),
- wsync, (data >> 3) & 1,
- m_formatting, data & 3 ));
-
- // abort previous command, if any
- m_op = OP_RESET;
- m_floppy_cmd->adjust(attotime::never);
-
- switch ( data & 3 )
- {
- case OP_RESET:
- m_stat0 = STAT0_FINISHED;
- break;
-
- case OP_WRITE_SECT:
- if ( qdd )
- logerror( "thmfc_floppy_w: smart operation 1 not supported for QDD\n" );
- else if ( floppy_find_sector( &id ) )
- {
- m_sector_id = id.data_id;
- m_data_idx = 0;
- m_data_size = m_sector_size + 3; // A1 A1 FB <data>
- m_data_finish = m_sector_size + 3;
- m_stat0 |= STAT0_BYTE_READY_OP;
- m_op = OP_WRITE_SECT;
- m_floppy_cmd->adjust(attotime::from_msec( 10 ));
- }
- break;
-
- case OP_READ_ADDR:
- if ( qdd )
- logerror( "thmfc_floppy_w: smart operation 2 not supported for QDD\n" );
- else if ( floppy_find_sector( &id ) )
- {
- m_data_size =
- floppy_make_addr( id, &m_data[0], m_sector_size );
- assert( m_data_size < THOM_MAXBUF );
- m_data_finish = 10;
- m_data_idx = 1;
- m_stat0 |= STAT0_BYTE_READY_OP;
- m_op = OP_READ_ADDR;
- m_floppy_cmd->adjust(attotime::from_msec( 1 ));
- }
- break;
-
- case OP_READ_SECT:
- if ( qdd )
- logerror( "thmfc_floppy_w: smart operation 3 not supported for QDD\n" );
- else if ( floppy_find_sector( &id ) )
- {
- m_data_size = floppy_make_sector
- ( get_floppy_image(), id, &m_data[0], m_sector_size );
- assert( m_data_size < THOM_MAXBUF );
- m_data_finish = m_sector_size + 4;
- m_data_idx = 1;
- m_stat0 |= STAT0_BYTE_READY_OP;
- m_op = OP_READ_SECT;
- m_floppy_cmd->adjust(attotime::from_msec( 10 ));
- }
- break;
- }
-
- // synchronize to word, if needed (QDD only)
- if ( wsync && qdd ) {
- if ( ! m_data_raw_size )
- m_data_raw_size = qdd_make_disk ( get_floppy_image(), &m_data[0] );
- while ( m_data_raw_idx < m_data_raw_size &&
- m_data[ m_data_raw_idx ] != m_wsync )
- {
- m_data_raw_idx++;
- }
- }
- }
-
- break;
-
-
- case 1: // CMD1
- m_data_raw_size = 0;
- m_sector_size = 128 << ( (data >> 5) & 3);
- m_side = (data >> 4) & 1;
- if ( m_sector_size > 256 )
- {
- logerror( "%s thmfc_floppy_w: sector size %i > 256 not handled\n",
- machine().describe_context(), m_sector_size );
- m_sector_size = 256;
- }
-
- LOG (( "%f %s thmfc_floppy_w: CMD1=$%02X sect-size=%i comp=%i head=%i\n",
- machine().time().as_double(), machine().describe_context(), data,
- m_sector_size, (data >> 1) & 7, m_side ));
- break;
-
-
- case 2: // CMD2
- {
- legacy_floppy_image_device * img;
- int seek = 0, motor;
- m_drive = data & 2;
-
- img = get_floppy_image();
- if ( floppy_is_qdd(img))
- {
- motor = !(data & 0x40);
- // no side select & no seek for QDD
- }
- else
- {
- if ( data & 0x10 )
- seek = (data & 0x20) ? 1 : -1;
- motor = (data >> 2) & 1;
- m_drive |= 1 ^ ((data >> 6) & 1);
- img = get_floppy_image();
- }
-
- m_floppy_active_cb( 0 );
-
- LOG (( "%f %s thmfc_floppy_w: CMD2=$%02X drv=%i step=%i motor=%i\n",
- machine().time().as_double(), machine().describe_context(), data,
- m_drive, seek, motor ));
-
- if ( seek )
- {
- m_data_raw_size = 0;
- img->floppy_drive_seek( seek );
- }
-
- /* in real life, to keep the motor running, it is sufficient to
- set motor to 1 every few seconds.
- instead of counting, we assume the motor is always running...
- */
- m_motor_on = CLEAR_LINE /* motor */;
- img->floppy_mon_w(m_motor_on);
- }
- break;
-
-
- case 3: // WDATA
- m_wsync = data;
- if ( floppy_is_qdd(get_floppy_image()))
- floppy_qdd_write_byte( data );
- else if ( m_op == OP_WRITE_SECT )
- floppy_write_byte( data );
- else if ( m_formatting )
- floppy_format_byte( data );
- else
- {
- // TODO: implement other forms of raw track writing
- LOG (( "%f %s thmfc_floppy_w: ignored raw WDATA $%02X\n",
- machine().time().as_double(), machine().describe_context(), data ));
- }
- break;
-
-
- case 4: // WCLK (unemulated)
- // clock configuration: FF for data, 0A for synchro
- LOG (( "%f %s thmfc_floppy_w: WCLK=$%02X (%s)\n",
- machine().time().as_double(), machine().describe_context(), data,
- (data == 0xff) ? "data" : (data == 0x0A) ? "synchro" : "?" ));
- break;
-
- case 5: // WSECT
- m_sector = data;
- LOG (( "%f %s thmfc_floppy_w: WSECT=%i\n",
- machine().time().as_double(), machine().describe_context(), data ));
- break;
-
- case 6: // WTRCK
- m_track = data;
- LOG (( "%f %s thmfc_floppy_w: WTRCK=%i (real=%i)\n",
- machine().time().as_double(), machine().describe_context(), data,
- get_floppy_image()->floppy_drive_get_current_track()));
- break;
-
- case 7: // WCELL
- // precompensation (unemulated)
- LOG (( "%f %s thmfc_floppy_w: WCELL=$%02X\n",
- machine().time().as_double(), machine().describe_context(), data ));
- break;
-
- default:
- logerror ( "%f %s thmfc_floppy_w: invalid write offset %i (data=$%02X)\n",
- machine().time().as_double(), machine().describe_context(), offset, data );
- }
-}
-
-
-
-void thmfc1_device::floppy_reset()
-{
- LOG(( "thmfc_floppy_reset: THMFC1 controller\n" ));
-
- for (auto &img : m_floppy_image)
- {
- img->floppy_drive_set_ready_state( FLOPPY_DRIVE_READY, 0 );
- img->floppy_drive_seek( - img->floppy_drive_get_current_track() );
- }
-
- m_op = OP_RESET;
- m_track = 0;
- m_sector = 0;
- m_side = 0;
- m_drive = 0;
- m_sector_size = 256;
- m_formatting = 0;
- m_stat0 = 0;
- m_data_idx = 0;
- m_data_size = 0;
- m_data_raw_idx = 0;
- m_data_raw_size = 0;
- m_data_crc = 0;
- m_wsync = 0;
- m_motor_on = 0;
- m_floppy_cmd->adjust(attotime::never);
-}
-
-
-
-void thmfc1_device::device_start()
-{
- m_data = make_unique_clear<uint8_t[]>(THOM_MAXBUF);
-
- m_floppy_cmd = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(thmfc1_device::floppy_cmd_complete_cb), this));
-
- save_item(NAME(m_op));
- save_item(NAME(m_sector));
- save_item(NAME(m_sector_id));
- save_item(NAME(m_track));
- save_item(NAME(m_side));
- save_item(NAME(m_drive));
- save_item(NAME(m_sector_size));
- save_item(NAME(m_formatting));
- save_item(NAME(m_ipl));
- save_item(NAME(m_data_idx));
- save_item(NAME(m_data_size));
- save_item(NAME(m_data_finish));
- save_item(NAME(m_stat0));
- save_item(NAME(m_data_raw_idx));
- save_item(NAME(m_data_raw_size));
- save_item(NAME(m_data_crc));
- save_item(NAME(m_wsync));
- save_item(NAME(m_motor_on));
- save_pointer(NAME(m_data), THOM_MAXBUF);
-}
-
-
-
-/*********************** Network ************************/
-
-/* The network extension is built as an external floppy controller.
- It uses the same ROM and I/O space, and so, it is natural to have the
- toplevel network emulation here!
-*/
-
-/* NOTE: This is work in progress!
- For the moment, only hand-checks works: the TO7 can take the line, then
- perform a DKBOOT request. We do not have the server emulated yet, so,
- no way to answer the request.
-*/
-
-TIMER_CALLBACK_MEMBER( thomson_state::ans4 )
-{
- LOG(( "%f ans4\n", machine().time().as_double() ));
- m_mc6854->set_cts( 0 );
-}
-
-TIMER_CALLBACK_MEMBER( thomson_state::ans3 )
-{
- LOG(( "%f ans3\n", machine().time().as_double() ));
- m_mc6854->set_cts( 1 );
- machine().scheduler().timer_set( attotime::from_usec( 100 ), timer_expired_delegate(FUNC(thomson_state::ans4),this));
-}
-
-TIMER_CALLBACK_MEMBER( thomson_state::ans2 )
-{
- LOG(( "%f ans2\n", machine().time().as_double() ));
- m_mc6854->set_cts( 0 );
- machine().scheduler().timer_set( attotime::from_usec( 100 ), timer_expired_delegate(FUNC(thomson_state::ans3),this));
-}
-
-TIMER_CALLBACK_MEMBER( thomson_state::ans )
-{
- LOG(( "%f ans\n", machine().time().as_double() ));
- m_mc6854->set_cts( 1 );
- machine().scheduler().timer_set( attotime::from_usec( 100 ), timer_expired_delegate(FUNC(thomson_state::ans2),this));
-}
-/* consigne DKBOOT
-
- MO5 BASIC
- $00 $00 $01 $00 $00 $00 $00 $00 $00 $00 $01 $00<$41 $00 $FF $20
- $3D $4C $01 $60 $20 $3C $4F $01 $05 $20 $3F $9C $19 $25 $03 $11
- $93 $15 $10 $25 $32 $8A $7E $FF $E1 $FD $E9 $41>$00 $00 $00 $00
- $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00
-
- TO7/70 BASIC
- $00 $00 $01 $00 $00 $00 $00 $00 $00 $00 $02 $00<$20 $42 $41 $53
- $49 $43 $20 $4D $49 $43 $52 $4F $53 $4F $46 $54 $20 $31 $2E $30
- $04 $00 $00 $00 $00 $00 $60 $FF $37 $9B $37 $9C>$00 $00 $00 $00
- $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00
-
- TO7 BASIC
- $00 $00 $01 $00 $00 $00 $00 $00 $00 $00 $00 $00<$20 $42 $41 $53
- $49 $43 $20 $4D $49 $43 $52 $4F $53 $4F $46 $54 $20 $31 $2E $30
- $04 $00 $00 $00 $00 $00 $60 $FF $37 $9B $37 $9C>$00 $00 $00 $00
- $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00
-
- TO7 LOGO
- $00 $00 $01 $00 $00 $00 $00 $00 $00 $00 $00 $00<$00 $00 $00 $00
- $00 $20 $4C $4F $47 $4F $04 $00 $00 $00 $00 $00 $00 $00 $00 $00
- $00 $00 $00 $00 $00 $00 $AA $FF $01 $16 $00 $C8>$00 $00 $00 $00
- $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00 $00
-
-
-*/
-
-void thomson_state::to7_network_got_frame(uint8_t *data, int length)
-{
- LOG(( "%f to7_network_got_frame:", machine().time().as_double() ));
- for ( int i = 0; i < length; i++ )
- LOG(( " $%02X", data[i] ));
- LOG(( "\n" ));
-
- if ( data[1] == 0xff )
- {
- LOG(( "to7_network_got_frame: %i phones %i\n", data[2], data[0] ));
- machine().scheduler().timer_set( attotime::from_usec( 100 ), timer_expired_delegate(FUNC(thomson_state::ans), this));
- m_mc6854->set_cts( 0 );
- }
- else if ( ! data[1] )
- {
- char name[33];
- memcpy( name, data + 12, 32 );
- name[32] = 0;
- for (int i=0;i<32;i++)
- {
- if ( name[i]<32 || name[i]>=127 )
- name[i]=' ';
- }
- LOG(( "to7_network_got_frame: DKBOOT system=%s appli=\"%s\"\n",
- (data[10] == 0) ? "TO7" : (data[10] == 1) ? "MO5" :
- (data[10] == 2) ? "TO7/70" : "?", name ));
- }
-}
-
-
-void thomson_state::to7_network_init()
-{
- LOG(( "to7_network_init: NR 07-005 network extension\n" ));
- logerror( "to7_network_init: network not handled!\n" );
-}
-
-
-
-void thomson_state::to7_network_reset()
-{
- LOG(( "to7_network_reset: NR 07-005 network extension\n" ));
- m_mc6854->set_cts( 0 );
- m_mc6854->set_cts( 1 );
-}
-
-
-
-uint8_t thomson_state::to7_network_r(offs_t offset)
-{
- if ( offset < 4 )
- return m_mc6854->read(offset);
-
- if ( offset == 8 )
- {
- // network ID of the computer
- uint8_t id = m_io_fconfig->read() >> 3;
- VLOG(( "%f $%04x to7_network_r: read id $%02X\n", machine().time().as_double(), m_maincpu->pc(), id ));
- return id;
- }
-
- logerror( "%f $%04x to7_network_r: invalid read offset %i\n", machine().time().as_double(), m_maincpu->pc(), offset );
- return 0;
-}
-
-
-
-void thomson_state::to7_network_w(offs_t offset, uint8_t data)
-{
- if ( offset < 4 )
- m_mc6854->write(offset, data);
- else
- {
- logerror( "%f $%04x to7_network_w: invalid write offset %i (data=$%02X)\n",
- machine().time().as_double(), m_maincpu->pc(), offset, data );
- }
-}
-
-
-
-/*********************** TO7 dispatch ************************/
-
-/* The TO7, TO7/70, MO5 and MO6 can use a variety of floppy controllers.
- We use a PORT_CONFSETTING to chose the current controller, and dispatch
- here.
-
- NOTE: you need to reset the computer after changing the floppy controller!
-
- The CD 90-351 controller seems similar to the THMFC1 gate-array
- => we reuse the THMFC code!
-*/
-
-
-
-void thomson_state::to7_floppy_init()
-{
- m_flopbank->configure_entry( 0, memregion("floppy_none")->base() );
- m_flopbank->configure_entry( 1, memregion("floppy_cd90_015")->base() );
- m_flopbank->configure_entry( 2, memregion("floppy_cd90_640")->base() );
- m_flopbank->configure_entries( 3, 4, memregion("floppy_cd90_351")->base(), 0x800 );
- m_flopbank->configure_entry( 7, memregion("floppy_cq90_028")->base() );
- m_flopbank->configure_entry( 8, memregion("floppy_nano")->base() );
- save_item(NAME(m_to7_controller_type));
- save_item(NAME(m_to7_floppy_bank));
- to7_5p14sd_init();
- to7_5p14_init();
- to7_network_init();
-}
-
-
-
-void thomson_state::to7_floppy_reset()
-{
- m_to7_controller_type = (m_io_fconfig->read() ) & 7;
-
- switch ( m_to7_controller_type )
- {
- case 1:
- m_to7_floppy_bank = 1;
- to7_5p14sd_reset();
- break;
-
- case 2:
- m_to7_floppy_bank = 2;
- to7_5p14_reset();
- break;
-
- case 3:
- m_to7_floppy_bank = 3;
- m_thmfc->floppy_reset();
- break;
-
- case 4:
- m_to7_floppy_bank = 7;
- m_to7qdd->qdd_reset();
- break;
-
- case 5:
- m_to7_floppy_bank = 8;
- to7_network_reset();
- break;
-
- default:
- m_to7_floppy_bank = 0;
- break;
- }
-
- m_flopbank->set_entry( m_to7_floppy_bank );
-}
-
-
-
-uint8_t thomson_state::to7_floppy_r(offs_t offset)
-{
- switch (m_to7_controller_type)
- {
- case 1:
- return to7_5p14sd_r(offset);
-
- case 2:
- return to7_5p14_r(offset);
-
- case 3:
- return m_thmfc->floppy_r(offset);
-
- case 4:
- return m_to7qdd->qdd_r(offset);
-
- case 5:
- return to7_network_r(offset);
- }
-
- return 0;
-}
-
-
-
-void thomson_state::to7_floppy_w(offs_t offset, uint8_t data)
-{
- switch (m_to7_controller_type)
- {
- case 1:
- to7_5p14sd_w(offset, data);
- return;
-
- case 2:
- to7_5p14_w(offset, data);
- break;
-
- case 3:
- if (offset == 8)
- {
- m_to7_floppy_bank = 3 + (data & 3);
- m_flopbank->set_entry(m_to7_floppy_bank);
- VLOG (( "to7_floppy_w: set CD 90-351 ROM bank to %i\n", data & 3 ));
- }
- else
- m_thmfc->floppy_w(offset, data);
- break;
-
- case 4:
- m_to7qdd->qdd_w(offset, data);
- break;
-
- case 5:
- to7_network_w(offset, data);
- break;
- }
-}
-
-
-
-/*********************** TO9 ************************/
-
-/* the internal controller is WD2793-based (so, similar to to7_5p14)
- we also emulate external controllers
-*/
-
-
-
-void thomson_state::to9_floppy_init( void* int_base )
-{
- to7_floppy_init();
- m_flopbank->configure_entry( TO7_NB_FLOP_BANK, int_base);
-}
-
-
-
-void thomson_state::to9_floppy_reset()
-{
- to7_floppy_reset();
- if ( THOM_FLOPPY_EXT )
- {
- LOG(( "to9_floppy_reset: external controller\n" ));
- }
- else
- {
- LOG(( "to9_floppy_reset: internal controller\n" ));
- to7_5p14_reset();
- m_flopbank->set_entry( TO7_NB_FLOP_BANK );
- }
-}
-
-
-
-uint8_t thomson_state::to9_floppy_r(offs_t offset)
-{
- if ( THOM_FLOPPY_EXT )
- return to7_floppy_r( offset );
- else
- return to7_5p14_r( offset );
-}
-
-void thomson_state::to9_floppy_w(offs_t offset, uint8_t data)
-{
- if ( THOM_FLOPPY_EXT )
- to7_floppy_w( offset, data );
- else
- to7_5p14_w( offset, data );
-}
-
-void thomson_state::thomson_index_callback(int index, int state)
-{
- switch ( m_to7_controller_type )
- {
- case 1:
- to7_5p14_index_pulse_callback(state);
- break;
-
- case 2:
- break;
-
- case 3:
- m_thmfc->index_pulse_cb(index, state);
- break;
-
- case 4:
- m_to7qdd->index_pulse_cb(state);
- break;
-
- default:
- break;
- }
-}
diff --git a/src/mame/machine/thomflop.h b/src/mame/machine/thomflop.h
deleted file mode 100644
index 4bb2b05882a..00000000000
--- a/src/mame/machine/thomflop.h
+++ /dev/null
@@ -1,159 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Antoine Mine
-/**********************************************************************
-
- Copyright (C) Antoine Mine' 2006
-
- Thomson 8-bit computers
-
-**********************************************************************/
-
-#ifndef THOMFLOP_H_
-#define THOMFLOP_H_
-
-#include "image.h"
-#include "imagedev/flopdrv.h"
-#include "machine/mc6843.h"
-#include "machine/mc6854.h"
-
-/* number of external floppy controller ROM banks */
-#define TO7_NB_FLOP_BANK 9
-
-/* external floppy / network controller active */
-#define THOM_FLOPPY_EXT (m_to7_controller_type >= 1)
-
-/* internal floppy controller active (no or network extension) */
-#define THOM_FLOPPY_INT (m_to7_controller_type == 0 || m_to7_controller_type > 4)
-
-
-/* external controllers */
-/* TO9 internal (WD2793) & external controllers */
-/* TO8 internal (THMFC1) controller */
-
-class thomson_legacy_floppy_interface : public device_interface
-{
-protected:
- thomson_legacy_floppy_interface(const machine_config &mconfig, device_t &device)
- : device_interface(device, "thom_flop")
- {
- }
-
- static int floppy_make_addr(chrn_id id, uint8_t *dst, int sector_size);
- static int floppy_make_sector(legacy_floppy_image_device *img, chrn_id id, uint8_t *dst, int sector_size);
- static int floppy_make_track(legacy_floppy_image_device *img, uint8_t *dst, int sector_size, int side);
-
- static int qdd_make_addr(int sector, uint8_t *dst);
- static int qdd_make_sector(legacy_floppy_image_device *img, int sector, uint8_t *dst);
- static int qdd_make_disk(legacy_floppy_image_device *img, uint8_t *dst);
-};
-
-class thmfc1_device : public device_t, public thomson_legacy_floppy_interface
-{
-public:
- thmfc1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
- auto floppy_active_cb() { return m_floppy_active_cb.bind(); }
-
- uint8_t floppy_r(offs_t offset);
- void floppy_w(offs_t offset, uint8_t data);
-
- void index_pulse_cb( int index, int state );
- void floppy_reset();
-
-protected:
- virtual void device_resolve_objects() override;
- virtual void device_start() override;
-
-private:
- // types of high-level operations
- enum thmfc1_op : uint8_t
- {
- OP_RESET = 0,
- OP_WRITE_SECT = 1,
- OP_READ_ADDR = 2,
- OP_READ_SECT = 3
- };
-
- TIMER_CALLBACK_MEMBER( floppy_cmd_complete_cb );
- legacy_floppy_image_device *get_floppy_image();
- bool floppy_is_qdd( legacy_floppy_image_device *image ) const;
- int floppy_find_sector( chrn_id* dst );
- void floppy_cmd_complete();
- uint8_t floppy_read_byte();
- uint8_t floppy_raw_read_byte();
- void floppy_qdd_write_byte( uint8_t data );
- void floppy_write_byte( uint8_t data );
- void floppy_format_byte( uint8_t data );
-
- required_device_array<legacy_floppy_image_device, 4> m_floppy_image;
-
- devcb_write_line m_floppy_active_cb;
-
- thmfc1_op m_op;
- uint8_t m_sector; // target sector, in [1,16]
- uint32_t m_sector_id;
- uint8_t m_track; // current track, in [0,79]
- uint8_t m_side; // current side, 0 or 1
- uint8_t m_drive; // 0 to 3
- uint16_t m_sector_size; // 128 or 256 (512, 1024 not supported)
- uint8_t m_formatting;
- uint8_t m_ipl; // index pulse / QDD start
- uint8_t m_wsync; // synchronization word
- int m_motor_on;
-
- std::unique_ptr<uint8_t[]> m_data; // enough for a whole track
- uint32_t m_data_idx; // reading / writing / formatting pos
- uint32_t m_data_size; // bytes to read / write
- uint32_t m_data_finish; // when to raise the finished flag
- uint32_t m_data_raw_idx; // byte index for raw track reading
- uint32_t m_data_raw_size; // size of track already cached in data
- uint8_t m_data_crc; // check-sum of written data
-
- uint8_t m_stat0; // status register
-
- emu_timer *m_floppy_cmd;
-};
-
-class cq90_028_device : public device_t, public thomson_legacy_floppy_interface
-{
-public:
- cq90_028_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
- uint8_t qdd_r(offs_t offset);
- void qdd_w(offs_t offset, uint8_t data);
-
- void index_pulse_cb(int state);
- void qdd_reset();
-
-protected:
- virtual void device_start() override;
-
-private:
- void stat_update();
- uint8_t qdd_read_byte();
- void qdd_write_byte(uint8_t data);
-
- required_device<legacy_floppy_image_device> m_qdd_image;
-
- // MC6852 registers
- uint8_t m_status;
- uint8_t m_ctrl1;
- uint8_t m_ctrl2;
- uint8_t m_ctrl3;
-
- // extra registers
- uint8_t m_drive;
-
- // internal state
- std::unique_ptr<uint8_t[]> m_data; // enough for a whole track
- uint32_t m_data_idx; // byte position in track
- uint32_t m_start_idx; // start of write position
- uint32_t m_data_size; // track length
- uint8_t m_data_crc; // checksum when writing
- uint8_t m_index_pulse; // one pulse per track
-};
-
-DECLARE_DEVICE_TYPE(THMFC1, thmfc1_device)
-DECLARE_DEVICE_TYPE(CQ90_028, cq90_028_device)
-
-#endif /* THOMFLOP_H_ */
diff --git a/src/mame/machine/thomson.cpp b/src/mame/machine/thomson.cpp
index 01a88fbef5e..16afac21ceb 100644
--- a/src/mame/machine/thomson.cpp
+++ b/src/mame/machine/thomson.cpp
@@ -10,8 +10,6 @@
#include "emu.h"
#include "includes/thomson.h"
-#include "machine/thomflop.h"
-#include "formats/thom_dsk.h"
#include "machine/6821pia.h"
#include "machine/ram.h"
@@ -915,7 +913,8 @@ void thomson_state::to7_game_reset()
uint8_t thomson_state::to7_midi_r()
{
- logerror( "to7_midi_r: not implemented\n" );
+ if(!machine().side_effects_disabled())
+ logerror( "to7_midi_r: not implemented\n" );
return 0;
}
@@ -953,14 +952,16 @@ MACHINE_RESET_MEMBER( thomson_state, to7 )
/* subsystems */
thom_irq_reset();
to7_game_reset();
- to7_floppy_reset();
to7_modem_reset();
to7_midi_reset();
+ m_extension->rom_map(m_maincpu->space(AS_PROGRAM), 0xe000, 0xe7bf);
+ m_extension->io_map (m_maincpu->space(AS_PROGRAM), 0xe7d0, 0xe7df);
+
/* video */
thom_set_video_mode( THOM_VMODE_TO770 );
m_thom_init_cb = &thomson_state::to7_set_init;
- m_thom_lightpen_cb = &thomson_state::to7_lightpen_cb;
+ m_thom_lightpen_cb = std::bind(&thomson_state::to7_lightpen_cb, this, std::placeholders::_1);
thom_set_lightpen_callback( 3 );
thom_set_mode_point( 0 );
thom_set_border_color( 0 );
@@ -986,10 +987,12 @@ MACHINE_START_MEMBER( thomson_state, to7 )
/* subsystems */
to7_game_init();
- to7_floppy_init();
to7_modem_init();
to7_midi_init();
+ m_extension->rom_map(m_maincpu->space(AS_PROGRAM), 0xe000, 0xe7bf);
+ m_extension->io_map (m_maincpu->space(AS_PROGRAM), 0xe7d0, 0xe7df);
+
/* memory */
m_thom_cart_bank = 0;
m_thom_vram = ram;
@@ -1175,14 +1178,16 @@ MACHINE_RESET_MEMBER( thomson_state, to770 )
/* subsystems */
thom_irq_reset();
to7_game_reset();
- to7_floppy_reset();
to7_modem_reset();
to7_midi_reset();
+ m_extension->rom_map(m_maincpu->space(AS_PROGRAM), 0xe000, 0xe7bf);
+ m_extension->io_map (m_maincpu->space(AS_PROGRAM), 0xe7d0, 0xe7df);
+
/* video */
thom_set_video_mode( THOM_VMODE_TO770 );
m_thom_init_cb = &thomson_state::to7_set_init;
- m_thom_lightpen_cb = &thomson_state::to7_lightpen_cb;
+ m_thom_lightpen_cb = std::bind(&thomson_state::to7_lightpen_cb, this, std::placeholders::_1);
thom_set_lightpen_callback( 3 );
thom_set_mode_point( 0 );
thom_set_border_color( 8 );
@@ -1210,10 +1215,12 @@ MACHINE_START_MEMBER( thomson_state, to770 )
/* subsystems */
to7_game_init();
- to7_floppy_init();
to7_modem_init();
to7_midi_init();
+ m_extension->rom_map(m_maincpu->space(AS_PROGRAM), 0xe000, 0xe7bf);
+ m_extension->io_map (m_maincpu->space(AS_PROGRAM), 0xe7d0, 0xe7df);
+
/* memory */
m_thom_cart_bank = 0;
m_thom_vram = ram;
@@ -1246,7 +1253,7 @@ MACHINE_START_MEMBER( thomson_state, to770 )
-void thomson_state::mo5_lightpen_cb( int step )
+void mo5_state::mo5_lightpen_cb( int step )
{
/* MO5 signals ca1 (TO7 signals cb1) */
if ( ! m_to7_lightpen )
@@ -1286,7 +1293,7 @@ void thomson_state::mo5_init_timer()
-void thomson_state::mo5_sys_porta_out(uint8_t data)
+void mo5_state::mo5_sys_porta_out(uint8_t data)
{
thom_set_mode_point( data & 1 ); /* bit 0: video bank switch */
thom_set_border_color( (data >> 1) & 15 ); /* bit 1-4: border color */
@@ -1295,7 +1302,7 @@ void thomson_state::mo5_sys_porta_out(uint8_t data)
-uint8_t thomson_state::mo5_sys_porta_in()
+uint8_t mo5_state::mo5_sys_porta_in()
{
return
((m_io_lightpen_button->read() & 1) ? 0x20 : 0) | /* bit 5: lightpen button */
@@ -1305,7 +1312,7 @@ uint8_t thomson_state::mo5_sys_porta_in()
-uint8_t thomson_state::mo5_sys_portb_in()
+uint8_t mo5_state::mo5_sys_portb_in()
{
uint8_t portb = m_pia_sys->b_output();
int col = (portb >> 1) & 7; /* key column */
@@ -1324,7 +1331,7 @@ uint8_t thomson_state::mo5_sys_portb_in()
-uint8_t thomson_state::mo5_gatearray_r(offs_t offset)
+uint8_t mo5_state::mo5_gatearray_r(offs_t offset)
{
struct thom_vsignal v = thom_get_vsignal();
struct thom_vsignal l = thom_get_lightpen_vsignal( MO5_LIGHTPEN_DECAL, m_to7_lightpen_step - 1, 0 );
@@ -1347,7 +1354,7 @@ uint8_t thomson_state::mo5_gatearray_r(offs_t offset)
-void thomson_state::mo5_gatearray_w(offs_t offset, uint8_t data)
+void mo5_state::mo5_gatearray_w(offs_t offset, uint8_t data)
{
if ( ! offset )
m_to7_lightpen = data & 1;
@@ -1419,7 +1426,7 @@ DEVICE_IMAGE_LOAD_MEMBER( thomson_state::mo5_cartridge )
-void thomson_state::mo5_update_cart_bank()
+void mo5_state::mo5_update_cart_bank()
{
address_space& space = m_maincpu->space(AS_PROGRAM);
int rom_is_ram = m_mo5_reg_cart & 4;
@@ -1475,8 +1482,8 @@ void thomson_state::mo5_update_cart_bank()
if ( m_old_cart_bank < 0 )
{
space.install_read_bank( 0xb000, 0xefff, m_cartbank);
- space.install_write_handler( 0xb000, 0xefff, write8sm_delegate(*this, FUNC(thomson_state::mo5_cartridge_w)) );
- space.install_read_handler( 0xbffc, 0xbfff, read8sm_delegate(*this, FUNC(thomson_state::mo5_cartridge_r)) );
+ space.install_write_handler( 0xb000, 0xefff, write8sm_delegate(*this, FUNC(mo5_state::mo5_cartridge_w)) );
+ space.install_read_handler( 0xbffc, 0xbfff, read8sm_delegate(*this, FUNC(mo5_state::mo5_cartridge_r)) );
}
LOG_BANK(( "mo5_update_cart_bank: CART is cartridge bank %i\n", bank ));
}
@@ -1487,7 +1494,7 @@ void thomson_state::mo5_update_cart_bank()
if ( m_old_cart_bank != 0 )
{
space.install_read_bank( 0xb000, 0xefff, m_cartbank);
- space.install_write_handler( 0xb000, 0xefff, write8sm_delegate(*this, FUNC(thomson_state::mo5_cartridge_w)) );
+ space.install_write_handler( 0xb000, 0xefff, write8sm_delegate(*this, FUNC(mo5_state::mo5_cartridge_w)) );
LOG_BANK(( "mo5_update_cart_bank: CART is internal\n"));
}
}
@@ -1501,7 +1508,7 @@ void thomson_state::mo5_update_cart_bank()
-void thomson_state::mo5_update_cart_bank_postload()
+void mo5_state::mo5_update_cart_bank_postload()
{
mo5_update_cart_bank();
}
@@ -1509,7 +1516,7 @@ void thomson_state::mo5_update_cart_bank_postload()
/* write signal to b000-cfff generates a bank switch */
-void thomson_state::mo5_cartridge_w(offs_t offset, uint8_t data)
+void mo5_state::mo5_cartridge_w(offs_t offset, uint8_t data)
{
if ( offset >= 0x2000 )
return;
@@ -1521,7 +1528,7 @@ void thomson_state::mo5_cartridge_w(offs_t offset, uint8_t data)
/* read signal to bffc-bfff generates a bank switch */
-uint8_t thomson_state::mo5_cartridge_r(offs_t offset)
+uint8_t mo5_state::mo5_cartridge_r(offs_t offset)
{
uint8_t data = m_cart_rom[offset + 0x3ffc + (m_thom_cart_bank % m_thom_cart_nb_banks) * 0x4000];
if ( !machine().side_effects_disabled() )
@@ -1535,7 +1542,7 @@ uint8_t thomson_state::mo5_cartridge_r(offs_t offset)
/* 0xa7cb bank-switch register */
-void thomson_state::mo5_ext_w(uint8_t data)
+void mo5_state::mo5_ext_w(uint8_t data)
{
m_mo5_reg_cart = data;
mo5_update_cart_bank();
@@ -1547,21 +1554,20 @@ void thomson_state::mo5_ext_w(uint8_t data)
-MACHINE_RESET_MEMBER( thomson_state, mo5 )
+MACHINE_RESET_MEMBER( mo5_state, mo5 )
{
LOG (( "mo5: machine reset called\n" ));
/* subsystems */
thom_irq_reset();
to7_game_reset();
- to7_floppy_reset();
to7_modem_reset();
to7_midi_reset();
mo5_init_timer();
/* video */
thom_set_video_mode( THOM_VMODE_MO5 );
- m_thom_lightpen_cb = &thomson_state::mo5_lightpen_cb;
+ m_thom_lightpen_cb = std::bind(&mo5_state::mo5_lightpen_cb, this, std::placeholders::_1);
thom_set_lightpen_callback( 3 );
thom_set_mode_point( 0 );
thom_set_border_color( 0 );
@@ -1579,7 +1585,7 @@ MACHINE_RESET_MEMBER( thomson_state, mo5 )
-MACHINE_START_MEMBER( thomson_state, mo5 )
+MACHINE_START_MEMBER( mo5_state, mo5 )
{
uint8_t* mem = memregion("maincpu")->base();
uint8_t* cartmem = &m_cart_rom[0];
@@ -1589,10 +1595,12 @@ MACHINE_START_MEMBER( thomson_state, mo5 )
/* subsystems */
to7_game_init();
- to7_floppy_init();
to7_modem_init();
to7_midi_init();
- m_mo5_periodic_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(thomson_state::mo5_periodic_cb),this));
+ m_mo5_periodic_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mo5_state::mo5_periodic_cb),this));
+
+ m_extension->rom_map(m_maincpu->space(AS_PROGRAM), 0xa000, 0xa7bf);
+ m_extension->io_map (m_maincpu->space(AS_PROGRAM), 0xa7d0, 0xa7df);
/* memory */
m_thom_cart_bank = 0;
@@ -1614,7 +1622,7 @@ MACHINE_START_MEMBER( thomson_state, mo5 )
save_item(NAME(m_to7_lightpen_step));
save_item(NAME(m_mo5_reg_cart));
save_pointer(NAME(cartmem), 0x10000 );
- machine().save().register_postload(save_prepost_delegate(FUNC(thomson_state::mo5_update_cart_bank_postload), this));
+ machine().save().register_postload(save_prepost_delegate(FUNC(mo5_state::mo5_update_cart_bank_postload), this));
}
@@ -1631,14 +1639,14 @@ MACHINE_START_MEMBER( thomson_state, mo5 )
-void thomson_state::to9_ieee_w(offs_t offset, uint8_t data)
+void to9_state::to9_ieee_w(offs_t offset, uint8_t data)
{
logerror( "$%04x %f to9_ieee_w: unhandled write $%02X to register %i\n", m_maincpu->pc(), machine().time().as_double(), data, offset );
}
-uint8_t thomson_state::to9_ieee_r(offs_t offset)
+uint8_t to9_state::to9_ieee_r(offs_t offset)
{
logerror( "$%04x %f to9_ieee_r: unhandled read from register %i\n", m_maincpu->pc(), machine().time().as_double(), offset );
return 0;
@@ -1654,7 +1662,7 @@ uint8_t thomson_state::to9_ieee_r(offs_t offset)
-uint8_t thomson_state::to9_gatearray_r(offs_t offset)
+uint8_t to9_state::to9_gatearray_r(offs_t offset)
{
struct thom_vsignal v = thom_get_vsignal();
struct thom_vsignal l = thom_get_lightpen_vsignal( TO9_LIGHTPEN_DECAL, m_to7_lightpen_step - 1, 0 );
@@ -1678,7 +1686,7 @@ uint8_t thomson_state::to9_gatearray_r(offs_t offset)
-void thomson_state::to9_gatearray_w(offs_t offset, uint8_t data)
+void to9_state::to9_gatearray_w(offs_t offset, uint8_t data)
{
if ( ! offset )
m_to7_lightpen = data & 1;
@@ -1691,7 +1699,7 @@ void thomson_state::to9_gatearray_w(offs_t offset, uint8_t data)
/* style: 0 => TO9, 1 => TO8/TO9, 2 => MO6 */
-void thomson_state::to9_set_video_mode( uint8_t data, int style )
+void to9_state::to9_set_video_mode( uint8_t data, int style )
{
switch ( data & 0x7f )
{
@@ -1744,7 +1752,7 @@ void thomson_state::to9_set_video_mode( uint8_t data, int style )
-uint8_t thomson_state::to9_vreg_r(offs_t offset)
+uint8_t to9_state::to9_vreg_r(offs_t offset)
{
switch ( offset )
{
@@ -1773,7 +1781,7 @@ uint8_t thomson_state::to9_vreg_r(offs_t offset)
-void thomson_state::to9_vreg_w(offs_t offset, uint8_t data)
+void to9_state::to9_vreg_w(offs_t offset, uint8_t data)
{
LOG_VIDEO(( "$%04x %f to9_vreg_w: off=%i ($%04X) data=$%02X\n", m_maincpu->pc(), machine().time().as_double(), offset, 0xe7da + offset, data ));
@@ -1810,7 +1818,7 @@ void thomson_state::to9_vreg_w(offs_t offset, uint8_t data)
-void thomson_state::to9_palette_init()
+void to9_state::to9_palette_init()
{
m_to9_palette_idx = 0;
memset( m_to9_palette_data, 0, sizeof( m_to9_palette_data ) );
@@ -1823,7 +1831,7 @@ void thomson_state::to9_palette_init()
/* ------------ RAM / ROM banking ------------ */
-void thomson_state::to9_update_cart_bank()
+void to9_state::to9_update_cart_bank()
{
address_space& space = m_maincpu->space(AS_PROGRAM);
int bank = 0;
@@ -1877,8 +1885,8 @@ void thomson_state::to9_update_cart_bank()
if ( m_old_cart_bank < 0 || m_old_cart_bank > 3 )
{
space.install_read_bank( 0x0000, 0x3fff, m_cartbank );
- space.install_write_handler( 0x0000, 0x3fff, write8sm_delegate(*this, FUNC(thomson_state::to9_cartridge_w)) );
- space.install_read_handler( 0x0000, 0x0003, read8sm_delegate(*this, FUNC(thomson_state::to9_cartridge_r)) );
+ space.install_write_handler( 0x0000, 0x3fff, write8sm_delegate(*this, FUNC(to9_state::to9_cartridge_w)) );
+ space.install_read_handler( 0x0000, 0x0003, read8sm_delegate(*this, FUNC(to9_state::to9_cartridge_r)) );
}
LOG_BANK(( "to9_update_cart_bank: CART is cartridge bank %i\n", m_thom_cart_bank ));
}
@@ -1902,7 +1910,7 @@ void thomson_state::to9_update_cart_bank()
-void thomson_state::to9_update_cart_bank_postload()
+void to9_state::to9_update_cart_bank_postload()
{
to9_update_cart_bank();
}
@@ -1910,7 +1918,7 @@ void thomson_state::to9_update_cart_bank_postload()
/* write signal to 0000-1fff generates a bank switch */
-void thomson_state::to9_cartridge_w(offs_t offset, uint8_t data)
+void to9_state::to9_cartridge_w(offs_t offset, uint8_t data)
{
int slot = ( m_mc6846->get_output_port() >> 4 ) & 3; /* bits 4-5: ROM bank */
@@ -1927,7 +1935,7 @@ void thomson_state::to9_cartridge_w(offs_t offset, uint8_t data)
/* read signal to 0000-0003 generates a bank switch */
-uint8_t thomson_state::to9_cartridge_r(offs_t offset)
+uint8_t to9_state::to9_cartridge_r(offs_t offset)
{
uint8_t data = m_cart_rom[offset + (m_thom_cart_bank % m_thom_cart_nb_banks) * 0x4000];
if ( !machine().side_effects_disabled() )
@@ -1940,7 +1948,7 @@ uint8_t thomson_state::to9_cartridge_r(offs_t offset)
-void thomson_state::to9_update_ram_bank()
+void to9_state::to9_update_ram_bank()
{
address_space& space = m_maincpu->space(AS_PROGRAM);
uint8_t port = m_mc6846->get_output_port();
@@ -1986,7 +1994,7 @@ void thomson_state::to9_update_ram_bank()
-void thomson_state::to9_update_ram_bank_postload()
+void to9_state::to9_update_ram_bank_postload()
{
to9_update_ram_bank();
}
@@ -2019,7 +2027,7 @@ void thomson_state::to9_update_ram_bank_postload()
/* quick keyboard scan */
-int thomson_state::to9_kbd_ktest()
+int to9_state::to9_kbd_ktest()
{
int line, bit;
uint8_t port;
@@ -2042,7 +2050,7 @@ int thomson_state::to9_kbd_ktest()
-void thomson_state::to9_kbd_update_irq()
+void to9_state::to9_kbd_update_irq()
{
if ( (m_to9_kbd_intr & 4) && (m_to9_kbd_status & ACIA_6850_RDRF) )
m_to9_kbd_status |= ACIA_6850_irq; /* byte received interrupt */
@@ -2058,7 +2066,7 @@ void thomson_state::to9_kbd_update_irq()
-uint8_t thomson_state::to9_kbd_r(offs_t offset)
+uint8_t to9_state::to9_kbd_r(offs_t offset)
{
/* ACIA 6850 registers */
@@ -2105,7 +2113,7 @@ uint8_t thomson_state::to9_kbd_r(offs_t offset)
-void thomson_state::to9_kbd_w(offs_t offset, uint8_t data)
+void to9_state::to9_kbd_w(offs_t offset, uint8_t data)
{
/* ACIA 6850 registers */
@@ -2186,7 +2194,7 @@ void thomson_state::to9_kbd_w(offs_t offset, uint8_t data)
note: parity is not used as a checksum but to actually transmit a 9-th bit
of information!
*/
-void thomson_state::to9_kbd_send( uint8_t data, int parity )
+void to9_state::to9_kbd_send( uint8_t data, int parity )
{
if ( m_to9_kbd_status & ACIA_6850_RDRF )
{
@@ -2250,7 +2258,7 @@ static const int to9_kbd_code[80][2] =
/* returns the ASCII code for the key, or 0 for no key */
-int thomson_state::to9_kbd_get_key()
+int to9_state::to9_kbd_get_key()
{
int control = ! (m_io_keyboard[7]->read() & 1);
int shift = ! (m_io_keyboard[9]->read() & 1);
@@ -2336,7 +2344,7 @@ int thomson_state::to9_kbd_get_key()
-TIMER_CALLBACK_MEMBER(thomson_state::to9_kbd_timer_cb)
+TIMER_CALLBACK_MEMBER(to9_state::to9_kbd_timer_cb)
{
if ( m_to9_kbd_periph )
{
@@ -2393,7 +2401,7 @@ TIMER_CALLBACK_MEMBER(thomson_state::to9_kbd_timer_cb)
-void thomson_state::to9_kbd_reset()
+void to9_state::to9_kbd_reset()
{
LOG(( "to9_kbd_reset called\n" ));
m_to9_kbd_overrun = 0; /* no byte lost */
@@ -2412,10 +2420,10 @@ void thomson_state::to9_kbd_reset()
-void thomson_state::to9_kbd_init()
+void to9_state::to9_kbd_init()
{
LOG(( "to9_kbd_init called\n" ));
- m_to9_kbd_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(thomson_state::to9_kbd_timer_cb),this));
+ m_to9_kbd_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(to9_state::to9_kbd_timer_cb),this));
save_item(NAME(m_to9_kbd_parity));
save_item(NAME(m_to9_kbd_intr));
save_item(NAME(m_to9_kbd_in));
@@ -2434,7 +2442,7 @@ void thomson_state::to9_kbd_init()
/* ------------ system PIA 6821 ------------ */
-uint8_t thomson_state::to9_sys_porta_in()
+uint8_t to9_state::to9_sys_porta_in()
{
uint8_t ktest = to9_kbd_ktest();
@@ -2446,7 +2454,7 @@ uint8_t thomson_state::to9_sys_porta_in()
-void thomson_state::to9_sys_porta_out(uint8_t data)
+void to9_state::to9_sys_porta_out(uint8_t data)
{
m_centronics->write_data1(BIT(data, 1));
m_centronics->write_data2(BIT(data, 2));
@@ -2459,7 +2467,7 @@ void thomson_state::to9_sys_porta_out(uint8_t data)
-void thomson_state::to9_sys_portb_out(uint8_t data)
+void to9_state::to9_sys_portb_out(uint8_t data)
{
m_centronics->write_data0(BIT(data, 0));
m_centronics->write_strobe(BIT(data, 1));
@@ -2476,7 +2484,7 @@ void thomson_state::to9_sys_portb_out(uint8_t data)
-void thomson_state::to9_timer_port_out(uint8_t data)
+void to9_state::to9_timer_port_out(uint8_t data)
{
thom_set_mode_point( data & 1 ); /* bit 0: video bank */
to9_update_ram_bank();
@@ -2488,21 +2496,23 @@ void thomson_state::to9_timer_port_out(uint8_t data)
-MACHINE_RESET_MEMBER( thomson_state, to9 )
+MACHINE_RESET_MEMBER( to9_state, to9 )
{
LOG (( "to9: machine reset called\n" ));
/* subsystems */
thom_irq_reset();
to7_game_reset();
- to9_floppy_reset();
to9_kbd_reset();
to7_modem_reset();
to7_midi_reset();
+ m_extension->rom_map(m_maincpu->space(AS_PROGRAM), 0xe000, 0xe7bf);
+ m_extension->io_map (m_maincpu->space(AS_PROGRAM), 0xe7d0, 0xe7df);
+
/* video */
thom_set_video_mode( THOM_VMODE_TO9 );
- m_thom_lightpen_cb = &thomson_state::to7_lightpen_cb;
+ m_thom_lightpen_cb = std::bind(&to9_state::to7_lightpen_cb, this, std::placeholders::_1);
thom_set_lightpen_callback( 3 );
thom_set_border_color( 8 );
thom_set_mode_point( 0 );
@@ -2522,9 +2532,8 @@ MACHINE_RESET_MEMBER( thomson_state, to9 )
-MACHINE_START_MEMBER( thomson_state, to9 )
+MACHINE_START_MEMBER( to9_state, to9 )
{
- uint8_t* mem = memregion("maincpu")->base();
uint8_t* cartmem = &m_cart_rom[0];
uint8_t* ram = m_ram->pointer();
@@ -2532,12 +2541,14 @@ MACHINE_START_MEMBER( thomson_state, to9 )
/* subsystems */
to7_game_init();
- to9_floppy_init( mem + 0xe000 );
to9_kbd_init();
to9_palette_init();
to7_modem_init();
to7_midi_init();
+ m_extension->rom_map(m_maincpu->space(AS_PROGRAM), 0xe000, 0xe7bf);
+ m_extension->io_map (m_maincpu->space(AS_PROGRAM), 0xe7d0, 0xe7df);
+
/* memory */
m_thom_vram = ram;
m_thom_cart_bank = 0;
@@ -2557,8 +2568,8 @@ MACHINE_START_MEMBER( thomson_state, to9 )
save_item(NAME(m_to7_lightpen_step));
save_item(NAME(m_to9_soft_bank));
save_pointer(NAME(cartmem), 0x10000 );
- machine().save().register_postload(save_prepost_delegate(FUNC(thomson_state::to9_update_ram_bank_postload), this));
- machine().save().register_postload(save_prepost_delegate(FUNC(thomson_state::to9_update_cart_bank_postload), this));
+ machine().save().register_postload(save_prepost_delegate(FUNC(to9_state::to9_update_ram_bank_postload), this));
+ machine().save().register_postload(save_prepost_delegate(FUNC(to9_state::to9_update_cart_bank_postload), this));
}
@@ -2600,7 +2611,7 @@ MACHINE_START_MEMBER( thomson_state, to9 )
/* quick keyboard scan */
-int thomson_state::to8_kbd_ktest()
+int to9_state::to8_kbd_ktest()
{
int line, bit;
uint8_t port;
@@ -2628,7 +2639,7 @@ int thomson_state::to8_kbd_ktest()
/* keyboard scan & return keycode (or -1) */
-int thomson_state::to8_kbd_get_key()
+int to9_state::to8_kbd_get_key()
{
int control = (m_io_keyboard[7]->read() & 1) ? 0 : 0x100;
int shift = (m_io_keyboard[9]->read() & 1) ? 0 : 0x080;
@@ -2699,7 +2710,7 @@ int thomson_state::to8_kbd_get_key()
*/
/* keyboard automaton */
-void thomson_state::to8_kbd_timer_func()
+void to9_state::to8_kbd_timer_func()
{
attotime d;
@@ -2771,7 +2782,7 @@ void thomson_state::to8_kbd_timer_func()
-TIMER_CALLBACK_MEMBER(thomson_state::to8_kbd_timer_cb)
+TIMER_CALLBACK_MEMBER(to9_state::to8_kbd_timer_cb)
{
to8_kbd_timer_func();
}
@@ -2779,7 +2790,7 @@ TIMER_CALLBACK_MEMBER(thomson_state::to8_kbd_timer_cb)
/* cpu <-> keyboard hand-check */
-void thomson_state::to8_kbd_set_ack( int data )
+void to9_state::to8_kbd_set_ack( int data )
{
if ( data == m_to8_kbd_ack )
return;
@@ -2850,7 +2861,7 @@ void thomson_state::to8_kbd_set_ack( int data )
-void thomson_state::to8_kbd_reset()
+void to9_state::to8_kbd_reset()
{
m_to8_kbd_last_key = 0xff;
m_to8_kbd_key_count = 0;
@@ -2864,9 +2875,9 @@ void thomson_state::to8_kbd_reset()
-void thomson_state::to8_kbd_init()
+void to9_state::to8_kbd_init()
{
- m_to8_kbd_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(thomson_state::to8_kbd_timer_cb),this));
+ m_to8_kbd_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(to9_state::to8_kbd_timer_cb),this));
m_to8_kbd_signal = machine().scheduler().timer_alloc(timer_expired_delegate());
save_item(NAME(m_to8_kbd_ack));
save_item(NAME(m_to8_kbd_data));
@@ -2880,30 +2891,7 @@ void thomson_state::to8_kbd_init()
/* ------------ RAM / ROM banking ------------ */
-void thomson_state::to8_update_floppy_bank()
-{
- int bank = (m_to8_reg_sys1 & 0x80) ? m_to7_floppy_bank : (m_to8_bios_bank + TO7_NB_FLOP_BANK);
-
- if ( bank != m_old_floppy_bank )
- {
- LOG_BANK(( "to8_update_floppy_bank: floppy ROM is %s bank %i\n",
- (m_to8_reg_sys1 & 0x80) ? "external" : "internal",
- bank % TO7_NB_FLOP_BANK ));
- m_flopbank->set_entry( bank );
- m_old_floppy_bank = bank;
- }
-}
-
-
-
-void thomson_state::to8_update_floppy_bank_postload()
-{
- to8_update_floppy_bank();
-}
-
-
-
-void thomson_state::to8_update_ram_bank()
+void to9_state::to8_update_ram_bank()
{
address_space& space = m_maincpu->space(AS_PROGRAM);
uint8_t bank = 0;
@@ -2961,14 +2949,14 @@ void thomson_state::to8_update_ram_bank()
-void thomson_state::to8_update_ram_bank_postload()
+void to9_state::to8_update_ram_bank_postload()
{
to8_update_ram_bank();
}
-void thomson_state::to8_update_cart_bank()
+void to9_state::to8_update_cart_bank()
{
address_space& space = m_maincpu->space(AS_PROGRAM);
int bank = 0;
@@ -2996,7 +2984,7 @@ void thomson_state::to8_update_cart_bank()
}
else
{
- space.install_write_handler( 0x0000, 0x3fff, write8sm_delegate(*this, FUNC(thomson_state::to8_vcart_w)));
+ space.install_write_handler( 0x0000, 0x3fff, write8sm_delegate(*this, FUNC(to9_state::to8_vcart_w)));
}
}
}
@@ -3038,7 +3026,7 @@ void thomson_state::to8_update_cart_bank()
{
if (m_to8_cart_vpage < 4)
{
- space.install_write_handler( 0x0000, 0x3fff, write8sm_delegate(*this, FUNC(thomson_state::to8_vcart_w)));
+ space.install_write_handler( 0x0000, 0x3fff, write8sm_delegate(*this, FUNC(to9_state::to8_vcart_w)));
}
else
{
@@ -3063,7 +3051,7 @@ void thomson_state::to8_update_cart_bank()
if ( m_old_cart_bank < 4 || m_old_cart_bank > 7 )
{
space.install_read_bank( 0x0000, 0x3fff, m_cartbank );
- space.install_write_handler( 0x0000, 0x3fff, write8sm_delegate(*this, FUNC(thomson_state::to8_cartridge_w)) );
+ space.install_write_handler( 0x0000, 0x3fff, write8sm_delegate(*this, FUNC(to9_state::to8_cartridge_w)) );
}
LOG_BANK(( "to8_update_cart_bank: CART is internal bank %i\n", m_to8_soft_bank ));
}
@@ -3079,8 +3067,8 @@ void thomson_state::to8_update_cart_bank()
if ( m_old_cart_bank < 0 || m_old_cart_bank > 3 )
{
space.install_read_bank( 0x0000, 0x3fff, m_cartbank );
- space.install_write_handler( 0x0000, 0x3fff, write8sm_delegate(*this, FUNC(thomson_state::to8_cartridge_w)) );
- space.install_read_handler( 0x0000, 0x0003, read8sm_delegate(*this, FUNC(thomson_state::to8_cartridge_r)) );
+ space.install_write_handler( 0x0000, 0x3fff, write8sm_delegate(*this, FUNC(to9_state::to8_cartridge_w)) );
+ space.install_read_handler( 0x0000, 0x0003, read8sm_delegate(*this, FUNC(to9_state::to8_cartridge_r)) );
}
LOG_BANK(( "to8_update_cart_bank: CART is external cartridge bank %i\n", bank ));
}
@@ -3104,7 +3092,7 @@ void thomson_state::to8_update_cart_bank()
-void thomson_state::to8_update_cart_bank_postload()
+void to9_state::to8_update_cart_bank_postload()
{
to8_update_cart_bank();
}
@@ -3112,7 +3100,7 @@ void thomson_state::to8_update_cart_bank_postload()
/* ROM bank switch */
-void thomson_state::to8_cartridge_w(offs_t offset, uint8_t data)
+void to9_state::to8_cartridge_w(offs_t offset, uint8_t data)
{
if ( offset >= 0x2000 )
return;
@@ -3128,7 +3116,7 @@ void thomson_state::to8_cartridge_w(offs_t offset, uint8_t data)
/* read signal to 0000-0003 generates a bank switch */
-uint8_t thomson_state::to8_cartridge_r(offs_t offset)
+uint8_t to9_state::to8_cartridge_r(offs_t offset)
{
uint8_t data = m_cart_rom[offset + (m_thom_cart_bank % m_thom_cart_nb_banks) * 0x4000];
if ( !machine().side_effects_disabled() )
@@ -3140,58 +3128,6 @@ uint8_t thomson_state::to8_cartridge_r(offs_t offset)
}
-/* ------------ floppy / network controller dispatch ------------ */
-
-
-
-void thomson_state::to8_floppy_init()
-{
- to7_floppy_init();
-}
-
-
-
-void thomson_state::to8_floppy_reset()
-{
- uint8_t* mem = memregion("maincpu")->base();
- to7_floppy_reset();
- if ( THOM_FLOPPY_INT )
- m_thmfc->floppy_reset();
- m_flopbank->configure_entries( TO7_NB_FLOP_BANK, 2, mem + 0x20000, 0x2000 );
-}
-
-
-
-uint8_t thomson_state::to8_floppy_r(offs_t offset)
-{
- if ( machine().side_effects_disabled() )
- return 0;
-
- if ( (m_to8_reg_sys1 & 0x80) && THOM_FLOPPY_EXT )
- /* external controller */
- return to7_floppy_r( offset );
- else if ( ! (m_to8_reg_sys1 & 0x80) && THOM_FLOPPY_INT )
- /* internal controller */
- return m_thmfc->floppy_r( offset );
- else
- /* no controller */
- return 0;
-}
-
-
-
-void thomson_state::to8_floppy_w(offs_t offset, uint8_t data)
-{
- if ( (m_to8_reg_sys1 & 0x80) && THOM_FLOPPY_EXT )
- /* external controller */
- to7_floppy_w( offset, data );
- else if ( ! (m_to8_reg_sys1 & 0x80) && THOM_FLOPPY_INT )
- /* internal controller */
- m_thmfc->floppy_w( offset, data );
-}
-
-
-
/* ------------ system gate-array ------------ */
@@ -3200,7 +3136,7 @@ void thomson_state::to8_floppy_w(offs_t offset, uint8_t data)
-uint8_t thomson_state::to8_gatearray_r(offs_t offset)
+uint8_t to9_state::to8_gatearray_r(offs_t offset)
{
struct thom_vsignal v = thom_get_vsignal();
struct thom_vsignal l = thom_get_lightpen_vsignal( TO8_LIGHTPEN_DECAL, m_to7_lightpen_step - 1, 6 );
@@ -3259,7 +3195,7 @@ uint8_t thomson_state::to8_gatearray_r(offs_t offset)
-void thomson_state::to8_gatearray_w(offs_t offset, uint8_t data)
+void to9_state::to8_gatearray_w(offs_t offset, uint8_t data)
{
LOG_VIDEO(( "$%04x %f to8_gatearray_w: off=%i ($%04X) data=$%02X\n",
m_maincpu->pc(), machine().time().as_double(),
@@ -3286,7 +3222,6 @@ void thomson_state::to8_gatearray_w(offs_t offset, uint8_t data)
case 3: /* system register 1 */
m_to8_reg_sys1 = data;
- to8_update_floppy_bank();
to8_update_ram_bank();
to8_update_cart_bank();
break;
@@ -3303,7 +3238,7 @@ void thomson_state::to8_gatearray_w(offs_t offset, uint8_t data)
-uint8_t thomson_state::to8_vreg_r(offs_t offset)
+uint8_t to9_state::to8_vreg_r(offs_t offset)
{
/* 0xe7dc from external floppy drive aliases the video gate-array */
if ( ( offset == 3 ) && ( m_to8_reg_ram & 0x80 ) && ( m_to8_reg_sys1 & 0x80 ) )
@@ -3311,10 +3246,7 @@ uint8_t thomson_state::to8_vreg_r(offs_t offset)
if ( machine().side_effects_disabled() )
return 0;
- if ( THOM_FLOPPY_EXT )
- return to7_floppy_r( 0xc );
- else
- return 0;
+ abort(); // return to7_floppy_r( 0xc );
}
switch ( offset )
@@ -3344,7 +3276,7 @@ uint8_t thomson_state::to8_vreg_r(offs_t offset)
-void thomson_state::to8_vreg_w(offs_t offset, uint8_t data)
+void to9_state::to8_vreg_w(offs_t offset, uint8_t data)
{
LOG_VIDEO(( "$%04x %f to8_vreg_w: off=%i ($%04X) data=$%02X\n",
m_maincpu->pc(), machine().time().as_double(),
@@ -3376,8 +3308,7 @@ void thomson_state::to8_vreg_w(offs_t offset, uint8_t data)
/* 0xe7dc from external floppy drive aliases the video gate-array */
if ( ( offset == 3 ) && ( m_to8_reg_ram & 0x80 ) && ( m_to8_reg_sys1 & 0x80 ) )
{
- if ( THOM_FLOPPY_EXT )
- to7_floppy_w( 0xc, data );
+ abort(); // to7_floppy_w( 0xc, data );
}
else
{
@@ -3397,7 +3328,7 @@ void thomson_state::to8_vreg_w(offs_t offset, uint8_t data)
/* ------------ system PIA 6821 ------------ */
-uint8_t thomson_state::to8_sys_porta_in()
+uint8_t to9_state::to8_sys_porta_in()
{
int ktest = to8_kbd_ktest();
@@ -3409,7 +3340,7 @@ uint8_t thomson_state::to8_sys_porta_in()
-void thomson_state::to8_sys_portb_out(uint8_t data)
+void to9_state::to8_sys_portb_out(uint8_t data)
{
m_centronics->write_data0(BIT(data, 0));
m_centronics->write_strobe(BIT(data, 1));
@@ -3425,12 +3356,12 @@ void thomson_state::to8_sys_portb_out(uint8_t data)
/* ------------ 6846 (timer, I/O) ------------ */
-WRITE_LINE_MEMBER(thomson_state::write_centronics_busy )
+WRITE_LINE_MEMBER(to9_state::write_centronics_busy )
{
m_centronics_busy = state;
}
-uint8_t thomson_state::to8_timer_port_in()
+uint8_t to9_state::to8_timer_port_in()
{
int lightpen = (m_io_lightpen_button->read() & 1) ? 2 : 0;
int cass = to7_get_cassette() ? 0x80 : 0;
@@ -3441,21 +3372,20 @@ uint8_t thomson_state::to8_timer_port_in()
-void thomson_state::to8_timer_port_out(uint8_t data)
+void to9_state::to8_timer_port_out(uint8_t data)
{
int ack = (data & 0x20) ? 1 : 0; /* bit 5: keyboard ACK */
m_to8_bios_bank = (data & 0x10) ? 1 : 0; /* bit 4: BIOS bank*/
thom_set_mode_point( data & 1 ); /* bit 0: video bank switch */
m_biosbank->set_entry( m_to8_bios_bank );
m_to8_soft_select = (data & 0x04) ? 1 : 0; /* bit 2: internal ROM select */
- to8_update_floppy_bank();
to8_update_cart_bank();
to8_kbd_set_ack(ack);
}
-WRITE_LINE_MEMBER( thomson_state::to8_timer_cp2_out )
+WRITE_LINE_MEMBER( to9_state::to8_timer_cp2_out )
{
/* mute */
m_to7_game_mute = state;
@@ -3467,7 +3397,7 @@ WRITE_LINE_MEMBER( thomson_state::to8_timer_cp2_out )
/* direct connection to interrupt line instead of through a PIA */
-void thomson_state::to8_lightpen_cb( int step )
+void to9_state::to8_lightpen_cb( int step )
{
if ( ! m_to7_lightpen )
return;
@@ -3483,14 +3413,13 @@ void thomson_state::to8_lightpen_cb( int step )
-MACHINE_RESET_MEMBER( thomson_state, to8 )
+MACHINE_RESET_MEMBER( to9_state, to8 )
{
LOG (( "to8: machine reset called\n" ));
/* subsystems */
thom_irq_reset();
to7_game_reset();
- to8_floppy_reset();
to8_kbd_reset();
to7_modem_reset();
to7_midi_reset();
@@ -3506,7 +3435,7 @@ MACHINE_RESET_MEMBER( thomson_state, to8 )
/* video */
thom_set_video_mode( THOM_VMODE_TO770 );
- m_thom_lightpen_cb = &thomson_state::to8_lightpen_cb;
+ m_thom_lightpen_cb = std::bind(&to9_state::to8_lightpen_cb, this, std::placeholders::_1);
thom_set_lightpen_callback( 4 );
thom_set_border_color( 0 );
thom_set_mode_point( 0 );
@@ -3516,21 +3445,19 @@ MACHINE_RESET_MEMBER( thomson_state, to8 )
m_old_ram_bank = -1;
m_old_cart_bank = -1;
m_old_cart_bank_was_read_only = 0;
- m_old_floppy_bank = -1;
m_to8_cart_vpage = 0;
m_to8_data_vpage = 0;
m_to8_soft_bank = 0;
m_to8_bios_bank = 0;
to8_update_ram_bank();
to8_update_cart_bank();
- to8_update_floppy_bank();
m_biosbank->set_entry( 0 );
/* thom_cart_bank not reset */
}
-MACHINE_START_MEMBER( thomson_state, to8 )
+MACHINE_START_MEMBER( to9_state, to8 )
{
uint8_t* mem = memregion("maincpu")->base();
uint8_t* cartmem = &m_cart_rom[0];
@@ -3540,12 +3467,14 @@ MACHINE_START_MEMBER( thomson_state, to8 )
/* subsystems */
to7_game_init();
- to8_floppy_init();
to8_kbd_init();
to9_palette_init();
to7_modem_init();
to7_midi_init();
+ m_extension->rom_map(m_maincpu->space(AS_PROGRAM), 0xe000, 0xe7bf);
+ m_extension->io_map (m_maincpu->space(AS_PROGRAM), 0xe7d0, 0xe7df);
+
/* memory */
m_thom_cart_bank = 0;
m_thom_vram = ram;
@@ -3594,9 +3523,8 @@ MACHINE_START_MEMBER( thomson_state, to8 )
save_item(NAME(m_to8_data_vpage));
save_item(NAME(m_to8_cart_vpage));
save_pointer(NAME(cartmem), 0x10000 );
- machine().save().register_postload(save_prepost_delegate(FUNC(thomson_state::to8_update_ram_bank_postload), this));
- machine().save().register_postload(save_prepost_delegate(FUNC(thomson_state::to8_update_cart_bank_postload), this));
- machine().save().register_postload(save_prepost_delegate(FUNC(thomson_state::to8_update_floppy_bank_postload), this));
+ machine().save().register_postload(save_prepost_delegate(FUNC(to9_state::to8_update_ram_bank_postload), this));
+ machine().save().register_postload(save_prepost_delegate(FUNC(to9_state::to8_update_cart_bank_postload), this));
}
@@ -3613,7 +3541,7 @@ MACHINE_START_MEMBER( thomson_state, to8 )
-uint8_t thomson_state::to9p_timer_port_in()
+uint8_t to9_state::to9p_timer_port_in()
{
int lightpen = (m_io_lightpen_button->read() & 1) ? 2 : 0;
int cass = to7_get_cassette() ? 0x80 : 0;
@@ -3623,26 +3551,24 @@ uint8_t thomson_state::to9p_timer_port_in()
-void thomson_state::to9p_timer_port_out(uint8_t data)
+void to9_state::to9p_timer_port_out(uint8_t data)
{
int bios_bank = (data & 0x10) ? 1 : 0; /* bit 4: BIOS bank */
thom_set_mode_point( data & 1 ); /* bit 0: video bank switch */
m_biosbank->set_entry( bios_bank );
m_to8_soft_select = (data & 0x04) ? 1 : 0; /* bit 2: internal ROM select */
- to8_update_floppy_bank();
to8_update_cart_bank();
}
/* ------------ init / reset ------------ */
-MACHINE_RESET_MEMBER( thomson_state, to9p )
+MACHINE_RESET_MEMBER( to9_state, to9p )
{
LOG (( "to9p: machine reset called\n" ));
/* subsystems */
thom_irq_reset();
to7_game_reset();
- to8_floppy_reset();
to9_kbd_reset();
to7_modem_reset();
to7_midi_reset();
@@ -3658,7 +3584,7 @@ MACHINE_RESET_MEMBER( thomson_state, to9p )
/* video */
thom_set_video_mode( THOM_VMODE_TO770 );
- m_thom_lightpen_cb = &thomson_state::to8_lightpen_cb;
+ m_thom_lightpen_cb = std::bind(&to9_state::to8_lightpen_cb, this, std::placeholders::_1);
thom_set_lightpen_callback( 4 );
thom_set_border_color( 0 );
thom_set_mode_point( 0 );
@@ -3667,21 +3593,19 @@ MACHINE_RESET_MEMBER( thomson_state, to9p )
/* memory */
m_old_ram_bank = -1;
m_old_cart_bank = -1;
- m_old_floppy_bank = -1;
m_to8_cart_vpage = 0;
m_to8_data_vpage = 0;
m_to8_soft_bank = 0;
m_to8_bios_bank = 0;
to8_update_ram_bank();
to8_update_cart_bank();
- to8_update_floppy_bank();
m_biosbank->set_entry( 0 );
/* thom_cart_bank not reset */
}
-MACHINE_START_MEMBER( thomson_state, to9p )
+MACHINE_START_MEMBER( to9_state, to9p )
{
uint8_t* mem = memregion("maincpu")->base();
uint8_t* cartmem = &m_cart_rom[0];
@@ -3691,12 +3615,14 @@ MACHINE_START_MEMBER( thomson_state, to9p )
/* subsystems */
to7_game_init();
- to8_floppy_init();
to9_kbd_init();
to9_palette_init();
to7_modem_init();
to7_midi_init();
+ m_extension->rom_map(m_maincpu->space(AS_PROGRAM), 0xe000, 0xe7bf);
+ m_extension->io_map (m_maincpu->space(AS_PROGRAM), 0xe7d0, 0xe7df);
+
/* memory */
m_thom_cart_bank = 0;
m_thom_vram = ram;
@@ -3733,9 +3659,8 @@ MACHINE_START_MEMBER( thomson_state, to9p )
save_item(NAME(m_to8_data_vpage));
save_item(NAME(m_to8_cart_vpage));
save_pointer(NAME(cartmem), 0x10000 );
- machine().save().register_postload(save_prepost_delegate(FUNC(thomson_state::to8_update_ram_bank_postload), this));
- machine().save().register_postload(save_prepost_delegate(FUNC(thomson_state::to8_update_cart_bank_postload), this));
- machine().save().register_postload(save_prepost_delegate(FUNC(thomson_state::to8_update_floppy_bank_postload), this));
+ machine().save().register_postload(save_prepost_delegate(FUNC(to9_state::to8_update_ram_bank_postload), this));
+ machine().save().register_postload(save_prepost_delegate(FUNC(to9_state::to8_update_cart_bank_postload), this));
}
@@ -3748,7 +3673,7 @@ MACHINE_START_MEMBER( thomson_state, to9p )
-void thomson_state::mo6_update_ram_bank()
+void mo6_state::mo6_update_ram_bank()
{
uint8_t bank = 0;
@@ -3767,14 +3692,14 @@ void thomson_state::mo6_update_ram_bank()
-void thomson_state::mo6_update_ram_bank_postload()
+void mo6_state::mo6_update_ram_bank_postload()
{
mo6_update_ram_bank();
}
-void thomson_state::mo6_update_cart_bank()
+void mo6_state::mo6_update_cart_bank()
{
address_space& space = m_maincpu->space(AS_PROGRAM);
int b = (m_pia_sys->a_output() >> 5) & 1;
@@ -3804,8 +3729,8 @@ void thomson_state::mo6_update_cart_bank()
}
else
{
- space.install_write_handler( 0xb000, 0xbfff, write8sm_delegate(*this, FUNC(thomson_state::mo6_vcart_lo_w)));
- space.install_write_handler( 0xc000, 0xefff, write8sm_delegate(*this, FUNC(thomson_state::mo6_vcart_hi_w)));
+ space.install_write_handler( 0xb000, 0xbfff, write8sm_delegate(*this, FUNC(mo6_state::mo6_vcart_lo_w)));
+ space.install_write_handler( 0xc000, 0xefff, write8sm_delegate(*this, FUNC(mo6_state::mo6_vcart_hi_w)));
}
}
}
@@ -3840,8 +3765,8 @@ void thomson_state::mo6_update_cart_bank()
{
if (m_to8_cart_vpage < 4)
{
- space.install_write_handler( 0xb000, 0xbfff, write8sm_delegate(*this, FUNC(thomson_state::mo6_vcart_lo_w)));
- space.install_write_handler( 0xc000, 0xefff, write8sm_delegate(*this, FUNC(thomson_state::mo6_vcart_hi_w)));
+ space.install_write_handler( 0xb000, 0xbfff, write8sm_delegate(*this, FUNC(mo6_state::mo6_vcart_lo_w)));
+ space.install_write_handler( 0xc000, 0xefff, write8sm_delegate(*this, FUNC(mo6_state::mo6_vcart_hi_w)));
}
else
{
@@ -3936,7 +3861,7 @@ void thomson_state::mo6_update_cart_bank()
{
space.install_read_bank( 0xb000, 0xbfff, m_cartlobank );
space.install_read_bank( 0xc000, 0xefff, m_carthibank );
- space.install_write_handler( 0xb000, 0xefff, write8sm_delegate(*this, FUNC(thomson_state::mo6_cartridge_w)) );
+ space.install_write_handler( 0xb000, 0xefff, write8sm_delegate(*this, FUNC(mo6_state::mo6_cartridge_w)) );
}
LOG_BANK(( "mo6_update_cart_bank: CART is internal ROM bank %i\n", b ));
}
@@ -3953,8 +3878,8 @@ void thomson_state::mo6_update_cart_bank()
{
space.install_read_bank( 0xb000, 0xbfff, m_cartlobank );
space.install_read_bank( 0xc000, 0xefff, m_carthibank );
- space.install_write_handler( 0xb000, 0xefff, write8sm_delegate(*this, FUNC(thomson_state::mo6_cartridge_w)) );
- space.install_read_handler( 0xbffc, 0xbfff, read8sm_delegate(*this, FUNC(thomson_state::mo6_cartridge_r)) );
+ space.install_write_handler( 0xb000, 0xefff, write8sm_delegate(*this, FUNC(mo6_state::mo6_cartridge_w)) );
+ space.install_read_handler( 0xbffc, 0xbfff, read8sm_delegate(*this, FUNC(mo6_state::mo6_cartridge_r)) );
}
LOG_BANK(( "mo6_update_cart_bank: CART is external cartridge bank %i\n", bank ));
}
@@ -3980,7 +3905,7 @@ void thomson_state::mo6_update_cart_bank()
-void thomson_state::mo6_update_cart_bank_postload()
+void mo6_state::mo6_update_cart_bank_postload()
{
mo6_update_cart_bank();
}
@@ -3988,7 +3913,7 @@ void thomson_state::mo6_update_cart_bank_postload()
/* write signal generates a bank switch */
-void thomson_state::mo6_cartridge_w(offs_t offset, uint8_t data)
+void mo6_state::mo6_cartridge_w(offs_t offset, uint8_t data)
{
if ( offset >= 0x2000 )
return;
@@ -4000,7 +3925,7 @@ void thomson_state::mo6_cartridge_w(offs_t offset, uint8_t data)
/* read signal generates a bank switch */
-uint8_t thomson_state::mo6_cartridge_r(offs_t offset)
+uint8_t mo6_state::mo6_cartridge_r(offs_t offset)
{
uint8_t data = m_cart_rom[offset + 0x3ffc + (m_thom_cart_bank % m_thom_cart_nb_banks) * 0x4000];
if ( !machine().side_effects_disabled() )
@@ -4013,7 +3938,7 @@ uint8_t thomson_state::mo6_cartridge_r(offs_t offset)
-void thomson_state::mo6_ext_w(uint8_t data)
+void mo6_state::mo6_ext_w(uint8_t data)
{
/* MO5 network extension compatible */
m_mo5_reg_cart = data;
@@ -4027,13 +3952,13 @@ void thomson_state::mo6_ext_w(uint8_t data)
/* similar to SX 90-018, but with a few differences: mute, printer */
-WRITE_LINE_MEMBER( thomson_state::mo6_centronics_busy )
+WRITE_LINE_MEMBER( mo6_state::mo6_centronics_busy )
{
m_pia_game->cb1_w(state);
}
-void thomson_state::mo6_game_porta_out(uint8_t data)
+void mo6_state::mo6_game_porta_out(uint8_t data)
{
LOG (( "$%04x %f mo6_game_porta_out: CENTRONICS set data=$%02X\n", m_maincpu->pc(), machine().time().as_double(), data ));
@@ -4043,7 +3968,7 @@ void thomson_state::mo6_game_porta_out(uint8_t data)
-WRITE_LINE_MEMBER( thomson_state::mo6_game_cb2_out )
+WRITE_LINE_MEMBER( mo6_state::mo6_game_cb2_out )
{
LOG (( "$%04x %f mo6_game_cb2_out: CENTRONICS set strobe=%i\n", m_maincpu->pc(), machine().time().as_double(), state ));
@@ -4053,7 +3978,7 @@ WRITE_LINE_MEMBER( thomson_state::mo6_game_cb2_out )
-TIMER_CALLBACK_MEMBER(thomson_state::mo6_game_update_cb)
+TIMER_CALLBACK_MEMBER(mo6_state::mo6_game_update_cb)
{
/* unlike the TO8, CB1 & CB2 are not connected to buttons */
if ( m_io_config->read() & 1 )
@@ -4073,10 +3998,10 @@ TIMER_CALLBACK_MEMBER(thomson_state::mo6_game_update_cb)
-void thomson_state::mo6_game_init()
+void mo6_state::mo6_game_init()
{
LOG (( "mo6_game_init called\n" ));
- m_to7_game_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(thomson_state::mo6_game_update_cb),this));
+ m_to7_game_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mo6_state::mo6_game_update_cb),this));
m_to7_game_timer->adjust(TO7_GAME_POLL_PERIOD, 0, TO7_GAME_POLL_PERIOD);
save_item(NAME(m_to7_game_sound));
save_item(NAME(m_to7_game_mute));
@@ -4084,7 +4009,7 @@ void thomson_state::mo6_game_init()
-void thomson_state::mo6_game_reset()
+void mo6_state::mo6_game_reset()
{
LOG (( "mo6_game_reset called\n" ));
m_pia_game->ca1_w( 0 );
@@ -4099,7 +4024,7 @@ void thomson_state::mo6_game_reset()
-uint8_t thomson_state::mo6_sys_porta_in()
+uint8_t mo6_state::mo6_sys_porta_in()
{
return
((m_io_lightpen_button->read() & 1) ? 2 : 0) | /* bit 1: lightpen button */
@@ -4110,7 +4035,7 @@ uint8_t thomson_state::mo6_sys_porta_in()
-uint8_t thomson_state::mo6_sys_portb_in()
+uint8_t mo6_state::mo6_sys_portb_in()
{
/* keyboard: 9 lines of 8 keys */
uint8_t porta = m_pia_sys->a_output();
@@ -4128,7 +4053,7 @@ uint8_t thomson_state::mo6_sys_portb_in()
-void thomson_state::mo6_sys_porta_out(uint8_t data)
+void mo6_state::mo6_sys_porta_out(uint8_t data)
{
thom_set_mode_point( data & 1 ); /* bit 0: video bank switch */
m_to7_game_mute = data & 4; /* bit 2: sound mute */
@@ -4140,7 +4065,7 @@ void thomson_state::mo6_sys_porta_out(uint8_t data)
-WRITE_LINE_MEMBER( thomson_state::mo6_sys_cb2_out )
+WRITE_LINE_MEMBER( mo6_state::mo6_sys_cb2_out )
{
/* SCART pin 8 = slow switch (?) */
LOG(( "mo6_sys_cb2_out: SCART slow switch set to %i\n", state ));
@@ -4154,7 +4079,7 @@ WRITE_LINE_MEMBER( thomson_state::mo6_sys_cb2_out )
-uint8_t thomson_state::mo6_gatearray_r(offs_t offset)
+uint8_t mo6_state::mo6_gatearray_r(offs_t offset)
{
struct thom_vsignal v = thom_get_vsignal();
struct thom_vsignal l = thom_get_lightpen_vsignal( MO6_LIGHTPEN_DECAL, m_to7_lightpen_step - 1, 6 );
@@ -4213,7 +4138,7 @@ uint8_t thomson_state::mo6_gatearray_r(offs_t offset)
-void thomson_state::mo6_gatearray_w(offs_t offset, uint8_t data)
+void mo6_state::mo6_gatearray_w(offs_t offset, uint8_t data)
{
LOG_VIDEO(( "$%04x %f mo6_gatearray_w: off=%i ($%04X) data=$%02X\n",
m_maincpu->pc(), machine().time().as_double(),
@@ -4254,13 +4179,13 @@ void thomson_state::mo6_gatearray_w(offs_t offset, uint8_t data)
-uint8_t thomson_state::mo6_vreg_r(offs_t offset)
+uint8_t mo6_state::mo6_vreg_r(offs_t offset)
{
/* 0xa7dc from external floppy drive aliases the video gate-array */
if ( ( offset == 3 ) && ( m_to8_reg_ram & 0x80 ) )
{
if ( !machine().side_effects_disabled() )
- return to7_floppy_r( 0xc );
+ abort(); // return to7_floppy_r( 0xc );
}
switch ( offset )
@@ -4281,7 +4206,7 @@ uint8_t thomson_state::mo6_vreg_r(offs_t offset)
-void thomson_state::mo6_vreg_w(offs_t offset, uint8_t data)
+void mo6_state::mo6_vreg_w(offs_t offset, uint8_t data)
{
LOG_VIDEO(( "$%04x %f mo6_vreg_w: off=%i ($%04X) data=$%02X\n",
m_maincpu->pc(), machine().time().as_double(),
@@ -4296,7 +4221,7 @@ void thomson_state::mo6_vreg_w(offs_t offset, uint8_t data)
case 2: /* display / external floppy register */
if ( ( m_to8_reg_sys1 & 0x80 ) && ( m_to8_reg_ram & 0x80 ) )
- to7_floppy_w( 0xc, data );
+ abort(); // to7_floppy_w( 0xc, data );
else
to9_set_video_mode( data, 2 );
break;
@@ -4304,7 +4229,7 @@ void thomson_state::mo6_vreg_w(offs_t offset, uint8_t data)
case 3: /* system register 2 */
/* 0xa7dc from external floppy drive aliases the video gate-array */
if ( ( offset == 3 ) && ( m_to8_reg_ram & 0x80 ) )
- to7_floppy_w( 0xc, data );
+ abort(); // to7_floppy_w( 0xc, data );
else
{
m_to8_reg_sys2 = data;
@@ -4325,14 +4250,13 @@ void thomson_state::mo6_vreg_w(offs_t offset, uint8_t data)
-MACHINE_RESET_MEMBER( thomson_state, mo6 )
+MACHINE_RESET_MEMBER( mo6_state, mo6 )
{
LOG (( "mo6: machine reset called\n" ));
/* subsystems */
thom_irq_reset();
mo6_game_reset();
- to7_floppy_reset();
to7_modem_reset();
to7_midi_reset();
mo5_init_timer();
@@ -4347,7 +4271,7 @@ MACHINE_RESET_MEMBER( thomson_state, mo6 )
/* video */
thom_set_video_mode( THOM_VMODE_MO5 );
- m_thom_lightpen_cb = &thomson_state::to8_lightpen_cb;
+ m_thom_lightpen_cb = std::bind(&mo6_state::to8_lightpen_cb, this, std::placeholders::_1);
thom_set_lightpen_callback( 3 );
thom_set_border_color( 0 );
thom_set_mode_point( 0 );
@@ -4366,7 +4290,7 @@ MACHINE_RESET_MEMBER( thomson_state, mo6 )
-MACHINE_START_MEMBER( thomson_state, mo6 )
+MACHINE_START_MEMBER( mo6_state, mo6 )
{
uint8_t* mem = memregion("maincpu")->base();
uint8_t* cartmem = &m_cart_rom[0];
@@ -4376,11 +4300,13 @@ MACHINE_START_MEMBER( thomson_state, mo6 )
/* subsystems */
mo6_game_init();
- to7_floppy_init();
to9_palette_init();
to7_modem_init();
to7_midi_init();
- m_mo5_periodic_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(thomson_state::mo5_periodic_cb),this));
+ m_mo5_periodic_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mo6_state::mo5_periodic_cb),this));
+
+ m_extension->rom_map(m_maincpu->space(AS_PROGRAM), 0xa000, 0xa7bf);
+ m_extension->io_map (m_maincpu->space(AS_PROGRAM), 0xa7d0, 0xa7df);
/* memory */
m_thom_cart_bank = 0;
@@ -4424,8 +4350,8 @@ MACHINE_START_MEMBER( thomson_state, mo6 )
save_item(NAME(m_to8_cart_vpage));
save_item(NAME(m_mo5_reg_cart));
save_pointer(NAME(cartmem), 0x10000 );
- machine().save().register_postload(save_prepost_delegate(FUNC(thomson_state::mo6_update_ram_bank_postload), this));
- machine().save().register_postload(save_prepost_delegate(FUNC(thomson_state::mo6_update_cart_bank_postload), this));
+ machine().save().register_postload(save_prepost_delegate(FUNC(mo6_state::mo6_update_ram_bank_postload), this));
+ machine().save().register_postload(save_prepost_delegate(FUNC(mo6_state::mo6_update_cart_bank_postload), this));
}
@@ -4434,35 +4360,6 @@ MACHINE_START_MEMBER( thomson_state, mo6 )
-/* ------------ network ( & external floppy) ------------ */
-
-
-
-uint8_t thomson_state::mo5nr_net_r(offs_t offset)
-{
- if ( machine().side_effects_disabled() )
- return 0;
-
- if ( m_to7_controller_type )
- return to7_floppy_r ( offset );
-
- logerror( "$%04x %f mo5nr_net_r: read from reg %i\n", m_maincpu->pc(), machine().time().as_double(), offset );
-
- return 0;
-}
-
-
-
-void thomson_state::mo5nr_net_w(offs_t offset, uint8_t data)
-{
- if ( m_to7_controller_type )
- to7_floppy_w ( offset, data );
- else
- logerror( "$%04x %f mo5nr_net_w: write $%02X to reg %i\n",
- m_maincpu->pc(), machine().time().as_double(), data, offset );
-}
-
-
/* ------------ printer ------------ */
/* Unlike the TO8, TO9, TO9+, MO6, the printer has its own ports and does not
@@ -4470,7 +4367,7 @@ void thomson_state::mo5nr_net_w(offs_t offset, uint8_t data)
*/
-uint8_t thomson_state::mo5nr_prn_r()
+uint8_t mo5nr_state::mo5nr_prn_r()
{
uint8_t result = 0;
@@ -4480,7 +4377,7 @@ uint8_t thomson_state::mo5nr_prn_r()
}
-void thomson_state::mo5nr_prn_w(uint8_t data)
+void mo5nr_state::mo5nr_prn_w(uint8_t data)
{
/* TODO: understand other bits */
m_centronics->write_strobe(BIT(data, 3));
@@ -4492,7 +4389,7 @@ void thomson_state::mo5nr_prn_w(uint8_t data)
-uint8_t thomson_state::mo5nr_sys_portb_in()
+uint8_t mo5nr_state::mo5nr_sys_portb_in()
{
/* keyboard: only 8 lines of 8 keys (MO6 has 9 lines) */
uint8_t portb = m_pia_sys->b_output();
@@ -4505,7 +4402,7 @@ uint8_t thomson_state::mo5nr_sys_portb_in()
-void thomson_state::mo5nr_sys_porta_out(uint8_t data)
+void mo5nr_state::mo5nr_sys_porta_out(uint8_t data)
{
/* no keyboard LED */
thom_set_mode_point( data & 1 ); /* bit 0: video bank switch */
@@ -4523,10 +4420,10 @@ void thomson_state::mo5nr_sys_porta_out(uint8_t data)
-void thomson_state::mo5nr_game_init()
+void mo5nr_state::mo5nr_game_init()
{
LOG (( "mo5nr_game_init called\n" ));
- m_to7_game_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(thomson_state::mo6_game_update_cb),this));
+ m_to7_game_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mo5nr_state::mo6_game_update_cb),this));
m_to7_game_timer->adjust( TO7_GAME_POLL_PERIOD, 0, TO7_GAME_POLL_PERIOD );
save_item(NAME(m_to7_game_sound));
save_item(NAME(m_to7_game_mute));
@@ -4534,7 +4431,7 @@ void thomson_state::mo5nr_game_init()
-void thomson_state::mo5nr_game_reset()
+void mo5nr_state::mo5nr_game_reset()
{
LOG (( "mo5nr_game_reset called\n" ));
m_pia_game->ca1_w( 0 );
@@ -4548,15 +4445,20 @@ void thomson_state::mo5nr_game_reset()
/* ------------ init / reset ------------ */
+uint8_t mo5nr_state::id_r()
+{
+ return (m_nanoreseau_config->read() >> 1) & 0x1f;
+}
-MACHINE_RESET_MEMBER( thomson_state, mo5nr )
+MACHINE_RESET_MEMBER( mo5nr_state, mo5nr )
{
LOG (( "mo5nr: machine reset called\n" ));
+ m_extension_view.select(m_nanoreseau_config->read() & 1);
+
/* subsystems */
thom_irq_reset();
mo5nr_game_reset();
- to7_floppy_reset();
to7_modem_reset();
to7_midi_reset();
mo5_init_timer();
@@ -4571,7 +4473,7 @@ MACHINE_RESET_MEMBER( thomson_state, mo5nr )
/* video */
thom_set_video_mode( THOM_VMODE_MO5 );
- m_thom_lightpen_cb = &thomson_state::to8_lightpen_cb;
+ m_thom_lightpen_cb = std::bind(&mo5nr_state::to8_lightpen_cb, this, std::placeholders::_1);
thom_set_lightpen_callback( 3 );
thom_set_border_color( 0 );
thom_set_mode_point( 0 );
@@ -4590,7 +4492,7 @@ MACHINE_RESET_MEMBER( thomson_state, mo5nr )
-MACHINE_START_MEMBER( thomson_state, mo5nr )
+MACHINE_START_MEMBER( mo5nr_state, mo5nr )
{
uint8_t* mem = memregion("maincpu")->base();
uint8_t* cartmem = &m_cart_rom[0];
@@ -4600,11 +4502,15 @@ MACHINE_START_MEMBER( thomson_state, mo5nr )
/* subsystems */
mo5nr_game_init();
- to7_floppy_init();
to9_palette_init();
to7_modem_init();
to7_midi_init();
- m_mo5_periodic_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(thomson_state::mo5_periodic_cb),this));
+ m_mo5_periodic_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mo5nr_state::mo5_periodic_cb),this));
+
+ m_extension->rom_map(m_extension_view[0], 0xa000, 0xa7bf);
+ m_extension->io_map (m_extension_view[0], 0xa7d0, 0xa7df);
+ m_extension_view[1].install_device(0xa000, 0xa7bf, *m_nanoreseau, &nanoreseau_device::rom_map );
+ m_extension_view[1].install_device(0xa7d0, 0xa7df, *m_nanoreseau, &nanoreseau_device::io_map );
/* memory */
m_thom_cart_bank = 0;
@@ -4649,6 +4555,6 @@ MACHINE_START_MEMBER( thomson_state, mo5nr )
save_item(NAME(m_to8_cart_vpage));
save_item(NAME(m_mo5_reg_cart));
save_pointer(NAME(cartmem), 0x10000 );
- machine().save().register_postload(save_prepost_delegate(FUNC(thomson_state::mo6_update_ram_bank_postload), this));
- machine().save().register_postload(save_prepost_delegate(FUNC(thomson_state::mo6_update_cart_bank_postload), this));
+ machine().save().register_postload(save_prepost_delegate(FUNC(mo5nr_state::mo6_update_ram_bank_postload), this));
+ machine().save().register_postload(save_prepost_delegate(FUNC(mo5nr_state::mo6_update_cart_bank_postload), this));
}
diff --git a/src/mame/mame.lst b/src/mame/mame.lst
index 45a48652761..c15b13f1729 100644
--- a/src/mame/mame.lst
+++ b/src/mame/mame.lst
@@ -40885,6 +40885,7 @@ outzoneb // TP-O18 (c) 1990 Toaplan
outzonec // TP-O18 (c) 1990 Toaplan
outzoneh // TP-O18 (c) 1990 Toaplan
outzonecv // TP-O18 (c) 1990 Toaplan (TP-015 conversion)
+outzoned // Bootleg
rallybik // B45 / TP-O12 (c) 1988 Taito
samesame // TP-O17 (c) 1989 Toaplan
samesame2 // TP-O17 (c) 1989 Toaplan
diff --git a/src/mame/video/thomson.cpp b/src/mame/video/thomson.cpp
index 120f1cf1167..3898033180f 100644
--- a/src/mame/video/thomson.cpp
+++ b/src/mame/video/thomson.cpp
@@ -172,7 +172,7 @@ TIMER_CALLBACK_MEMBER( thomson_state::thom_lightpen_step )
int step = param;
if ( m_thom_lightpen_cb )
- (this->*m_thom_lightpen_cb)( step );
+ m_thom_lightpen_cb( step );
if ( step < m_thom_lightpen_nb )
m_thom_lightpen_timer->adjust(attotime::from_usec( 64 ), step + 1);
@@ -902,10 +902,6 @@ TIMER_CALLBACK_MEMBER( thomson_state::thom_scanline_start )
/* -------------- misc --------------- */
-#define FLOP_STATE (m_thom_floppy_wcount ? 2 : m_thom_floppy_rcount ? 1 : 0)
-
-
-
void thomson_state::thom_set_mode_point( int point )
{
assert( point >= 0 && point <= 1 );
@@ -915,24 +911,6 @@ void thomson_state::thom_set_mode_point( int point )
-void thomson_state::thom_floppy_active( int write )
-{
- int fold = FLOP_STATE, fnew;
-
- /* stays up for a few frames */
- if ( write )
- m_thom_floppy_wcount = 25;
- else
- m_thom_floppy_rcount = 25;
-
- /* update icon */
- fnew = FLOP_STATE;
- if ( fold != fnew )
- m_floppy_led = fnew;
-}
-
-
-
/* -------------- main update function --------------- */
@@ -1065,22 +1043,12 @@ WRITE_LINE_MEMBER(thomson_state::thom_vblank)
// rising edge
if (state)
{
- int fnew, fold = FLOP_STATE;
int i;
uint16_t b = 0;
struct thom_vsignal l = thom_get_lightpen_vsignal( 0, -1, 0 );
LOG("%f thom: video eof called\n", machine().time().as_double());
- /* floppy indicator count */
- if ( m_thom_floppy_wcount )
- m_thom_floppy_wcount--;
- if ( m_thom_floppy_rcount )
- m_thom_floppy_rcount--;
- fnew = FLOP_STATE;
- if ( fnew != fold )
- m_floppy_led = fnew;
-
/* prepare state for next frame */
for ( i = 0; i <= THOM_TOTAL_HEIGHT; i++ )
{
@@ -1194,12 +1162,6 @@ void thomson_state::video_start()
save_item(NAME(m_thom_mode_point));
m_vrambank->set_entry( 0 );
- m_thom_floppy_rcount = 0;
- m_thom_floppy_wcount = 0;
- save_item(NAME(m_thom_floppy_wcount));
- save_item(NAME(m_thom_floppy_rcount));
- m_floppy_led.resolve();
-
m_caps_led.resolve();
m_thom_video_timer = machine().scheduler().timer_alloc(timer_expired_delegate());
@@ -1258,7 +1220,7 @@ void thomson_state::thom_palette(palette_device &palette)
thom_configure_palette(1.0 / 2.8, thom_pal_init, palette);
}
-void thomson_state::mo5_palette(palette_device &palette)
+void mo5_state::mo5_palette(palette_device &palette)
{
LOG("thom: MO5 palette init called\n");
@@ -1334,7 +1296,7 @@ void thomson_state::to770_vram_w(offs_t offset, uint8_t data)
/* write to video memory through system space (always page 1) */
-void thomson_state::to8_sys_lo_w(offs_t offset, uint8_t data)
+void to9_state::to8_sys_lo_w(offs_t offset, uint8_t data)
{
uint8_t* dst = m_thom_vram + offset + 0x6000;
assert( offset < 0x2000 );
@@ -1347,7 +1309,7 @@ void thomson_state::to8_sys_lo_w(offs_t offset, uint8_t data)
-void thomson_state::to8_sys_hi_w(offs_t offset, uint8_t data)
+void to9_state::to8_sys_hi_w(offs_t offset, uint8_t data)
{
uint8_t* dst = m_thom_vram + offset + 0x4000;
assert( offset < 0x2000 );
@@ -1361,7 +1323,7 @@ void thomson_state::to8_sys_hi_w(offs_t offset, uint8_t data)
/* write to video memory through data space */
-void thomson_state::to8_data_lo_w(offs_t offset, uint8_t data)
+void to9_state::to8_data_lo_w(offs_t offset, uint8_t data)
{
uint8_t* dst = m_thom_vram + ( ( offset + 0x4000 * m_to8_data_vpage + 0x2000 ) & m_ram->mask() );
assert( offset < 0x2000 );
@@ -1376,7 +1338,7 @@ void thomson_state::to8_data_lo_w(offs_t offset, uint8_t data)
-void thomson_state::to8_data_hi_w(offs_t offset, uint8_t data)
+void to9_state::to8_data_hi_w(offs_t offset, uint8_t data)
{
uint8_t* dst = m_thom_vram + ( ( offset + 0x4000 * m_to8_data_vpage ) & m_ram->mask() );
assert( offset < 0x2000 );
@@ -1392,7 +1354,7 @@ void thomson_state::to8_data_hi_w(offs_t offset, uint8_t data)
/* write to video memory page through cartridge addresses space */
-void thomson_state::to8_vcart_w(offs_t offset, uint8_t data)
+void to9_state::to8_vcart_w(offs_t offset, uint8_t data)
{
uint8_t* dst = m_thom_vram + ( ( offset + 0x4000 * m_to8_cart_vpage ) & m_ram->mask() );
assert( offset < 0x4000 );
@@ -1405,7 +1367,7 @@ void thomson_state::to8_vcart_w(offs_t offset, uint8_t data)
m_thom_vmem_dirty[ (offset & 0x1fff) / 40 ] = true;
}
-void thomson_state::mo6_vcart_lo_w(offs_t offset, uint8_t data)
+void mo6_state::mo6_vcart_lo_w(offs_t offset, uint8_t data)
{
uint8_t* dst = m_thom_vram + ( ( offset + 0x3000 + 0x4000 * m_to8_cart_vpage ) & m_ram->mask() );
assert( offset < 0x1000 );
@@ -1418,7 +1380,7 @@ void thomson_state::mo6_vcart_lo_w(offs_t offset, uint8_t data)
m_thom_vmem_dirty[ (offset & 0x1fff) / 40 ] = true;
}
-void thomson_state::mo6_vcart_hi_w(offs_t offset, uint8_t data)
+void mo6_state::mo6_vcart_hi_w(offs_t offset, uint8_t data)
{
uint8_t* dst = m_thom_vram + ( ( offset + 0x4000 * m_to8_cart_vpage ) & m_ram->mask() );
assert( offset < 0x3000 );