From 5ae175ff115ab674fd3de623175c6571b522e765 Mon Sep 17 00:00:00 2001 From: mooglyguy Date: Wed, 18 Apr 2018 19:15:22 +0200 Subject: vp415 skeleton updates, nw --- scripts/src/machine.lua | 13 ++ scripts/target/mame/mess.lua | 1 + src/devices/machine/ncr5385.cpp | 120 +++++++++++++ src/devices/machine/ncr5385.h | 141 +++++++++++++++ src/mame/drivers/vp415.cpp | 387 +++++++++++++++++++++------------------- 5 files changed, 479 insertions(+), 183 deletions(-) create mode 100644 src/devices/machine/ncr5385.cpp create mode 100644 src/devices/machine/ncr5385.h diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index f08a592ffae..91d5da4519a 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -153,6 +153,19 @@ if (MACHINES["NCR53C7XX"]~=null) then } end +--------------------------------------------------- +-- +--@src/devices/machine/ncr5385.h,MACHINES["NCR5385"] = true +--------------------------------------------------- + +if (MACHINES["NCR5385"]~=null) then + MACHINES["NSCSI"] = true + files { + MAME_DIR .. "src/devices/machine/ncr5385.cpp", + MAME_DIR .. "src/devices/machine/ncr5385.h", + } +end + --------------------------------------------------- -- --@src/devices/machine/53c810.h,MACHINES["LSI53C810"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 48f9c605c5b..9eae21510c5 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -505,6 +505,7 @@ MACHINES["MSM6242"] = true MACHINES["MYB3K_KEYBOARD"] = true MACHINES["NCR5380"] = true MACHINES["NCR5380N"] = true +MACHINES["NCR5385"] = true MACHINES["NCR5390"] = true MACHINES["NCR539x"] = true MACHINES["NCR53C7XX"] = true diff --git a/src/devices/machine/ncr5385.cpp b/src/devices/machine/ncr5385.cpp new file mode 100644 index 00000000000..df2d61f07d0 --- /dev/null +++ b/src/devices/machine/ncr5385.cpp @@ -0,0 +1,120 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/*********************************************************************** + + NCR 5385E SCSI Controller + + TOOD: + - Everything. + +***********************************************************************/ + +#include "emu.h" +#include "ncr5385.h" + +DEFINE_DEVICE_TYPE(NCR5385, ncr5385_device, "ncr5385", "NCR 5385E SCSI Controller") + +ncr5385_device::ncr5385_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, NCR5385, tag, owner, clock) + , m_int(*this) +{ +} + +void ncr5385_device::device_start() +{ + m_int.resolve_safe(); +} + +void ncr5385_device::device_reset() +{ + m_state = STATE_IDLE; + m_int_reg = 0; + m_ctrl_reg = 0; + m_aux_status_reg = AUX_STATUS_TC_ZERO; + m_diag_status_reg = DIAG_COMPLETE; +} + +WRITE8_MEMBER(ncr5385_device::write) +{ + switch (offset) + { + case 0x0: // Data Register + switch (m_state) + { + case STATE_DIAGNOSTIC_GOOD_PARITY: + m_aux_status_reg &= ~AUX_STATUS_PARITY_ERR; + m_aux_status_reg |= AUX_STATUS_DATA_FULL; + m_int_reg = INT_FUNC_COMPLETE; + m_diag_status_reg = DIAG_COMPLETE | DIAG_TURN_GOOD_PARITY; + m_state = STATE_IDLE; + m_int(1); + logerror("%s: ncr5385_w: data=%02x (diagnostic w/ good parity)\n", machine().describe_context(), data); + break; + case STATE_DIAGNOSTIC_BAD_PARITY: + m_aux_status_reg |= AUX_STATUS_PARITY_ERR | AUX_STATUS_DATA_FULL; + m_int_reg = INT_FUNC_COMPLETE; + m_diag_status_reg = DIAG_COMPLETE | DIAG_TURN_BAD_PARITY; + m_state = STATE_IDLE; + m_int(1); + logerror("%s: ncr5385_w: data=%02x (diagnostic w/ bad parity)\n", machine().describe_context(), data); + break; + default: + logerror("%s: ncr5385_w: data=%02x\n", machine().describe_context(), data); + break; + } + break; + case 0x1: // Command Register + switch (data & 0x3f) + { + case 0x00: // Chip Reset + logerror("%s: ncr5385_w: command: reset\n", machine().describe_context()); + m_state = STATE_IDLE; + m_int_reg = 0; + m_aux_status_reg = AUX_STATUS_TC_ZERO; + m_diag_status_reg = DIAG_COMPLETE; + m_int(0); + break; + case 0x0b: // Diagnostic + logerror("%s: ncr5385_w: command: diagnostic (%s parity)\n", machine().describe_context(), BIT(data, 6) ? "bad" : "good"); + if (BIT(data, 6)) + m_state = STATE_DIAGNOSTIC_BAD_PARITY; + else + m_state = STATE_DIAGNOSTIC_GOOD_PARITY; + break; + default: + logerror("%s: ncr5385_w: command: %02x\n", machine().describe_context(), data); + break; + } + break; + case 0x2: // Control Register + m_ctrl_reg = data & 0x07; + logerror("%s: ncr5385_w: control: parity_en=%d, reselect_en=%d, select_en=%d\n", machine().describe_context(), BIT(data, CTRL_PARITY_BIT), BIT(data, CTRL_RESELECT_BIT), BIT(data, CTRL_SELECT_BIT)); + break; + default: + logerror("%s: ncr5385_w: %x=%02x\n", machine().describe_context(), offset, data); + break; + } +} + +READ8_MEMBER(ncr5385_device::read) +{ + switch (offset) + { + case 0x2: + logerror("%s: ncr5385_r: control (%02x)\n", machine().describe_context(), m_ctrl_reg); + return m_ctrl_reg; + case 0x4: + logerror("%s: ncr5385_r: aux status (%02x)\n", machine().describe_context(), m_aux_status_reg); + return m_aux_status_reg; + case 0x6: + logerror("%s: ncr5385_r: interrupt (%02x)\n", machine().describe_context(), m_int_reg); + m_int(1); + return m_int_reg; + case 0x9: + logerror("%s: ncr5385_r: diagnostic status (%02x)\n", machine().describe_context(), m_diag_status_reg); + return m_diag_status_reg; + default: + logerror("%s: ncr5385_r: %x (%02x)\n", machine().describe_context(), offset, 0); + return 0; + } +} diff --git a/src/devices/machine/ncr5385.h b/src/devices/machine/ncr5385.h new file mode 100644 index 00000000000..576b7f2b065 --- /dev/null +++ b/src/devices/machine/ncr5385.h @@ -0,0 +1,141 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/*********************************************************************** + + NCR 5385 SCSI Controller emulation + + TODO: + - Everything. Currently, just enough is implemented to make the + Philips VP415 CPU / Datagrabber board satisfied that the + controller has passed its internal diagnostics. + +************************************************************************ + _____ _____ + D2 1 |* \_/ | 48 VCC + D1 2 | | 47 D3 + D0 3 | | 46 D4 + RESET 4 | | 45 D5 + ATN 5 | | 44 D6 + IGS 6 | | 43 D7 + I/O 7 | | 42 BSYOUT + C/D 8 | | 41 SB7 + MSG 9 | | 40 SB6 + ACK 10 | | 39 SB5 + REQ 11 | | 38 SB4 + /ID2 12 | NCR 5385E | 37 SB3 + /ID1 13 | | 36 SB2 + /ID0 14 | | 35 SB1 + ARB 15 | | 34 SB9 + CLK 16 | | 33 SBP + BSY IN 17 | | 32 SELOUT + SEL IN 18 | | 31 /RD + INT 19 | | 30 /WR + /SBEN 20 | | 29 DREQ + /CS 21 | | 28 TGS + A0 22 | | 27 /DACK + A1 23 | | 26 A3 + GND 24 |_____________| 25 A2 + +************************************************************************/ + +#ifndef MAME_MACHINE_NCR5385_H +#define MAME_MACHINE_NCR5385_H + +#pragma once + + + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_NCR5385_INT_CB(_int) \ + devcb = &downcast(*device).set_int_callback(DEVCB_##_int); + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> ncr5385_device + +class ncr5385_device : public device_t +{ +public: + // construction/destruction + ncr5385_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + template devcb_base &set_int_callback(Object &&cb) { return m_int.set_callback(std::forward(cb)); } + + DECLARE_WRITE8_MEMBER(write); + DECLARE_READ8_MEMBER(read); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + +private: + enum + { + STATE_IDLE, + STATE_DIAGNOSTIC_GOOD_PARITY, + STATE_DIAGNOSTIC_BAD_PARITY, + }; + + enum + { + DIAG_TURN_MISCOMPARE_INITIAL = 0x08, + DIAG_TURN_MISCOMPARE_FINAL = 0x10, + DIAG_TURN_GOOD_PARITY = 0x18, + DIAG_TURN_BAD_PARITY = 0x20, + DIAG_COMPLETE = 0x80, + + DIAG_COMPLETE_BIT = 7, + }; + + enum + { + INT_FUNC_COMPLETE = 0x01, + INT_INVALID_CMD = 0x40, + + INT_FUNC_COMPLETE_BIT = 0, + INT_INVALID_CMD_BIT = 6, + }; + + enum + { + AUX_STATUS_TC_ZERO = 0x02, + AUX_STATUS_PAUSED = 0x04, + AUX_STATUS_PARITY_ERR = 0x40, + AUX_STATUS_DATA_FULL = 0x80, + + AUX_STATUS_TC_ZERO_BIT = 1, + AUX_STATUS_PAUSED_BIT = 2, + AUX_STATUS_PARITY_ERR_BIT = 6, + AUX_STATUS_DATA_FULL_BIT = 7, + }; + + enum + { + CTRL_SELECT = 0x01, + CTRL_RESELECT = 0x02, + CTRL_PARITY = 0x04, + + CTRL_SELECT_BIT = 0, + CTRL_RESELECT_BIT = 1, + CTRL_PARITY_BIT = 2, + }; + + devcb_write_line m_int; + + uint32_t m_state; + uint8_t m_ctrl_reg; + uint8_t m_int_reg; + uint8_t m_aux_status_reg; + uint8_t m_diag_status_reg; +}; + +// device type definition +DECLARE_DEVICE_TYPE(NCR5385, ncr5385_device) + +#endif // MAME_MACHINE_NCR5385_H diff --git a/src/mame/drivers/vp415.cpp b/src/mame/drivers/vp415.cpp index 93029472926..73bd342f740 100644 --- a/src/mame/drivers/vp415.cpp +++ b/src/mame/drivers/vp415.cpp @@ -48,10 +48,12 @@ #include "screen.h" #include "cpu/mcs51/mcs51.h" +#include "cpu/mcs48/mcs48.h" #include "cpu/z80/z80.h" #include "machine/i8155.h" #include "machine/i8255.h" +#include "machine/ncr5385.h" #include "machine/saa1043.h" #include "video/mb88303.h" @@ -60,8 +62,11 @@ class vp415_state : public driver_device public: vp415_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) - , m_maincpu(*this, Z80CPU_TAG) + , m_datacpu(*this, Z80CPU_TAG) + , m_scsi(*this, SCSI_TAG) , m_drivecpu(*this, DRIVECPU_TAG) + , m_ctrlcpu(*this, CTRLCPU_TAG) + , m_ctrlmcu(*this, CTRLMCU_TAG) , m_chargen(*this, CHARGEN_TAG) , m_mainram(*this, Z80RAM_TAG) , m_ctrlram(*this, CTRLRAM_TAG) @@ -75,8 +80,8 @@ public: uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - DECLARE_WRITE8_MEMBER(ncr5385_w); - DECLARE_READ8_MEMBER(ncr5385_r); + DECLARE_WRITE_LINE_MEMBER(cpu_int1_w); + DECLARE_WRITE8_MEMBER(sel34_w); DECLARE_READ8_MEMBER(sel37_r); @@ -87,6 +92,11 @@ public: DECLARE_WRITE8_MEMBER(ctrl_cpu_port3_w); DECLARE_READ8_MEMBER(ctrl_cpu_port3_r); + DECLARE_WRITE8_MEMBER(ctrl_mcu_port1_w); + DECLARE_READ8_MEMBER(ctrl_mcu_port1_r); + DECLARE_WRITE8_MEMBER(ctrl_mcu_port2_w); + DECLARE_READ8_MEMBER(ctrl_mcu_port2_r); + DECLARE_READ8_MEMBER(drive_i8155_pb_r); DECLARE_READ8_MEMBER(drive_i8155_pc_r); @@ -94,12 +104,15 @@ public: DECLARE_WRITE8_MEMBER(drive_i8255_pb_w); DECLARE_READ8_MEMBER(drive_i8255_pc_r); DECLARE_WRITE8_MEMBER(drive_cpu_port1_w); + DECLARE_WRITE8_MEMBER(drive_cpu_port3_w); DECLARE_WRITE_LINE_MEMBER(refv_w); static const char* Z80CPU_TAG; static const char* Z80RAM_TAG; + static const char* SCSI_TAG; static const char* CTRLCPU_TAG; + static const char* CTRLMCU_TAG; static const char* CTRLRAM_TAG; static const char* DRIVECPU_TAG; static const char* DESCRAMBLE_ROM_TAG; @@ -113,6 +126,7 @@ public: static const char* SYNCGEN_TAG; protected: + // CPU Board enums enum { SEL34_INTR_N = 0x01, @@ -142,60 +156,19 @@ protected: SEL37_SK1d_BIT = 7, }; + // Control Board enums enum { - DIAG_TURN_MISCOMPARE_INITIAL = 0x08, - DIAG_TURN_MISCOMPARE_FINAL = 0x10, - DIAG_TURN_GOOD_PARITY = 0x18, - DIAG_TURN_BAD_PARITY = 0x20, - DIAG_COMPLETE = 0x80, - - DIAG_COMPLETE_BIT = 7, - }; - - enum - { - INT_FUNC_COMPLETE = 0x01, - INT_INVALID_CMD = 0x40, - - INT_FUNC_COMPLETE_BIT = 0, - INT_INVALID_CMD_BIT = 6, - }; - - enum - { - AUX_STATUS_TC_ZERO = 0x02, - AUX_STATUS_PAUSED = 0x04, - AUX_STATUS_PARITY_ERR = 0x40, - AUX_STATUS_DATA_FULL = 0x80, - - AUX_STATUS_TC_ZERO_BIT = 1, - AUX_STATUS_PAUSED_BIT = 2, - AUX_STATUS_PARITY_ERR_BIT = 6, - AUX_STATUS_DATA_FULL_BIT = 7, - }; + CTRL_P3_INT1 = 0x08, - enum - { - STATE_IDLE, - STATE_DIAGNOSTIC_GOOD_PARITY, - STATE_DIAGNOSTIC_BAD_PARITY, - }; - - enum - { - CTRL_SELECT = 0x01, - CTRL_RESELECT = 0x02, - CTRL_PARITY = 0x04, - - CTRL_SELECT_BIT = 0, - CTRL_RESELECT_BIT = 1, - CTRL_PARITY_BIT = 2, + CTRL_P3_INT1_BIT = 3 }; + // Drive Board enums enum { I8255PC_NOT_FOCUSED = 0x02, + I8255PC_0RPM_N = 0x08, I8255PC_DISC_REFLECTION = 0x10, }; @@ -220,22 +193,59 @@ protected: I8255PB_STR1_BIT = 7, }; + enum + { + I8155PB_2PPR = 0x01, + I8155PB_RAD_MIR = 0x04, + I8155PB_FRLOCK = 0x08, + + I8155PB_2PPR_BIT = 0, + I8155PB_RAD_MIR_BIT = 2, + I8155PB_FRLOCK_BIT = 3, + }; + + enum + { + DRIVE_P1_CP1 = 0x01, + DRIVE_P1_CP2 = 0x02, + DRIVE_P1_LDI = 0x04, + DRIVE_P1_ATN_N = 0x08, + DRIVE_P1_TX = 0x10, + DRIVE_P1_STB_N = 0x20, + DRIVE_P1_STR0_N = 0x40, + DRIVE_P1_TP2 = 0x80, + + DRIVE_P1_CP1_BIT = 0, + DRIVE_P1_CP2_BIT = 1, + DRIVE_P1_LDI_BIT = 2, + DRIVE_P1_ATN_N_BIT = 3, + DRIVE_P1_TX_BIT = 4, + DRIVE_P1_STB_N_BIT = 5, + DRIVE_P1_STR0_N_BIT = 6, + DRIVE_P1_TP2_BIT = 7 + }; + virtual void video_start() override; void z80_program_map(address_map &map); void z80_io_map(address_map &map); - void set_intn_line(uint8_t line, uint8_t value); + void set_int_line(uint8_t line, uint8_t value); + void update_cpu_int(); void ctrl_program_map(address_map &map); void ctrl_io_map(address_map &map); + void ctrlmcu_program_map(address_map &map); void sd_w(uint8_t data); uint8_t sd_r(); void drive_program_map(address_map &map); void drive_io_map(address_map &map); - required_device m_maincpu; + required_device m_datacpu; + required_device m_scsi; required_device m_drivecpu; + required_device m_ctrlcpu; + required_device m_ctrlmcu; required_device m_chargen; required_shared_ptr m_mainram; required_shared_ptr m_ctrlram; @@ -244,25 +254,27 @@ protected: uint8_t m_sel34; uint8_t m_sel37; - uint32_t m_state; - uint8_t m_ctrl_reg; - uint8_t m_int_reg; - uint8_t m_aux_status_reg; - uint8_t m_diag_status_reg; - uint8_t m_intn_lines[2]; + uint8_t m_int_lines[2]; uint8_t m_refv; - uint8_t m_ctrl_p1; - uint8_t m_ctrl_p3; + uint8_t m_ctrl_cpu_p1; + uint8_t m_ctrl_cpu_p3; + uint8_t m_ctrl_mcu_p1; + uint8_t m_ctrl_mcu_p2; uint8_t m_drive_p1; uint8_t m_drive_pc_bits; + + uint8_t m_drive_rad_mir_dac; + uint8_t m_drive_i8255_pb; }; /*static*/ const char* vp415_state::Z80CPU_TAG = "z80cpu"; /*static*/ const char* vp415_state::Z80RAM_TAG = "z80ram"; +/*static*/ const char* vp415_state::SCSI_TAG = "ncr5385"; /*static*/ const char* vp415_state::CTRLCPU_TAG = "ctrlcpu"; +/*static*/ const char* vp415_state::CTRLMCU_TAG = "ctrlmcu"; /*static*/ const char* vp415_state::CTRLRAM_TAG = "ctrlram"; /*static*/ const char* vp415_state::DRIVECPU_TAG = "drivecpu"; /*static*/ const char* vp415_state::DESCRAMBLE_ROM_TAG = "descramblerom"; @@ -277,23 +289,23 @@ protected: void vp415_state::machine_reset() { - m_state = STATE_IDLE; - m_int_reg = 0; - m_ctrl_reg = 0; - m_aux_status_reg = AUX_STATUS_TC_ZERO; - m_diag_status_reg = DIAG_COMPLETE; - m_sel34 = 0; m_sel37 = SEL37_BRD | SEL37_MON_N | SEL37_SK1c | SEL37_SK1d; - m_intn_lines[0] = 1; - m_intn_lines[1] = 1; + m_int_lines[0] = 0; + m_int_lines[1] = 0; - m_ctrl_p1 = 0; - m_ctrl_p3 = 0; + m_ctrl_cpu_p1 = 0; + m_ctrl_cpu_p3 = 0; + + m_ctrl_mcu_p1 = 0; + m_ctrl_mcu_p2 = 0; m_drive_p1 = 0; + m_drive_i8255_pb = 0; m_drive_pc_bits = I8255PC_DISC_REFLECTION | I8255PC_NOT_FOCUSED; + + m_drive_rad_mir_dac = 0; } void vp415_state::machine_start() @@ -309,89 +321,9 @@ WRITE_LINE_MEMBER(vp415_state::refv_w) // CPU Datagrabber Module (W) -WRITE8_MEMBER(vp415_state::ncr5385_w) +WRITE_LINE_MEMBER(vp415_state::cpu_int1_w) { - switch (offset) - { - case 0x0: // Data Register - switch (m_state) - { - case STATE_DIAGNOSTIC_GOOD_PARITY: - m_aux_status_reg &= ~AUX_STATUS_PARITY_ERR; - m_aux_status_reg |= AUX_STATUS_DATA_FULL; - m_int_reg = INT_FUNC_COMPLETE; - m_diag_status_reg = DIAG_COMPLETE | DIAG_TURN_GOOD_PARITY; - m_state = STATE_IDLE; - set_intn_line(1, 0); - logerror("%s: ncr5385_w: data=%02x (diagnostic w/ good parity)\n", machine().describe_context(), data); - break; - case STATE_DIAGNOSTIC_BAD_PARITY: - m_aux_status_reg |= AUX_STATUS_PARITY_ERR | AUX_STATUS_DATA_FULL; - m_int_reg = INT_FUNC_COMPLETE; - m_diag_status_reg = DIAG_COMPLETE | DIAG_TURN_BAD_PARITY; - m_state = STATE_IDLE; - set_intn_line(1, 0); - logerror("%s: ncr5385_w: data=%02x (diagnostic w/ bad parity)\n", machine().describe_context(), data); - break; - default: - logerror("%s: ncr5385_w: data=%02x\n", machine().describe_context(), data); - break; - } - break; - case 0x1: // Command Register - switch (data & 0x3f) - { - case 0x00: // Chip Reset - logerror("%s: ncr5385_w: command: reset\n", machine().describe_context()); - m_state = STATE_IDLE; - m_int_reg = 0; - m_aux_status_reg = AUX_STATUS_TC_ZERO; - m_diag_status_reg = DIAG_COMPLETE; - set_intn_line(1, 1); - break; - case 0x0b: // Diagnostic - logerror("%s: ncr5385_w: command: diagnostic (%s parity)\n", machine().describe_context(), BIT(data, 6) ? "bad" : "good"); - if (BIT(data, 6)) - m_state = STATE_DIAGNOSTIC_BAD_PARITY; - else - m_state = STATE_DIAGNOSTIC_GOOD_PARITY; - break; - default: - logerror("%s: ncr5385_w: command: %02x\n", machine().describe_context(), data); - break; - } - break; - case 0x2: // Control Register - m_ctrl_reg = data & 0x07; - logerror("%s: ncr5385_w: control: parity_en=%d, reselect_en=%d, select_en=%d\n", machine().describe_context(), BIT(data, CTRL_PARITY_BIT), BIT(data, CTRL_RESELECT_BIT), BIT(data, CTRL_SELECT_BIT)); - break; - default: - logerror("%s: ncr5385_w: %x=%02x\n", machine().describe_context(), offset, data); - break; - } -} - -READ8_MEMBER(vp415_state::ncr5385_r) -{ - switch (offset) - { - case 0x2: - logerror("%s: ncr5385_r: control (%02x)\n", machine().describe_context(), m_ctrl_reg); - return m_ctrl_reg; - case 0x4: - logerror("%s: ncr5385_r: aux status (%02x)\n", machine().describe_context(), m_aux_status_reg); - return m_aux_status_reg; - case 0x6: - logerror("%s: ncr5385_r: interrupt (%02x)\n", machine().describe_context(), m_int_reg); - set_intn_line(1, 1); - return m_int_reg; - case 0x9: - logerror("%s: ncr5385_r: diagnostic status (%02x)\n", machine().describe_context(), m_diag_status_reg); - return m_diag_status_reg; - default: - logerror("%s: ncr5385_r: %x (%02x)\n", machine().describe_context(), offset, 0); - return 0; - } + set_int_line(0, state); } WRITE8_MEMBER(vp415_state::sel34_w) @@ -402,6 +334,7 @@ WRITE8_MEMBER(vp415_state::sel34_w) if (!BIT(data, SEL34_INTR_N_BIT)) { m_sel37 &= ~(SEL37_ID0 | SEL37_ID1); + update_cpu_int(); } } @@ -411,22 +344,19 @@ READ8_MEMBER(vp415_state::sel37_r) return m_sel37; } -void vp415_state::set_intn_line(uint8_t line, uint8_t value) +void vp415_state::set_int_line(uint8_t line, uint8_t value) { - if (value == 0) + if (value) { - m_sel37 |= line ? SEL37_ID0 : SEL37_ID1; + m_sel37 |= line ? SEL37_ID1 : SEL37_ID0; } - m_intn_lines[line] = value; - if (m_intn_lines[0] && m_intn_lines[1]) - { - m_maincpu->set_input_line(0, CLEAR_LINE); - } - else - { - m_maincpu->set_input_line(0, ASSERT_LINE); - } + update_cpu_int(); +} + +void vp415_state::update_cpu_int() +{ + m_datacpu->set_input_line(0, (m_sel37 & (SEL37_ID0 | SEL37_ID1)) ? ASSERT_LINE : CLEAR_LINE); } void vp415_state::z80_program_map(address_map &map) @@ -438,7 +368,7 @@ void vp415_state::z80_program_map(address_map &map) void vp415_state::z80_io_map(address_map &map) { map.global_mask(0xff); - map(0x00, 0x0f).rw(this, FUNC(vp415_state::ncr5385_r), FUNC(vp415_state::ncr5385_w)); + map(0x00, 0x0f).rw(SCSI_TAG, FUNC(ncr5385_device::read), FUNC(ncr5385_device::write)); // 0x20, 0x21: Connected to A0 + D0..D7 of SLAVE i8041 map(0x34, 0x34).w(this, FUNC(vp415_state::sel34_w)); map(0x37, 0x37).r(this, FUNC(vp415_state::sel37_r)); @@ -458,7 +388,8 @@ WRITE8_MEMBER(vp415_state::ctrl_regs_w) sd_w(data); break; case 1: // WR3 - logerror("%s: ctrl_regs_w: WR3 (UPI-41, not yet dumped/implemented): %02x\n", machine().describe_context(), data); + logerror("%s: ctrl_regs_w: WR3 (UPI-41): %d=%02x\n", machine().describe_context(), (offset >> 9) & 1, data); + m_ctrlmcu->upi41_master_w(space, (offset >> 9) & 1, data); break; case 2: logerror("%s: ctrl_regs_w: N.C. write %02x\n", machine().describe_context(), data); @@ -479,10 +410,11 @@ READ8_MEMBER(vp415_state::ctrl_regs_r) value = sd_r(); logerror("%s: ctrl_regs_r: RDEN: %02x\n", machine().describe_context(), value); break; - case 1: // RD3 - logerror("%s: ctrl_regs_r: RD3 (UPI-41, not yet dumped/implemented): %02x\n", machine().describe_context(), 0); + case 1: // /RD3 + value = m_ctrlmcu->upi41_master_r(space, (offset >> 9) & 1); + logerror("%s: ctrl_regs_r: RD3 (UPI-41): %d (%02x)\n", machine().describe_context(), (offset >> 9) & 1, value); break; - case 2: // RD2 + case 2: // /RD2 logerror("%s: ctrl_regs_r: N.C. read\n", machine().describe_context()); break; case 3: @@ -495,10 +427,10 @@ READ8_MEMBER(vp415_state::ctrl_regs_r) WRITE8_MEMBER(vp415_state::ctrl_cpu_port1_w) { - uint8_t old = m_ctrl_p1; - m_ctrl_p1 = data; + uint8_t old = m_ctrl_cpu_p1; + m_ctrl_cpu_p1 = data; - if ((m_ctrl_p1 ^ old) & 0xdf) // Ignore petting the watchdog (bit 5) + if ((m_ctrl_cpu_p1 ^ old) & 0xdf) // Ignore petting the watchdog (bit 5) { logerror("%s: ctrl_cpu_port1_w: %02x\n", machine().describe_context(), data); } @@ -506,25 +438,54 @@ WRITE8_MEMBER(vp415_state::ctrl_cpu_port1_w) READ8_MEMBER(vp415_state::ctrl_cpu_port1_r) { - uint8_t ret = m_ctrl_p1; - m_ctrl_p1 ^= 0x10; + uint8_t ret = m_ctrl_cpu_p1; + m_ctrl_cpu_p1 ^= 0x10; logerror("%s: ctrl_cpu_port1_r (%02x)\n", machine().describe_context(), ret); - return ret;// | (m_refv << 4); + return ret; } WRITE8_MEMBER(vp415_state::ctrl_cpu_port3_w) { - m_ctrl_p3 = data; + m_ctrl_cpu_p3 = ~data; logerror("%s: ctrl_cpu_port3_w: %02x\n", machine().describe_context(), data); } READ8_MEMBER(vp415_state::ctrl_cpu_port3_r) { - uint8_t ret = m_ctrl_p3; + uint8_t ret = m_ctrl_cpu_p3; logerror("%s: ctrl_cpu_port3_r (%02x)\n", machine().describe_context(), ret); return ret; } +WRITE8_MEMBER(vp415_state::ctrl_mcu_port1_w) +{ + m_ctrl_mcu_p1 = data; + logerror("%s: ctrl_mcu_port1_w: %02x\n", machine().describe_context(), data); +} + +READ8_MEMBER(vp415_state::ctrl_mcu_port1_r) +{ + uint8_t value = m_ctrl_mcu_p1; + logerror("%s: ctrl_mcu_port1_r: %02x\n", machine().describe_context(), value); + return value; +} + +WRITE8_MEMBER(vp415_state::ctrl_mcu_port2_w) +{ + m_ctrl_mcu_p2 = data; + if (BIT(data, 4)) + m_ctrl_cpu_p3 &= CTRL_P3_INT1; + else + m_ctrl_cpu_p3 |= CTRL_P3_INT1; + logerror("%s: ctrl_mcu_port2_w: %02x\n", machine().describe_context(), data); +} + +READ8_MEMBER(vp415_state::ctrl_mcu_port2_r) +{ + logerror("%s: ctrl_mcu_port2_r: %02x\n", machine().describe_context(), 0); + return 0; +} + uint8_t vp415_state::sd_r() { return 0; @@ -542,15 +503,23 @@ void vp415_state::ctrl_program_map(address_map &map) void vp415_state::ctrl_io_map(address_map &map) { map(0x0000, 0x1fff).ram().share(CTRLRAM_TAG); - map(0xe000, 0xffff).rw(this, FUNC(vp415_state::ctrl_regs_r), FUNC(vp415_state::ctrl_regs_w)).mask(0x1c00); + map(0xe000, 0xffff).rw(this, FUNC(vp415_state::ctrl_regs_r), FUNC(vp415_state::ctrl_regs_w)).mask(0x1e00); +} + +void vp415_state::ctrlmcu_program_map(address_map &map) +{ + map(0x0000, 0x03ff).rom().region(CTRLMCU_TAG, 0); } // Drive Processor Module (R) READ8_MEMBER(vp415_state::drive_i8155_pb_r) { - logerror("%s: drive_i8155_pb_r: %02x\n", machine().describe_context(), 0); - return 0; + uint8_t ret = I8155PB_FRLOCK; + if (m_drive_rad_mir_dac >= 0x7e && m_drive_rad_mir_dac < 0x82 && BIT(m_drive_i8255_pb, I8255PB_RLS_N_BIT)) + ret |= I8155PB_RAD_MIR; + logerror("%s: drive_i8155_pb_r: %02x\n", machine().describe_context(), ret); + return ret; } READ8_MEMBER(vp415_state::drive_i8155_pc_r) @@ -561,11 +530,13 @@ READ8_MEMBER(vp415_state::drive_i8155_pc_r) WRITE8_MEMBER(vp415_state::drive_i8255_pa_w) { - logerror("%s: drive_i8255_pa_w: %02x\n", machine().describe_context(), data); + logerror("%s: drive_i8255_pa_w: radial mirror DAC = %02x\n", machine().describe_context(), data); + m_drive_rad_mir_dac = data; } WRITE8_MEMBER(vp415_state::drive_i8255_pb_w) { + m_drive_i8255_pb = data; logerror("%s: drive_i8255_pb_w: COMM-1:%d, COMM-2:%d, COMM-3:%d, COMM-4:%d, /RLS:%d, SL-PWR:%d, /RAD-FS:%d, STR1:%d\n" , machine().describe_context() , BIT(data, I8255PB_COMM1_BIT) @@ -578,12 +549,14 @@ WRITE8_MEMBER(vp415_state::drive_i8255_pb_w) , BIT(data, I8255PB_STR1_BIT)); if (BIT(data, I8255PB_RLS_N_BIT)) { + } } READ8_MEMBER(vp415_state::drive_i8255_pc_r) { static int focus_kludge = 250; + static int motor_kludge = 200; logerror("%s: drive_i8255_pc_r: %02x\n", machine().describe_context(), m_drive_pc_bits); if (focus_kludge > 0) { @@ -593,6 +566,14 @@ READ8_MEMBER(vp415_state::drive_i8255_pc_r) { m_drive_pc_bits &= ~I8255PC_NOT_FOCUSED; } + if (motor_kludge > 0) + { + motor_kludge--; + } + else + { + m_drive_pc_bits |= I8255PC_0RPM_N; + } return m_drive_pc_bits; } @@ -602,11 +583,34 @@ WRITE8_MEMBER(vp415_state::drive_cpu_port1_w) m_drive_p1 = data; if ((m_drive_p1 ^ old) & 0xfb) // Ignore bit 2 when logging (LDI) { - logerror("%s: drive_cpu_port1_w: %02x\n", machine().describe_context(), data); + logerror("%s: drive_cpu_port1_w: TP2:%d /STR0:%d /STB:%d TX:%d /ATN:%d LDI:%d CP2:%d CP1:%d\n", machine().describe_context() + , BIT(data, DRIVE_P1_TP2_BIT) + , BIT(data, DRIVE_P1_STR0_N_BIT) + , BIT(data, DRIVE_P1_STB_N_BIT) + , BIT(data, DRIVE_P1_TX_BIT) + , BIT(data, DRIVE_P1_ATN_N_BIT) + , BIT(data, DRIVE_P1_LDI_BIT) + , BIT(data, DRIVE_P1_CP2_BIT) + , BIT(data, DRIVE_P1_CP1_BIT)); } m_chargen->ldi_w(BIT(data, 2)); } +//READ_LINE_MEMBER(vp415_state::drive_rxd_r) +//{ +// logerror("%s: drive_rxd_r: %d\n", machine().describe_context(), 0); +// return 0; +//} + +//WRITE_LINE_MEMBER(vp415_state::drive_txd_w) +//{ +// logerror("%s: drive_txd_w: %d\n", machine().describe_context(), state); +//} +WRITE8_MEMBER(vp415_state::drive_cpu_port3_w) +{ + logerror("%s: drive_cpu_port3_w: %02x\n", machine().describe_context(), data); +} + void vp415_state::drive_program_map(address_map &map) { map(0x0000, 0x3fff).rom().region(DRIVE_ROM_TAG, 0); @@ -653,20 +657,34 @@ static INPUT_PORTS_START( vp415 ) INPUT_PORTS_END MACHINE_CONFIG_START(vp415_state::vp415) + // Module W: CPU Datagrabber MCFG_CPU_ADD(Z80CPU_TAG, Z80, XTAL(8'000'000)/2) // 8MHz through a /2 flip-flop divider, per schematic MCFG_CPU_PROGRAM_MAP(z80_program_map) MCFG_CPU_IO_MAP(z80_io_map) + MCFG_DEVICE_ADD(SCSI_TAG, NCR5385, XTAL(8'000'000)/2) // Same clock signal as above, per schematic + MCFG_NCR5385_INT_CB(WRITELINE(vp415_state, cpu_int1_w)) + + // Module S: Control MCFG_CPU_ADD(CTRLCPU_TAG, I8031, XTAL(11'059'200)) // 11.059MHz, per schematic MCFG_MCS51_PORT_P1_OUT_CB(WRITE8(vp415_state, ctrl_cpu_port1_w)); MCFG_MCS51_PORT_P1_IN_CB(READ8(vp415_state, ctrl_cpu_port1_r)); - MCFG_MCS51_PORT_P3_OUT_CB(WRITE8(vp415_state, ctrl_cpu_port1_w)); - MCFG_MCS51_PORT_P3_IN_CB(READ8(vp415_state, ctrl_cpu_port1_r)); + MCFG_MCS51_PORT_P3_OUT_CB(WRITE8(vp415_state, ctrl_cpu_port3_w)); + MCFG_MCS51_PORT_P3_IN_CB(READ8(vp415_state, ctrl_cpu_port3_r)); MCFG_CPU_PROGRAM_MAP(ctrl_program_map) MCFG_CPU_IO_MAP(ctrl_io_map) + // Module R: Drive + MCFG_CPU_ADD(CTRLMCU_TAG, I8041, XTAL(4'000'000)) + MCFG_MCS48_PORT_P1_IN_CB(READ8(vp415_state, ctrl_mcu_port1_r)); + MCFG_MCS48_PORT_P1_OUT_CB(WRITE8(vp415_state, ctrl_mcu_port1_w)); + MCFG_MCS48_PORT_P2_IN_CB(READ8(vp415_state, ctrl_mcu_port2_r)); + MCFG_MCS48_PORT_P2_OUT_CB(WRITE8(vp415_state, ctrl_mcu_port2_w)); + MCFG_CPU_PROGRAM_MAP(ctrlmcu_program_map) + MCFG_CPU_ADD(DRIVECPU_TAG, I8031, XTAL(12'000'000)) // 12MHz, per schematic MCFG_MCS51_PORT_P1_OUT_CB(WRITE8(vp415_state, drive_cpu_port1_w)); + MCFG_MCS51_PORT_P3_OUT_CB(WRITE8(vp415_state, drive_cpu_port3_w)); MCFG_CPU_PROGRAM_MAP(drive_program_map) MCFG_CPU_IO_MAP(drive_io_map) @@ -702,6 +720,9 @@ ROM_START(vp415) ROM_REGION(0x10000, vp415_state::CONTROL_ROM_TAG, 0) // Version 1.8 ROM_LOAD( "s.3104 103 6804.9_control.ic2", 0x0000, 0x10000, CRC(10564765) SHA1(8eb6cff7ca7cbfcb3db8b04b697cdd7e364be805) ) + ROM_REGION(0x400, vp415_state::CTRLMCU_TAG, 0) + ROM_LOAD( "d8041ahc 152.ic11", 0x000, 0x400, CRC(02b6a9b2) SHA1(4123690c3fb4cc987c2ea2dd878e39c8bf0cb4ea) ) + /* Module W */ ROM_REGION(0x8000, vp415_state::Z80CPU_TAG, 0) ROM_LOAD( "w.3104 103 6805.3_cpu", 0x0000, 0x4000, CRC(c2cf4f25) SHA1(e55e1ac917958eb42244bff17a0016b74627c8fa) ) // Version 1.3 -- cgit v1.2.3