From c037dfd82238537752e2078f52a3276badfbff83 Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Tue, 16 Feb 2021 21:51:47 +0100 Subject: thomson: Turn the extensions into slot devices, modernize the floppies --- scripts/src/bus.lua | 22 + scripts/target/mame/arcade.lua | 1 + src/devices/bus/bml3/bml3bus.h | 11 +- src/devices/bus/bml3/bml3mp1805.cpp | 90 +- src/devices/bus/bml3/bml3mp1805.h | 8 +- src/devices/bus/thomson/cd90_015.cpp | 120 ++ src/devices/bus/thomson/cd90_015.h | 48 + src/devices/bus/thomson/cd90_351.cpp | 495 +++++++++ src/devices/bus/thomson/cd90_351.h | 122 +++ src/devices/bus/thomson/cd90_640.cpp | 91 ++ src/devices/bus/thomson/cd90_640.h | 46 + src/devices/bus/thomson/cq90_028.cpp | 76 ++ src/devices/bus/thomson/cq90_028.h | 42 + src/devices/bus/thomson/extension.cpp | 40 + src/devices/bus/thomson/extension.h | 39 + src/devices/bus/thomson/nanoreseau.cpp | 205 ++++ src/devices/bus/thomson/nanoreseau.h | 66 ++ src/devices/machine/mc6843.cpp | 1493 +++++++++++++------------ src/devices/machine/mc6843.h | 230 ++-- src/devices/machine/wd_fdc.cpp | 2 +- src/lib/formats/all.cpp | 8 + src/lib/formats/thom_dsk.cpp | 462 +------- src/lib/formats/thom_dsk.h | 38 +- src/lib/formats/wd177x_dsk.cpp | 2 +- src/mame/drivers/thomson.cpp | 624 ++++------- src/mame/includes/thomson.h | 524 ++++----- src/mame/machine/thomflop.cpp | 1867 -------------------------------- src/mame/machine/thomflop.h | 159 --- src/mame/machine/thomson.cpp | 482 ++++----- src/mame/mame.lst | 1 + src/mame/video/thomson.cpp | 56 +- 31 files changed, 3203 insertions(+), 4267 deletions(-) create mode 100644 src/devices/bus/thomson/cd90_015.cpp create mode 100644 src/devices/bus/thomson/cd90_015.h create mode 100644 src/devices/bus/thomson/cd90_351.cpp create mode 100644 src/devices/bus/thomson/cd90_351.h create mode 100644 src/devices/bus/thomson/cd90_640.cpp create mode 100644 src/devices/bus/thomson/cd90_640.h create mode 100644 src/devices/bus/thomson/cq90_028.cpp create mode 100644 src/devices/bus/thomson/cq90_028.h create mode 100644 src/devices/bus/thomson/extension.cpp create mode 100644 src/devices/bus/thomson/extension.h create mode 100644 src/devices/bus/thomson/nanoreseau.cpp create mode 100644 src/devices/bus/thomson/nanoreseau.h delete mode 100644 src/mame/machine/thomflop.cpp delete mode 100644 src/mame/machine/thomflop.h 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 - 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 m_floppy; + required_device_array m_floppy; required_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 m_fdc; + required_device_array 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 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 m_fdc; + required_device_array 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 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(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 +{ +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 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 void set_floppy_drive(T &&tag) { m_floppy[Id].set_tag(std::forward(tag)); } - template void set_floppy_drives(T &&tag0, U &&tag1, V &&tag2, W &&tag3) - { - m_floppy[0].set_tag(std::forward(tag0)); - m_floppy[1].set_tag(std::forward(tag1)); - m_floppy[2].set_tag(std::forward(tag2)); - m_floppy[3].set_tag(std::forward(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 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 -#include #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> 8; - buf[buflen+5] = crc & 0xff; - for (i=0;isector_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, §or, 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; +const floppy_format_type FLOPPY_THOMSON_35_FORMAT = &floppy_image_format_creator; 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 &c break; } int ns = 0; - for(int j = 0; j < 256 && j < sectors.size(); j++) + for(int j=0; jset_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")->set_init(FUNC(thomson_state::mo5_palette)); + subdevice("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 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 m_maincpu; required_device m_cassette; @@ -401,10 +259,10 @@ private: required_device m_ram; optional_device m_mc6846; optional_device m_mc6843; - required_device m_wd2793_fdc; required_device m_screen; required_device m_mainirq; required_device m_mainfirq; + required_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 m_cart_rom; - required_device m_to7qdd; - required_device m_thmfc; - output_finder<> m_floppy_led; - required_device_array 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 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 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("0")->get_device(); - if (BIT(data, 2)) floppy = m_wd2793_fdc->subdevice("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(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 - 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(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 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 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 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 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 ); -- cgit v1.2.3