diff --git a/scripts/src/netlist.lua b/scripts/src/netlist.lua index d49ffbf75b5..62981122d80 100644 --- a/scripts/src/netlist.lua +++ b/scripts/src/netlist.lua @@ -145,6 +145,8 @@ project "netlist" MAME_DIR .. "src/lib/netlist/devices/nld_74153.h", MAME_DIR .. "src/lib/netlist/devices/nld_74161.cpp", MAME_DIR .. "src/lib/netlist/devices/nld_74161.h", + MAME_DIR .. "src/lib/netlist/devices/nld_74164.cpp", + MAME_DIR .. "src/lib/netlist/devices/nld_74164.h", MAME_DIR .. "src/lib/netlist/devices/nld_74165.cpp", MAME_DIR .. "src/lib/netlist/devices/nld_74165.h", MAME_DIR .. "src/lib/netlist/devices/nld_74166.cpp", diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index c06831fb7dc..c12b156813c 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -369,6 +369,7 @@ MACHINES["TTL74148"] = true MACHINES["TTL74153"] = true MACHINES["TTL74157"] = true --MACHINES["TTL74161"] = true +--MACHINES["TTL74164"] = true --MACHINES["TTL74175"] = true MACHINES["TTL74181"] = true MACHINES["TTL7474"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index abd85388465..032e9698218 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -548,6 +548,7 @@ MACHINES["TTL74148"] = true MACHINES["TTL74153"] = true --MACHINES["TTL74157"] = true MACHINES["TTL74161"] = true +MACHINES["TTL74164"] = true MACHINES["TTL74175"] = true MACHINES["TTL74181"] = true MACHINES["TTL7474"] = true @@ -2530,6 +2531,8 @@ files { createMESSProjects(_target, _subtarget, "prodigy") files { MAME_DIR .. "src/mame/drivers/prodigy.cpp", + MAME_DIR .. "src/mame/machine/nl_prodigy.cpp", + MAME_DIR .. "src/mame/machine/nl_prodigy.h", } createMESSProjects(_target, _subtarget, "psion") diff --git a/scripts/target/mame/nl.lua b/scripts/target/mame/nl.lua index 9ea0dfb1966..f94bcb4d5f8 100644 --- a/scripts/target/mame/nl.lua +++ b/scripts/target/mame/nl.lua @@ -124,6 +124,10 @@ files{ MAME_DIR .. "src/mame/machine/nl_stuntcyc.cpp", MAME_DIR .. "src/mame/machine/nl_stuntcyc.h", + MAME_DIR .. "src/mame/drivers/prodigy.cpp", + MAME_DIR .. "src/mame/machine/nl_prodigy.cpp", + MAME_DIR .. "src/mame/machine/nl_prodigy.h", + MAME_DIR .. "src/mame/drivers/hazeltin.cpp", MAME_DIR .. "src/mame/drivers/1942.cpp", diff --git a/src/devices/machine/6522via.cpp b/src/devices/machine/6522via.cpp index 79085eecbca..23b680cce50 100644 --- a/src/devices/machine/6522via.cpp +++ b/src/devices/machine/6522via.cpp @@ -13,7 +13,6 @@ T2 pulse counting mode Pulse mode handshake output - More shift register **********************************************************************/ @@ -22,6 +21,10 @@ vc20 random number generation only partly working (reads (uninitialized) timer 1 and timer 2 counter) timer init, reset, read changed + + 2017-Feb-15 Edstrom + Fixed shift registers to be more accurate, eg 50/50 duty cycle, latching + on correct flanks and leading and trailing flanks added + logging. */ #include "emu.h" @@ -33,13 +36,18 @@ #define LOG_SETUP (1U << 1) #define LOG_SHIFT (1U << 2) +#define LOG_READ (1U << 3) +#define LOG_INT (1U << 4) + +//#define VERBOSE (LOG_SHIFT|LOG_SETUP|LOG_READ) +//#define LOG_OUTPUT_FUNC printf -#define VERBOSE 0 // (LOG_SETUP|LOG_SHIFT) -#define LOG_OUTPUT_FUNC printf #include "logmacro.h" #define LOGSETUP(...) LOGMASKED(LOG_SETUP, __VA_ARGS__) #define LOGSHIFT(...) LOGMASKED(LOG_SHIFT, __VA_ARGS__) +#define LOGR(...) LOGMASKED(LOG_READ, __VA_ARGS__) +#define LOGINT(...) LOGMASKED(LOG_INT, __VA_ARGS__) /*************************************************************************** @@ -170,7 +178,8 @@ via6522_device::via6522_device(const machine_config &mconfig, const char *tag, d m_pcr(0), m_acr(0), m_ier(0), - m_ifr(0) + m_ifr(0), + m_shift_state(SHIFTER_IDLE) { } @@ -291,6 +300,7 @@ void via6522_device::output_irq() { if ((m_ifr & INT_ANY) == 0) { + LOGINT("INT asserted\n"); m_ifr |= INT_ANY; m_irq_handler(ASSERT_LINE); } @@ -299,6 +309,7 @@ void via6522_device::output_irq() { if (m_ifr & INT_ANY) { + LOGINT("INT cleared\n"); m_ifr &= ~INT_ANY; m_irq_handler(CLEAR_LINE); } @@ -318,8 +329,13 @@ void via6522_device::set_int(int data) output_irq(); + LOGINT("granted\n"); LOG("%s:6522VIA chip %s: IFR = %02X\n", machine().describe_context(), tag(), m_ifr); } + else + { + LOGINT("denied\n"); + } } @@ -346,36 +362,36 @@ void via6522_device::clear_int(int data) void via6522_device::shift_out() { - LOGSHIFT("Shift Out SR: %02x->", m_sr); + LOGSHIFT(" %s shift Out SR: %02x->", tag(), m_sr); m_out_cb2 = (m_sr >> 7) & 1; m_sr = (m_sr << 1) | m_out_cb2; - LOGSHIFT("%02x\n", m_sr); + LOGSHIFT("%02x CB2: %d\n", m_sr, m_out_cb2); m_cb2_handler(m_out_cb2); if (!SO_T2_RATE(m_acr)) { - m_shift_counter = (m_shift_counter - 1) & 7; - if (m_shift_counter == 0) { - set_int(INT_SR); + LOGINT("SHIFT out INT request "); + set_int(INT_SR); // TODO: this interrupt is 1-2 clock cycles too early for O2 control mode } + m_shift_counter = (m_shift_counter - 1) & 7; } } void via6522_device::shift_in() { - LOGSHIFT("Shift In SR: %02x->", m_sr); + LOGSHIFT("%s shift In SR: %02x->", tag(), m_sr); m_sr = (m_sr << 1) | (m_in_cb2 & 1); LOGSHIFT("%02x\n", m_sr); - m_shift_counter = (m_shift_counter - 1) & 7; - if (m_shift_counter == 0) { - set_int(INT_SR); + LOGINT("SHIFT in INT request "); + set_int(INT_SR);// TODO: this interrupt is 1-2 clock cycles too early for O2 control mode } + m_shift_counter = (m_shift_counter - 1) & 7; } @@ -384,22 +400,52 @@ void via6522_device::device_timer(emu_timer &timer, device_timer_id id, int para switch (id) { case TIMER_SHIFT: - LOGSHIFT("SHIFT timer event\n"); + LOGSHIFT("SHIFT timer event CB1 %s edge, %d\n", m_out_cb1 & 1 ? "falling" : "raising", m_shift_counter); m_out_cb1 ^= 1; m_cb1_handler(m_out_cb1); + if ((SO_O2_CONTROL(m_acr) || SI_O2_CONTROL(m_acr)) && m_shift_state == SHIFTER_FINISH) + { + if (m_out_cb1 & 1) // last raising flank + { + shift_in(); + m_shift_state = SHIFTER_IDLE; + m_shift_timer->adjust(attotime::never); + LOGSHIFT("Timer stops"); + } + else // last falling flank (just for shift in) + { + m_shift_timer->adjust(clocks_to_attotime(1)); + } + break; + } + if (m_out_cb1 & 1) // raising flank { if (SI_T2_CONTROL(m_acr) || SI_O2_CONTROL(m_acr)) { - shift_in(); + shift_in(); // close latch + + // Shift in also on the last flanks + if (m_shift_counter == 0) + { + m_shift_state = SHIFTER_FINISH; + m_shift_timer->adjust(clocks_to_attotime(1)); + } } } else // falling flank { if (SO_T2_RATE(m_acr) || SO_T2_CONTROL(m_acr) || SO_O2_CONTROL(m_acr)) { - shift_out(); + shift_out(); // close latch + } + + // Let external devices latch also on last raising edge. + if ((SO_T2_CONTROL(m_acr) || SO_O2_CONTROL(m_acr)) && m_shift_counter == 0) + { + m_shift_state = SHIFTER_FINISH; + m_shift_timer->adjust(clocks_to_attotime(1)); } } @@ -415,7 +461,6 @@ void via6522_device::device_timer(emu_timer &timer, device_timer_id id, int para } } break; - case TIMER_T1: if (T1_CONTINUOUS (m_acr)) { @@ -434,6 +479,7 @@ void via6522_device::device_timer(emu_timer &timer, device_timer_id id, int para output_pb(); } + LOGINT("T1 INT request "); set_int(INT_T1); break; @@ -441,6 +487,7 @@ void via6522_device::device_timer(emu_timer &timer, device_timer_id id, int para m_t2_active = 0; m_time2 = machine().time(); + LOGINT("T2 INT request "); set_int(INT_T2); break; @@ -627,12 +674,14 @@ READ8_MEMBER( via6522_device::read ) LOGSHIFT("Read SR: %02x ", m_sr); val = m_sr; m_out_cb1 = 1; + m_cb1_handler(m_out_cb1); m_shift_counter = 8; clear_int(INT_SR); LOGSHIFT("ACR: %02x ", m_acr); if (SI_O2_CONTROL(m_acr)) { m_shift_timer->adjust(clocks_to_attotime(1)); + shift_in(); LOGSHIFT("SI_O2 starts timer "); } else if (SI_T2_CONTROL(m_acr)) @@ -664,6 +713,9 @@ READ8_MEMBER( via6522_device::read ) val = m_ifr; break; } + LOGR(" * %s Reg %02x -> %02x - %s\n", tag(), offset, val, std::array + {{"IRB", "IRA", "DDRB", "DDRA", "T1CL","T1CH","T1LL","T1LH","T2CL","T2CH","SR","ACR","PCR","IFR","IER","IRA (nh)"}}[offset]); + return val; } @@ -676,7 +728,8 @@ WRITE8_MEMBER( via6522_device::write ) { offset &=0x0f; - LOGSETUP(" * %s Reg %02x <- %02x \n", tag(), offset, data); + LOGSETUP(" * %s Reg %02x <- %02x - %s\n", tag(), offset, data, std::array + {{"ORB", "ORA", "DDRB", "DDRA", "T1CL","T1CH","T1LL","T1LH","T2CL","T2CH","SR","ACR","PCR","IFR","IER","ORA (nh)"}}[offset]); switch (offset) { @@ -799,13 +852,21 @@ WRITE8_MEMBER( via6522_device::write ) case VIA_SR: m_sr = data; LOGSHIFT("Write SR: %02x\n", m_sr); - m_out_cb1 = 1; + + // make sure CB1 is high - this should not be needed though + if (m_out_cb1 != 1) + { + logerror("VIA: CB1 is low starting shifter\n"); + m_out_cb1 = 1; + m_cb1_handler(m_out_cb1); + } + m_shift_counter = 8; clear_int(INT_SR); - LOGSHIFT("ACR: %02x ", m_acr); + LOGSHIFT(" - ACR is: %02x ", m_acr); if (SO_O2_CONTROL(m_acr)) { - m_shift_timer->adjust(clocks_to_attotime(1)); + m_shift_timer->adjust(clocks_to_attotime(1)); // Let CB1 clock it on into to remote device LOGSHIFT("SO_O2 starts timer"); } else if (SO_T2_RATE(m_acr) || SO_T2_CONTROL(m_acr)) @@ -927,6 +988,7 @@ WRITE_LINE_MEMBER( via6522_device::write_ca1 ) m_latch_a = input_pa(); } + LOGINT("CA1 INT request "); set_int(INT_CA1); if (!m_out_ca2 && CA2_AUTO_HS(m_pcr)) @@ -953,6 +1015,7 @@ WRITE_LINE_MEMBER( via6522_device::write_ca2 ) { if ((m_in_ca2 && CA2_LOW_TO_HIGH(m_pcr)) || (!m_in_ca2 && CA2_HIGH_TO_LOW(m_pcr))) { + LOGINT("CA2 INT request "); set_int(INT_CA2); } } @@ -999,6 +1062,7 @@ WRITE_LINE_MEMBER( via6522_device::write_cb1 ) shift_in(); } + LOGINT("CB1 INT request "); set_int(INT_CB1); if (!m_out_cb2 && CB2_AUTO_HS(m_pcr)) @@ -1032,11 +1096,13 @@ WRITE_LINE_MEMBER( via6522_device::write_cb2 ) if (m_in_cb2 != state) { m_in_cb2 = state; + LOGSHIFT("CB2 IN: %d\n", m_in_cb2); if (CB2_INPUT(m_pcr)) { if ((m_in_cb2 && CB2_LOW_TO_HIGH(m_pcr)) || (!m_in_cb2 && CB2_HIGH_TO_LOW(m_pcr))) { + LOGINT("CB2 INT request "); set_int(INT_CB2); } } diff --git a/src/devices/machine/6522via.h b/src/devices/machine/6522via.h index 0c06863494c..785fa0f50a2 100644 --- a/src/devices/machine/6522via.h +++ b/src/devices/machine/6522via.h @@ -18,9 +18,6 @@ #ifndef __6522VIA_H__ #define __6522VIA_H__ - - - //************************************************************************** // INTERFACE CONFIGURATION MACROS //************************************************************************** @@ -210,6 +207,14 @@ private: emu_timer *m_shift_timer; uint8_t m_shift_counter; + enum m_shift_state_t + { + SHIFTER_IDLE, + SHIFTER_SHIFT, + SHIFTER_FINISH, + SHIFTER_IRQ + }; + m_shift_state_t m_shift_state; }; diff --git a/src/lib/netlist/devices/net_lib.cpp b/src/lib/netlist/devices/net_lib.cpp index eb9a58480ff..661df946512 100644 --- a/src/lib/netlist/devices/net_lib.cpp +++ b/src/lib/netlist/devices/net_lib.cpp @@ -78,6 +78,7 @@ namespace netlist ENTRYX(74123, TTL_74123, "") ENTRYX(74153, TTL_74153, "+C0,+C1,+C2,+C3,+A,+B,+G") ENTRYX(74161, TTL_74161, "+A,+B,+C,+D,+CLRQ,+LOADQ,+CLK,+ENABLEP,+ENABLET") + ENTRYX(74164, TTL_74164, "+A,+B,+CLRQ,+CLK") ENTRYX(74165, TTL_74165, "+CLK,+CLKINH,+SH_LDQ,+SER,+A,+B,+C,+D,+E,+F,+G,+H") ENTRYX(74166, TTL_74166, "+CLK,+CLKINH,+SH_LDQ,+SER,+A,+B,+C,+D,+E,+F,+G,+H,+CLRQ") ENTRYX(74174, TTL_74174, "+CLK,+D1,+D2,+D3,+D4,+D5,+D6,+CLRQ") @@ -125,6 +126,7 @@ namespace netlist ENTRYX(74123_dip, TTL_74123_DIP, "") ENTRYX(74153_dip, TTL_74153_DIP, "") ENTRYX(74161_dip, TTL_74161_DIP, "") + ENTRYX(74164_dip, TTL_74164_DIP, "") ENTRYX(74165_dip, TTL_74165_DIP, "") ENTRYX(74166_dip, TTL_74166_DIP, "") ENTRYX(74174_dip, TTL_74174_DIP, "") diff --git a/src/lib/netlist/devices/net_lib.h b/src/lib/netlist/devices/net_lib.h index 30b6c1d04aa..3521bd744ba 100644 --- a/src/lib/netlist/devices/net_lib.h +++ b/src/lib/netlist/devices/net_lib.h @@ -52,6 +52,7 @@ #include "nld_74123.h" #include "nld_74153.h" #include "nld_74161.h" +#include "nld_74164.h" #include "nld_74165.h" #include "nld_74166.h" #include "nld_74174.h" diff --git a/src/lib/netlist/devices/nld_74164.cpp b/src/lib/netlist/devices/nld_74164.cpp new file mode 100644 index 00000000000..5b2b1d8d080 --- /dev/null +++ b/src/lib/netlist/devices/nld_74164.cpp @@ -0,0 +1,104 @@ +// license:BSD-3-Clause +// copyright-holders:Joakim Larsson Edstrom +/* + * nld_74164.cpp + * + * Thanks to the 74161 work of Ryan and the huge Netlist effort by Couriersud + * implementing this was simple. + * + */ + +#include "nld_74164.h" +#include "../nl_base.h" + +namespace netlist +{ + namespace devices + { + NETLIB_OBJECT(74164) + { + NETLIB_CONSTRUCTOR(74164) + , m_A(*this, "A") + , m_B(*this, "B") + , m_CLRQ(*this, "CLRQ") + , m_CLK(*this, "CLK") + , m_cnt(*this, "m_cnt", 0) + , m_last_CLK(*this, "m_last_CLK", 0) + , m_Q(*this, {{"QA", "QB", "QC", "QD", "QE", "QF", "QG", "QH"}}) + { + } + + NETLIB_RESETI(); + NETLIB_UPDATEI(); + + protected: + logic_input_t m_A; + logic_input_t m_B; + logic_input_t m_CLRQ; + logic_input_t m_CLK; + + state_var m_cnt; + state_var m_last_CLK; + + object_array_t m_Q; + }; + + NETLIB_OBJECT_DERIVED(74164_dip, 74164) + { + NETLIB_CONSTRUCTOR_DERIVED(74164_dip, 74164) + { + register_subalias("1", m_A); + register_subalias("2", m_B); + register_subalias("3", m_Q[0]); + register_subalias("4", m_Q[1]); + register_subalias("5", m_Q[2]); + register_subalias("6", m_Q[3]); + + register_subalias("8", m_CLK); + register_subalias("9", m_CLRQ); + register_subalias("10", m_Q[4]); + register_subalias("11", m_Q[5]); + register_subalias("12", m_Q[6]); + register_subalias("13", m_Q[7]); + + } + }; + + NETLIB_RESET(74164) + { + m_cnt = 0; + m_last_CLK = 0; + } + + NETLIB_UPDATE(74164) + { + if (!m_CLRQ()) + { + m_cnt = 0; + } + else if (m_CLK() && !m_last_CLK) + { + m_cnt = (m_cnt << 1) & 0xfe; + if (m_A() && m_B()) + { + m_cnt |= 0x01; + } + else + { + m_cnt &= 0xfe; + } + } + + m_last_CLK = m_CLK(); + + for (std::size_t i=0; i<8; i++) + { + m_Q[i].push((m_cnt >> i) & 1, NLTIME_FROM_NS(30)); + } + } + + NETLIB_DEVICE_IMPL(74164) + NETLIB_DEVICE_IMPL(74164_dip) + + } //namespace devices +} // namespace netlist diff --git a/src/lib/netlist/devices/nld_74164.h b/src/lib/netlist/devices/nld_74164.h new file mode 100644 index 00000000000..d7f29d386de --- /dev/null +++ b/src/lib/netlist/devices/nld_74164.h @@ -0,0 +1,57 @@ +// license:BSD-3-Clause +// copyright-holders:Joakim Larsson Edstrom +/***************************************************************************** + + 5/74164 8-bit parallel-out serial shift registers + +*********************************************************************** + + Connection Diagram: + ___ ___ + A 1 |* u | 14 Vcc + B 2 | | 13 QH + QA 3 | | 12 QG + QB 4 | | 11 QF + QC 5 | | 10 QE + QD 6 | | 9 *Clear + GND 7 |_______| 8 Clock + +*********************************************************************** + Function Table: + +-------------------------+----------------+ + | Inputs | Qutputs* | + +-------+-------+---------+----------------+ + | Clear | Clock | A B | QA QB ... QH | + +-------+-------+---------+----------------+ + | L | X | X X | L L L | + | H | L | X X | QA0 QB0 QH0 | + | H | ^ | H H | H QAn QGn | + | H | ^ | L X | L QAn QGn | + | H | ^ | X L | L QAn QGn | + +-------+-------+---------+----------------+ + + H = High Level (steady state) + L = Low Level (steady state) + X = Don't Care + ^ = Transition from low to high level + QA0, QB0 ... QH0 = The level of QA, QB ... QH before the indicated steady-state input conditions were established. + QAn, QGn = The level of QA or QG before the most recent ^ transition of the clock; indicates a 1 bit shift. + +**********************************************************************/ + +#ifndef NLD_74164_H_ +#define NLD_74164_H_ + +#include "../nl_setup.h" + +#define TTL_74164(name, cA, cB, cCLRQ, cCLK) \ + NET_REGISTER_DEV(TTL_74164, name) \ + NET_CONNECT(name, A, cA) \ + NET_CONNECT(name, B, cB) \ + NET_CONNECT(name, CLRQ, cCLRQ) \ + NET_CONNECT(name, CLK, cCLK) + +#define TTL_74164_DIP(name) \ + NET_REGISTER_DEV(TTL_74164_DIP, name) + +#endif /* NLD_74164_H_ */ diff --git a/src/mame/drivers/prodigy.cpp b/src/mame/drivers/prodigy.cpp index 8ffc003f7af..7a7fd723e22 100644 --- a/src/mame/drivers/prodigy.cpp +++ b/src/mame/drivers/prodigy.cpp @@ -31,11 +31,60 @@ |LEDS-> O O O O O O O O OOOOOOOOOOO KPDCN | +-------------------------------------------------------------------------------------+ -******************************************************************************/ + Tracing the image shows that VIA Port A is used on the ROWCN and Port B on COLCN + + The VIA pins CB1 and CB2 together with PB0 and PB1 via the 74145 drives the BCD display. + The BCD display is of common anode type and each anode a0-a3 selects which digit that + will be lit selected by PB0 and PB1. The segments to be lit is selected by the 8 bits + shifted into the 74164 by clock from VIA CB1 and data from CB2. + + Behind the BCD display we find the following supporting circuit + + 4x7 segment BCD display + +---+ +-----+ +---+---+---+---+ ++-----------------+ CB1 |74 |==/4/=>|2x |==/8/====>| 0 1 2 3 | +| | VIA CB2 |164|==/4/=>|75491| segments | | +| 4 char BCD LED | ===> 6522 +---+ +-----+ +---+---+---+---+ ++-----------------+ PB1--->|74 | | | | | +||||||||||||||||||| PB2--->|145|=/4/=/R/=>b(4x )c=/4/==============> + +---+ (PN2907)e=+ anodes + |+5v +*******************************************************************************************/ #include "emu.h" #include "cpu/m6502/m6502.h" +#include "machine/74145.h" +#include "machine/netlist.h" +#include "machine/nl_prodigy.h" #include "machine/6522via.h" +// Generated artwork includes +#include "prodigy.lh" + +#define LOG_SETUP (1U << 1) +#define LOG_READ (1U << 2) +#define LOG_BCD (1U << 3) +#define LOG_NETLIST (1U << 4) +#define LOG_CLK (1U << 5) + +//#define VERBOSE (LOG_BCD|LOG_NETLIST|LOG_SETUP) +//#define LOG_OUTPUT_FUNC printf + +#include "logmacro.h" + +#define LOGSETUP(...) LOGMASKED(LOG_SETUP, __VA_ARGS__) +#define LOGR(...) LOGMASKED(LOG_READ, __VA_ARGS__) +#define LOGBCD(...) LOGMASKED(LOG_BCD, __VA_ARGS__) +#define LOGNL(...) LOGMASKED(LOG_NETLIST, __VA_ARGS__) +#define LOGCLK(...) LOGMASKED(LOG_CLK, __VA_ARGS__) + +#ifdef _MSC_VER +#define FUNCNAME __func__ +#else +#define FUNCNAME __PRETTY_FUNCTION__ +#endif + +#define NETLIST_TAG "bcd" +#define TTL74164DEV 0 class prodigy_state : public driver_device { @@ -43,13 +92,123 @@ public: prodigy_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") + , m_74145(*this, "io_74145") + , m_segments(0) , m_via(*this, "via") + , m_bcd(*this, NETLIST_TAG) + , m_cb1(*this, "bcd:cb1") + , m_cb2(*this, "bcd:cb2") + , m_digit(0.0) { } + + NETDEV_LOGIC_CALLBACK_MEMBER(bcd_bit0_cb); + NETDEV_LOGIC_CALLBACK_MEMBER(bcd_bit1_cb); + NETDEV_LOGIC_CALLBACK_MEMBER(bcd_bit2_cb); + NETDEV_LOGIC_CALLBACK_MEMBER(bcd_bit3_cb); + NETDEV_LOGIC_CALLBACK_MEMBER(bcd_bit4_cb); + NETDEV_LOGIC_CALLBACK_MEMBER(bcd_bit5_cb); + NETDEV_LOGIC_CALLBACK_MEMBER(bcd_bit6_cb); + NETDEV_LOGIC_CALLBACK_MEMBER(bcd_bit7_cb); + + DECLARE_WRITE8_MEMBER( via_pb_w ); + DECLARE_WRITE_LINE_MEMBER(via_cb1_w); + DECLARE_WRITE_LINE_MEMBER(via_cb2_w); + DECLARE_WRITE_LINE_MEMBER(irq_handler); + private: required_device m_maincpu; + required_device m_74145; + uint8_t m_segments; required_device m_via; +#if TTL74164DEV + required_device m_shift; +#else + required_device m_bcd; + required_device m_cb1; + required_device m_cb2; +#endif + uint8_t m_digit; + void update_bcd(); + + virtual void device_reset() override; }; +NETDEV_LOGIC_CALLBACK_MEMBER(prodigy_state::bcd_bit0_cb) { if (data != 0) m_digit |= 0x01; else m_digit &= ~(0x01); LOGBCD("%s: %d m_digit: %02x\n", FUNCNAME, data, m_digit); } +NETDEV_LOGIC_CALLBACK_MEMBER(prodigy_state::bcd_bit1_cb) { if (data != 0) m_digit |= 0x02; else m_digit &= ~(0x02); LOGBCD("%s: %d m_digit: %02x\n", FUNCNAME, data, m_digit); } +NETDEV_LOGIC_CALLBACK_MEMBER(prodigy_state::bcd_bit2_cb) { if (data != 0) m_digit |= 0x04; else m_digit &= ~(0x04); LOGBCD("%s: %d m_digit: %02x\n", FUNCNAME, data, m_digit); } +NETDEV_LOGIC_CALLBACK_MEMBER(prodigy_state::bcd_bit3_cb) { if (data != 0) m_digit |= 0x08; else m_digit &= ~(0x08); LOGBCD("%s: %d m_digit: %02x\n", FUNCNAME, data, m_digit); } +NETDEV_LOGIC_CALLBACK_MEMBER(prodigy_state::bcd_bit4_cb) { if (data != 0) m_digit |= 0x10; else m_digit &= ~(0x10); LOGBCD("%s: %d m_digit: %02x\n", FUNCNAME, data, m_digit); } +NETDEV_LOGIC_CALLBACK_MEMBER(prodigy_state::bcd_bit5_cb) { if (data != 0) m_digit |= 0x20; else m_digit &= ~(0x20); LOGBCD("%s: %d m_digit: %02x\n", FUNCNAME, data, m_digit); } +NETDEV_LOGIC_CALLBACK_MEMBER(prodigy_state::bcd_bit6_cb) { if (data != 0) m_digit |= 0x40; else m_digit &= ~(0x40); LOGBCD("%s: %d m_digit: %02x\n", FUNCNAME, data, m_digit); } +NETDEV_LOGIC_CALLBACK_MEMBER(prodigy_state::bcd_bit7_cb) { if (data != 0) m_digit |= 0x80; else m_digit &= ~(0x80); LOGBCD("%s: %d m_digit: %02x\n", FUNCNAME, data, m_digit); } + +void prodigy_state::device_reset() +{ +#if TTL74164DEV + m_shift->b_w(1); + m_shift->clear_w(1); +#endif +} + +WRITE_LINE_MEMBER(prodigy_state::via_cb1_w) +{ + LOGCLK("%s: %d\n", FUNCNAME, state); + m_cb1->write(state); +} + +WRITE_LINE_MEMBER(prodigy_state::via_cb2_w) +{ + LOGCLK("%s: %d\n", FUNCNAME, state); + m_cb2->write(state); +} + +WRITE_LINE_MEMBER(prodigy_state::irq_handler) +{ + LOGBCD("%s: %d\n", FUNCNAME, state); + m_maincpu->set_input_line(M6502_IRQ_LINE, state); + update_bcd(); +} + +/* Pulling the base of the PN2907 PNP transistor low by the output of the 74145 controlled by PB0 and PB1 will feed + the coresponding anode enabling the correct digit and lit the segments currently held by the outputs of the 74164 + serial to 8 bit parallel converter fed by serial data using CB1 clock and CB2 data + + PB2 and PB3 is also connected to the 74145, usage to be traced.... +*/ +WRITE8_MEMBER( prodigy_state::via_pb_w ) // Needs to trace which port decides what digit +{ + LOGBCD("%s: %02x ANODE %02x\n", FUNCNAME, data, data & 0x03); + m_74145->write( data & 0x0f ); // Write PB0-PB3 to the 74145 +} + +void prodigy_state::update_bcd() +{ + LOGBCD("%s\n", FUNCNAME); + uint8_t ttl74145_data; + uint8_t digit_nbr = 4; + + ttl74145_data = m_74145->read(); + LOGBCD(" - 74145: %02x\n", ttl74145_data); + + if ((ttl74145_data & 0x0f) != 0x00) + { + switch (ttl74145_data & 0x0f) + { + case 0x01: digit_nbr = 0; break; + case 0x02: digit_nbr = 1; break; + case 0x04: digit_nbr = 2; break; + case 0x08: digit_nbr = 3; break; + default: logerror("Wrong BCD digit, shouldn't happen, call the maintainer!\n"); + } + + LOGBCD(" - digit number: %d\n", digit_nbr); + LOGBCD(" - segments: %02x -> ", m_digit); + m_segments = m_digit; + LOGBCD("%02x\n", m_segments); + output().set_digit_value( digit_nbr, m_segments); + } +} + static ADDRESS_MAP_START( maincpu_map, AS_PROGRAM, 8, prodigy_state ) AM_RANGE(0x0000, 0x07ff) AM_RAM AM_RANGE(0x2000, 0x200f) AM_DEVREADWRITE("via", via6522_device, read, write) @@ -63,9 +222,72 @@ static MACHINE_CONFIG_START( prodigy, prodigy_state ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", M6502, XTAL_2MHz) MCFG_CPU_PROGRAM_MAP(maincpu_map) + MCFG_DEFAULT_LAYOUT(layout_prodigy) + + MCFG_DEVICE_ADD("io_74145", TTL74145, 0) + MCFG_DEVICE_ADD("via", VIA6522, XTAL_2MHz) + MCFG_VIA6522_IRQ_HANDLER(WRITELINE(prodigy_state, irq_handler)); + MCFG_VIA6522_WRITEPB_HANDLER(WRITE8(prodigy_state, via_pb_w)) + MCFG_VIA6522_CB1_HANDLER(WRITELINE(prodigy_state, via_cb1_w)) + MCFG_VIA6522_CB2_HANDLER(WRITELINE(prodigy_state, via_cb2_w)) + + MCFG_DEVICE_ADD(NETLIST_TAG, NETLIST_CPU, XTAL_2MHz * 30) + MCFG_NETLIST_SETUP(prodigy) + + MCFG_NETLIST_LOGIC_INPUT(NETLIST_TAG, "cb1", "cb1.IN", 0) + MCFG_NETLIST_LOGIC_INPUT(NETLIST_TAG, "cb2", "cb2.IN", 0) + MCFG_NETLIST_LOGIC_OUTPUT(NETLIST_TAG, "bcd_bit0", "bcd_bit0", prodigy_state, bcd_bit0_cb, "") + MCFG_NETLIST_LOGIC_OUTPUT(NETLIST_TAG, "bcd_bit1", "bcd_bit1", prodigy_state, bcd_bit1_cb, "") + MCFG_NETLIST_LOGIC_OUTPUT(NETLIST_TAG, "bcd_bit2", "bcd_bit2", prodigy_state, bcd_bit2_cb, "") + MCFG_NETLIST_LOGIC_OUTPUT(NETLIST_TAG, "bcd_bit3", "bcd_bit3", prodigy_state, bcd_bit3_cb, "") + MCFG_NETLIST_LOGIC_OUTPUT(NETLIST_TAG, "bcd_bit4", "bcd_bit4", prodigy_state, bcd_bit4_cb, "") + MCFG_NETLIST_LOGIC_OUTPUT(NETLIST_TAG, "bcd_bit5", "bcd_bit5", prodigy_state, bcd_bit5_cb, "") + MCFG_NETLIST_LOGIC_OUTPUT(NETLIST_TAG, "bcd_bit6", "bcd_bit6", prodigy_state, bcd_bit6_cb, "") + MCFG_NETLIST_LOGIC_OUTPUT(NETLIST_TAG, "bcd_bit7", "bcd_bit7", prodigy_state, bcd_bit7_cb, "") MACHINE_CONFIG_END +/* + * 6522 VIA init sequence + * :via Reg 03 <- 00 - DDRA - Data Direction A, pin A0-A7 programmed as inputs + * :via Reg 02 <- 8f - DDRB - Data Direction B, pin B4-B6 programmed as inputs, other pins as outputs + * :via Reg 0c <- e0 - PCR - Peripheral Control Register, CB2 out pos out, CB1 ints on neg edg, CA2 inp neg act edg, CA1 ints on neg edg + * :via Reg 0b <- 58 - ACR - Auxilary Control Register, con ints, B7 dis, timed ints, shift out on 0/2, PA and PB latches disabled + * :via Reg 09 <- 58 - T2C-H - Timer 2 High Order Counter value + * :via Reg 04 <- ff - T1C-L - Timer 1 Low Order Latches + * :via Reg 0e <- a0 - IER - Interrupt Enable Register, Timer 2 Interrupts enabled + * + * ISR VIA accesses + * Reg 08 -> e1 - T2C-L - T2 low order counter + * Reg 08 <- 6e - T2C-L - T2 low order latches + * Reg 09 <- 20 - T2C-H - T2 High Order Counter + * Reg 0a <- 00 - SR - Shift Register + * Reg 00 <- 09 + * Reg 01 -> ff + * Reg 00 -> 09 + * Reg 00 <- 08 + * Reg 01 -> ff + * Reg 00 -> 08 + * Reg 00 <- 07 + * Reg 01 -> ff + * Reg 00 <- 06 + * Reg 01 -> ff + * Reg 00 <- 05 + * Reg 01 -> ff + * Reg 00 <- 04 + * Reg 01 -> ff + * Reg 00 <- 03 + * Reg 01 -> ff + * Reg 00 <- 02 + * Reg 01 -> ff + * Reg 00 <- 01 + * Reg 01 -> ff + * Reg 00 <- 00 + * Reg 01 -> ff + * Reg 0a <- 00 + * Reg 00 <- 05 + * Reg 08 -> e2 +*/ ROM_START(prodigy) ROM_REGION(0x2000, "roms", 0) ROM_LOAD("0x2000.bin", 0x0000, 0x02000, CRC(8d60345a) SHA1(fff18ff12e1b1be91f8eac1178605a682564eff2)) diff --git a/src/mame/layout/prodigy.lay b/src/mame/layout/prodigy.lay new file mode 100644 index 00000000000..fee2ebe74ce --- /dev/null +++ b/src/mame/layout/prodigy.lay @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mame/machine/nl_prodigy.cpp b/src/mame/machine/nl_prodigy.cpp new file mode 100644 index 00000000000..06ec65dd667 --- /dev/null +++ b/src/mame/machine/nl_prodigy.cpp @@ -0,0 +1,33 @@ +// license:BSD-3-Clause +// copyright-holders:Joakim Larsson Edstrom + +/*************************************************************************** + + Netlist (prodigy) included from prodigy.cpp + +***************************************************************************/ + +#include "netlist/devices/net_lib.h" + +NETLIST_START(prodigy) + + SOLVER(Solver, 48000) + PARAM(Solver.ACCURACY, 1e-4) // works and is sufficient + + TTL_INPUT(high, 1) + TTL_INPUT(low, 0) + + TTL_INPUT(cb1, 0) + TTL_INPUT(cb2, 0) + + TTL_74164(SHIFT, cb2, cb2, high, cb1) + ALIAS(bcd_bit0, SHIFT.QA) + ALIAS(bcd_bit1, SHIFT.QB) + ALIAS(bcd_bit2, SHIFT.QC) + ALIAS(bcd_bit3, SHIFT.QD) + ALIAS(bcd_bit4, SHIFT.QE) + ALIAS(bcd_bit5, SHIFT.QF) + ALIAS(bcd_bit6, SHIFT.QG) + ALIAS(bcd_bit7, SHIFT.QH) + +NETLIST_END() diff --git a/src/mame/machine/nl_prodigy.h b/src/mame/machine/nl_prodigy.h new file mode 100644 index 00000000000..37fb3a4e724 --- /dev/null +++ b/src/mame/machine/nl_prodigy.h @@ -0,0 +1,6 @@ +// license:BSD-3-Clause +// copyright-holders:Joakim Larsson Edstrom + +#include "netlist/nl_setup.h" + +NETLIST_EXTERNAL(prodigy)