1 // license:BSD-3-Clause
2 // copyright-holders:Olivier Galibert
3 /***************************************************************************
4 
5     h8.h
6 
7     H8-300 base cpu emulation
8 
9 
10 ***************************************************************************/
11 
12 #ifndef MAME_CPU_H8_H8_H
13 #define MAME_CPU_H8_H8_H
14 
15 #pragma once
16 
17 class h8_dma_device;
18 class h8_dtc_device;
19 struct h8_dma_state;
20 struct h8_dtc_state;
21 
22 class h8_device : public cpu_device {
23 public:
24 	enum {
25 		// digital I/O ports
26 		// ports 4-B are valid on 16-bit H8/3xx, ports 1-9 on 8-bit H8/3xx
27 		// H8S/2394 has 12 ports named 1-6 and A-G
28 		PORT_1,  // 0
29 		PORT_2,  // 1
30 		PORT_3,  // 2
31 		PORT_4,  // 3
32 		PORT_5,  // 4
33 		PORT_6,  // 5
34 		PORT_7,  // 6
35 		PORT_8,  // 7
36 		PORT_9,  // 8
37 		PORT_A,  // 9
38 		PORT_B,  // A
39 		PORT_C,  // B
40 		PORT_D,  // C
41 		PORT_E,  // D
42 		PORT_F,  // E
43 		PORT_G,  // F
44 
45 		// analog inputs
46 		ADC_0,
47 		ADC_1,
48 		ADC_2,
49 		ADC_3,
50 		ADC_4,
51 		ADC_5,
52 		ADC_6,
53 		ADC_7
54 	};
55 
56 	enum {
57 		STATE_RESET              = 0x10000,
58 		STATE_IRQ                = 0x10001,
59 		STATE_TRACE              = 0x10002,
60 		STATE_DMA                = 0x10003,
61 		STATE_DTC                = 0x10004,
62 		STATE_DTC_VECTOR         = 0x10005,
63 		STATE_DTC_WRITEBACK      = 0x10006
64 	};
65 
66 	void internal_update();
67 	void set_irq(int irq_vector, int irq_level, bool irq_nmi);
68 	bool trigger_dma(int vector);
69 	void set_current_dma(h8_dma_state *state);
70 	void set_current_dtc(h8_dtc_state *state);
71 	void request_state(int state);
access_is_dma()72 	bool access_is_dma() const { return inst_state == STATE_DMA || inst_state == STATE_DTC; }
73 
74 protected:
75 	enum {
76 		F_I  = 0x80,
77 		F_UI = 0x40,
78 		F_H  = 0x20,
79 		F_U  = 0x10,
80 		F_N  = 0x08,
81 		F_Z  = 0x04,
82 		F_V  = 0x02,
83 		F_C  = 0x01,
84 
85 		EXR_T  = 0x80,
86 		EXR_NC = 0x78,
87 		EXR_I  = 0x07
88 	};
89 
90 	h8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor map_delegate);
91 
92 	// device-level overrides
93 	virtual void device_config_complete() override;
94 	virtual void device_start() override;
95 	virtual void device_reset() override;
96 
97 	// device_execute_interface overrides
98 	virtual uint32_t execute_min_cycles() const noexcept override;
99 	virtual uint32_t execute_max_cycles() const noexcept override;
100 	virtual uint32_t execute_input_lines() const noexcept override;
101 	virtual bool execute_input_edge_triggered(int inputnum) const noexcept override;
102 	virtual void execute_run() override;
103 
104 	// device_memory_interface overrides
105 	virtual space_config_vector memory_space_config() const override;
106 
107 	// device_state_interface overrides
108 	virtual void state_import(const device_state_entry &entry) override;
109 	virtual void state_export(const device_state_entry &entry) override;
110 	virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
111 
112 	// device_disasm_interface overrides
113 	virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
114 
115 	address_space_config program_config, io_config;
116 	memory_access<32, 1, 0, ENDIANNESS_BIG>::cache cache;
117 	memory_access<32, 1, 0, ENDIANNESS_BIG>::specific program;
118 	memory_access<16, 1, -1, ENDIANNESS_BIG>::specific io;
119 	h8_dma_device *dma_device;
120 	h8_dtc_device *dtc_device;
121 	h8_dma_state *current_dma;
122 	h8_dtc_state *current_dtc;
123 
124 	uint32_t  PPC;                    /* previous program counter */
125 	uint32_t  NPC;                    /* next start-of-instruction program counter */
126 	uint32_t  PC;                     /* program counter */
127 	uint16_t  PIR;                    /* Prefetched word */
128 	uint16_t  IR[5];                  /* Fetched instruction */
129 	uint16_t  R[16];                  /* Rn (0-7), En (8-15, h8-300h+) */
130 	uint8_t   EXR;                    /* Interrupt/trace register (h8s/2000+) */
131 	uint8_t   CCR;                    /* Condition-code register */
132 	int64_t   MAC;                    /* Multiply accumulator (h8s/2600+) */
133 	uint8_t   MACF;                   /* MAC flags (h8s/2600+) */
134 	uint32_t  TMP1, TMP2;
135 	uint32_t  TMPR;                   /* For debugger ER register import */
136 
137 	bool has_exr, has_trace, supports_advanced, mode_advanced, mode_a20, mac_saturating;
138 
139 	int inst_state, inst_substate, requested_state;
140 	int icount, bcount, count_before_instruction_step;
141 	int irq_vector, taken_irq_vector;
142 	int irq_level, taken_irq_level;
143 	bool irq_required, irq_nmi;
144 
145 	virtual void do_exec_full();
146 	virtual void do_exec_partial();
147 	static void add_event(uint64_t &event_time, uint64_t new_event);
148 	virtual bool exr_in_stack() const;
149 	virtual void update_irq_filter() = 0;
150 	virtual void interrupt_taken() = 0;
151 	virtual void internal_update(uint64_t current_time) = 0;
152 	void recompute_bcount(uint64_t event_time);
153 	virtual int trace_setup();
154 	virtual int trapa_setup();
155 	virtual void irq_setup() = 0;
156 
157 	uint16_t read16i(uint32_t adr);
158 	uint16_t fetch();
fetch(int slot)159 	inline void fetch(int slot) { IR[slot] = fetch(); }
160 	uint8_t read8(uint32_t adr);
161 	void write8(uint32_t adr, uint8_t data);
162 	uint16_t read16(uint32_t adr);
163 	void write16(uint32_t adr, uint16_t data);
164 	void internal(int cycles);
prefetch()165 	inline void prefetch() { prefetch_start(); prefetch_done(); }
prefetch_noirq()166 	inline void prefetch_noirq() { prefetch_start(); prefetch_done_noirq(); }
prefetch_noirq_notrace()167 	inline void prefetch_noirq_notrace() { prefetch_start(); prefetch_done_noirq_notrace(); }
prefetch_start()168 	void prefetch_start() { NPC = PC & 0xffffff; PIR = fetch(); }
prefetch_switch(uint32_t pc,uint16_t ir)169 	void prefetch_switch(uint32_t pc, uint16_t ir) { NPC = pc & 0xffffff; PC = pc+2; PIR = ir; }
170 	void prefetch_done();
171 	void prefetch_done_noirq();
172 	void prefetch_done_noirq_notrace();
173 	void illegal();
174 
175 	uint8_t do_addx8(uint8_t a, uint8_t b);
176 	uint8_t do_subx8(uint8_t a, uint8_t b);
177 
178 	uint8_t do_inc8(uint8_t a, uint8_t b);
179 	uint16_t do_inc16(uint16_t a, uint16_t b);
180 	uint32_t do_inc32(uint32_t a, uint32_t b);
181 
182 	uint8_t do_add8(uint8_t a, uint8_t b);
183 	uint16_t do_add16(uint16_t a, uint16_t b);
184 	uint32_t do_add32(uint32_t a, uint32_t b);
185 
186 	uint8_t do_dec8(uint8_t a, uint8_t b);
187 	uint16_t do_dec16(uint16_t a, uint16_t b);
188 	uint32_t do_dec32(uint32_t a, uint32_t b);
189 
190 	uint8_t do_sub8(uint8_t a, uint8_t b);
191 	uint16_t do_sub16(uint16_t a, uint16_t b);
192 	uint32_t do_sub32(uint32_t a, uint32_t b);
193 
194 	uint8_t do_shal8(uint8_t v);
195 	uint16_t do_shal16(uint16_t v);
196 	uint32_t do_shal32(uint32_t v);
197 
198 	uint8_t do_shar8(uint8_t v);
199 	uint16_t do_shar16(uint16_t v);
200 	uint32_t do_shar32(uint32_t v);
201 
202 	uint8_t do_shll8(uint8_t v);
203 	uint16_t do_shll16(uint16_t v);
204 	uint32_t do_shll32(uint32_t v);
205 
206 	uint8_t do_shlr8(uint8_t v);
207 	uint16_t do_shlr16(uint16_t v);
208 	uint32_t do_shlr32(uint32_t v);
209 
210 	uint8_t do_rotl8(uint8_t v);
211 	uint16_t do_rotl16(uint16_t v);
212 	uint32_t do_rotl32(uint32_t v);
213 
214 	uint8_t do_rotr8(uint8_t v);
215 	uint16_t do_rotr16(uint16_t v);
216 	uint32_t do_rotr32(uint32_t v);
217 
218 	uint8_t do_rotxl8(uint8_t v);
219 	uint16_t do_rotxl16(uint16_t v);
220 	uint32_t do_rotxl32(uint32_t v);
221 
222 	uint8_t do_rotxr8(uint8_t v);
223 	uint16_t do_rotxr16(uint16_t v);
224 	uint32_t do_rotxr32(uint32_t v);
225 
226 	uint8_t do_shal2_8(uint8_t v);
227 	uint16_t do_shal2_16(uint16_t v);
228 	uint32_t do_shal2_32(uint32_t v);
229 
230 	uint8_t do_shar2_8(uint8_t v);
231 	uint16_t do_shar2_16(uint16_t v);
232 	uint32_t do_shar2_32(uint32_t v);
233 
234 	uint8_t do_shll2_8(uint8_t v);
235 	uint16_t do_shll2_16(uint16_t v);
236 	uint32_t do_shll2_32(uint32_t v);
237 
238 	uint8_t do_shlr2_8(uint8_t v);
239 	uint16_t do_shlr2_16(uint16_t v);
240 	uint32_t do_shlr2_32(uint32_t v);
241 
242 	uint8_t do_rotl2_8(uint8_t v);
243 	uint16_t do_rotl2_16(uint16_t v);
244 	uint32_t do_rotl2_32(uint32_t v);
245 
246 	uint8_t do_rotr2_8(uint8_t v);
247 	uint16_t do_rotr2_16(uint16_t v);
248 	uint32_t do_rotr2_32(uint32_t v);
249 
250 	uint8_t do_rotxl2_8(uint8_t v);
251 	uint16_t do_rotxl2_16(uint16_t v);
252 	uint32_t do_rotxl2_32(uint32_t v);
253 
254 	uint8_t do_rotxr2_8(uint8_t v);
255 	uint16_t do_rotxr2_16(uint16_t v);
256 	uint32_t do_rotxr2_32(uint32_t v);
257 
258 	void set_nzv8(uint8_t v);
259 	void set_nzv16(uint16_t v);
260 	void set_nzv32(uint32_t v);
261 
262 	void set_nz16(uint16_t v);
263 	void set_nz32(uint32_t v);
264 
r8_w(int reg,uint8_t val)265 	inline void r8_w(int reg, uint8_t val) {
266 		if(reg & 8)
267 			R[reg & 7] = (R[reg & 7] & 0xff00) | val;
268 		else
269 			R[reg & 7] = (R[reg & 7] & 0xff) | (val << 8);
270 	}
271 
r8_r(int reg)272 	inline uint8_t r8_r(int reg) {
273 		if(reg & 8)
274 			return R[reg & 7];
275 		else
276 			return R[reg & 7] >> 8;
277 	}
278 
279 	// Note that the decode is so that there's no risk of a h8-300
280 	// hitting the E registers even with the 0xf mask - the
281 	// instruction would not be called in the first place
282 	//
283 	// Well, except for the instructions where the h8-300 mode is r16
284 	// and the h8-300h is r32 of course, we have to be careful to mask
285 	// in h8.lst there if the top bit is 1.
286 
r16_w(int reg,uint16_t val)287 	inline void r16_w(int reg, uint16_t val) { R[reg & 0xf] = val; }
r16_r(int reg)288 	inline uint16_t r16_r(int reg) { return R[reg & 0xf]; }
289 
290 #define O(o) void o ## _full(); void o ## _partial()
291 	O(add_b_imm8_r8u); O(add_b_r8h_r8l); O(add_w_imm16_r16l); O(add_w_r16h_r16l);
292 	O(adds_l_one_r16l); O(adds_l_two_r16l); O(adds_l_four_r16l);
293 	O(addx_b_imm8_r8u); O(addx_b_r8h_r8l);
294 	O(and_b_imm8_r8u); O(and_w_imm16_r16l); O(and_b_r8h_r8l);
295 	O(andc_imm8_ccr);
296 	O(band_imm3_abs16); O(band_imm3_abs8); O(band_imm3_r8l); O(band_imm3_r16ihh);
297 	O(bcc_rel8);
298 	O(bclr_imm3_abs16); O(bclr_imm3_abs8); O(bclr_imm3_r8l); O(bclr_imm3_r16ihh); O(bclr_r8h_abs16); O(bclr_r8h_abs8); O(bclr_r8h_r8l); O(bclr_r8h_r16ihh);
299 	O(bcs_rel8);
300 	O(beq_rel8);
301 	O(bf_rel8);
302 	O(bge_rel8);
303 	O(bgt_rel8);
304 	O(bhi_rel8);
305 	O(biand_imm3_abs16); O(biand_imm3_abs8); O(biand_imm3_r8l); O(biand_imm3_r16ihh);
306 	O(bild_imm3_abs16); O(bild_imm3_abs8); O(bild_imm3_r8l); O(bild_imm3_r16ihh);
307 	O(bior_imm3_abs16); O(bior_imm3_abs8); O(bior_imm3_r8l); O(bior_imm3_r16ihh);
308 	O(bist_imm3_abs16); O(bist_imm3_abs8); O(bist_imm3_r8l); O(bist_imm3_r16ihh);
309 	O(bixor_imm3_abs16); O(bixor_imm3_abs8); O(bixor_imm3_r8l); O(bixor_imm3_r16ihh);
310 	O(bld_imm3_abs16); O(bld_imm3_abs8); O(bld_imm3_r8l); O(bld_imm3_r16ihh);
311 	O(ble_rel8);
312 	O(bls_rel8);
313 	O(blt_rel8);
314 	O(bmi_rel8);
315 	O(bne_rel8);
316 	O(bnot_imm3_abs16); O(bnot_imm3_abs8); O(bnot_imm3_r8l); O(bnot_imm3_r16ihh);
317 	O(bnot_r8h_abs16); O(bnot_r8h_abs8); O(bnot_r8h_r8l); O(bnot_r8h_r16ihh);
318 	O(bor_imm3_abs16); O(bor_imm3_abs8); O(bor_imm3_r8l); O(bor_imm3_r16ihh);
319 	O(bpl_rel8);
320 	O(bset_imm3_abs16); O(bset_imm3_abs8); O(bset_imm3_r8l); O(bset_imm3_r16ihh);
321 	O(bset_r8h_abs16); O(bset_r8h_abs8); O(bset_r8h_r8l); O(bset_r8h_r16ihh);
322 	O(bsr_rel8);
323 	O(bst_imm3_abs16); O(bst_imm3_abs8); O(bst_imm3_r8l); O(bst_imm3_r16ihh);
324 	O(bt_rel8);
325 	O(btst_imm3_abs16); O(btst_imm3_abs8); O(btst_imm3_r8l); O(btst_imm3_r16ihh);
326 	O(btst_r8h_abs16); O(btst_r8h_abs8); O(btst_r8h_r8l); O(btst_r8h_r16ihh);
327 	O(bvc_rel8);
328 	O(bvs_rel8);
329 	O(bxor_imm3_abs16); O(bxor_imm3_abs8); O(bxor_imm3_r8l); O(bxor_imm3_r16ihh);
330 	O(cmp_b_imm8_r8u); O(cmp_b_r8h_r8l); O(cmp_w_imm16_r16l); O(cmp_w_r16h_r16l);
331 	O(daa_b_r8l);
332 	O(das_b_r8l);
333 	O(dec_b_one_r8l); O(dec_w_one_r16l); O(dec_w_two_r16l);
334 	O(divxu_b_r8h_r16l);
335 	O(eepmov_b);
336 	O(inc_b_one_r8l);
337 	O(jmp_abs8i); O(jmp_abs16e);
338 	O(jsr_abs8i); O(jsr_abs16e); O(jsr_r16h);
339 	O(ldc_imm8_ccr); O(ldc_r8l_ccr);
340 	O(mov_b_abs16_r8l); O(mov_b_abs8_r8u); O(mov_b_imm8_r8u); O(mov_b_r8h_r8l); O(mov_b_r8l_abs16); O(mov_b_r8u_abs8); O(mov_b_r16ih_r8l); O(mov_b_r8l_r16ih); O(mov_b_r16d16h_r8l); O(mov_b_r8l_r16d16h); O(mov_b_r16ph_r8l); O(mov_b_r8l_pr16h);
341 	O(mov_w_abs16_r16l); O(mov_w_imm16_r16l); O(mov_w_r16h_r16l); O(mov_w_r16l_abs16); O(mov_w_r16ih_r16l); O(mov_w_r16l_r16ih); O(mov_w_r16ph_r16l); O(mov_w_r16l_pr16h); O(mov_w_r16l_r16d16h); O(mov_w_r16d16h_r16l);
342 	O(movfpe_abs16_r8l);
343 	O(movtpe_r8l_abs16);
344 	O(mulxu_b_r8h_r16l);
345 	O(neg_b_r8l);
346 	O(nop);
347 	O(not_b_r8l);
348 	O(or_b_imm8_r8u); O(or_b_r8h_r8l); O(or_w_imm16_r16l);
349 	O(orc_imm8_ccr);
350 	O(rotl_b_r8l);
351 	O(rotr_b_r8l);
352 	O(rotxl_b_r8l);
353 	O(rotxr_b_r8l);
354 	O(rte);
355 	O(rts);
356 	O(shal_b_r8l);
357 	O(shar_b_r8l);
358 	O(shll_b_r8l);
359 	O(shlr_b_r8l);
360 	O(sleep);
361 	O(stc_ccr_r8l); O(stc_exr_r8l);
362 	O(sub_b_r8h_r8l); O(sub_w_imm16_r16l); O(sub_w_r16h_r16l);
363 	O(subs_l_one_r16l); O(subs_l_two_r16l); O(subs_l_four_r16l);
364 	O(subx_b_imm8_r8u); O(subx_b_r8h_r8l);
365 	O(xor_b_imm8_r8u); O(xor_b_r8h_r8l); O(xor_w_imm16_r16l);
366 	O(xorc_imm8_ccr);
367 
368 	O(dispatch_0100);
369 	O(dispatch_01007800);
370 	O(dispatch_0110);
371 	O(dispatch_0120);
372 	O(dispatch_0130);
373 	O(dispatch_0140);
374 	O(dispatch_01407800);
375 	O(dispatch_01407880);
376 	O(dispatch_0141);
377 	O(dispatch_01417800);
378 	O(dispatch_01417880);
379 	O(dispatch_0160);
380 	O(dispatch_01c0);
381 	O(dispatch_01d0);
382 	O(dispatch_01e0);
383 	O(dispatch_01f0);
384 	O(dispatch_6a10);
385 	O(dispatch_6a18);
386 	O(dispatch_6a30);
387 	O(dispatch_6a38);
388 	O(dispatch_7800);
389 	O(dispatch_7b5c);
390 	O(dispatch_7bd4);
391 	O(dispatch_7c00);
392 	O(dispatch_7d00);
393 	O(dispatch_7e00);
394 	O(dispatch_7f00);
395 
396 	O(state_reset);
397 	O(state_irq);
398 	O(state_dma);
399 #undef O
400 };
401 
402 enum {
403 	H8_PC  = 1,
404 	H8_R0,
405 	H8_R1,
406 	H8_R2,
407 	H8_R3,
408 	H8_R4,
409 	H8_R5,
410 	H8_R6,
411 	H8_R7,
412 	H8_E0,
413 	H8_E1,
414 	H8_E2,
415 	H8_E3,
416 	H8_E4,
417 	H8_E5,
418 	H8_E6,
419 	H8_E7,
420 	H8_CCR,
421 	H8_EXR
422 };
423 
424 #endif // MAME_CPU_H8_H8_H
425