1 // license:BSD-3-Clause
2 // copyright-holders:Vas Crabb
3 /***************************************************************************
4 
5     m6500_1.h
6 
7     MOS Technology 6500/1, original NMOS variant with onboard peripherals:
8     * 6502 CPU
9     * 2048*8 mask ROM
10     * 64*8 static RAM
11     * Four eight-bit open drain I/O ports
12     * Sixteen-bit programmable counter/latch
13 
14                             _____   _____
15                    Vrr   1 |*    \_/     | 40  /NMI
16                    PD7   2 |             | 38  /RES
17                    PD6   3 |             | 38  PA0
18                    PD5   4 |             | 37  PA1
19                    PD4   5 |             | 36  PA2
20                    PD3   6 |             | 35  PA3
21                    PD2   7 |             | 34  PA4
22                    PD1   8 |             | 33  PA5
23                    PD0   9 |             | 32  PA6
24                   XTLI  10 |   6500/1    | 31  PA7
25                   XTLO  11 |             | 30  Vcc
26                    Vss  12 |             | 29  PB0
27                    PC7  13 |             | 28  PB1
28                    PC6  14 |             | 27  PB2
29                    PC5  15 |             | 26  PB3
30                    PC4  16 |             | 25  PB4
31                    PC3  17 |             | 24  PB5
32                    PC2  18 |             | 23  PB6
33                    PC1  19 |             | 22  PB7
34                    PC0  20 |_____________| 21  CNTR
35 
36 ***************************************************************************/
37 #ifndef MAME_CPU_M6502_M6500_1_H
38 #define MAME_CPU_M6502_M6500_1_H
39 
40 #pragma once
41 
42 #include "m6502.h"
43 
44 class m6500_1_device : public m6502_mcu_device
45 {
46 public:
47 	m6500_1_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
48 
pa_in_cb()49 	auto pa_in_cb() { return m_port_in_cb[0].bind(); }
pb_in_cb()50 	auto pb_in_cb() { return m_port_in_cb[1].bind(); }
pc_in_cb()51 	auto pc_in_cb() { return m_port_in_cb[2].bind(); }
pd_in_cb()52 	auto pd_in_cb() { return m_port_in_cb[3].bind(); }
pa_out_cb()53 	auto pa_out_cb() { return m_port_out_cb[0].bind(); }
pb_out_cb()54 	auto pb_out_cb() { return m_port_out_cb[1].bind(); }
pc_out_cb()55 	auto pc_out_cb() { return m_port_out_cb[2].bind(); }
pd_out_cb()56 	auto pd_out_cb() { return m_port_out_cb[3].bind(); }
cntr_out_cb()57 	auto cntr_out_cb() { return m_cntr_out_cb.bind(); }
58 
pa_r()59 	u8 pa_r() { return m_port_buf[0]; }
pb_r()60 	u8 pb_r() { return m_port_buf[1]; }
pc_r()61 	u8 pc_r() { return m_port_buf[2]; }
pd_r()62 	u8 pd_r() { return m_port_buf[3]; }
63 	void pa_w(u8 data);
64 	void pb_w(u8 data);
65 	void pc_w(u8 data);
66 	void pd_w(u8 data);
67 
68 	DECLARE_WRITE_LINE_MEMBER(cntr_w);
69 
70 protected:
71 	enum
72 	{
73 		M6500_1_CR = M6502_IR + 1,
74 		M6500_1_UL,
75 		M6500_1_LL,
76 		M6500_1_UC,
77 		M6500_1_LC
78 	};
79 
80 	virtual void device_resolve_objects() override;
81 	virtual void device_start() override;
82 	virtual void device_reset() override;
83 
84 	virtual u64 execute_clocks_to_cycles(u64 clocks) const noexcept override;
85 	virtual u64 execute_cycles_to_clocks(u64 cycles) const noexcept override;
86 
87 	virtual void state_import(device_state_entry const &entry) override;
88 	virtual void state_export(device_state_entry const &entry) override;
89 
90 	virtual void internal_update(u64 current_time) override;
91 	using m6502_mcu_device::internal_update;
92 
93 	u8 read_control_register();
94 	void write_control_register(u8 data);
95 	void update_irq();
96 
97 	u8 read_port(offs_t offset);
98 	void write_port(offs_t offset, u8 data);
99 	void clear_edge(offs_t offset, u8 data);
100 	template <unsigned Port> TIMER_CALLBACK_MEMBER(set_port_in);
101 
102 	u8 read_upper_count();
103 	u8 read_lower_count();
104 	template <bool Transfer> void write_upper_latch(u8 data);
105 	void write_lower_latch(u8 data);
106 	u64 update_counter(u64 current_time);
107 	bool should_count() const;
108 	bool pulse_generator_mode() const;
109 	bool event_counter_mode() const;
110 	TIMER_CALLBACK_MEMBER(set_cntr_in);
111 	void toggle_cntr();
112 
113 	void memory_map(address_map &map);
114 
115 private:
116 	devcb_read8::array<4>   m_port_in_cb;
117 	devcb_write8::array<4>  m_port_out_cb;
118 	devcb_write_line        m_cntr_out_cb;
119 
120 	u8  m_cr;
121 
122 	u8  m_port_in[4], m_port_buf[4];
123 
124 	u64 m_counter_base;
125 	u16 m_counter, m_latch;
126 	u8  m_cntr_in, m_cntr_out;
127 
128 	u8  m_ul, m_ll, m_uc, m_lc;
129 };
130 
131 DECLARE_DEVICE_TYPE(M6500_1, m6500_1_device)
132 
133 #endif // MAME_CPU_M6502_M6500_1_H
134