1 // license:BSD-3-Clause
2 // copyright-holders:Wilbert Pol
3 #ifndef MAME_CPU_LR35902_LR35902_H
4 #define MAME_CPU_LR35902_LR35902_H
5 
6 #pragma once
7 
8 enum
9 {
10 	LR35902_PC=1, LR35902_SP, LR35902_A, LR35902_F, LR35902_B, LR35902_C, LR35902_D, LR35902_E, LR35902_H, LR35902_L,
11 	LR35902_IRQ_STATE,
12 	/* Pseudo registers to keep track of the interrupt statuses */
13 	LR35902_IE, LR35902_IF,
14 	/* Pseudo register to change and check the cpu operating speed */
15 	LR35902_SPEED
16 };
17 
18 
19 class lr35902_cpu_device : public cpu_device
20 {
21 public:
22 	// construction/destruction
23 	lr35902_cpu_device(const machine_config &mconfig, const char *_tag, device_t *_owner, uint32_t _clock);
24 
25 	// configuration helpers
timer_cb()26 	auto timer_cb() { return m_timer_func.bind(); }
27 
28 	// The GameBoy has a bug where OAM data gets corrupted if you inc/dec
29 	// a 16-bit register in the $fe** region.
30 	// note: oldval is in hiword, newval is in loword
incdec16_cb()31 	auto incdec16_cb() { return m_incdec16_func.bind(); }
32 
33 	// The first release of this CPU has a bug where the programcounter
34 	// is not incremented properly after an interrupt after the halt opcode.
35 	// This was fixed in a newer revision.
set_halt_bug(bool has_halt_bug)36 	void set_halt_bug(bool has_halt_bug) { m_has_halt_bug = has_halt_bug; }
37 
38 	uint8_t get_speed();
39 	void set_speed(uint8_t speed_request);
40 
get_ie()41 	inline uint8_t get_ie() { return m_IE; }
set_ie(uint8_t data)42 	inline void set_ie(uint8_t data) { m_IE = data; }
43 
get_if()44 	inline uint8_t get_if() { return m_IF; }
set_if(uint8_t data)45 	inline void set_if(uint8_t data) { m_IF = data; }
46 
dma_cycles_to_burn(uint16_t cycles_to_burn)47 	inline void dma_cycles_to_burn(uint16_t cycles_to_burn) { m_dma_cycles_to_burn += cycles_to_burn; }
48 
49 	// Needed for some gameboy operation which needs to read the results
50 	// of setting an input during the currently running timeslice.
51 	// Can become protected again once this core becomes cycle accurate.
52 	virtual void execute_set_input(int inputnum, int state) override;
53 
54 	enum
55 	{
56 		/* Interrupts */
57 		VBL_INT = 0,    /* V-Blank    */
58 		LCD_INT = 1,    /* LCD Status */
59 		TIM_INT = 2,    /* Timer      */
60 		SIO_INT = 3,    /* Serial I/O */
61 		EXT_INT = 4     /* Joypad     */
62 	};
63 
64 protected:
65 
66 	// device-level overrides
67 	virtual void device_start() override;
68 	virtual void device_reset() override;
69 
70 	// device_execute_interface overrides
execute_min_cycles()71 	virtual uint32_t execute_min_cycles() const noexcept override { return 1; }
execute_max_cycles()72 	virtual uint32_t execute_max_cycles() const noexcept override { return 16; }
execute_input_lines()73 	virtual uint32_t execute_input_lines() const noexcept override { return 5; }
74 	virtual void execute_run() override;
75 
76 	// device_memory_interface overrides
77 	virtual space_config_vector memory_space_config() const override;
78 
79 	// device_state_interface overrides
80 	virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
81 
82 	// device_disasm_interface overrides
83 	virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
84 
85 	inline void cycles_passed(uint8_t cycles);
86 	inline uint8_t mem_read_byte(uint16_t addr);
87 	inline void mem_write_byte(uint16_t addr, uint8_t data);
88 	inline uint16_t mem_read_word(uint16_t addr);
89 	inline void mem_write_word(uint16_t addr, uint16_t data);
90 	inline void check_interrupts();
91 
92 	address_space_config m_program_config;
93 
94 	uint8_t m_A;
95 	uint8_t m_F;
96 	uint8_t m_B;
97 	uint8_t m_C;
98 	uint8_t m_D;
99 	uint8_t m_E;
100 	uint8_t m_H;
101 	uint8_t m_L;
102 
103 	uint16_t m_SP;
104 	uint16_t m_PC;
105 
106 	/* Interrupt related */
107 	uint8_t m_IE;
108 	uint8_t m_IF;
109 	int m_irq_state;
110 	bool m_handle_ei_delay;
111 	address_space *m_program;
112 	int m_icount;
113 
114 	/* Fetch & execute related */
115 	int m_execution_state;
116 	uint8_t m_op;
117 
118 	/* Others */
119 	int m_gb_speed;
120 	int m_gb_speed_change_pending;
121 	int m_enable;
122 	bool m_has_halt_bug;
123 	uint32_t m_dma_cycles_to_burn;
124 	bool m_entering_halt;
125 
126 	/* Callbacks */
127 	devcb_write8 m_timer_func;
128 	devcb_write32 m_incdec16_func;
129 };
130 
131 DECLARE_DEVICE_TYPE(LR35902, lr35902_cpu_device)
132 
133 #endif // MAME_CPU_LR35902_LR35902_H
134