// license:BSD-3-Clause
// copyright-holders:AJR
/**********************************************************************
Am9513A/Am9513 System Timing Controller
***********************************************************************
_____ _____
VCC 1 |* \_/ | 40 OUT 3
OUT 2 2 | | 39 GATE 2
OUT 1 3 | | 38 OUT 4
GATE 1 4 | | 37 OUT 5
X1 5 | | 36 GATE 3
X2 6 | | 35 GATE 4
FOUT 7 | | 34 GATE 5
C/_D 8 | | 33 SOURCE 1
_WR 9 | | 32 SOURCE 2
_CS 10 | Am9513A | 31 SOURCE 3
_RD 11 | Am9513 | 30 SOURCE 4
DB0 12 | | 29 SOURCE 5
DB1 13 | | 28 DB15
DB2 14 | | 27 DB14
DB3 15 | | 26 DB13
DB4 16 | | 25 DB12/GATE 5A
DB5 17 | | 24 DB11/GATE 4A
DB6 18 | | 23 DB10/GATE 3A
DB7 19 | | 22 DB9/GATE 2A
GATE 1A/DB8 20 |_____________| 21 VSS
**********************************************************************/
#ifndef MAME_MACHINE_AM9513_H
#define MAME_MACHINE_AM9513_H
#pragma once
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> am9513_device
class am9513_device : public device_t
{
public:
// device type constructor
am9513_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
// static configuration
auto out1_cb() { return m_out_cb[0].bind(); }
auto out2_cb() { return m_out_cb[1].bind(); }
auto out3_cb() { return m_out_cb[2].bind(); }
auto out4_cb() { return m_out_cb[3].bind(); }
auto out5_cb() { return m_out_cb[4].bind(); }
auto fout_cb() { return m_fout_cb.bind(); }
// 8-bit data bus interface
u8 read8(offs_t offset);
void write8(offs_t offset, u8 data);
// 16-bit data bus interface
u16 read16(offs_t offset);
void write16(offs_t offset, u16 data);
// Source N inputs
DECLARE_WRITE_LINE_MEMBER(source1_w) { write_source(0, state); }
DECLARE_WRITE_LINE_MEMBER(source2_w) { write_source(1, state); }
DECLARE_WRITE_LINE_MEMBER(source3_w) { write_source(2, state); }
DECLARE_WRITE_LINE_MEMBER(source4_w) { write_source(3, state); }
DECLARE_WRITE_LINE_MEMBER(source5_w) { write_source(4, state); }
// Gate N inputs
DECLARE_WRITE_LINE_MEMBER(gate1_w) { write_gate(0, state); }
DECLARE_WRITE_LINE_MEMBER(gate2_w) { write_gate(1, state); }
DECLARE_WRITE_LINE_MEMBER(gate3_w) { write_gate(2, state); }
DECLARE_WRITE_LINE_MEMBER(gate4_w) { write_gate(3, state); }
DECLARE_WRITE_LINE_MEMBER(gate5_w) { write_gate(4, state); }
// Gate N alternate inputs (8-bit mode only; multiplexed with DB8-DB12)
DECLARE_WRITE_LINE_MEMBER(gate1a_w) { write_gate_alt(0, state); }
DECLARE_WRITE_LINE_MEMBER(gate2a_w) { write_gate_alt(1, state); }
DECLARE_WRITE_LINE_MEMBER(gate3a_w) { write_gate_alt(2, state); }
DECLARE_WRITE_LINE_MEMBER(gate4a_w) { write_gate_alt(3, state); }
DECLARE_WRITE_LINE_MEMBER(gate5a_w) { write_gate_alt(4, state); }
// diagnostic helper
std::string describe_register() const;
protected:
// base constructor
am9513_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, bool is_am9513a);
// device-level overrides
virtual void device_start() override;
virtual void device_clock_changed() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
private:
// internal helpers
TIMER_CALLBACK_MEMBER(clear_outputs);
void master_reset();
void init_freq_timer(int f);
void select_freq_timer(int f, int c, bool selected, bool cycle);
void set_master_mode(u16 data);
bool counter_is_mode_x(int c) const;
bool compare_count(int c) const;
void set_counter_mode(int c, u16 data);
void arm_counter(int c);
void disarm_counter(int c);
void save_counter(int c);
void set_output(int c, bool state);
void set_toggle(int c, bool state);
void set_tc(int c, bool state);
void write_source(int s, bool level);
void count_edge(int c);
bool reload_from_hold(int c) const;
void step_counter(int c, bool force_load);
void gate_count(int c, bool state);
void write_gate(int g, bool level);
void write_gate_alt(int c, bool level);
u16 internal_read() const;
void internal_write(u16 data);
void advance_dpr();
void command_write(u8 data);
u8 status_read() const;
bool bus_is_16_bit() const;
u16 data_read();
void data_write(u16 data);
void fout_tick();
// output callbacks
devcb_write_line m_out_cb[5];
devcb_write_line m_fout_cb;
const bool m_is_am9513a;
u8 m_dpr;
u16 m_mmr;
u8 m_status;
bool m_write_prefetch;
// counter-specific registers
u16 m_count[5];
u16 m_counter_load[5];
u16 m_counter_hold[5];
u16 m_counter_mode[5];
u16 m_alarm[2];
bool m_counter_armed[5];
bool m_counter_running[5];
bool m_alternate_count[5];
// input state
bool m_src[5];
bool m_gate[5];
bool m_gate_alt[5];
bool m_gate_active[5];
// internal outputs
bool m_tc[5];
bool m_toggle[5];
// frequency timer
u8 m_f;
enum
{
TIMER_F1,
TIMER_F2,
TIMER_F3,
TIMER_F4,
TIMER_F5
};
emu_timer *m_freq_timer[5];
u8 m_freq_timer_selected[5];
u8 m_freq_timer_cycle[5];
bool m_fout;
int m_fout_counter;
};
// ======================> am9513a_device
class am9513a_device : public am9513_device
{
public:
// device type constructor
am9513a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
// device type declarations
DECLARE_DEVICE_TYPE(AM9513, am9513_device)
DECLARE_DEVICE_TYPE(AM9513A, am9513a_device)
#endif // MAME_MACHINE_AM9513_H