1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
// license:BSD-3-Clause
// copyright-holders:Dirk Best, Vas Crabb
/***************************************************************************
Input Merger
Used to connect multiple lines to a single device input while keeping it
pulled high or low.
Default initial input pin(s) state:
- ANY_HIGH: 0
- ALL_HIGH: 1
- ANY_LOW: 1
- ALL_LOW: 0
TODO:
- Change the strange initial input state, eg. right now it's all 1 for an AND
gate. All 0 for all devices would be more intuitive, but that would need a
config handler for setting the number of input pins since otherwise it can't
know if the state is active or not.
- Call m_output_handler at reset, eg. a NOR gate whose inputs are low at power-on
should output 1 (to avoid surprises, this should be done after machine_reset).
- Related to currently not calling m_output_handler at reset, if the hardware
1st value written equals the initial state, m_output_handler is not called,
eg. writing 1 to an AND gate pin when the default initial state is 1.
***************************************************************************/
#include "emu.h"
#include "input_merger.h"
#include <algorithm>
#include <iterator>
//#define VERBOSE 1
#include "logmacro.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(INPUT_MERGER_ANY_HIGH, input_merger_any_high_device, "ipt_merge_any_hi", "Input Merger (any high)") // OR
DEFINE_DEVICE_TYPE(INPUT_MERGER_ALL_HIGH, input_merger_all_high_device, "ipt_merge_all_hi", "Input Merger (all high)") // AND
DEFINE_DEVICE_TYPE(INPUT_MERGER_ANY_LOW, input_merger_any_low_device, "ipt_merge_any_lo", "Input Merger (any low)") // NAND
DEFINE_DEVICE_TYPE(INPUT_MERGER_ALL_LOW, input_merger_all_low_device, "ipt_merge_all_lo", "Input Merger (all low)") // NOR
//**************************************************************************
// INPUT ADAPTER
//**************************************************************************
//-------------------------------------------------
// input_merger_device - constructor
//-------------------------------------------------
input_merger_device::input_merger_device(
machine_config const &mconfig,
device_type type,
char const *tag,
device_t *owner,
uint32_t clock,
u32 initval,
u32 xorval,
int active)
: device_t(mconfig, type, tag, owner, clock)
, m_output_handler(*this)
, m_initval(initval)
, m_xorval(xorval)
, m_active(active)
, m_state(initval)
{
}
//-------------------------------------------------
// input_merger_device - destructor
//-------------------------------------------------
input_merger_device::~input_merger_device()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void input_merger_device::device_start()
{
m_output_handler.resolve_safe();
save_item(NAME(m_state));
m_state = m_initval;
}
//-------------------------------------------------
// update_state - verify current input line state
//-------------------------------------------------
TIMER_CALLBACK_MEMBER(input_merger_device::update_state)
{
if (BIT(m_state, param >> 1) != BIT(param, 0))
{
LOG("state[%d] = %d\n", param >> 1, BIT(param, 0));
m_state ^= u32(1) << (param >> 1);
m_output_handler((m_state ^ m_xorval) ? m_active : !m_active);
}
}
//**************************************************************************
// SPECIALISATIONS
//**************************************************************************
input_merger_any_high_device::input_merger_any_high_device(machine_config const &mconfig, char const *tag, device_t *owner, const XTAL &clock)
: input_merger_device(mconfig, INPUT_MERGER_ANY_HIGH, tag, owner, clock, u32(0), u32(0), 1)
{
}
input_merger_all_high_device::input_merger_all_high_device(machine_config const &mconfig, char const *tag, device_t *owner, const XTAL &clock)
: input_merger_device(mconfig, INPUT_MERGER_ALL_HIGH, tag, owner, clock, ~u32(0), ~u32(0), 0)
{
}
input_merger_any_low_device::input_merger_any_low_device(machine_config const &mconfig, char const *tag, device_t *owner, const XTAL &clock)
: input_merger_device(mconfig, INPUT_MERGER_ANY_LOW, tag, owner, clock, ~u32(0), ~u32(0), 1)
{
}
input_merger_all_low_device::input_merger_all_low_device(machine_config const &mconfig, char const *tag, device_t *owner, const XTAL &clock)
: input_merger_device(mconfig, INPUT_MERGER_ALL_LOW, tag, owner, clock, u32(0), u32(0), 0)
{
}
|