From c1ac6705794c9ce275fc438152806fb6b13f4df8 Mon Sep 17 00:00:00 2001 From: mooglyguy Date: Wed, 12 Jun 2019 08:32:28 +0200 Subject: -dpb7000: Various changes. [Ryan Holtz] * Fixed FFDxxx range to pull a bus error. System now attempts disk boot. * Fixed screen size and visible area. * Fixed field in/out timers. * Began adding FDC support. * Added additional microcode logging. * Assorted disc sequencer card condition code fixes. * Modernized logging. --- src/mame/drivers/dpb7000.cpp | 474 ++++++++++++++++++++++++++++++++----------- 1 file changed, 359 insertions(+), 115 deletions(-) diff --git a/src/mame/drivers/dpb7000.cpp b/src/mame/drivers/dpb7000.cpp index 1a1a2f6d3fe..780e302c4e2 100644 --- a/src/mame/drivers/dpb7000.cpp +++ b/src/mame/drivers/dpb7000.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "bus/rs232/rs232.h" #include "cpu/m68000/m68000.h" +#include "cpu/m6800/m6801.h" #include "machine/6850acia.h" #include "machine/am2910.h" #include "machine/com8116.h" @@ -18,6 +19,21 @@ #include "video/mc6845.h" #include "emupal.h" #include "screen.h" +#include + +#define LOG_UNKNOWN (1 << 0) +#define LOG_UCODE (1 << 2) +#define LOG_MORE_UCODE (1 << 3) +#define LOG_CSR (1 << 4) +#define LOG_CTRLBUS (1 << 5) +#define LOG_SYS_CTRL (1 << 6) +#define LOG_FDC_CTRL (1 << 7) +#define LOG_FDC_PORT (1 << 8) +#define LOG_FDC_CMD (1 << 9) +#define LOG_ALL (LOG_UNKNOWN | LOG_UCODE | LOG_MORE_UCODE | LOG_CSR | LOG_CTRLBUS | LOG_SYS_CTRL | LOG_FDC_CTRL | LOG_FDC_PORT | LOG_FDC_CMD) + +#define VERBOSE (LOG_ALL &~ LOG_FDC_CTRL) +#include "logmacro.h" class dpb7000_state : public driver_device { @@ -40,26 +56,30 @@ public: , m_diskseq(*this, "diskseq") , m_diskseq_ucode(*this, "diskseq_ucode") , m_diskseq_prom(*this, "diskseq_prom") + , m_fddcpu(*this, "fddcpu") + , m_fdd_serial(*this, "fddserial") { } void dpb7000(machine_config &config); private: - void main_map(address_map &map); - virtual void machine_start() override; virtual void machine_reset() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; static constexpr device_timer_id TIMER_DISKSEQ = 0; static constexpr device_timer_id TIMER_FIELD_IN = 1; - static constexpr device_timer_id TIMER_FIELD_OUT = 1; + static constexpr device_timer_id TIMER_FIELD_OUT = 2; + + void main_map(address_map &map); + void fddcpu_map(address_map &map); DECLARE_READ16_MEMBER(bus_error_r); DECLARE_WRITE16_MEMBER(bus_error_w); DECLARE_WRITE8_MEMBER(csr_w); + DECLARE_READ8_MEMBER(csr_r); DECLARE_READ16_MEMBER(cpu_ctrlbus_r); DECLARE_WRITE16_MEMBER(cpu_ctrlbus_w); @@ -67,6 +87,13 @@ private: DECLARE_WRITE_LINE_MEMBER(req_a_w); DECLARE_WRITE_LINE_MEMBER(req_b_w); + DECLARE_READ8_MEMBER(fdd_ctrl_r); + DECLARE_READ8_MEMBER(fdd_cmd_r); + DECLARE_WRITE8_MEMBER(fddcpu_p1_w); + DECLARE_READ8_MEMBER(fddcpu_p2_r); + DECLARE_WRITE8_MEMBER(fddcpu_p2_w); + DECLARE_WRITE_LINE_MEMBER(fddcpu_debug_rx); + enum : uint16_t { SYSCTRL_AUTO_START = 0x0001, @@ -97,12 +124,24 @@ private: required_memory_region m_vdu_char_rom; required_ioport m_baud_dip; required_ioport m_auto_start; + required_ioport m_config_sw12; required_ioport m_config_sw34; + required_device m_diskseq; required_memory_region m_diskseq_ucode; required_memory_region m_diskseq_prom; + required_device m_fddcpu; + required_device m_fdd_serial; + std::deque m_fdd_debug_rx_bits; + size_t m_fdd_debug_rx_bit_count; + size_t m_fdd_debug_rx_byte_count; + size_t m_fdd_debug_rx_recv_count; + uint8_t m_fdd_ctrl; + uint8_t m_fdd_port1; + uint8_t m_fdd_track; + emu_timer *m_diskseq_clk; emu_timer *m_field_in_clk; emu_timer *m_field_out_clk; @@ -140,11 +179,14 @@ private: uint16_t m_sys_ctrl; int m_diskseq_cp; bool m_diskseq_reset; + bool m_diskseq_halt; uint8_t m_diskseq_line_cnt; // EF/EE uint8_t m_diskseq_ed_cnt; // ED uint8_t m_diskseq_head_cnt; // EC - uint16_t m_diskseq_cyl; // AE/BH - uint16_t m_diskseq_cmd; // DD/CC + uint16_t m_diskseq_cyl_from_cpu; // AE/BH + uint16_t m_diskseq_cmd_from_cpu; // DD/CC + uint8_t m_diskseq_cyl_to_ctrl; + uint8_t m_diskseq_cmd_to_ctrl; uint8_t m_diskseq_status_in; // CG uint8_t m_diskseq_status_out; // BC uint8_t m_diskseq_ucode_latch[7]; // GG/GF/GE/GD/GC/GB/GA @@ -156,11 +198,13 @@ void dpb7000_state::main_map(address_map &map) map(0x000000, 0x07ffff).rom().region("monitor", 0); map(0xb00000, 0xb7ffff).rw(FUNC(dpb7000_state::bus_error_r), FUNC(dpb7000_state::bus_error_w)); map(0xb80000, 0xbfffff).ram(); + map(0xffd000, 0xffd3ff).rw(FUNC(dpb7000_state::bus_error_r), FUNC(dpb7000_state::bus_error_w)); map(0xffe000, 0xffefff).ram().share("vduram").umask16(0x00ff); map(0xfff801, 0xfff801).rw(m_crtc, FUNC(sy6545_1_device::status_r), FUNC(sy6545_1_device::address_w)).cswidth(16); map(0xfff803, 0xfff803).rw(m_crtc, FUNC(sy6545_1_device::register_r), FUNC(sy6545_1_device::register_w)).cswidth(16); map(0xfff805, 0xfff805).rw(m_acia[0], FUNC(acia6850_device::status_r), FUNC(acia6850_device::control_w)).cswidth(16); map(0xfff807, 0xfff807).rw(m_acia[0], FUNC(acia6850_device::data_r), FUNC(acia6850_device::data_w)).cswidth(16); + map(0xfff808, 0xfff808).r(FUNC(dpb7000_state::csr_r)).cswidth(16); map(0xfff809, 0xfff809).w(FUNC(dpb7000_state::csr_w)).cswidth(16); map(0xfff80a, 0xfff80b).rw(FUNC(dpb7000_state::cpu_ctrlbus_r), FUNC(dpb7000_state::cpu_ctrlbus_w)); map(0xfff80c, 0xfff80d).rw(FUNC(dpb7000_state::cpu_sysctrl_r), FUNC(dpb7000_state::cpu_sysctrl_w)); @@ -170,6 +214,13 @@ void dpb7000_state::main_map(address_map &map) map(0xfff817, 0xfff817).rw(m_acia[2], FUNC(acia6850_device::data_r), FUNC(acia6850_device::data_w)).cswidth(16); } +void dpb7000_state::fddcpu_map(address_map &map) +{ + map(0x4000, 0x4000).r(FUNC(dpb7000_state::fdd_ctrl_r)); + map(0x4001, 0x4001).r(FUNC(dpb7000_state::fdd_cmd_r)); + map(0xf800, 0xffff).rom().region("fddprom", 0); +} + static INPUT_PORTS_START( dpb7000 ) PORT_START("BAUD") PORT_DIPNAME( 0x0f, 0x0e, "Baud Rate for Terminal") @@ -196,102 +247,99 @@ static INPUT_PORTS_START( dpb7000 ) PORT_BIT( 0xfffe, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_START("CONFIGSW12") - PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:8") + PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x0001, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:7") - PORT_DIPSETTING( 0x0002, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0004, 0x0004, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:6") + PORT_DIPNAME( 0x0002, 0x0002, "NTSC/PAL" ) + PORT_DIPSETTING( 0x0002, "NTSC" ) + PORT_DIPSETTING( 0x0000, "PAL" ) + PORT_DIPNAME( 0x0004, 0x0004, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x0004, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0008, 0x0008, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:5") + PORT_DIPNAME( 0x0008, 0x0008, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x0008, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:4") + PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x0010, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:3") + PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x0020, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:2") + PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x0040, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:1") + PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x0080, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:8") + PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x0100, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:7") + PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x0200, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:6") + PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x0400, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:5") + PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x0800, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:4") + PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x1000, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:3") + PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x2000, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:2") + PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x4000, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:1") + PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x8000, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) PORT_START("CONFIGSW34") - PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW3:8") - PORT_DIPSETTING( 0x0001, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW3:7") - PORT_DIPSETTING( 0x0002, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0004, 0x0004, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW3:6") - PORT_DIPSETTING( 0x0004, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0008, 0x0008, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW3:5") - PORT_DIPSETTING( 0x0008, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW3:4") - PORT_DIPSETTING( 0x0010, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW3:3") - PORT_DIPSETTING( 0x0020, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW3:2") - PORT_DIPSETTING( 0x0040, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW3:1") - PORT_DIPSETTING( 0x0080, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW4:8") - PORT_DIPSETTING( 0x0100, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW4:7") - PORT_DIPSETTING( 0x0200, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW4:6") - PORT_DIPSETTING( 0x0400, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW4:5") - PORT_DIPSETTING( 0x0800, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW4:4") - PORT_DIPSETTING( 0x1000, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW4:3") - PORT_DIPSETTING( 0x2000, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW4:2") - PORT_DIPSETTING( 0x4000, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW4:1") + PORT_DIPNAME( 0x0003, 0x0003, "Disc Group 1 Count" ) + PORT_DIPSETTING( 0x0003, "One" ) + PORT_DIPSETTING( 0x0002, "Two" ) + PORT_DIPSETTING( 0x0001, "Three" ) + PORT_DIPSETTING( 0x0000, "Four" ) + PORT_DIPNAME( 0x001c, 0x001c, "Disc Group 0 Type" ) + PORT_DIPSETTING( 0x001c, "160Mb CDC Fixed" ) + PORT_DIPSETTING( 0x0018, "80Mb CDC Removable" ) + PORT_DIPSETTING( 0x0014, "NTSC/Floppy/PAL/Conv" ) + PORT_DIPSETTING( 0x0010, "Floppy Disc" ) + PORT_DIPSETTING( 0x000c, "80Mb Fujitsu" ) + PORT_DIPSETTING( 0x0008, "330Mb Fujitsu" ) + PORT_DIPSETTING( 0x0004, "160Mb Fujitsu" ) + PORT_DIPSETTING( 0x0000, "Unsupported" ) + PORT_DIPNAME( 0x0060, 0x0060, "Disc Group 1 Count" ) + PORT_DIPSETTING( 0x0060, "One" ) + PORT_DIPSETTING( 0x0040, "Two" ) + PORT_DIPSETTING( 0x0020, "Three" ) + PORT_DIPSETTING( 0x0000, "Four" ) + PORT_DIPNAME( 0x0380, 0x0380, "Disc Group 1 Type" ) + PORT_DIPSETTING( 0x0380, "160Mb CDC Fixed" ) + PORT_DIPSETTING( 0x0300, "80Mb CDC Removable" ) + PORT_DIPSETTING( 0x0280, "NTSC/Floppy/PAL/Conv" ) + PORT_DIPSETTING( 0x0200, "Floppy Disc" ) + PORT_DIPSETTING( 0x0180, "80Mb Fujitsu" ) + PORT_DIPSETTING( 0x0100, "330Mb Fujitsu" ) + PORT_DIPSETTING( 0x0080, "160Mb Fujitsu" ) + PORT_DIPSETTING( 0x0000, "Unsupported" ) + PORT_DIPNAME( 0x0c00, 0x0c00, "Disc Group 2 Count" ) + PORT_DIPSETTING( 0x0c00, "One" ) + PORT_DIPSETTING( 0x0800, "Two" ) + PORT_DIPSETTING( 0x0400, "Three" ) + PORT_DIPSETTING( 0x0000, "Four" ) + PORT_DIPNAME( 0x7000, 0x7000, "Disc Group 2 Type" ) + PORT_DIPSETTING( 0x7000, "160Mb CDC Fixed" ) + PORT_DIPSETTING( 0x6000, "80Mb CDC Removable" ) + PORT_DIPSETTING( 0x5000, "NTSC/Floppy/PAL/Conv" ) + PORT_DIPSETTING( 0x4000, "Floppy Disc" ) + PORT_DIPSETTING( 0x3000, "80Mb Fujitsu" ) + PORT_DIPSETTING( 0x2000, "330Mb Fujitsu" ) + PORT_DIPSETTING( 0x1000, "160Mb Fujitsu" ) + PORT_DIPSETTING( 0x0000, "Unsupported" ) + PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x8000, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) INPUT_PORTS_END @@ -302,15 +350,24 @@ void dpb7000_state::machine_start() save_item(NAME(m_sys_ctrl)); save_item(NAME(m_diskseq_cp)); save_item(NAME(m_diskseq_reset)); + save_item(NAME(m_diskseq_halt)); save_item(NAME(m_diskseq_line_cnt)); save_item(NAME(m_diskseq_ed_cnt)); save_item(NAME(m_diskseq_head_cnt)); - save_item(NAME(m_diskseq_cyl)); - save_item(NAME(m_diskseq_cmd)); + save_item(NAME(m_diskseq_cyl_from_cpu)); + save_item(NAME(m_diskseq_cmd_from_cpu)); + save_item(NAME(m_diskseq_cyl_to_ctrl)); + save_item(NAME(m_diskseq_cmd_to_ctrl)); save_item(NAME(m_diskseq_status_in)); save_item(NAME(m_diskseq_status_out)); save_item(NAME(m_diskseq_ucode_latch)); save_item(NAME(m_diskseq_cc_inputs)); + save_item(NAME(m_fdd_debug_rx_bit_count)); + save_item(NAME(m_fdd_debug_rx_byte_count)); + save_item(NAME(m_fdd_debug_rx_recv_count)); + save_item(NAME(m_fdd_ctrl)); + save_item(NAME(m_fdd_port1)); + save_item(NAME(m_fdd_track)); m_diskseq_clk = timer_alloc(TIMER_DISKSEQ); m_diskseq_clk->adjust(attotime::never); @@ -318,7 +375,7 @@ void dpb7000_state::machine_start() m_field_in_clk = timer_alloc(TIMER_FIELD_IN); m_field_in_clk->adjust(attotime::never); - m_field_out_clk = timer_alloc(TIMER_FIELD_IN); + m_field_out_clk = timer_alloc(TIMER_FIELD_OUT); m_field_out_clk->adjust(attotime::never); } @@ -326,14 +383,17 @@ void dpb7000_state::machine_reset() { m_brg->stt_w(m_baud_dip->read()); m_csr = 0; - m_sys_ctrl = 0; + m_sys_ctrl = SYSCTRL_REQ_B_IN; m_diskseq_cp = 0; m_diskseq_reset = false; + m_diskseq_halt = true; m_diskseq_line_cnt = 0; m_diskseq_ed_cnt = 0; m_diskseq_head_cnt = 0; - m_diskseq_cyl = 0; - m_diskseq_cmd = 0; + m_diskseq_cyl_from_cpu = 0; + m_diskseq_cmd_from_cpu = 0; + m_diskseq_cyl_to_ctrl = 0; + m_diskseq_cmd_to_ctrl = 0; m_diskseq_status_in = 0; m_diskseq_status_out = 0; memset(m_diskseq_ucode_latch, 0, 7); @@ -341,7 +401,15 @@ void dpb7000_state::machine_reset() m_diskseq_clk->adjust(attotime::from_hz(1000000), 0, attotime::from_hz(1000000)); m_field_in_clk->adjust(attotime::from_hz(59.94), 0, attotime::from_hz(59.94)); - m_field_out_clk->adjust(attotime::from_hz(59.94) + attotime::from_hz(15734.0 / 9.0), 0, attotime::from_hz(59.94)); + m_field_out_clk->adjust(attotime::from_hz(59.94) + attotime::from_hz(15734.0 / 1.0), 0, attotime::from_hz(59.94)); + + m_fdd_debug_rx_bits.clear(); + m_fdd_debug_rx_bit_count = 0; + m_fdd_debug_rx_byte_count = 0; + m_fdd_debug_rx_recv_count = 0; + m_fdd_ctrl = 0; + m_fdd_port1 = 0; + m_fdd_track = 20; } void dpb7000_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) @@ -375,7 +443,7 @@ MC6845_UPDATE_ROW(dpb7000_state::crtc_update_row) int x = (column * 8) + bit; int color = BIT(data, 7) && de; - bitmap.pix32(vbp + y, hbp + x) = pen[color]; + bitmap.pix32(y, x) = pen[color]; data <<= 1; } @@ -397,7 +465,7 @@ WRITE16_MEMBER(dpb7000_state::diskseq_y_w) m_diskseq_ucode_latch[i] = ucode_prom[data | (i << 8)]; } - if (m_diskseq_reset) + if (m_diskseq_halt) { m_diskseq->i_w(0); } @@ -426,7 +494,7 @@ WRITE16_MEMBER(dpb7000_state::diskseq_y_w) m_diskseq_cc_inputs[0] |= m_diskseq_prom->base()[m_diskseq_line_cnt & 0x1f] & 3; m_diskseq_cc_inputs[0] |= BIT(m_diskseq_ed_cnt, 2) << 2; m_diskseq_cc_inputs[0] |= BIT(m_diskseq_head_cnt, 0) << 3; - m_diskseq_cc_inputs[0] |= BIT(m_diskseq_status_in, DSEQ_STATUS_READY_BIT) << 5; + m_diskseq_cc_inputs[0] |= BIT(~m_diskseq_status_in, DSEQ_STATUS_READY_BIT) << 5; m_diskseq_cc_inputs[0] |= BIT(m_diskseq_status_in, DSEQ_STATUS_FAULT_BIT) << 6; m_diskseq_cc_inputs[0] |= BIT(m_diskseq_status_in, DSEQ_STATUS_ONCYL_BIT) << 7; @@ -441,9 +509,9 @@ WRITE16_MEMBER(dpb7000_state::diskseq_y_w) m_diskseq_cc_inputs[2] |= BIT(m_diskseq_status_in, DSEQ_STATUS_RAM_ADDR_OVFLO_BIT); // C17..C19 tied low - m_diskseq_cc_inputs[2] |= (m_diskseq_cmd & 0xf) << 4; + m_diskseq_cc_inputs[2] |= ~(m_diskseq_cmd_from_cpu & 0xf) << 4; - m_diskseq_cc_inputs[3] = (m_diskseq_cmd >> 4) & 0xff; + m_diskseq_cc_inputs[3] = ~(m_diskseq_cmd_from_cpu >> 4) & 0xff; // S15, S16: Select which bank of 8 lines is treated as /CC input to Am2910 const uint8_t fx_bank_sel = (BIT(m_diskseq_ucode_latch[2], 0) << 1) | BIT(m_diskseq_ucode_latch[1], 7); @@ -451,24 +519,68 @@ WRITE16_MEMBER(dpb7000_state::diskseq_y_w) // S12, S13, S14: Select which bit from the bank is treated as /CC input to Am2910 const uint8_t fx_bit_sel = (BIT(m_diskseq_ucode_latch[1], 6) << 2) | (BIT(m_diskseq_ucode_latch[1], 5) << 1) | BIT(m_diskseq_ucode_latch[1], 4); - m_diskseq->cc_w(BIT(m_diskseq_cc_inputs[fx_bank_sel], fx_bit_sel) ? 0 : 1); + const int cc = BIT(m_diskseq_cc_inputs[fx_bank_sel], fx_bit_sel) ? 1 : 0; + if (!m_diskseq_halt) + { +#if (VERBOSE & (LOG_UCODE | LOG_MORE_UCODE)) + char debug_buf[1024]; + int buf_idx = 0; + + buf_idx += sprintf(debug_buf + buf_idx, "%02x: %02x%02x%02x%02x%02x%02x%02x ", data, + m_diskseq_ucode_latch[6], m_diskseq_ucode_latch[5], m_diskseq_ucode_latch[4], m_diskseq_ucode_latch[3], + m_diskseq_ucode_latch[2], m_diskseq_ucode_latch[1], m_diskseq_ucode_latch[0]); + + switch (m_diskseq_ucode_latch[1] & 0x0f) + { + case 0: buf_idx += sprintf(debug_buf + buf_idx, "JZ ; "); break; + case 1: buf_idx += sprintf(debug_buf + buf_idx, "CJS %02x ; ", m_diskseq_ucode_latch[0]); break; + case 2: buf_idx += sprintf(debug_buf + buf_idx, "JMAP ; "); break; + case 3: buf_idx += sprintf(debug_buf + buf_idx, "CJP %02x ; ", m_diskseq_ucode_latch[0]); break; + case 4: buf_idx += sprintf(debug_buf + buf_idx, "PUSH %02x ; ", m_diskseq_ucode_latch[0]); break; + case 5: buf_idx += sprintf(debug_buf + buf_idx, "JSRP %02x ; ", m_diskseq_ucode_latch[0]); break; + case 6: buf_idx += sprintf(debug_buf + buf_idx, "CJV %02x ; ", m_diskseq_ucode_latch[0]); break; + case 7: buf_idx += sprintf(debug_buf + buf_idx, "JRP %02x ; ", m_diskseq_ucode_latch[0]); break; + case 8: buf_idx += sprintf(debug_buf + buf_idx, "RFCT ; "); break; + case 9: buf_idx += sprintf(debug_buf + buf_idx, "RPCT ; "); break; + case 10: buf_idx += sprintf(debug_buf + buf_idx, "CRTN ; "); break; + case 11: buf_idx += sprintf(debug_buf + buf_idx, "CJPP %02x ; ", m_diskseq_ucode_latch[0]); break; + case 12: buf_idx += sprintf(debug_buf + buf_idx, "LDCT %02x ; ", m_diskseq_ucode_latch[0]); break; + case 13: buf_idx += sprintf(debug_buf + buf_idx, "LOOP ; "); break; + case 14: buf_idx += sprintf(debug_buf + buf_idx, "CONT ; "); break; + case 15: buf_idx += sprintf(debug_buf + buf_idx, "TWB %02x ; ", m_diskseq_ucode_latch[0]); break; + } + +#if LOG_MORE_UCODE + buf_idx += sprintf(debug_buf + buf_idx, "CCSel:%2d, CCx:%02x%02x%02x%02x, CC:%d, ", fx_bank_sel * 8 + fx_bit_sel, m_diskseq_cc_inputs[3], m_diskseq_cc_inputs[2], m_diskseq_cc_inputs[1], m_diskseq_cc_inputs[0], cc); + buf_idx += sprintf(debug_buf + buf_idx, "FCyl:%d, FHD:%d, FCmd:%d, FSel:%d", BIT(m_diskseq_ucode_latch[2], 7), BIT(m_diskseq_ucode_latch[4], 2), BIT(m_diskseq_ucode_latch[4], 4), BIT(m_diskseq_ucode_latch[4], 5)); +#endif + LOGMASKED(LOG_UCODE, "%s\n", debug_buf); +#endif + } + m_diskseq->cc_w(cc); // S25: End of sequencer program - //logerror("ucode latches %02x: %02x %02x %02x %02x %02x %02x %02x\n", data, - //m_diskseq_ucode_latch[0], m_diskseq_ucode_latch[1], m_diskseq_ucode_latch[2], m_diskseq_ucode_latch[3], - //m_diskseq_ucode_latch[4], m_diskseq_ucode_latch[5], m_diskseq_ucode_latch[6]); - req_b_w(BIT(m_diskseq_ucode_latch[3], 1) ? 0 : 1); + if (BIT(m_diskseq_ucode_latch[3], 1)) + { + m_diskseq_halt = true; + req_b_w(1); + } // S23: FCYL TAG - // S24: Push cylinder number onto the bus cable // S26, S28..S34: Command word to push onto bus cable - // S27: Push command word from S26, S28..S34 onto bus cable // S35: FHD TAG // S36: FCMD TAG // S37: FSEL TAG // S38: N/C // S39: N/C from PROM, contains D INDEX status bit - // S40..S47: Outgoing control signals + // S40: CK SEL 0 + // S41: CK SEL 1 + // S42: ADDR W. PERMIT + // S43: ZERO RAM + // S44: WRITE RAM + // S45: WORD READ RAM + // S46: WRITE SYNC + // S47: SYNC DET EN // S48: CPU Status Byte D0 // S49: CPU Status Byte D1 // S50: CPU Status Byte D2 @@ -478,11 +590,33 @@ WRITE16_MEMBER(dpb7000_state::diskseq_y_w) // ED Bit 1: CPU Status Byte D6 // C6 (D FAULT): CPU Status Byte D7 - m_diskseq_status_out = m_diskseq_ucode_latch[6] & 7; - m_diskseq_status_out |= BIT(m_diskseq_status_in, DSEQ_STATUS_READY_BIT) << 3; - m_diskseq_status_out |= BIT(m_diskseq_status_in, DSEQ_STATUS_WTPROT_BIT) << 4; - m_diskseq_status_out |= (m_diskseq_ed_cnt & 3) << 5; - m_diskseq_status_out |= BIT(m_diskseq_status_in, DSEQ_STATUS_FAULT_BIT) << 7; + if (BIT(m_diskseq_ucode_latch[3], 3)) // S27: Push command word from S26, S28..S34 onto bus cable + { + uint8_t disk_cmd = BIT(m_diskseq_ucode_latch[4], 2); + disk_cmd |= BIT(m_diskseq_ucode_latch[4], 1) << 1; + disk_cmd |= BIT(m_diskseq_ucode_latch[4], 0) << 4; + disk_cmd |= BIT(m_diskseq_ucode_latch[3], 7) << 5; + disk_cmd |= BIT(m_diskseq_ucode_latch[3], 6) << 6; + disk_cmd |= BIT(m_diskseq_ucode_latch[3], 5) << 7; + disk_cmd |= BIT(m_diskseq_ucode_latch[3], 4) << 8; + m_diskseq_cmd_to_ctrl = disk_cmd; + m_fdd_ctrl |= 0x10; + } + + if (BIT(m_diskseq_ucode_latch[3], 0)) // S24: Push cylinder number onto the bus cable + { + m_diskseq_cyl_to_ctrl = m_diskseq_cyl_from_cpu; + m_fdd_ctrl |= 0x40; + } + + if (BIT(m_diskseq_ucode_latch[6], 4)) + { + m_diskseq_status_out = m_diskseq_ucode_latch[6] & 7; + m_diskseq_status_out |= BIT(m_diskseq_status_in, DSEQ_STATUS_READY_BIT) << 3; + m_diskseq_status_out |= BIT(m_diskseq_status_in, DSEQ_STATUS_WTPROT_BIT) << 4; + m_diskseq_status_out |= (m_diskseq_ed_cnt & 3) << 5; + m_diskseq_status_out |= 0x80;//BIT(m_diskseq_status_in, DSEQ_STATUS_FAULT_BIT) << 7; + } } void dpb7000_state::diskseq_tick() @@ -492,7 +626,6 @@ void dpb7000_state::diskseq_tick() if (m_diskseq_cp && m_diskseq_reset) { - req_b_w(0); m_diskseq_reset = false; } } @@ -520,29 +653,35 @@ WRITE16_MEMBER(dpb7000_state::bus_error_w) WRITE8_MEMBER(dpb7000_state::csr_w) { - logerror("%s: Card Select write: %02x\n", machine().describe_context(), data & 0x0f); + LOGMASKED(LOG_CSR, "%s: Card Select write: %02x\n", machine().describe_context(), data & 0x0f); m_csr = data & 0x0f; } +READ8_MEMBER(dpb7000_state::csr_r) +{ + LOGMASKED(LOG_CSR, "%s: Card Select read(?): %02x\n", machine().describe_context(), m_csr); + return m_csr; +} + READ16_MEMBER(dpb7000_state::cpu_ctrlbus_r) { uint16_t ret = 0; switch (m_csr) { + case 1: + LOGMASKED(LOG_CTRLBUS, "%s: CPU read from Control Bus, Disk Sequencer Card status: %02x\n", machine().describe_context(), m_diskseq_status_out); + ret = m_diskseq_status_out; + break; case 12: ret = m_config_sw34->read(); - logerror("%s: CPU read from Control Bus, Config Switches 1/2: %04x\n", machine().describe_context(), ret); + LOGMASKED(LOG_CTRLBUS, "%s: CPU read from Control Bus, Config Switches 1/2: %04x\n", machine().describe_context(), ret); break; case 14: ret = m_config_sw12->read(); - logerror("%s: CPU read from Control Bus, Config Switches 3/4: %04x\n", machine().describe_context(), ret); - break; - case 15: - logerror("%s: CPU read from Control Bus, Disk Sequencer Card status: %02x\n", machine().describe_context(), m_diskseq_status_out); - ret = m_diskseq_status_out; + LOGMASKED(LOG_CTRLBUS, "%s: CPU read from Control Bus, Config Switches 3/4: %04x\n", machine().describe_context(), ret); break; default: - logerror("%s: CPU read from Control Bus, unknown CSR %d\n", machine().describe_context(), m_csr); + LOGMASKED(LOG_CTRLBUS | LOG_UNKNOWN, "%s: CPU read from Control Bus, unknown CSR %d\n", machine().describe_context(), m_csr); break; } return ret; @@ -557,27 +696,29 @@ WRITE16_MEMBER(dpb7000_state::cpu_ctrlbus_w) const uint8_t hi_nybble = data >> 12; if (hi_nybble == 0) { - m_diskseq_cyl = data & 0x3ff; - logerror("%s: CPU write to Control Bus, Disk Sequencer Card, Cylinder Number: %04x\n", machine().describe_context(), m_diskseq_cyl); + m_diskseq_cyl_from_cpu = data & 0x3ff; + LOGMASKED(LOG_CTRLBUS, "%s: CPU write to Control Bus, Disk Sequencer Card, Cylinder Number: %04x\n", machine().describe_context(), m_diskseq_cyl_from_cpu); } else if (hi_nybble == 2) { - m_diskseq_cmd = data & 0xfff; - req_b_w(1); - logerror("%s: CPU write to Control Bus, Disk Sequencer Card, Command: %04x\n", machine().describe_context(), m_diskseq_cmd); + m_diskseq_cmd_from_cpu = data & 0xfff; + m_diskseq_halt = false; + req_b_w(0); + LOGMASKED(LOG_CTRLBUS, "%s: CPU write to Control Bus, Disk Sequencer Card, Command: %04x\n", machine().describe_context(), m_diskseq_cmd_from_cpu); } else { - logerror("%s: CPU write to Control Bus, Disk Sequencer Card, Unrecognized hi nybble: %04x\n", machine().describe_context(), data); + LOGMASKED(LOG_CTRLBUS | LOG_UNKNOWN, "%s: CPU write to Control Bus, Disk Sequencer Card, Unrecognized hi nybble: %04x\n", machine().describe_context(), data); } break; } case 15: // Disk Sequencer Card, panic reset - logerror("%s: CPU write to Control Bus, Disk Sequencer Card, panic reset\n", machine().describe_context()); + LOGMASKED(LOG_CTRLBUS, "%s: CPU write to Control Bus, Disk Sequencer Card, panic reset\n", machine().describe_context()); m_diskseq_reset = true; + m_diskseq_halt = true; break; default: - logerror("%s: CPU write to Control Bus, unknown CSR %d: %04x\n", machine().describe_context(), m_csr, data); + LOGMASKED(LOG_CTRLBUS | LOG_UNKNOWN, "%s: CPU write to Control Bus, unknown CSR %d: %04x\n", machine().describe_context(), m_csr, data); break; } } @@ -607,14 +748,14 @@ READ16_MEMBER(dpb7000_state::cpu_sysctrl_r) const uint16_t ctrl = m_sys_ctrl &~ SYSCTRL_AUTO_START; const uint16_t auto_start = m_auto_start->read() ? SYSCTRL_AUTO_START : 0; const uint16_t ret = ctrl | auto_start; - logerror("%s: CPU read from System Control: %04x\n", machine().describe_context(), ret); + LOGMASKED(LOG_SYS_CTRL, "%s: CPU read from System Control: %04x\n", machine().describe_context(), ret); return ret; } WRITE16_MEMBER(dpb7000_state::cpu_sysctrl_w) { const uint16_t mask = (SYSCTRL_REQ_A_EN | SYSCTRL_REQ_B_EN); - logerror("%s: CPU to Control Bus write: %04x\n", machine().describe_context(), data); + LOGMASKED(LOG_SYS_CTRL, "%s: CPU to Control Bus write: %04x\n", machine().describe_context(), data); m_sys_ctrl &= ~mask; m_sys_ctrl |= (data & mask); @@ -627,8 +768,95 @@ void dpb7000_state::update_req_irqs() m_maincpu->set_input_line(4, (m_sys_ctrl & SYSCTRL_REQ_B_IN) && (m_sys_ctrl & SYSCTRL_REQ_B_EN) ? ASSERT_LINE : CLEAR_LINE); } +READ8_MEMBER(dpb7000_state::fdd_ctrl_r) +{ + // D4: Command Tag Flag + // D5: Restore Flag + // D6: Cylinder Tag Flag + // D7: Debug Switch + const uint8_t ret = m_fdd_ctrl; + m_fdd_ctrl &= ~0x70; + LOGMASKED(LOG_FDC_CTRL, "%s: Floppy CPU Ctrl Read: %02x\n", machine().describe_context(), ret); + return ret; +} + +WRITE8_MEMBER(dpb7000_state::fddcpu_p1_w) +{ + LOGMASKED(LOG_FDC_PORT, "%s: Floppy CPU Port 1 Write: %02x\n", machine().describe_context(), data); + const uint8_t old_value = m_fdd_port1; + m_fdd_port1 = data; + if (!BIT(old_value, 0) && BIT(m_fdd_port1, 0)) + { + if (BIT(m_fdd_port1, 1) && m_fdd_track < 40) + { + m_fdd_track++; + } + else if (!BIT(m_fdd_port1, 1) && m_fdd_track > 0) + { + m_fdd_track--; + } + + if (m_fdd_track == 0) + m_fdd_ctrl |= 4; + else + m_fdd_ctrl &= ~4; + } + if (BIT(m_fdd_port1, 7)) + m_diskseq_status_in |= (1 << DSEQ_STATUS_READY_BIT); + else + m_diskseq_status_in &= ~(1 << DSEQ_STATUS_READY_BIT); +} + +WRITE8_MEMBER(dpb7000_state::fddcpu_p2_w) +{ + m_fdd_serial->write_txd(BIT(data, 4)); +} + +READ8_MEMBER(dpb7000_state::fddcpu_p2_r) +{ + uint8_t ret = 0; + if (m_fdd_debug_rx_byte_count) + { + ret |= m_fdd_debug_rx_bits[0] << 3; + m_fdd_debug_rx_bits.pop_front(); + + m_fdd_debug_rx_recv_count++; + if (m_fdd_debug_rx_recv_count == 10) + { + m_fdd_debug_rx_recv_count = 0; + m_fdd_debug_rx_byte_count--; + } + } + else + { + ret |= 1 << 3; + } + return ret; +} + +READ8_MEMBER(dpb7000_state::fdd_cmd_r) +{ + LOGMASKED(LOG_FDC_CMD, "%s: Floppy CPU command read: %02x\n", m_diskseq_cmd_to_ctrl); + return m_diskseq_cmd_to_ctrl; +} + +WRITE_LINE_MEMBER(dpb7000_state::fddcpu_debug_rx) +{ + if (m_fdd_debug_rx_bit_count < 10) + { + m_fdd_debug_rx_bits.push_back(state); + m_fdd_debug_rx_bit_count++; + } + else + { + m_fdd_debug_rx_bit_count = 0; + m_fdd_debug_rx_byte_count++; + } +} + void dpb7000_state::dpb7000(machine_config &config) { + // Computer Card 1 & 2 M68000(config, m_maincpu, 16_MHz_XTAL / 2); m_maincpu->set_addrmap(AS_PROGRAM, &dpb7000_state::main_map); @@ -660,8 +888,8 @@ void dpb7000_state::dpb7000(machine_config &config) screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); screen.set_refresh_hz(60); - screen.set_size(640, 480); - screen.set_visarea(0, 639, 0, 479); // Not accurate + screen.set_size(696, 276); + screen.set_visarea(56, 695, 36, 275); screen.set_screen_update("crtc", FUNC(mc6845_device::screen_update)); PALETTE(config, m_palette, palette_device::MONOCHROME); @@ -675,11 +903,24 @@ void dpb7000_state::dpb7000(machine_config &config) m_crtc->set_update_row_callback(FUNC(dpb7000_state::crtc_update_row), this); m_crtc->set_on_update_addr_change_callback(FUNC(dpb7000_state::crtc_addr_changed), this); + // Disc Sequencer Card AM2910(config, m_diskseq, 0); // We drive the clock manually from the driver m_diskseq->ci_w(1); m_diskseq->rld_w(1); m_diskseq->ccen_w(0); m_diskseq->y().set(FUNC(dpb7000_state::diskseq_y_w)); + + // Floppy Disc Unit + M6803(config, m_fddcpu, 4.9152_MHz_XTAL); + m_fddcpu->set_addrmap(AS_PROGRAM, &dpb7000_state::fddcpu_map); + m_fddcpu->out_p1_cb().set(FUNC(dpb7000_state::fddcpu_p1_w)); + m_fddcpu->in_p2_cb().set(FUNC(dpb7000_state::fddcpu_p2_r)); + m_fddcpu->out_p2_cb().set(FUNC(dpb7000_state::fddcpu_p2_w)); + + RS232_PORT(config, m_fdd_serial, default_rs232_devices, nullptr); + m_fdd_serial->rxd_handler().set(FUNC(dpb7000_state::fddcpu_debug_rx)); + + config.m_perfect_cpu_quantum = subtag("fddcpu"); } @@ -716,6 +957,9 @@ ROM_START( dpb7000 ) ROM_REGION(0x700, "diskseq_prom", 0) ROM_LOAD("17704a-dfa-32.bin", 0x00, 0x20, CRC(ce5b8b46) SHA1(49a1e619f52101b6078e2f51d82ce5947fe2c011)) + + ROM_REGION(0x800, "fddprom", 0) + ROM_LOAD("17446a-gd-m2716.bin", 0x000, 0x800, CRC(a0be00ca) SHA1(48c4f8c07b9f6bc9b68698e1e326782e0b01e1b0)) ROM_END COMP( 1981, dpb7000, 0, 0, dpb7000, dpb7000, dpb7000_state, empty_init, "Quantel", "DPB-7000", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW ) -- cgit v1.2.3