From f63e8f0a55f08cea675dfd332cf8197a08bf5358 Mon Sep 17 00:00:00 2001 From: AJR Date: Sun, 27 Oct 2024 10:14:19 -0400 Subject: Thomson floppy disk updates - to8, to9 & to9p now include the FDC in the base configuration. to9 uses a WD1770 (WD2793 appears to fail calibration), while to8 & to9p use the THM-FC-1 gate array (now a separate device). This eliminates the need to, and ability to, configure floppy disk extensions for the to8, to9 and to9p. - Changed sector offsets for double-sided .fd images so that they load correctly (usually). --- scripts/src/machine.lua | 12 + src/devices/bus/thomson/cd90_351.cpp | 417 +-------------------------------- src/devices/bus/thomson/cd90_351.h | 79 +------ src/devices/bus/thomson/cd90_640.cpp | 4 +- src/devices/machine/thmfc1.cpp | 438 +++++++++++++++++++++++++++++++++++ src/devices/machine/thmfc1.h | 106 +++++++++ src/lib/formats/thom_dsk.cpp | 11 + src/lib/formats/thom_dsk.h | 4 + src/mame/thomson/thomson.cpp | 57 ++++- src/mame/thomson/thomson.h | 11 + src/mame/thomson/thomson_m.cpp | 32 +++ src/mame/thomson/to_kbd.cpp | 2 +- 12 files changed, 678 insertions(+), 495 deletions(-) create mode 100644 src/devices/machine/thmfc1.cpp create mode 100644 src/devices/machine/thmfc1.h diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index 053caa56129..acbf897cc85 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -3594,6 +3594,18 @@ if (MACHINES["TE7750"]~=null) then } end +--------------------------------------------------- +-- +--@src/devices/machine/thmfc1.h,MACHINES["THMFC1"] = true +--------------------------------------------------- + +if (MACHINES["THMFC1"]~=null) then + files { + MAME_DIR .. "src/devices/machine/thmfc1.cpp", + MAME_DIR .. "src/devices/machine/thmfc1.h", + } +end + --------------------------------------------------- -- --@src/devices/machine/ticket.h,MACHINES["TICKET"] = true diff --git a/src/devices/bus/thomson/cd90_351.cpp b/src/devices/bus/thomson/cd90_351.cpp index d4a610c1f3f..870c0843733 100644 --- a/src/devices/bus/thomson/cd90_351.cpp +++ b/src/devices/bus/thomson/cd90_351.cpp @@ -11,13 +11,13 @@ #include "emu.h" #include "cd90_351.h" #include "formats/thom_dsk.h" +#include "machine/thmfc1.h" DEFINE_DEVICE_TYPE(CD90_351, cd90_351_device, "cd90_351", "Thomson CD 90-351 Diskette 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), + device_t(mconfig, CD90_351, tag, owner, clock), thomson_extension_interface(mconfig, *this), - m_floppy(*this, "%u", 0U), m_rom(*this, "rom"), m_rom_bank(*this, "rom_bank") { @@ -41,14 +41,7 @@ void cd90_351_device::rom_map(address_map &map) void cd90_351_device::io_map(address_map &map) { - map(0x10, 0x10).rw(FUNC(cd90_351_device::stat0_r), FUNC(cd90_351_device::cmd0_w)); - map(0x11, 0x11).rw(FUNC(cd90_351_device::stat1_r), FUNC(cd90_351_device::cmd1_w)); - map(0x12, 0x12).w(FUNC(cd90_351_device::cmd2_w)); - map(0x13, 0x13).rw(FUNC(cd90_351_device::rdata_r), FUNC(cd90_351_device::wdata_w)); - map(0x14, 0x14).w(FUNC(cd90_351_device::wclk_w)); - map(0x15, 0x15).w(FUNC(cd90_351_device::wsect_w)); - map(0x16, 0x16).w(FUNC(cd90_351_device::wtrck_w)); - map(0x17, 0x17).w(FUNC(cd90_351_device::wcell_w)); + map(0x10, 0x17).m("thmfc1", FUNC(thmfc1_device::map)); map(0x18, 0x18).w(FUNC(cd90_351_device::bank_w)); } @@ -71,248 +64,19 @@ void cd90_351_device::floppy_formats(format_registration &fr) 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); + THMFC1(config, "thmfc1", 16000000); + FLOPPY_CONNECTOR(config, "thmfc1:0", floppy_drives, "dd90_352", floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, "thmfc1: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(FUNC(cd90_351_device::motor_off), this); - - 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; -} - -TIMER_CALLBACK_MEMBER(cd90_351_device::motor_off) -{ - logerror("motor off\n"); - if(m_cur_floppy) - m_cur_floppy->mon_w(1); -} - -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) @@ -320,172 +84,3 @@ 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 index 6b4b0784f3b..de5e40e1ac2 100644 --- a/src/devices/bus/thomson/cd90_351.h +++ b/src/devices/bus/thomson/cd90_351.h @@ -15,7 +15,7 @@ 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); + cd90_351_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); virtual ~cd90_351_device() = default; virtual void rom_map(address_map &map) override ATTR_COLD; @@ -26,92 +26,15 @@ protected: virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; virtual void device_start() override ATTR_COLD; virtual void device_reset() override ATTR_COLD; - virtual void device_post_load() override; - - TIMER_CALLBACK_MEMBER(motor_off); private: - 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) diff --git a/src/devices/bus/thomson/cd90_640.cpp b/src/devices/bus/thomson/cd90_640.cpp index 86453d795be..a49d579704e 100644 --- a/src/devices/bus/thomson/cd90_640.cpp +++ b/src/devices/bus/thomson/cd90_640.cpp @@ -43,7 +43,7 @@ const tiny_rom_entry *cd90_640_device::device_rom_region() const void cd90_640_device::floppy_drives(device_slot_interface &device) { - device.option_add("dd90_640", FLOPPY_525_DD); + device.option_add("dd90_320", FLOPPY_525_DD); } void cd90_640_device::floppy_formats(format_registration &fr) @@ -54,7 +54,7 @@ void cd90_640_device::floppy_formats(format_registration &fr) 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[0], floppy_drives, "dd90_320", floppy_formats).enable_sound(true); FLOPPY_CONNECTOR(config, m_floppy[1], floppy_drives, nullptr, floppy_formats).enable_sound(true); } diff --git a/src/devices/machine/thmfc1.cpp b/src/devices/machine/thmfc1.cpp new file mode 100644 index 00000000000..e485859f9b9 --- /dev/null +++ b/src/devices/machine/thmfc1.cpp @@ -0,0 +1,438 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert + +// Custom Thomson 3.5"/5.25"/QDD diskette controller gate array used in CD 90-351, TO8 and TO9+ + + +#include "emu.h" +#include "thmfc1.h" + +DEFINE_DEVICE_TYPE(THMFC1, thmfc1_device, "thmfc1", "SGS-Thomson THM-FC-1 Diskette Controller") // SGS logo used on silkscreen + +thmfc1_device::thmfc1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, THMFC1, tag, owner, clock), + m_floppy(*this, "%u", 0U) +{ +} + +void thmfc1_device::map(address_map &map) +{ + map(0, 0).rw(FUNC(thmfc1_device::stat0_r), FUNC(thmfc1_device::cmd0_w)); + map(1, 1).rw(FUNC(thmfc1_device::stat1_r), FUNC(thmfc1_device::cmd1_w)); + map(2, 2).w(FUNC(thmfc1_device::cmd2_w)); + map(3, 3).rw(FUNC(thmfc1_device::rdata_r), FUNC(thmfc1_device::wdata_w)); + map(4, 4).w(FUNC(thmfc1_device::wclk_w)); + map(5, 5).w(FUNC(thmfc1_device::wsect_w)); + map(6, 6).w(FUNC(thmfc1_device::wtrck_w)); + map(7, 7).w(FUNC(thmfc1_device::wcell_w)); +} + +void thmfc1_device::device_start() +{ + m_timer_motoroff = timer_alloc(FUNC(thmfc1_device::motor_off), this); + + 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 thmfc1_device::device_reset() +{ + 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; +} + +TIMER_CALLBACK_MEMBER(thmfc1_device::motor_off) +{ + logerror("motor off\n"); + if(m_cur_floppy) + m_cur_floppy->mon_w(1); +} + +void thmfc1_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 thmfc1_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 thmfc1_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 thmfc1_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 thmfc1_device::wdata_w(u8 data) +{ + m_data = data; + m_stat0 &= ~(S0_BYTE | S0_DREQ); + logerror("wdata_w %02x\n", data); +} + +void thmfc1_device::wclk_w(u8 data) +{ + sync(); + + m_clk = data; + logerror("wclk_w %02x\n", data); +} + +void thmfc1_device::wsect_w(u8 data) +{ + sync(); + + m_sect = data; + logerror("wsect_w %02x\n", data); +} + +void thmfc1_device::wtrck_w(u8 data) +{ + sync(); + + m_trck = data; + logerror("wtrck_w %02x\n", data); +} + +void thmfc1_device::wcell_w(u8 data) +{ + sync(); + + m_cell = data; + logerror("wcell_w %02x\n", data); +} + +u8 thmfc1_device::stat0_r() +{ + if(!machine().side_effects_disabled()) { + sync(); +#if 0 + 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; +#endif + } + return m_stat0; +} + +u8 thmfc1_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 thmfc1_device::rdata_r() +{ + if(!machine().side_effects_disabled()) { + logerror("rdata_r %02X (stat0=%02X)\n", m_data, m_stat0); + m_stat0 &= ~(S0_BYTE | S0_DREQ); + } + return m_data; +} + +u64 thmfc1_device::time_to_cycles(const attotime &tm) const +{ + return tm.as_ticks(clock()); +} + +attotime thmfc1_device::cycles_to_time(u64 cycles) const +{ + return attotime::from_ticks(cycles, clock()); +} + +bool thmfc1_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 thmfc1_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 thmfc1_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/machine/thmfc1.h b/src/devices/machine/thmfc1.h new file mode 100644 index 00000000000..60a6d0f9183 --- /dev/null +++ b/src/devices/machine/thmfc1.h @@ -0,0 +1,106 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert + +#ifndef MAME_MACHINE_THMFC1_H +#define MAME_MACHINE_THMFC1_H + +#pragma once + +#include "imagedev/floppy.h" + +class thmfc1_device : public device_t +{ +public: + thmfc1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + virtual ~thmfc1_device() = default; + + void map(address_map &map) ATTR_COLD; + +protected: + virtual void device_start() override ATTR_COLD; + virtual void device_reset() override ATTR_COLD; + virtual void device_post_load() override; + + TIMER_CALLBACK_MEMBER(motor_off); + +private: + 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; + 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; + + 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); + + 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(THMFC1, thmfc1_device) + +#endif // MAME_MACHINE_THMFC1_H diff --git a/src/lib/formats/thom_dsk.cpp b/src/lib/formats/thom_dsk.cpp index ad2e4495ca2..f63b35f06ad 100644 --- a/src/lib/formats/thom_dsk.cpp +++ b/src/lib/formats/thom_dsk.cpp @@ -50,6 +50,12 @@ const thomson_525_format::format thomson_525_format::formats[] = { {} }; +int thomson_525_format::get_image_offset(const format &f, int head, int track) const +{ + return (track + (head ? f.track_count : 0)) * compute_track_size(f); +} + + thomson_35_format::thomson_35_format() : wd177x_format(formats) { @@ -90,5 +96,10 @@ const thomson_35_format::format thomson_35_format::formats[] = { {} }; +int thomson_35_format::get_image_offset(const format &f, int head, int track) const +{ + return (track + (head ? f.track_count : 0)) * compute_track_size(f); +} + const thomson_525_format FLOPPY_THOMSON_525_FORMAT; const thomson_35_format FLOPPY_THOMSON_35_FORMAT; diff --git a/src/lib/formats/thom_dsk.h b/src/lib/formats/thom_dsk.h index 52927f15de8..09ea1cbec0c 100644 --- a/src/lib/formats/thom_dsk.h +++ b/src/lib/formats/thom_dsk.h @@ -16,6 +16,8 @@ public: virtual const char *description() const noexcept override; virtual const char *extensions() const noexcept override; + int get_image_offset(const format &f, int head, int track) const override; + private: static const format formats[]; }; @@ -29,6 +31,8 @@ public: virtual const char *description() const noexcept override; virtual const char *extensions() const noexcept override; + int get_image_offset(const format &f, int head, int track) const override; + private: static const format formats[]; }; diff --git a/src/mame/thomson/thomson.cpp b/src/mame/thomson/thomson.cpp index 67d77a2f035..2d6e844c1f5 100644 --- a/src/mame/thomson/thomson.cpp +++ b/src/mame/thomson/thomson.cpp @@ -92,12 +92,11 @@ #include "bus/thomson/speech.h" #include "machine/clock.h" #include "machine/ram.h" -#include "machine/wd_fdc.h" +#include "machine/thmfc1.h" #include "softlist_dev.h" #include "speaker.h" -#include "formats/basicdsk.h" #include "formats/thom_cas.h" #include "formats/thom_dsk.h" @@ -474,6 +473,23 @@ static INPUT_PORTS_START ( t9000 ) PORT_INCLUDE ( to7 ) INPUT_PORTS_END +static void to9_floppy_drives(device_slot_interface &device) +{ + device.option_add("dd90_352", FLOPPY_35_DD); +} + +static void to8_floppy_drives(device_slot_interface &device) +{ + device.option_add("dd90_352", FLOPPY_35_DD); + // device.option_add("qd90_280", FLOPPY_28_QDD); +} + +static void to35_floppy_formats(format_registration &fr) +{ + fr.add_pc_formats(); + fr.add(FLOPPY_THOMSON_35_FORMAT); +} + /* ------------ driver ------------ */ void thomson_state::to7_base(machine_config &config, bool is_mo) @@ -1037,7 +1053,7 @@ It was replaced quickly with the improved TO9+. - MD 90-120: MODEM extension (identical to the TO7) - IEEE extension ? (unemulated) - floppy: - . integrated floppy controller, based on WD2793 + . integrated floppy controller, based on WD1770 or WD2793 . integrated one-sided double-density 3''1/2 . external two-sided double-density 3''1/2, 5''1/4 or QDD (extension) . floppies are TO7 and MO5 compatible @@ -1057,6 +1073,8 @@ void to9_state::to9_map(address_map &map) 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, 0xe7d3).mirror(4).rw(m_fdc, FUNC(wd_fdc_device_base::read), FUNC(wd_fdc_device_base::write)); + map(0xe7d8, 0xe7d8).rw(FUNC(to9_state::to9_floppy_control_r), FUNC(to9_state::to9_floppy_control_w)); map(0xe7da, 0xe7dd).rw(FUNC(to9_state::to9_vreg_r), FUNC(to9_state::to9_vreg_w)); map(0xe7de, 0xe7df).rw(m_to9_kbd, FUNC(to9_keyboard_device::kbd_acia_r), FUNC(to9_keyboard_device::kbd_acia_w)); map(0xe7e4, 0xe7e7).rw(FUNC(to9_state::to9_gatearray_r), FUNC(to9_state::to9_gatearray_w)); @@ -1164,6 +1182,16 @@ void to9_state::to9(machine_config &config) m_mc6846->out_port().set(FUNC(to9_state::to9_timer_port_out)); + WD1770(config, m_fdc, 16_MHz_XTAL / 2); + FLOPPY_CONNECTOR(config, m_floppy[0], to9_floppy_drives, "dd90_352", to35_floppy_formats, true).enable_sound(true); + FLOPPY_CONNECTOR(config, m_floppy[1], to9_floppy_drives, nullptr, to35_floppy_formats, false).enable_sound(true); + + m_extension->option_remove("cd90_015"); + m_extension->option_remove("cq90_028"); + m_extension->option_remove("cd90_351"); + m_extension->option_remove("cd90_640"); + m_extension->option_remove("nanoreseau"); + CENTRONICS(config, m_centronics, centronics_devices, "printer"); m_centronics->busy_handler().set(FUNC(to9_state::write_centronics_busy)); @@ -1252,6 +1280,7 @@ void to9_state::to8_map(address_map &map) 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, 0xe7d7).m("thmfc1", FUNC(thmfc1_device::map)); 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(0xe7f0, 0xe7f7).rw(FUNC(to9_state::to9_ieee_r), FUNC(to9_state::to9_ieee_w )); */ @@ -1361,6 +1390,16 @@ void to9_state::to8(machine_config &config) m_pia_sys->cb2_handler().set_nop(); m_pia_sys->irqa_handler().set_nop(); + THMFC1(config, "thmfc1", 16_MHz_XTAL); + FLOPPY_CONNECTOR(config, "thmfc1:0", to8_floppy_drives, "dd90_352", to35_floppy_formats, false).enable_sound(true); + FLOPPY_CONNECTOR(config, "thmfc1:1", to8_floppy_drives, nullptr, to35_floppy_formats, false).enable_sound(true); + + m_extension->option_remove("cd90_015"); + m_extension->option_remove("cq90_028"); + m_extension->option_remove("cd90_351"); + m_extension->option_remove("cd90_640"); + m_extension->option_remove("nanoreseau"); + CENTRONICS(config, m_centronics, centronics_devices, "printer"); m_centronics->busy_handler().set(FUNC(to9_state::write_centronics_busy)); @@ -1380,6 +1419,7 @@ void to9_state::to8(machine_config &config) void to9_state::to8d(machine_config &config) { to8(config); + subdevice("thmfc1:0")->set_fixed(true); } @@ -1439,6 +1479,7 @@ void to9_state::to9p_map(address_map &map) 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, 0xe7d7).m("thmfc1", FUNC(thmfc1_device::map)); map(0xe7da, 0xe7dd).rw(FUNC(to9_state::to8_vreg_r), FUNC(to9_state::to8_vreg_w)); map(0xe7de, 0xe7df).rw(m_to9_kbd, FUNC(to9_keyboard_device::kbd_acia_r), FUNC(to9_keyboard_device::kbd_acia_w)); map(0xe7e4, 0xe7e7).rw(FUNC(to9_state::to8_gatearray_r), FUNC(to9_state::to8_gatearray_w)); @@ -1516,6 +1557,16 @@ void to9_state::to9p(machine_config &config) m_pia_sys->irqa_handler().set_nop(); m_pia_sys->irqb_handler().set("mainfirq", FUNC(input_merger_device::in_w<1>)); + THMFC1(config, "thmfc1", 16_MHz_XTAL); + FLOPPY_CONNECTOR(config, "thmfc1:0", to8_floppy_drives, "dd90_352", to35_floppy_formats, true).enable_sound(true); + FLOPPY_CONNECTOR(config, "thmfc1:1", to8_floppy_drives, nullptr, to35_floppy_formats, false).enable_sound(true); + + m_extension->option_remove("cd90_015"); + m_extension->option_remove("cq90_028"); + m_extension->option_remove("cd90_351"); + m_extension->option_remove("cd90_640"); + m_extension->option_remove("nanoreseau"); + CENTRONICS(config, m_centronics, centronics_devices, "printer"); m_centronics->busy_handler().set(FUNC(to9_state::write_centronics_busy)); diff --git a/src/mame/thomson/thomson.h b/src/mame/thomson/thomson.h index 905a7105698..69467714003 100644 --- a/src/mame/thomson/thomson.h +++ b/src/mame/thomson/thomson.h @@ -17,10 +17,12 @@ #include "cpu/m6809/m6809.h" #include "imagedev/cassette.h" +#include "imagedev/floppy.h" #include "machine/6821pia.h" #include "machine/input_merger.h" #include "machine/mc6846.h" #include "machine/ram.h" +#include "machine/wd_fdc.h" #include "sound/dac.h" #include "bus/thomson/extension.h" #include "bus/thomson/nanoreseau.h" @@ -388,6 +390,8 @@ public: thomson_state(mconfig, type, tag), m_to8_kbd(*this, "to8_kbd"), m_to9_kbd(*this, "to9_kbd"), + m_fdc(*this, "fdc"), + m_floppy(*this, "fdc:%u", 0U), m_centronics(*this, "centronics"), m_cent_data_out(*this, "cent_data_out"), m_syslobank(*this, TO8_SYS_LO), @@ -406,6 +410,8 @@ public: protected: optional_device m_to8_kbd; optional_device m_to9_kbd; + optional_device m_fdc; + optional_device_array m_floppy; optional_device m_centronics; optional_device m_cent_data_out; @@ -470,6 +476,10 @@ protected: void to9_sys_porta_out(uint8_t data); void to9_sys_portb_out(uint8_t data); void to9_timer_port_out(uint8_t data); + uint8_t to9_fdc_r(offs_t offset); + void to9_fdc_w(offs_t offset, uint8_t data); + uint8_t to9_floppy_control_r(); + void to9_floppy_control_w(uint8_t data); DECLARE_MACHINE_RESET( to9 ); DECLARE_MACHINE_START( to9 ); uint8_t to9p_timer_port_in(); @@ -481,6 +491,7 @@ protected: void to9_map(address_map &map) ATTR_COLD; void to9p_map(address_map &map) ATTR_COLD; + uint8_t m_to9_floppy_control = 0; uint8_t m_to9_palette_data[32]{}; uint8_t m_to9_palette_idx = 0; uint8_t m_to9_soft_bank = 0; diff --git a/src/mame/thomson/thomson_m.cpp b/src/mame/thomson/thomson_m.cpp index b5bc183160d..7046871267b 100644 --- a/src/mame/thomson/thomson_m.cpp +++ b/src/mame/thomson/thomson_m.cpp @@ -1728,6 +1728,33 @@ void to9_state::to9_timer_port_out(uint8_t data) } + +/* ------------ WD disk controller ------------ */ + + + +void to9_state::to9_floppy_control_w(u8 data) +{ + m_to9_floppy_control = data; + + floppy_image_device *floppy = nullptr; + if (BIT(m_to9_floppy_control, 1)) + floppy = m_floppy[0]->get_device(); + else if (BIT(m_to9_floppy_control, 2)) + floppy = m_floppy[1]->get_device(); + if (floppy) + floppy->ss_w(BIT(m_to9_floppy_control, 0)); + m_fdc->set_floppy(floppy); + + m_fdc->dden_w(BIT(m_to9_floppy_control, 7)); +} + +uint8_t to9_state::to9_floppy_control_r() +{ + return m_to9_floppy_control & 0x80; +} + + /* ------------ init / reset ------------ */ @@ -1780,6 +1807,10 @@ MACHINE_START_MEMBER( to9_state, to9 ) m_extension->rom_map(m_maincpu->space(AS_PROGRAM), 0xe000, 0xe7bf); m_extension->io_map (m_maincpu->space(AS_PROGRAM), 0xe7c0, 0xe7ff); + m_to9_floppy_control = 0; + m_fdc->set_floppy(nullptr); + m_fdc->dden_w(0); + /* memory */ m_thom_vram = ram; m_thom_cart_bank = 0; @@ -1799,6 +1830,7 @@ MACHINE_START_MEMBER( to9_state, to9 ) save_item(NAME(m_to7_lightpen)); save_item(NAME(m_to7_lightpen_step)); save_item(NAME(m_to9_soft_bank)); + save_item(NAME(m_to9_floppy_control)); save_pointer(NAME(cartmem), 0x10000 ); 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)); diff --git a/src/mame/thomson/to_kbd.cpp b/src/mame/thomson/to_kbd.cpp index daf653db12c..12bbc042910 100644 --- a/src/mame/thomson/to_kbd.cpp +++ b/src/mame/thomson/to_kbd.cpp @@ -16,7 +16,7 @@ #define LOG_KBD (1U << 1) #define LOG_ERRORS (1U << 2) -#define VERBOSE (LOG_KBD | LOG_ERRORS) +//#define VERBOSE (LOG_KBD | LOG_ERRORS) #include "logmacro.h" -- cgit v1.2.3