Merge pull request #2068 from JoakimLarsson/prodigy_display

Prodigy display
This commit is contained in:
R. Belmont 2017-02-17 21:59:51 -05:00 committed by GitHub
commit 7b193346a8
14 changed files with 556 additions and 25 deletions

View File

@ -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",

View File

@ -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

View File

@ -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")

View File

@ -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",

View File

@ -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<char const *, 16>
{{"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<char const *, 16>
{{"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);
}
}

View File

@ -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;
};

View File

@ -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, "")

View File

@ -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"

View File

@ -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<unsigned> m_cnt;
state_var<unsigned> m_last_CLK;
object_array_t<logic_output_t, 8> 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

View File

@ -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_ */

View File

@ -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<cpu_device> m_maincpu;
required_device<ttl74145_device> m_74145;
uint8_t m_segments;
required_device<via6522_device> m_via;
#if TTL74164DEV
required_device<ttl74164_device> m_shift;
#else
required_device<netlist_mame_device_t> m_bcd;
required_device<netlist_mame_logic_input_t> m_cb1;
required_device<netlist_mame_logic_input_t> 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))

View File

@ -0,0 +1,25 @@
<?xml version="1.0"?>
<mamelayout version="2">
<element name="digit" defstate="1">
<led7seg>
<color red="0.75" green="0.0" blue="0.0" />
</led7seg>
</element>
<view name="Full Artwork">
<bounds left="0" top="0" right="840" bottom="1105" />
<bezel name="digit0" element="digit">
<bounds left="70" top="840" right="100" bottom="885" />
</bezel>
<bezel name="digit1" element="digit">
<bounds left="100" top="840" right="125" bottom="885" />
</bezel>
<bezel name="digit2" element="digit">
<bounds left="125" top="840" right="150" bottom="885" />
</bezel>
<bezel name="digit3" element="digit">
<bounds left="150" top="840" right="175" bottom="885" />
</bezel>
</view>
</mamelayout>

View File

@ -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()

View File

@ -0,0 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Joakim Larsson Edstrom
#include "netlist/nl_setup.h"
NETLIST_EXTERNAL(prodigy)