1 // license:BSD-3-Clause
2 // copyright-holders:Bryan McPhail
3 /*****************************************************************************
4 
5     h6280.h Portable Hu6280 emulator interface
6 
7     Copyright Bryan McPhail, mish@tendril.co.uk
8 
9     This source code is based (with permission!) on the 6502 emulator by
10     Juergen Buchmueller.  It is released as part of the Mame emulator project.
11     Let me know if you intend to use this code in any other project.
12 
13 ******************************************************************************/
14 
15 #ifndef MAME_CPU_H6280_H6280_H
16 #define MAME_CPU_H6280_H6280_H
17 
18 #pragma once
19 
20 #include "sound/c6280.h"
21 
22 #define H6280_LAZY_FLAGS  0
23 
24 //**************************************************************************
25 //  TYPE DEFINITIONS
26 //**************************************************************************
27 
28 // ======================> h6280_device
29 
30 // Used by core CPU interface
31 class h6280_device : public cpu_device, public device_mixer_interface
32 {
33 public:
34 	// construction/destruction
35 	h6280_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
36 
37 	// public interfaces
38 	void set_irq_line(int irqline, int state);
39 
40 	// configuration
port_in_cb()41 	auto port_in_cb() { return m_port_in_cb.bind(); } // K0-7 at Pinout
port_out_cb()42 	auto port_out_cb() { return m_port_out_cb.bind(); } // O0-7 at Pinout
43 
44 	// hack to fix music speed in some Data East games (core bug, external strapping, DE 45 customization or ???)
set_timer_scale(int scale)45 	void set_timer_scale(int scale) { m_timer_scale = scale; }
46 
47 	/* functions for use by the PSG and joypad port only! */
48 	uint8_t io_get_buffer();
49 	void io_set_buffer(uint8_t);
50 
51 protected:
52 	// register enumeration
53 	enum
54 	{
55 		H6280_PC = 1,
56 		H6280_S,
57 		H6280_P,
58 		H6280_A,
59 		H6280_X,
60 		H6280_Y,
61 		H6280_IRQ_MASK,
62 		H6280_TIMER_STATE,
63 		H6280_NMI_STATE,
64 		H6280_IRQ1_STATE,
65 		H6280_IRQ2_STATE,
66 		H6280_IRQT_STATE,
67 		H6280_MPR0,
68 		H6280_MPR1,
69 		H6280_MPR2,
70 		H6280_MPR3,
71 		H6280_MPR4,
72 		H6280_MPR5,
73 		H6280_MPR6,
74 		H6280_MPR7
75 	};
76 
77 	// device-level overrides
78 	virtual void device_add_mconfig(machine_config &config) override;
79 	virtual void device_start() override;
80 	virtual void device_reset() override;
81 	virtual void device_stop() override;
82 
83 	// device_execute_interface overrides
84 	virtual uint32_t execute_min_cycles() const noexcept override;
85 	virtual uint32_t execute_max_cycles() const noexcept override;
86 	virtual uint32_t execute_input_lines() const noexcept override;
87 	virtual bool execute_input_edge_triggered(int inputnum) const noexcept override;
88 	virtual void execute_run() override;
89 	virtual void execute_set_input(int inputnum, int state) override;
90 
91 	// device_memory_interface overrides
92 	virtual space_config_vector memory_space_config() const override;
93 	virtual bool memory_translate(int spacenum, int intention, offs_t &address) override;
94 
95 	// device_disasm_interface overrides
96 	virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
97 
98 	// device_state_interface overrides
99 	virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
100 
101 	// opcode accessors
102 	uint8_t program_read8(offs_t addr);
103 	void program_write8(offs_t addr, uint8_t data);
104 	uint8_t program_read8z(offs_t addr);
105 	void program_write8z(offs_t addr, uint8_t data);
106 	uint16_t program_read16(offs_t addr);
107 	uint16_t program_read16z(offs_t addr);
108 	void push(uint8_t value);
109 	void pull(uint8_t &value);
110 	uint8_t read_opcode();
111 	uint8_t read_opcode_arg();
112 
113 #undef PROTOTYPES
114 #define PROTOTYPES(prefix) \
115 	void prefix##_00(); void prefix##_01(); void prefix##_02(); void prefix##_03(); \
116 	void prefix##_04(); void prefix##_05(); void prefix##_06(); void prefix##_07(); \
117 	void prefix##_08(); void prefix##_09(); void prefix##_0a(); void prefix##_0b(); \
118 	void prefix##_0c(); void prefix##_0d(); void prefix##_0e(); void prefix##_0f(); \
119 	void prefix##_10(); void prefix##_11(); void prefix##_12(); void prefix##_13(); \
120 	void prefix##_14(); void prefix##_15(); void prefix##_16(); void prefix##_17(); \
121 	void prefix##_18(); void prefix##_19(); void prefix##_1a(); void prefix##_1b(); \
122 	void prefix##_1c(); void prefix##_1d(); void prefix##_1e(); void prefix##_1f(); \
123 	void prefix##_20(); void prefix##_21(); void prefix##_22(); void prefix##_23(); \
124 	void prefix##_24(); void prefix##_25(); void prefix##_26(); void prefix##_27(); \
125 	void prefix##_28(); void prefix##_29(); void prefix##_2a(); void prefix##_2b(); \
126 	void prefix##_2c(); void prefix##_2d(); void prefix##_2e(); void prefix##_2f(); \
127 	void prefix##_30(); void prefix##_31(); void prefix##_32(); void prefix##_33(); \
128 	void prefix##_34(); void prefix##_35(); void prefix##_36(); void prefix##_37(); \
129 	void prefix##_38(); void prefix##_39(); void prefix##_3a(); void prefix##_3b(); \
130 	void prefix##_3c(); void prefix##_3d(); void prefix##_3e(); void prefix##_3f(); \
131 	void prefix##_40(); void prefix##_41(); void prefix##_42(); void prefix##_43(); \
132 	void prefix##_44(); void prefix##_45(); void prefix##_46(); void prefix##_47(); \
133 	void prefix##_48(); void prefix##_49(); void prefix##_4a(); void prefix##_4b(); \
134 	void prefix##_4c(); void prefix##_4d(); void prefix##_4e(); void prefix##_4f(); \
135 	void prefix##_50(); void prefix##_51(); void prefix##_52(); void prefix##_53(); \
136 	void prefix##_54(); void prefix##_55(); void prefix##_56(); void prefix##_57(); \
137 	void prefix##_58(); void prefix##_59(); void prefix##_5a(); void prefix##_5b(); \
138 	void prefix##_5c(); void prefix##_5d(); void prefix##_5e(); void prefix##_5f(); \
139 	void prefix##_60(); void prefix##_61(); void prefix##_62(); void prefix##_63(); \
140 	void prefix##_64(); void prefix##_65(); void prefix##_66(); void prefix##_67(); \
141 	void prefix##_68(); void prefix##_69(); void prefix##_6a(); void prefix##_6b(); \
142 	void prefix##_6c(); void prefix##_6d(); void prefix##_6e(); void prefix##_6f(); \
143 	void prefix##_70(); void prefix##_71(); void prefix##_72(); void prefix##_73(); \
144 	void prefix##_74(); void prefix##_75(); void prefix##_76(); void prefix##_77(); \
145 	void prefix##_78(); void prefix##_79(); void prefix##_7a(); void prefix##_7b(); \
146 	void prefix##_7c(); void prefix##_7d(); void prefix##_7e(); void prefix##_7f(); \
147 	void prefix##_80(); void prefix##_81(); void prefix##_82(); void prefix##_83(); \
148 	void prefix##_84(); void prefix##_85(); void prefix##_86(); void prefix##_87(); \
149 	void prefix##_88(); void prefix##_89(); void prefix##_8a(); void prefix##_8b(); \
150 	void prefix##_8c(); void prefix##_8d(); void prefix##_8e(); void prefix##_8f(); \
151 	void prefix##_90(); void prefix##_91(); void prefix##_92(); void prefix##_93(); \
152 	void prefix##_94(); void prefix##_95(); void prefix##_96(); void prefix##_97(); \
153 	void prefix##_98(); void prefix##_99(); void prefix##_9a(); void prefix##_9b(); \
154 	void prefix##_9c(); void prefix##_9d(); void prefix##_9e(); void prefix##_9f(); \
155 	void prefix##_a0(); void prefix##_a1(); void prefix##_a2(); void prefix##_a3(); \
156 	void prefix##_a4(); void prefix##_a5(); void prefix##_a6(); void prefix##_a7(); \
157 	void prefix##_a8(); void prefix##_a9(); void prefix##_aa(); void prefix##_ab(); \
158 	void prefix##_ac(); void prefix##_ad(); void prefix##_ae(); void prefix##_af(); \
159 	void prefix##_b0(); void prefix##_b1(); void prefix##_b2(); void prefix##_b3(); \
160 	void prefix##_b4(); void prefix##_b5(); void prefix##_b6(); void prefix##_b7(); \
161 	void prefix##_b8(); void prefix##_b9(); void prefix##_ba(); void prefix##_bb(); \
162 	void prefix##_bc(); void prefix##_bd(); void prefix##_be(); void prefix##_bf(); \
163 	void prefix##_c0(); void prefix##_c1(); void prefix##_c2(); void prefix##_c3(); \
164 	void prefix##_c4(); void prefix##_c5(); void prefix##_c6(); void prefix##_c7(); \
165 	void prefix##_c8(); void prefix##_c9(); void prefix##_ca(); void prefix##_cb(); \
166 	void prefix##_cc(); void prefix##_cd(); void prefix##_ce(); void prefix##_cf(); \
167 	void prefix##_d0(); void prefix##_d1(); void prefix##_d2(); void prefix##_d3(); \
168 	void prefix##_d4(); void prefix##_d5(); void prefix##_d6(); void prefix##_d7(); \
169 	void prefix##_d8(); void prefix##_d9(); void prefix##_da(); void prefix##_db(); \
170 	void prefix##_dc(); void prefix##_dd(); void prefix##_de(); void prefix##_df(); \
171 	void prefix##_e0(); void prefix##_e1(); void prefix##_e2(); void prefix##_e3(); \
172 	void prefix##_e4(); void prefix##_e5(); void prefix##_e6(); void prefix##_e7(); \
173 	void prefix##_e8(); void prefix##_e9(); void prefix##_ea(); void prefix##_eb(); \
174 	void prefix##_ec(); void prefix##_ed(); void prefix##_ee(); void prefix##_ef(); \
175 	void prefix##_f0(); void prefix##_f1(); void prefix##_f2(); void prefix##_f3(); \
176 	void prefix##_f4(); void prefix##_f5(); void prefix##_f6(); void prefix##_f7(); \
177 	void prefix##_f8(); void prefix##_f9(); void prefix##_fa(); void prefix##_fb(); \
178 	void prefix##_fc(); void prefix##_fd(); void prefix##_fe(); void prefix##_ff();
179 
180 	PROTOTYPES(op)
181 
182 	uint32_t translated(uint16_t addr);
183 	void h6280_cycles(int cyc);
184 	void set_nz(uint8_t n);
185 	void clear_t();
186 	void do_interrupt(uint16_t vector);
187 	void check_and_take_irq_lines();
188 	void check_irq_lines();
189 	void check_vdc_vce_penalty(uint16_t addr);
190 	void bra(bool cond);
191 	void ea_zpg();
192 	void ea_tflg();
193 	void ea_zpx();
194 	void ea_zpy();
195 	void ea_abs();
196 	void ea_abx();
197 	void ea_aby();
198 	void ea_zpi();
199 	void ea_idx();
200 	void ea_idy();
201 	void ea_ind();
202 	void ea_iax();
203 	uint8_t rd_imm();
204 	uint8_t rd_zpg();
205 	uint8_t rd_zpx();
206 	uint8_t rd_zpy();
207 	uint8_t rd_abs();
208 	uint8_t rd_abx();
209 	uint8_t rd_aby();
210 	uint8_t rd_zpi();
211 	uint8_t rd_idx();
212 	uint8_t rd_idy();
213 	uint8_t rd_tfl();
214 	void wr_zpg(uint8_t tmp);
215 	void wr_zpx(uint8_t tmp);
216 	void wr_zpy(uint8_t tmp);
217 	void wr_abs(uint8_t tmp);
218 	void wr_abx(uint8_t tmp);
219 	void wr_aby(uint8_t tmp);
220 	void wr_zpi(uint8_t tmp);
221 	void wr_idx(uint8_t tmp);
222 	void wr_idy(uint8_t tmp);
223 	void wb_ea(uint8_t tmp);
224 	void wb_eaz(uint8_t tmp);
225 	void compose_p(uint8_t set, uint8_t clr);
226 	void tadc(uint8_t tmp);
227 	void adc(uint8_t tmp);
228 	void tand(uint8_t tmp);
229 	void and_a(uint8_t tmp);
230 	uint8_t asl(uint8_t tmp);
231 	void bbr(int bit, uint8_t tmp);
232 	void bbs(int bit, uint8_t tmp);
233 	void bcc();
234 	void bcs();
235 	void beq();
236 	void bit(uint8_t tmp);
237 	void bmi();
238 	void bne();
239 	void bpl();
240 	void brk();
241 	void bsr();
242 	void bvc();
243 	void bvs();
244 	void cla();
245 	void clc();
246 	void cld();
247 	void cli();
248 	void clv();
249 	void clx();
250 	void cly();
251 	void cmp(uint8_t tmp);
252 	void cpx(uint8_t tmp);
253 	void cpy(uint8_t tmp);
254 	uint8_t dec(uint8_t tmp);
255 	void dex();
256 	void dey();
257 	void teor(uint8_t tmp);
258 	void eor(uint8_t tmp);
259 	uint8_t inc(uint8_t tmp);
260 	void inx();
261 	void iny();
262 	void jmp();
263 	void jsr();
264 	void lda(uint8_t tmp);
265 	void ldx(uint8_t tmp);
266 	void ldy(uint8_t tmp);
267 	uint8_t lsr(uint8_t tmp);
268 	void nop();
269 	void tora(uint8_t tmp);
270 	void ora(uint8_t tmp);
271 	void pha();
272 	void php();
273 	void phx();
274 	void phy();
275 	void pla();
276 	void plp();
277 	void plx();
278 	void ply();
279 	uint8_t rmb(int bit, uint8_t tmp);
280 	uint8_t rol(uint8_t tmp);
281 	uint8_t ror(uint8_t tmp);
282 	void rti();
283 	void rts();
284 	void sax();
285 	void say();
286 	void tsbc(uint8_t tmp);
287 	void sbc(uint8_t tmp);
288 	void sec();
289 	void sed();
290 	void sei();
291 	void set();
292 	uint8_t smb(int bit, uint8_t tmp);
293 	void st0(uint8_t tmp);
294 	void st1(uint8_t tmp);
295 	void st2(uint8_t tmp);
296 	uint8_t sta();
297 	uint8_t stx();
298 	uint8_t sty();
299 	uint8_t stz();
300 	void sxy();
301 	void tai();
302 	void tam(uint8_t tmp);
303 	void tax();
304 	void tay();
305 	void tdd();
306 	void tia();
307 	void tii();
308 	void tin();
309 	void tma(uint8_t tmp);
310 	uint8_t trb(uint8_t tmp);
311 	uint8_t tsb(uint8_t tmp);
312 	void tsx();
313 	void tst(uint8_t imm, uint8_t tmp);
314 	void txa();
315 	void txs();
316 	void tya();
317 	void csh();
318 	void csl();
319 
320 	enum
321 	{
322 		H6280_RESET_VEC = 0xfffe,
323 		H6280_NMI_VEC =  0xfffc,
324 		H6280_TIMER_VEC = 0xfffa,
325 		H6280_IRQ1_VEC = 0xfff8,
326 		H6280_IRQ2_VEC = 0xfff6 /* Aka BRK vector */
327 	};
328 
329 	// address spaces
330 	const address_space_config m_program_config;
331 	const address_space_config m_io_config;
332 
333 	// CPU registers
334 	PAIR  m_ppc;            /* previous program counter */
335 	PAIR  m_pc;             /* program counter */
336 	PAIR  m_sp;             /* stack pointer (always 100 - 1FF) */
337 	PAIR  m_zp;             /* zero page address */
338 	PAIR  m_ea;             /* effective address */
339 	uint8_t m_a;              /* Accumulator */
340 	uint8_t m_x;              /* X index register */
341 	uint8_t m_y;              /* Y index register */
342 	uint8_t m_p;              /* Processor status */
343 	uint8_t m_mmr[8];         /* Hu6280 memory mapper registers */
344 	uint8_t m_irq_mask;       /* interrupt enable/disable */
345 	uint8_t m_timer_status;   /* timer status */
346 	uint8_t m_timer_ack;      /* timer acknowledge */
347 	uint8_t m_clocks_per_cycle; /* 4 = low speed mode, 1 = high speed mode */
348 	int32_t m_timer_value;    /* timer interrupt */
349 	int32_t m_timer_load;     /* reload value */
350 	uint8_t m_nmi_state;
351 	uint8_t m_irq_state[3];
352 	uint8_t m_irq_pending;
353 #if H6280_LAZY_FLAGS
354 	int32_t m_nz;         /* last value (lazy N and Z flag) */
355 #endif
356 	uint8_t m_io_buffer;  /* last value written to the PSG, timer, and interrupt pages */
357 
358 	// internal registers
359 	void internal_map(address_map &map);
360 	uint8_t irq_status_r(offs_t offset);
361 	void irq_status_w(offs_t offset, uint8_t data);
362 
363 	uint8_t timer_r();
364 	void timer_w(offs_t offset, uint8_t data);
365 
366 	uint8_t port_r();
367 	void port_w(uint8_t data);
368 
369 	uint8_t io_buffer_r();
370 	void psg_w(offs_t offset, uint8_t data);
371 
372 	devcb_read8 m_port_in_cb;
373 	devcb_write8 m_port_out_cb;
374 
375 	required_device<c6280_device> m_psg;
376 
377 	// other internal states
378 	int m_icount;
379 
380 	uint8_t m_timer_scale;
381 
382 	// address spaces
383 	memory_access<21, 0, 0, ENDIANNESS_LITTLE>::cache m_cache;
384 	memory_access<21, 0, 0, ENDIANNESS_LITTLE>::specific m_program;
385 	memory_access< 2, 0, 0, ENDIANNESS_LITTLE>::specific m_io;
386 
387 	typedef void (h6280_device::*ophandler)();
388 
389 	ophandler m_opcode[256];
390 
391 	static const ophandler s_opcodetable[256];
392 };
393 
394 DECLARE_DEVICE_TYPE(H6280, h6280_device)
395 
396 #endif // MAME_CPU_H6280_H6280_H
397