1 // license:BSD-3-Clause
2 // copyright-holders:Ryan Holtz
3 /**********************************************************************
4 
5     STmicro ST6-series microcontroller emulation
6 
7 **********************************************************************
8                             _____   _____
9                    Vdd   1 |*    \_/     | 28  Vss
10                  TIMER   2 |             | 27  PA0
11                  OSCin   3 |             | 26  PA1
12                 OSCout   4 |             | 25  PA2/ARTIMout
13                    NMI   5 |             | 24  PA3/ARTIMin
14                    PC7   6 |             | 23  PA4
15                    PC6   7 |  ST62T28C   | 22  PA5
16                Ain/PC5   8 |  ST62E28C   | 21  PD1/Ain/Scl
17                Ain/PC4   9 |             | 20  PD2/Ain/Sin
18               TEST/Vpp  10 |             | 19  PD3/Ain/Sout
19                 /RESET  11 |             | 18  PD4/Ain/RXD1
20                Ain/PB6  12 |             | 17  PD5/Ain/TXD1
21                Ain/PB5  13 |             | 16  PD6/Ain
22                Ain/PB4  14 |_____________| 15  PD7/Ain
23 
24 **********************************************************************/
25 
26 #ifndef MAME_CPU_ST62XX_H
27 #define MAME_CPU_ST62XX_H
28 
29 #pragma once
30 
31 class st6228_device : public cpu_device
32 {
33 public:
34 	st6228_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
35 
port_a()36 	template <unsigned Bit> auto port_a()
37 	{
38 		static_assert(Bit < 6, "ST6228 port A bit must be in the range 0..5\n");
39 		return m_porta_out[Bit].bind();
40 	}
port_b()41 	template <unsigned Bit> auto port_b()
42 	{
43 		static_assert(Bit >= 4 && Bit <= 6, "ST6228 port B bit must be in the range 4..6\n");
44 		return m_portb_out[Bit - 4].bind();
45 	}
port_c()46 	template <unsigned Bit> auto port_c()
47 	{
48 		static_assert(Bit >= 4 && Bit <= 7, "ST6228 port C bit must be in the range 4..7\n");
49 		return m_portc_out[Bit - 4].bind();
50 	}
port_d()51 	template <unsigned Bit> auto port_d()
52 	{
53 		static_assert(Bit >= 1 && Bit <= 7, "ST6228 port D bit must be in the range 1..7\n");
54 		return m_portd_out[Bit - 1].bind();
55 	}
56 
57 	DECLARE_WRITE_LINE_MEMBER(porta0_w);
58 	DECLARE_WRITE_LINE_MEMBER(porta1_w);
59 	DECLARE_WRITE_LINE_MEMBER(porta2_w);
60 	DECLARE_WRITE_LINE_MEMBER(porta3_w);
61 	DECLARE_WRITE_LINE_MEMBER(porta4_w);
62 	DECLARE_WRITE_LINE_MEMBER(porta5_w);
63 
64 	DECLARE_WRITE_LINE_MEMBER(portb4_w);
65 	DECLARE_WRITE_LINE_MEMBER(portb5_w);
66 	DECLARE_WRITE_LINE_MEMBER(portb6_w);
67 
68 	DECLARE_WRITE_LINE_MEMBER(portc4_w);
69 	DECLARE_WRITE_LINE_MEMBER(portc5_w);
70 	DECLARE_WRITE_LINE_MEMBER(portc6_w);
71 	DECLARE_WRITE_LINE_MEMBER(portc7_w);
72 
73 	DECLARE_WRITE_LINE_MEMBER(portd1_w);
74 	DECLARE_WRITE_LINE_MEMBER(portd2_w);
75 	DECLARE_WRITE_LINE_MEMBER(portd3_w);
76 	DECLARE_WRITE_LINE_MEMBER(portd4_w);
77 	DECLARE_WRITE_LINE_MEMBER(portd5_w);
78 	DECLARE_WRITE_LINE_MEMBER(portd6_w);
79 	DECLARE_WRITE_LINE_MEMBER(portd7_w);
80 
81 protected:
82 	// device-level overrides
83 	virtual void device_start() override;
84 	virtual void device_reset() override;
85 
86 	// device_execute_interface overrides
87 	virtual uint32_t execute_min_cycles() const noexcept override;
88 	virtual uint32_t execute_max_cycles() const noexcept override;
89 	virtual uint32_t execute_input_lines() const noexcept override;
90 	virtual void execute_run() override;
91 	virtual void execute_set_input(int inputnum, int state) override;
92 
93 	// device_memory_interface overrides
94 	virtual space_config_vector memory_space_config() const override;
95 
96 	// device_disasm_interface overrides
97 	virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
98 
99 	// device_state_interface overrides
100 	virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
101 
102 	// address spaces
103 	void st6228_program_map(address_map &map);
104 	void st6228_data_map(address_map &map);
105 
106 	void unimplemented_opcode(uint8_t op);
107 	void tick_timers(int cycles);
108 	void update_port_mode(uint8_t index, uint8_t changed);
109 	void set_port_output_bit(uint8_t index, uint8_t bit, uint8_t state);
110 
111 	void regs_w(offs_t offset, uint8_t data);
112 	uint8_t regs_r(offs_t offset);
113 
114 	enum
115 	{
116 		STATE_FLAGS = 1,
117 		STATE_PC,
118 		STATE_SP,
119 		STATE_STACK0,
120 		STATE_STACK1,
121 		STATE_STACK2,
122 		STATE_STACK3,
123 		STATE_STACK4,
124 		STATE_STACK5,
125 		STATE_A,
126 		STATE_X,
127 		STATE_Y,
128 		STATE_V,
129 		STATE_W
130 	};
131 
132 	enum
133 	{
134 		PROGRAM_ROM_START       = 0x40,
135 		REGS_START              = 0x80,
136 		REG_X                   = 0x80,
137 		REG_Y                   = 0x81,
138 		REG_V                   = 0x82,
139 		REG_W                   = 0x83,
140 		DATA_RAM_START          = 0x84,
141 		REG_PORTA_DATA          = 0xc0,
142 		REG_PORTB_DATA          = 0xc1,
143 		REG_PORTC_DATA          = 0xc2,
144 		REG_PORTD_DATA          = 0xc3,
145 		REG_PORTA_DIR           = 0xc4,
146 		REG_PORTB_DIR           = 0xc5,
147 		REG_PORTC_DIR           = 0xc6,
148 		REG_PORTD_DIR           = 0xc7,
149 		REG_INT_OPTION          = 0xc8,
150 		REG_DATA_ROM_WINDOW     = 0xc9,
151 		REG_ROM_BANK_SELECT     = 0xca,
152 		REG_RAM_BANK_SELECT     = 0xcb,
153 		REG_PORTA_OPTION        = 0xcc,
154 		REG_PORTB_OPTION        = 0xcd,
155 		REG_PORTC_OPTION        = 0xce,
156 		REG_PORTD_OPTION        = 0xcf,
157 		REG_AD_DATA             = 0xd0,
158 		REG_AD_CONTROL          = 0xd1,
159 		REG_TIMER_PRESCALE      = 0xd2,
160 		REG_TIMER_COUNT         = 0xd3,
161 		REG_TIMER_CONTROL       = 0xd4,
162 		REG_UART_DATA           = 0xd6,
163 		REG_UART_CONTROL        = 0xd7,
164 		REG_WATCHDOG            = 0xd8,
165 		REG_INT_POLARITY        = 0xda,
166 		REG_SPI_INT_DISABLE     = 0xdc,
167 		REG_SPI_DATA            = 0xdd,
168 		REG_ARTIMER_MODE        = 0xe5,
169 		REG_ARTIMER_ARCS0       = 0xe6,
170 		REG_ARTIMER_ARCS1       = 0xe7,
171 		REG_ARTIMER_RELOAD      = 0xe9,
172 		REG_ARTIMER_COMPARE     = 0xea,
173 		REG_ARTIMER_LOAD        = 0xeb,
174 		REG_A                   = 0xff
175 	};
176 
177 	enum
178 	{
179 		MODE_NORMAL,
180 		MODE_IRQ,
181 		MODE_NMI
182 	};
183 
184 	enum
185 	{
186 		VEC_IRQ0  = 0xff0,
187 		VEC_IRQ1  = 0xff2,
188 		VEC_IRQ2  = 0xff4,
189 		VEC_IRQ3  = 0xff6,
190 		VEC_NMI   = 0xffc,
191 		VEC_RESET = 0xffe
192 	};
193 
194 	enum
195 	{
196 		FLAG_C  = 0x01,
197 		FLAG_Z  = 0x02
198 	};
199 
200 	enum
201 	{
202 		PORT_A = 0,
203 		PORT_B,
204 		PORT_C,
205 		PORT_D
206 	};
207 
208 	// CPU registers
209 	uint8_t m_regs[0x100];
210 	uint8_t m_ram[64*2];
211 
212 	uint16_t m_pc;
213 	uint8_t m_mode;
214 	uint8_t m_prev_mode;
215 	uint8_t m_flags[3];
216 
217 	uint16_t m_stack[6];
218 	uint8_t m_stack_index;
219 
220 	int m_icount;
221 
222 	const address_space_config m_program_config;
223 	const address_space_config m_data_config;
224 
225 	devcb_write_line::array<6> m_porta_out;
226 	devcb_write_line::array<3> m_portb_out;
227 	devcb_write_line::array<4> m_portc_out;
228 	devcb_write_line::array<7> m_portd_out;
229 
230 	uint8_t m_port_dir[4];
231 	uint8_t m_port_option[4];
232 	uint8_t m_port_data[4];
233 	uint8_t m_port_pullup[4];
234 	uint8_t m_port_analog[4];
235 	uint8_t m_port_input[4];
236 	uint8_t m_port_irq_enable[4];
237 
238 	address_space *m_program;
239 	address_space *m_data;
240 
241 	// FIXME: memory banks do not currently work with internal maps.
242 	required_memory_bank m_rambank;
243 	required_memory_bank m_program_rombank;
244 	required_memory_bank m_data_rombank;
245 	required_memory_region m_rom;
246 };
247 
248 DECLARE_DEVICE_TYPE(ST6228, st6228_device)
249 
250 #endif // MAME_CPU_ST62XX_H
251