1 // license:BSD-3-Clause
2 // copyright-holders:smf
3 /*
4  * PlayStation CPU emulator
5  *
6  * Copyright 2003-2017 smf
7  *
8  */
9 
10 #ifndef MAME_CPU_PSX_PSX_H
11 #define MAME_CPU_PSX_PSX_H
12 
13 #pragma once
14 
15 #include "machine/ram.h"
16 #include "dma.h"
17 #include "gte.h"
18 #include "irq.h"
19 #include "sio.h"
20 #include "psxdasm.h"
21 
22 //**************************************************************************
23 //  CONSTANTS
24 //**************************************************************************
25 
26 // interrupts
27 
28 enum
29 {
30 	PSXCPU_IRQ0 = 0,
31 	PSXCPU_IRQ1,
32 	PSXCPU_IRQ2,
33 	PSXCPU_IRQ3,
34 	PSXCPU_IRQ4,
35 	PSXCPU_IRQ5,
36 };
37 
38 // register enumeration
39 
40 enum
41 {
42 	PSXCPU_PC = 1,
43 	PSXCPU_DELAYV, PSXCPU_DELAYR,
44 	PSXCPU_HI, PSXCPU_LO,
45 	PSXCPU_BIU,
46 	PSXCPU_R0, PSXCPU_R1,
47 	PSXCPU_R2, PSXCPU_R3,
48 	PSXCPU_R4, PSXCPU_R5,
49 	PSXCPU_R6, PSXCPU_R7,
50 	PSXCPU_R8, PSXCPU_R9,
51 	PSXCPU_R10, PSXCPU_R11,
52 	PSXCPU_R12, PSXCPU_R13,
53 	PSXCPU_R14, PSXCPU_R15,
54 	PSXCPU_R16, PSXCPU_R17,
55 	PSXCPU_R18, PSXCPU_R19,
56 	PSXCPU_R20, PSXCPU_R21,
57 	PSXCPU_R22, PSXCPU_R23,
58 	PSXCPU_R24, PSXCPU_R25,
59 	PSXCPU_R26, PSXCPU_R27,
60 	PSXCPU_R28, PSXCPU_R29,
61 	PSXCPU_R30, PSXCPU_R31,
62 	PSXCPU_CP0R0, PSXCPU_CP0R1,
63 	PSXCPU_CP0R2, PSXCPU_CP0R3,
64 	PSXCPU_CP0R4, PSXCPU_CP0R5,
65 	PSXCPU_CP0R6, PSXCPU_CP0R7,
66 	PSXCPU_CP0R8, PSXCPU_CP0R9,
67 	PSXCPU_CP0R10, PSXCPU_CP0R11,
68 	PSXCPU_CP0R12, PSXCPU_CP0R13,
69 	PSXCPU_CP0R14, PSXCPU_CP0R15,
70 	PSXCPU_CP2DR0, PSXCPU_CP2DR1,
71 	PSXCPU_CP2DR2, PSXCPU_CP2DR3,
72 	PSXCPU_CP2DR4, PSXCPU_CP2DR5,
73 	PSXCPU_CP2DR6, PSXCPU_CP2DR7,
74 	PSXCPU_CP2DR8, PSXCPU_CP2DR9,
75 	PSXCPU_CP2DR10, PSXCPU_CP2DR11,
76 	PSXCPU_CP2DR12, PSXCPU_CP2DR13,
77 	PSXCPU_CP2DR14, PSXCPU_CP2DR15,
78 	PSXCPU_CP2DR16, PSXCPU_CP2DR17,
79 	PSXCPU_CP2DR18, PSXCPU_CP2DR19,
80 	PSXCPU_CP2DR20, PSXCPU_CP2DR21,
81 	PSXCPU_CP2DR22, PSXCPU_CP2DR23,
82 	PSXCPU_CP2DR24, PSXCPU_CP2DR25,
83 	PSXCPU_CP2DR26, PSXCPU_CP2DR27,
84 	PSXCPU_CP2DR28, PSXCPU_CP2DR29,
85 	PSXCPU_CP2DR30, PSXCPU_CP2DR31,
86 	PSXCPU_CP2CR0, PSXCPU_CP2CR1,
87 	PSXCPU_CP2CR2, PSXCPU_CP2CR3,
88 	PSXCPU_CP2CR4, PSXCPU_CP2CR5,
89 	PSXCPU_CP2CR6, PSXCPU_CP2CR7,
90 	PSXCPU_CP2CR8, PSXCPU_CP2CR9,
91 	PSXCPU_CP2CR10, PSXCPU_CP2CR11,
92 	PSXCPU_CP2CR12, PSXCPU_CP2CR13,
93 	PSXCPU_CP2CR14, PSXCPU_CP2CR15,
94 	PSXCPU_CP2CR16, PSXCPU_CP2CR17,
95 	PSXCPU_CP2CR18, PSXCPU_CP2CR19,
96 	PSXCPU_CP2CR20, PSXCPU_CP2CR21,
97 	PSXCPU_CP2CR22, PSXCPU_CP2CR23,
98 	PSXCPU_CP2CR24, PSXCPU_CP2CR25,
99 	PSXCPU_CP2CR26, PSXCPU_CP2CR27,
100 	PSXCPU_CP2CR28, PSXCPU_CP2CR29,
101 	PSXCPU_CP2CR30, PSXCPU_CP2CR31
102 };
103 
104 // delay slot sentinels
105 
106 enum
107 {
108 	PSXCPU_DELAYR_PC = 32,
109 	PSXCPU_DELAYR_NOTPC = 33
110 };
111 
112 
113 //**************************************************************************
114 //  TYPE DEFINITIONS
115 //**************************************************************************
116 
117 // ======================> psxcpu_device
118 
119 class psxcpu_device : public cpu_device, psxcpu_disassembler::config
120 {
121 public:
122 	// configuration helpers
gpu_read()123 	auto gpu_read() { return m_gpu_read_handler.bind(); }
gpu_write()124 	auto gpu_write() { return m_gpu_write_handler.bind(); }
spu_read()125 	auto spu_read() { return m_spu_read_handler.bind(); }
spu_write()126 	auto spu_write() { return m_spu_write_handler.bind(); }
cd_read()127 	auto cd_read() { return m_cd_read_handler.bind(); }
cd_write()128 	auto cd_write() { return m_cd_write_handler.bind(); }
129 
130 	// public interfaces
131 	void berr_w(uint32_t data);
132 	uint32_t berr_r();
133 
134 	uint32_t exp_base();
135 
136 	void exp_base_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
137 	uint32_t exp_base_r();
138 
139 	void exp_config_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
140 	uint32_t exp_config_r();
141 
142 	void ram_config_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
143 	uint32_t ram_config_r();
144 
145 	void rom_config_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
146 	uint32_t rom_config_r();
147 
148 	void biu_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
149 	uint32_t biu_r();
150 
151 	void gpu_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
152 	uint32_t gpu_r(offs_t offset, uint32_t mem_mask = ~0);
153 
154 	void spu_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
155 	uint16_t spu_r(offs_t offset, uint16_t mem_mask = ~0);
156 
157 	void cd_w(offs_t offset, uint8_t data, uint8_t mem_mask = ~0);
158 	uint8_t cd_r(offs_t offset, uint8_t mem_mask = ~0);
159 
160 	void com_delay_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
161 	uint32_t com_delay_r(offs_t offset, uint32_t mem_mask = ~0);
162 
getcpu(device_t & device,const char * cputag)163 	static psxcpu_device *getcpu( device_t &device, const char *cputag ) { return downcast<psxcpu_device *>( device.subdevice( cputag ) ); }
164 	void set_disable_rom_berr(bool mode);
165 
166 	void psxcpu_internal_map(address_map &map);
167 protected:
168 	static constexpr unsigned ICACHE_ENTRIES = 0x400;
169 	static constexpr unsigned DCACHE_ENTRIES = 0x100;
170 
171 	psxcpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
172 
173 	// device-level overrides
174 	virtual void device_start() override;
175 	virtual void device_reset() override;
176 	virtual void device_post_load() override;
177 	virtual void device_add_mconfig(machine_config &config) override;
178 
179 	// device_execute_interface overrides
execute_min_cycles()180 	virtual uint32_t execute_min_cycles() const noexcept override { return 1; }
execute_max_cycles()181 	virtual uint32_t execute_max_cycles() const noexcept override { return 40; }
execute_input_lines()182 	virtual uint32_t execute_input_lines() const noexcept override { return 6; }
execute_clocks_to_cycles(uint64_t clocks)183 	virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const noexcept override { return ( clocks + 3 ) / 4; }
execute_cycles_to_clocks(uint64_t cycles)184 	virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const noexcept override { return cycles * 4; }
185 	virtual void execute_run() override;
186 	virtual void execute_set_input(int inputnum, int state) override;
187 
188 	// device_memory_interface overrides
189 	virtual space_config_vector memory_space_config() const override;
190 
191 	// device_state_interface overrides
192 	virtual void state_import(const device_state_entry &entry) override;
193 	virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
194 
195 	// device_disasm_interface overrides
196 	virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
197 
198 	// CPU registers
199 	uint32_t m_pc;
200 	uint32_t m_r[ 32 ];
201 	uint32_t m_cp0r[ 16 ];
202 	uint32_t m_hi;
203 	uint32_t m_lo;
204 
205 	// internal stuff
206 	uint32_t m_op;
207 
208 	// address spaces
209 	const address_space_config m_program_config;
210 	address_space *m_program;
211 	memory_access<32, 2, 0, ENDIANNESS_LITTLE>::cache m_instruction;
212 	memory_access<32, 2, 0, ENDIANNESS_LITTLE>::specific m_data;
213 
214 	// other internal states
215 	int m_icount;
216 	uint32_t m_com_delay;
217 	uint32_t m_delayv;
218 	uint32_t m_delayr;
219 	uint32_t m_berr;
220 	uint32_t m_biu;
221 	uint32_t m_icacheTag[ ICACHE_ENTRIES / 4 ];
222 	uint32_t m_icache[ ICACHE_ENTRIES ];
223 	uint32_t m_dcache[ DCACHE_ENTRIES ];
224 	int m_multiplier_operation;
225 	uint32_t m_multiplier_operand1;
226 	uint32_t m_multiplier_operand2;
227 	int m_bus_attached;
228 	uint32_t m_bad_byte_address_mask;
229 	uint32_t m_bad_half_address_mask;
230 	uint32_t m_bad_word_address_mask;
231 	uint32_t m_exp_base;
232 	uint32_t m_exp_config;
233 	uint32_t m_ram_config;
234 	uint32_t m_rom_config;
235 
236 	void stop();
237 	uint32_t cache_readword( uint32_t offset );
238 	void cache_writeword( uint32_t offset, uint32_t data );
239 	uint8_t readbyte( uint32_t address );
240 	uint16_t readhalf( uint32_t address );
241 	uint32_t readword( uint32_t address );
242 	uint32_t readword_masked( uint32_t address, uint32_t mask );
243 	void writeword( uint32_t address, uint32_t data );
244 	void writeword_masked( uint32_t address, uint32_t data, uint32_t mask );
245 	uint32_t log_bioscall_parameter( int parm );
246 	const char *log_bioscall_string( int parm );
247 	const char *log_bioscall_hex( int parm );
248 	const char *log_bioscall_char( int parm );
249 	void log_bioscall();
250 	void log_syscall();
251 	void update_memory_handlers();
252 	void funct_mthi();
253 	void funct_mtlo();
254 	void funct_mult();
255 	void funct_multu();
256 	void funct_div();
257 	void funct_divu();
258 	void multiplier_update();
259 	uint32_t get_hi();
260 	uint32_t get_lo();
261 	int execute_unstoppable_instructions( int executeCop2 );
262 	void update_address_masks();
263 	void update_scratchpad();
264 	void update_ram_config();
265 	void update_rom_config();
266 	void update_cop0( int reg );
267 	void commit_delayed_load();
268 	void set_pc( unsigned pc );
269 	void fetch_next_op();
270 	void advance_pc();
271 	void load( uint32_t reg, uint32_t value );
272 	void delayed_load( uint32_t reg, uint32_t value );
273 	void branch( uint32_t address );
274 	void conditional_branch( int takeBranch );
275 	void unconditional_branch();
276 	void common_exception( int exception, uint32_t romOffset, uint32_t ramOffset );
277 	void exception( int exception );
278 	void breakpoint_exception();
279 	void fetch_bus_error_exception();
280 	void load_bus_error_exception();
281 	void store_bus_error_exception();
282 	void load_bad_address( uint32_t address );
283 	void store_bad_address( uint32_t address );
284 	int program_counter_breakpoint();
285 	int data_address_breakpoint( int dcic_rw, int dcic_status, uint32_t address );
286 	int load_data_address_breakpoint( uint32_t address );
287 	int store_data_address_breakpoint( uint32_t address );
288 
289 	uint32_t get_register_from_pipeline( int reg );
290 	int cop0_usable();
291 	void lwc( int cop, int sr_cu );
292 	void swc( int cop, int sr_cu );
293 	void bc( int cop, int sr_cu, int condition );
294 
295 	uint32_t getcp1dr( int reg );
296 	void setcp1dr( int reg, uint32_t value );
297 	uint32_t getcp1cr( int reg );
298 	void setcp1cr( int reg, uint32_t value );
299 	uint32_t getcp3dr( int reg );
300 	void setcp3dr( int reg, uint32_t value );
301 	uint32_t getcp3cr( int reg );
302 	void setcp3cr( int reg, uint32_t value );
303 
304 	gte m_gte;
305 
306 	devcb_read32 m_gpu_read_handler;
307 	devcb_write32 m_gpu_write_handler;
308 	devcb_read16 m_spu_read_handler;
309 	devcb_write16 m_spu_write_handler;
310 	devcb_read8 m_cd_read_handler;
311 	devcb_write8 m_cd_write_handler;
312 	required_device<ram_device> m_ram;
313 	memory_region *m_rom;
314 	bool m_disable_rom_berr;
315 
316 private:
317 	// disassembler interface
pc()318 	virtual uint32_t pc() override { return m_pc; }
delayr()319 	virtual uint32_t delayr() override { return m_delayr; }
delayv()320 	virtual uint32_t delayv() override { return m_delayv; }
r(int i)321 	virtual uint32_t r(int i) override { return m_r[ i ]; }
322 };
323 
324 class cxd8530aq_device : public psxcpu_device
325 {
326 public:
327 	// construction/destruction
328 	cxd8530aq_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
329 };
330 
331 class cxd8530bq_device : public psxcpu_device
332 {
333 public:
334 	// construction/destruction
335 	cxd8530bq_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
336 };
337 
338 class cxd8530cq_device : public psxcpu_device
339 {
340 public:
341 	// construction/destruction
342 	cxd8530cq_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
343 };
344 
345 class cxd8661r_device : public psxcpu_device
346 {
347 public:
348 	// construction/destruction
349 	cxd8661r_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
350 };
351 
352 class cxd8606bq_device : public psxcpu_device
353 {
354 public:
355 	// construction/destruction
356 	cxd8606bq_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
357 };
358 
359 class cxd8606cq_device : public psxcpu_device
360 {
361 public:
362 	// construction/destruction
363 	cxd8606cq_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
364 };
365 
366 // device type definition
367 DECLARE_DEVICE_TYPE(CXD8530AQ, cxd8530aq_device)
368 DECLARE_DEVICE_TYPE(CXD8530BQ, cxd8530bq_device)
369 DECLARE_DEVICE_TYPE(CXD8530CQ, cxd8530cq_device)
370 DECLARE_DEVICE_TYPE(CXD8661R,  cxd8661r_device)
371 DECLARE_DEVICE_TYPE(CXD8606BQ, cxd8606bq_device)
372 DECLARE_DEVICE_TYPE(CXD8606CQ, cxd8606cq_device)
373 
374 
375 #endif // MAME_CPU_PSX_PSX_H
376