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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
|
// license:BSD-3-Clause
// copyright-holders:Michael Zapf
/*****************************************************************************
74610: Memory mappers
Variant Output Type
----------------------------------------
74610 latched tristate
74611 latched open collector
74612 direct tristate
74613 direct open collector
Connection Diagram:
_________
RS2 1 | | | | 40 Vcc
MA3 2 | --- | 39 MA2
RS3 3 | | 38 RS1
CS* 4 | | 37 MA1
STROBE* 5 | | 36 RS0
R/W* 6 | | 35 MA0
D0 7 | | 34 D11
D1 8 | | 33 D10
D2 9 | | 33 D9
D3 10 | | 31 D8
D4 11 | | 30 D7
D5 12 | | 29 D6
MM* 13 | | 28 C (610/611), nc (612/613)
MO0 14 | | 27 MO11
MO1 15 | | 26 MO10
MO2 16 | | 25 MO9
MO3 17 | | 24 MO8
MO4 18 | | 23 MO7
MO5 19 | | 22 MO6
GND 20 |_________| 21 ME*
Data bus connection: D0-D11
Map output: MO0-MO11
The internal memory is a 16 words (selected by RS3...RS0) by 12 bit RAM.
The mapper is intended to expand e.g. a 16-bit address by 8 additional bits,
making it a 24-bit address.
=====================++
|| D11 ... D0
MA3...MA0 _____________
==============| |---------------
| |
--------------| | MO11 ... MO0
RS3 ... RS0 | | (A23 ... A12)
(A15...A12) | |
--------------|_____________|---------------
A11 ... A0 A11 ... A0
--------------------------------------------
The mapping value can be changed by loading the new value into the chip at
the selected address (via the data bus). If the computer's data bus is
smaller (e.g. 8 bit), the remaining four bits may be set by mapping the
chip at different memory locations:
4000: D11=0, D10=0, D9=0, D8=0
4001: D11=0, D10=0, D9=0, D8=1
4002: D11=0, D10=0, D9=1, D8=0
...
400F: D11=1, D10=1, D9=1, D8=1
*****************************************************************************/
#include "emu.h"
#include "74610.h"
DEFINE_DEVICE_TYPE(TTL74610, ttl74610_device, "ttl74610", "SN74LS610 Memory mapper (latched, tristate)")
DEFINE_DEVICE_TYPE(TTL74611, ttl74611_device, "ttl74611", "SN74LS611 Memory mapper (latched, openc)")
DEFINE_DEVICE_TYPE(TTL74612, ttl74612_device, "ttl74612", "SN74LS612 Memory mapper (tristate)")
DEFINE_DEVICE_TYPE(TTL74613, ttl74613_device, "ttl74613", "SN74LS613 Memory mapper (openc)")
ttl7461x_device::ttl7461x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock),
m_has_tristate(true),
m_enabled(false),
m_map_output(*this),
m_map_mode(false)
{
}
ttl7461x_latched_device::ttl7461x_latched_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: ttl7461x_device(mconfig, type, tag, owner, clock),
m_latch_enabled(false),
m_latched_output(0)
{
}
ttl74610_device::ttl74610_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: ttl7461x_latched_device(mconfig, TTL74610, tag, owner, clock)
{
}
ttl74611_device::ttl74611_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: ttl7461x_latched_device(mconfig, TTL74611, tag, owner, clock)
{
m_has_tristate = false;
}
ttl74612_device::ttl74612_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: ttl7461x_device(mconfig, TTL74612, tag, owner, clock)
{
}
ttl74613_device::ttl74613_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: ttl7461x_device(mconfig, TTL74613, tag, owner, clock)
{
m_has_tristate = false;
}
void ttl7461x_device::device_start()
{
for (auto & elem : m_map) elem = 0;
save_item(NAME(m_map));
save_item(NAME(m_map_mode));
save_item(NAME(m_enabled));
}
void ttl7461x_device::device_reset()
{
}
void ttl7461x_device::set_register(int num, uint16_t value)
{
m_map[num & 0x0f] = value & 0x03ff;
}
uint16_t ttl7461x_device::get_register(int num)
{
return m_map[num & 0x0f];
}
/*
To make full use of the tristate/open collector feature, this method
should be used.
*/
void ttl7461x_device::mapper_output_rz(uint8_t num, uint16_t& value)
{
if (m_enabled)
{
if (m_has_tristate)
value = get_mapper_output(num);
else
// open collectors can only pull down
value &= get_mapper_output(num);
}
}
uint16_t ttl7461x_device::get_mapper_output(uint8_t num)
{
if (m_map_mode)
return m_map[num & 0x0f];
else
return num;
}
void ttl7461x_device::map_mode_w(int mapping)
{
m_map_mode = (((line_state)mapping) == ASSERT_LINE);
}
void ttl7461x_device::map_enable_w(int enable)
{
m_enabled = (((line_state)enable) == ASSERT_LINE);
}
// Latched versions
void ttl7461x_latched_device::device_start()
{
ttl7461x_device::device_start();
save_item(NAME(m_latch_enabled));
save_item(NAME(m_latched_output));
}
uint16_t ttl7461x_latched_device::get_mapper_output()
{
return m_latched_output;
}
void ttl7461x_latched_device::mapper_output_rz(uint16_t& value)
{
if (m_enabled) value = get_mapper_output();
}
void ttl7461x_latched_device::latch_enable_w(int enable)
{
m_latch_enabled = (((line_state)enable) == ASSERT_LINE);
}
void ttl7461x_latched_device::set_map_address(uint8_t num)
{
uint16_t mapvalue = ttl7461x_device::get_mapper_output(num);
if (m_latch_enabled)
m_latched_output = mapvalue;
if (m_enabled)
m_map_output(mapvalue);
}
|