1
/**********************************************************************
3
Zilog Z8536 Counter/Timer and Parallel I/O emulation
6
Visit http://mamedev.org for licensing and usage restrictions.
8
**********************************************************************/
12
#include "machine/devhelpr.h"
16
//**************************************************************************
18
//**************************************************************************
42
MASTER_INTERRUPT_CONTROL = 0,
43
MASTER_CONFIGURATION_CONTROL,
44
PORT_A_INTERRUPT_VECTOR,
45
PORT_B_INTERRUPT_VECTOR,
46
COUNTER_TIMER_INTERRUPT_VECTOR,
47
PORT_C_DATA_PATH_POLARITY,
48
PORT_C_DATA_DIRECTION,
49
PORT_C_SPECIAL_IO_CONTROL,
50
PORT_A_COMMAND_AND_STATUS,
51
PORT_B_COMMAND_AND_STATUS,
52
COUNTER_TIMER_1_COMMAND_AND_STATUS,
53
COUNTER_TIMER_2_COMMAND_AND_STATUS,
54
COUNTER_TIMER_3_COMMAND_AND_STATUS,
58
COUNTER_TIMER_1_CURRENT_COUNT_MS_BYTE,
59
COUNTER_TIMER_1_CURRENT_COUNT_LS_BYTE,
60
COUNTER_TIMER_2_CURRENT_COUNT_MS_BYTE,
61
COUNTER_TIMER_2_CURRENT_COUNT_LS_BYTE,
62
COUNTER_TIMER_3_CURRENT_COUNT_MS_BYTE,
63
COUNTER_TIMER_3_CURRENT_COUNT_LS_BYTE,
64
COUNTER_TIMER_1_TIME_CONSTANT_MS_BYTE,
65
COUNTER_TIMER_1_TIME_CONSTANT_LS_BYTE,
66
COUNTER_TIMER_2_TIME_CONSTANT_MS_BYTE,
67
COUNTER_TIMER_2_TIME_CONSTANT_LS_BYTE,
68
COUNTER_TIMER_3_TIME_CONSTANT_MS_BYTE,
69
COUNTER_TIMER_3_TIME_CONSTANT_LS_BYTE,
70
COUNTER_TIMER_1_MODE_SPECIFICATION,
71
COUNTER_TIMER_2_MODE_SPECIFICATION,
72
COUNTER_TIMER_3_MODE_SPECIFICATION,
74
PORT_A_MODE_SPECIFICATION,
75
PORT_A_HANDSHAKE_SPECIFICATION,
76
PORT_A_DATA_PATH_POLARITY,
77
PORT_A_DATA_DIRECTION,
78
PORT_A_SPECIAL_IO_CONTROL,
79
PORT_A_PATTERN_POLARITY,
80
PORT_A_PATTERN_TRANSITION,
82
PORT_B_MODE_SPECIFICATION,
83
PORT_B_HANDSHAKE_SPECIFICATION,
84
PORT_B_DATA_PATH_POLARITY,
85
PORT_B_DATA_DIRECTION,
86
PORT_B_SPECIAL_IO_CONTROL,
87
PORT_B_PATTERN_POLARITY,
88
PORT_B_PATTERN_TRANSITION,
93
// counter/timer link control
113
// pattern mode specification
123
// handshake specification
133
// request/wait specification
141
RWS_INPUT_REQUEST = 7
145
// pattern specification
167
// master interrupt control register
168
#define MICR_RESET 0x01 // reset
169
#define MICR_RJA 0x02 // right justified address
170
#define MICR_CT_VIS 0x04 // counter/timer vector includes status
171
#define MICR_PB_VIS 0x08 // port B vector includes status
172
#define MICR_PA_VIS 0x10 // port A vector includes status
173
#define MICR_NV 0x20 // no vector
174
#define MICR_DLC 0x40 // disable lower chain
175
#define MICR_MIE 0x80 // master interrupt enable
178
// master configuration control register
179
#define MCCR_LC_MASK 0x03 // counter/timer link controls
180
#define MCCR_PAE 0x04 // port A enable
181
#define MCCR_PLC 0x08 // port link control
182
#define MCCR_PCE_CT3E 0x10 // port C and counter/timer 3 enable
183
#define MCCR_CT2E 0x20 // counter/timer 2 enable
184
#define MCCR_CT1E 0x40 // counter/timer 1 enable
185
#define MCCR_PBE 0x80 // port B enable
188
// port mode specification registers
189
#define PMS_LPM 0x01 // latch on pattern match
190
#define PMS_PMS_MASK 0x06 // pattern mode specification
191
#define PMS_IMO 0x08 // interrupt on match only
192
#define PMS_SB 0x10 // single buffer
193
#define PMS_ITB 0x20 // interrupt on two bytes
194
#define PMS_PTS_MASK 0xc0 // port type select
197
// port handshake specification registers
198
#define PHS_DTS_MASK 0x07 // deskew time specification
199
#define PHS_RWS_MASK 0x38 // request/wait specification
200
#define PHS_HTS_MASK 0xc0 // handshake type specification
203
// port command and status registers
204
#define PCS_IOE 0x01 // interrupt on error
205
#define PCS_PMF 0x02 // pattern match flag (read only)
206
#define PCS_IRF 0x04 // input register full (read only)
207
#define PCS_ORE 0x08 // output register empty (read only)
208
#define PCS_ERR 0x10 // interrupt error (read only)
209
#define PCS_IP 0x20 // interrupt pending
210
#define PCS_IE 0x40 // interrupt enable
211
#define PCS_IUS 0x80 // interrupt under service
214
// counter/timer mode specification registers
215
#define CTMS_DCS_MASK 0x03 // output duty cycle
216
#define CTMS_REB 0x04 // retrigger enable bit
217
#define CTMS_EDE 0x08 // external gate enable
218
#define CTMS_ETE 0x10 // external trigger enable
219
#define CTMS_ECE 0x20 // external count enable
220
#define CTMS_EOE 0x40 // external output enable
221
#define CTMS_CSC 0x80 // continuous single cycle
224
// counter/timer command and status registers
225
#define CTCS_CIP 0x01 // count in progress (read only)
226
#define CTCS_TCB 0x02 // trigger command bit (write only - read returns 0)
227
#define CTCS_GCB 0x04 // gate command bit
228
#define CTCS_RCC 0x08 // read counter control (read/set only - cleared by reading CCR LSB)
229
#define CTCS_ERR 0x10 // interrupt error (read only)
230
#define CTCS_IP 0x20 // interrupt pending
231
#define CTCS_IE 0x40 // interrupt enable
232
#define CTCS_IUS 0x80 // interrupt under service
236
//**************************************************************************
237
// DEVICE DEFINITIONS
238
//**************************************************************************
240
const device_type Z8536 = z8536_device_config::static_alloc_device_config;
244
//**************************************************************************
245
// DEVICE CONFIGURATION
246
//**************************************************************************
248
GENERIC_DEVICE_CONFIG_SETUP(z8536, "Zilog Z8536")
251
//-------------------------------------------------
252
// device_config_complete - perform any
253
// operations now that the configuration is
255
//-------------------------------------------------
257
void z8536_device_config::device_config_complete()
259
// inherit a copy of the static data
260
const z8536_interface *intf = reinterpret_cast<const z8536_interface *>(static_config());
262
*static_cast<z8536_interface *>(this) = *intf;
264
// or initialize to defaults if none provided
267
memset(&m_out_int_func, 0, sizeof(m_out_int_func));
268
memset(&m_in_pa_func, 0, sizeof(m_in_pa_func));
269
memset(&m_out_pa_func, 0, sizeof(m_out_pa_func));
270
memset(&m_in_pb_func, 0, sizeof(m_in_pb_func));
271
memset(&m_out_pb_func, 0, sizeof(m_out_pb_func));
272
memset(&m_in_pc_func, 0, sizeof(m_in_pc_func));
273
memset(&m_out_pc_func, 0, sizeof(m_out_pc_func));
279
//**************************************************************************
281
//**************************************************************************
283
//-------------------------------------------------
284
// read_register - read from register
285
//-------------------------------------------------
287
inline UINT8 z8536_device::read_register(offs_t offset)
291
data = m_register[offset]; // HACK
296
data = devcb_call_read8(&m_in_pa_func, 0);
300
data = devcb_call_read8(&m_in_pb_func, 0);
304
data = 0xf0 | (devcb_call_read8(&m_in_pc_func, 0) & 0x0f);
308
logerror("Z8536 '%s' Unimplemented read from register %u\n", tag(), offset);
315
//-------------------------------------------------
316
// read_register - masked read from register
317
//-------------------------------------------------
319
inline UINT8 z8536_device::read_register(offs_t offset, UINT8 mask)
321
return read_register(offset) & mask;
325
//-------------------------------------------------
326
// write_register - write to register
327
//-------------------------------------------------
329
inline void z8536_device::write_register(offs_t offset, UINT8 data)
333
case MASTER_INTERRUPT_CONTROL:
334
if (data & MICR_RESET)
338
else if (m_state == STATE_RESET)
345
devcb_call_write8(&m_out_pa_func, 0, data);
349
devcb_call_write8(&m_out_pb_func, 0, data);
354
UINT8 mask = (data & 0xf0) | (data >> 4);
356
m_output[PORT_C] = (m_output[PORT_C] & mask) | ((data & 0x0f) & (mask ^ 0xff));
358
devcb_call_write8(&m_out_pc_func, 0, m_output[PORT_C]);
363
logerror("Z8536 '%s' Unimplemented write %02x to register %u\n", tag(), data, offset);
366
m_register[offset] = data; // HACK
370
//-------------------------------------------------
371
// write_register - masked write to register
372
//-------------------------------------------------
374
inline void z8536_device::write_register(offs_t offset, UINT8 data, UINT8 mask)
376
UINT8 combined_data = (data & mask) | (m_register[offset] & (mask ^ 0xff));
378
write_register(offset, combined_data);
382
//-------------------------------------------------
384
//-------------------------------------------------
386
inline void z8536_device::count(device_timer_id id)
391
//-------------------------------------------------
393
//-------------------------------------------------
395
inline void z8536_device::trigger(device_timer_id id)
400
//-------------------------------------------------
402
//-------------------------------------------------
404
inline void z8536_device::gate(device_timer_id id)
410
//**************************************************************************
412
//**************************************************************************
414
//-------------------------------------------------
415
// z8536_device - constructor
416
//-------------------------------------------------
418
z8536_device::z8536_device(running_machine &_machine, const z8536_device_config &config)
419
: device_t(_machine, config),
425
//-------------------------------------------------
426
// device_start - device-specific startup
427
//-------------------------------------------------
429
void z8536_device::device_start()
432
m_timer[TIMER_1] = timer_alloc(TIMER_1);
433
m_timer[TIMER_2] = timer_alloc(TIMER_2);
434
m_timer[TIMER_3] = timer_alloc(TIMER_3);
437
devcb_resolve_write_line(&m_out_int_func, &m_config.m_out_int_func, this);
438
devcb_resolve_read8(&m_in_pa_func, &m_config.m_in_pa_func, this);
439
devcb_resolve_write8(&m_out_pa_func, &m_config.m_out_pa_func, this);
440
devcb_resolve_read8(&m_in_pb_func, &m_config.m_in_pb_func, this);
441
devcb_resolve_write8(&m_out_pb_func, &m_config.m_out_pb_func, this);
442
devcb_resolve_read8(&m_in_pc_func, &m_config.m_in_pc_func, this);
443
devcb_resolve_write8(&m_out_pc_func, &m_config.m_out_pc_func, this);
447
//-------------------------------------------------
448
// device_start - device-specific reset
449
//-------------------------------------------------
451
void z8536_device::device_reset()
453
m_state = STATE_RESET;
455
for (int i = 0; i < 48; i++)
460
m_register[MASTER_INTERRUPT_CONTROL] = MICR_RESET;
465
//-------------------------------------------------
466
// device_timer - handler timer events
467
//-------------------------------------------------
469
void z8536_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
488
//-------------------------------------------------
489
// read - register read
490
//-------------------------------------------------
492
READ8_MEMBER( z8536_device::read )
496
if (m_state == STATE_RESET)
499
data = read_register(m_pointer, 0x01);
503
switch (offset & 0x03)
506
data = read_register(PORT_C_DATA);
510
data = read_register(PORT_B_DATA);
514
data = read_register(PORT_A_DATA);
524
data = read_register(m_pointer);
535
//-------------------------------------------------
536
// write - register write
537
//-------------------------------------------------
539
WRITE8_MEMBER( z8536_device::write )
541
if (m_state == STATE_RESET)
544
write_register(m_pointer, data, 0x01);
548
switch (offset & 0x03)
551
write_register(PORT_C_DATA, data);
555
write_register(PORT_B_DATA, data);
559
write_register(PORT_A_DATA, data);
571
write_register(m_pointer, data);
580
//-------------------------------------------------
581
// intack_w - interrupt acknowledge
582
//-------------------------------------------------
584
WRITE_LINE_MEMBER( z8536_device::intack_w )
589
//-------------------------------------------------
590
// pb*_w - port B bits 0-7 write
591
//-------------------------------------------------
593
WRITE_LINE_MEMBER( z8536_device::pb0_w ) { }
594
WRITE_LINE_MEMBER( z8536_device::pb1_w ) { }
595
WRITE_LINE_MEMBER( z8536_device::pb2_w ) { }
596
WRITE_LINE_MEMBER( z8536_device::pb3_w ) { }
597
WRITE_LINE_MEMBER( z8536_device::pb4_w ) { }
598
WRITE_LINE_MEMBER( z8536_device::pb5_w ) { }
599
WRITE_LINE_MEMBER( z8536_device::pb6_w ) { }
600
WRITE_LINE_MEMBER( z8536_device::pb7_w ) { }
603
//-------------------------------------------------
604
// pc*_w - port C bits 0-3 write
605
//-------------------------------------------------
607
WRITE_LINE_MEMBER( z8536_device::pc0_w ) { }
608
WRITE_LINE_MEMBER( z8536_device::pc1_w ) { }
609
WRITE_LINE_MEMBER( z8536_device::pc2_w ) { }
610
WRITE_LINE_MEMBER( z8536_device::pc3_w ) { }