1 // license:BSD-3-Clause
2 // copyright-holders:Sandro Ronco
3 /**********************************************************************
4 
5     Sanyo LC8670
6 
7 **********************************************************************/
8 
9 #ifndef MAME_CPU_LC8670_LC8670_H
10 #define MAME_CPU_LC8670_LC8670_H
11 
12 #pragma once
13 
14 
15 //**************************************************************************
16 //  DEFINITION
17 //**************************************************************************
18 
19 // input ports
20 enum
21 {
22 	LC8670_PORT1,       // 8-bit I/O port
23 	LC8670_PORT3,       // 8-bit I/O port
24 	LC8670_PORT7        // 4-bit I port
25 };
26 
27 // external input lines
28 enum
29 {
30 	LC8670_EXT_INT0 = 0,    // P70
31 	LC8670_EXT_INT1,        // P71
32 	LC8670_EXT_INT2,        // P72
33 	LC8670_EXT_INT3         // P73
34 };
35 
36 //**************************************************************************
37 //  TYPE DEFINITIONS
38 //**************************************************************************
39 
40 #define LC8670_LCD_UPDATE(name) uint32_t name(bitmap_ind16 &bitmap, const rectangle &cliprect, uint8_t* vram, bool lcd_enabled, uint8_t stad)
41 
42 // ======================> lc8670_cpu_device
43 
44 class lc8670_cpu_device : public cpu_device
45 {
46 public:
47 	enum class clock_source
48 	{
49 		SUB = 0,
50 		RC,
51 		CF
52 	};
53 
54 	typedef device_delegate<uint32_t (bitmap_ind16 &bitmap, const rectangle &cliprect, uint8_t* vram, bool lcd_enabled, uint8_t stad)> lcd_update_delegate;
55 
56 	// construction/destruction
57 	lc8670_cpu_device(const machine_config &mconfig, const char *_tag, device_t *_owner, uint32_t _clock);
58 
59 	// public interfaces
60 	uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
61 
62 	// internal map handlers
63 	uint8_t regs_r(offs_t offset);
64 	void regs_w(offs_t offset, uint8_t data);
65 	uint8_t mram_r(offs_t offset);
66 	void mram_w(offs_t offset, uint8_t data);
67 	uint8_t xram_r(offs_t offset);
68 	void xram_w(offs_t offset, uint8_t data);
69 
70 	// configuration helpers
set_cpu_clock(clock_source source,uint32_t clock)71 	void set_cpu_clock(clock_source source, uint32_t clock) { m_clocks[unsigned(source)] = clock; }
set_cpu_clock(clock_source source,const XTAL & clock)72 	void set_cpu_clock(clock_source source, const XTAL &clock) { set_cpu_clock(source, clock.value()); }
73 	template <typename T, typename U, typename V>
set_clock_sources(T && sub_clock,U && rc_clock,V && cf_clock)74 	void set_clock_sources(T &&sub_clock, U &&rc_clock, V &&cf_clock)
75 	{
76 		set_cpu_clock(lc8670_cpu_device::clock_source::SUB, std::forward<T>(sub_clock));
77 		set_cpu_clock(lc8670_cpu_device::clock_source::RC, std::forward<U>(rc_clock));
78 		set_cpu_clock(lc8670_cpu_device::clock_source::CF, std::forward<V>(cf_clock));
79 	}
80 
bank_cb()81 	auto bank_cb() { return m_bankswitch_func.bind(); }
82 
set_lcd_update_cb(T &&...args)83 	template <typename... T> void set_lcd_update_cb(T &&... args) { m_lcd_update_func.set(std::forward<T>(args)...); }
84 
85 	void lc8670_internal_map(address_map &map);
86 protected:
87 	enum
88 	{
89 		LC8670_PC = 1,
90 		LC8670_SFR
91 	};
92 
93 	// device-level overrides
94 	virtual void device_start() override;
95 	virtual void device_reset() override;
96 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
97 
98 	// device_execute_interface overrides
execute_min_cycles()99 	virtual uint32_t execute_min_cycles() const noexcept override { return 1; }
execute_max_cycles()100 	virtual uint32_t execute_max_cycles() const noexcept override { return 7; }
execute_input_lines()101 	virtual uint32_t execute_input_lines() const noexcept override { return 4; }
102 	virtual void execute_run() override;
103 	virtual void execute_set_input(int inputnum, int state) override;
104 
105 	// device_state_interface overrides
106 	virtual void state_import(const device_state_entry &entry) override;
107 	virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
108 
109 	// device_memory_interface overrides
110 	virtual space_config_vector memory_space_config() const override;
111 
112 	// device_disasm_interface overrides
113 	virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
114 
115 private:
116 	// helpers
117 	inline uint8_t fetch();
118 	inline void  push(uint8_t data);
119 	inline uint8_t pop();
120 	inline uint8_t read_data(uint16_t offset);
121 	inline void write_data(uint16_t offset, uint8_t data);
122 	inline uint8_t read_data_latch(uint16_t offset);
123 	inline void write_data_latch(uint16_t offset, uint8_t data);
124 	inline void update_port1(uint8_t data);
125 	inline void set_pc(uint16_t new_pc);
126 	inline uint8_t get_data();
127 	inline uint16_t get_addr();
128 	inline void change_clock_source();
129 	inline void check_p_flag();
130 	inline void check_p3int();
131 	inline void set_irq_flag(int source);
132 	int decode_op(uint8_t op);
133 	void check_irqs();
134 	void timer0_prescaler_tick();
135 	void timer0_tick(bool ext_line = false);
136 	void timer1_tick();
137 	void base_timer_tick();
138 
139 	// opcodes handlers
140 	int op_nop();
141 	int op_br();
142 	int op_ld();
143 	int op_call();
144 	int op_callr();
145 	int op_brf();
146 	int op_st();
147 	int op_callf();
148 	int op_jmpf();
149 	int op_mov();
150 	int op_jmp();
151 	int op_mul();
152 	int op_be();
153 	int op_be_ri();
154 	int op_div();
155 	int op_bne();
156 	int op_bne_ri();
157 	int op_ldf();
158 	int op_stf();
159 	int op_dbnz();
160 	int op_bpc();
161 	int op_push();
162 	int op_inc();
163 	int op_bp();
164 	int op_pop();
165 	int op_dec();
166 	int op_bz();
167 	int op_add();
168 	int op_bn();
169 	int op_bnz();
170 	int op_addc();
171 	int op_ret();
172 	int op_sub();
173 	int op_not1();
174 	int op_reti();
175 	int op_subc();
176 	int op_ror();
177 	int op_ldc();
178 	int op_xch();
179 	int op_clr1();
180 	int op_rorc();
181 	int op_or();
182 	int op_rol();
183 	int op_and();
184 	int op_set1();
185 	int op_rolc();
186 	int op_xor();
187 
188 	address_space_config  m_program_config;
189 	address_space_config  m_data_config;
190 	address_space_config  m_io_config;
191 
192 	memory_access<16, 0, 0, ENDIANNESS_BIG>::cache m_cache;
193 	memory_access<16, 0, 0, ENDIANNESS_BIG>::specific m_program; // program space (ROM or flash)
194 	memory_access< 9, 0, 0, ENDIANNESS_BIG>::specific m_data;    // internal RAM/register
195 	memory_access< 8, 0, 0, ENDIANNESS_BIG>::specific m_io;      // I/O ports
196 
197 	// timers
198 	static const device_timer_id BASE_TIMER = 1;
199 	static const device_timer_id CLOCK_TIMER = 2;
200 	emu_timer *           m_basetimer;
201 	emu_timer *           m_clocktimer;
202 
203 	// internal state
204 	int                   m_icount;
205 	uint16_t              m_pc;
206 	uint16_t              m_ppc;
207 	uint8_t               m_op;
208 	uint8_t               m_sfr[0x80];            // special function registers
209 	uint8_t               m_mram[0x200];          // main RAM
210 	uint8_t               m_xram[0xc6];           // XRAM
211 	uint8_t               m_vtrbf[0x200];         // work RAM
212 	uint16_t              m_irq_flag;
213 	uint8_t               m_irq_lev;
214 	bool                  m_after_reti;
215 	uint8_t               m_p1_data;
216 	uint8_t               m_timer0_prescaler;
217 	uint8_t               m_timer0[2];
218 	uint8_t               m_timer1[2];
219 	uint8_t               m_timer1_comparator[2];
220 	uint8_t               m_base_timer[2];
221 	bool                  m_clock_changed;
222 	int                   m_input_lines[4];
223 
224 	// configuration
225 	uint32_t              m_clocks[3];       // clock sources
226 	devcb_write8          m_bankswitch_func; // bankswitch CB
227 	lcd_update_delegate   m_lcd_update_func; // LCD update CB
228 
229 	// interrupts vectors
230 	static const uint16_t s_irq_vectors[16];
231 
232 	// opcodes table
233 	typedef int (lc8670_cpu_device::*op_handler)();
234 	static const op_handler s_opcode_table[80];
235 };
236 
237 DECLARE_DEVICE_TYPE(LC8670, lc8670_cpu_device)
238 
239 #endif // MAME_CPU_LC8670_LC8670_H
240