1 // license:BSD-3-Clause
2 // copyright-holders:Angelo Salese, R. Belmont, Anthony Kruize, Fabio Priuli, Ryan Holtz
3 
4 #ifndef MAME_INCLUDES_SNES_H
5 #define MAME_INCLUDES_SNES_H
6 
7 #include "cpu/g65816/g65816.h"
8 #include "machine/s_smp.h"
9 #include "sound/s_dsp.h"
10 #include "video/snes_ppu.h"
11 #include "screen.h"
12 
13 /*
14     SNES timing theory:
15 
16     the master clock drives the CPU and PPU
17     4  MC ticks = 1 PPU dot
18     6  MC ticks = 1 65816 cycle for 3.58 MHz (3.579545)
19     8  MC ticks = 1 65816 cycle for 2.68 MHz (2.684659)
20     12 MC ticks = 1 65816 cycle for 1.78 MHz (1.789772)
21 
22     Each scanline has 341 readable positions and 342 actual dots.
23     This is because 2 dots are "long" dots that last 6 MC ticks, resulting in 1 extra dot per line.
24 */
25 
26 // Useful definitions
27 #define SNES_DMA_BASE         0x4300    /* Base DMA register address */
28 #define SNES_MODE_20          0x01      /* Lo-ROM cart */
29 #define SNES_MODE_21          0x02      /* Hi-ROM cart */
30 #define SNES_MODE_22          0x04      /* Extended Lo-ROM cart - SDD-1 */
31 #define SNES_MODE_25          0x08      /* Extended Hi-ROM cart */
32 #define SNES_MODE_BSX         0x10
33 #define SNES_MODE_BSLO        0x20
34 #define SNES_MODE_BSHI        0x40
35 #define SNES_MODE_ST          0x80
36 #define SNES_EXROM_START      0x1000000
37 
38 // some PPU registers we still use in machine/snes.c
39 #define INIDISP        0x2100
40 #define OAMADDL        0x2102
41 #define OAMADDH        0x2103
42 #define SETINI         0x2133
43 #define MPYL           0x2134
44 #define MPYM           0x2135
45 #define MPYH           0x2136
46 
47 #define APU00          0x2140
48 #define APU01          0x2141
49 #define APU02          0x2142
50 #define APU03          0x2143
51 
52 #define WMDATA         0x2180
53 #define WMADDL         0x2181
54 #define WMADDM         0x2182
55 #define WMADDH         0x2183
56 
57 // Definitions for CPU Memory-Mapped registers
58 #define OLDJOY1        0x4016
59 #define OLDJOY2        0x4017
60 #define NMITIMEN       0x4200
61 #define WRIO           0x4201
62 //#define WRMPYA         0x4202
63 //#define WRMPYB         0x4203
64 //#define WRDIVL         0x4204
65 //#define WRDIVH         0x4205
66 //#define WRDVDD         0x4206
67 #define HTIMEL         0x4207
68 #define HTIMEH         0x4208
69 #define VTIMEL         0x4209
70 #define VTIMEH         0x420A
71 #define MDMAEN         0x420B
72 #define HDMAEN         0x420C
73 //#define MEMSEL         0x420D
74 #define RDNMI          0x4210
75 #define TIMEUP         0x4211
76 #define HVBJOY         0x4212
77 #define RDIO           0x4213
78 //#define RDDIVL         0x4214
79 //#define RDDIVH         0x4215
80 //#define RDMPYL         0x4216
81 //#define RDMPYH         0x4217
82 #define JOY1L          0x4218
83 #define JOY1H          0x4219
84 #define JOY2L          0x421A
85 #define JOY2H          0x421B
86 #define JOY3L          0x421C
87 #define JOY3H          0x421D
88 #define JOY4L          0x421E
89 #define JOY4H          0x421F
90 /* DMA */
91 #define DMAP0          0x4300
92 #define BBAD0          0x4301
93 #define A1T0L          0x4302
94 #define A1T0H          0x4303
95 #define A1B0           0x4304
96 #define DAS0L          0x4305
97 #define DAS0H          0x4306
98 #define DSAB0          0x4307
99 #define A2A0L          0x4308
100 #define A2A0H          0x4309
101 #define NTRL0          0x430A
102 #define DMAP1          0x4310
103 #define BBAD1          0x4311
104 #define A1T1L          0x4312
105 #define A1T1H          0x4313
106 #define A1B1           0x4314
107 #define DAS1L          0x4315
108 #define DAS1H          0x4316
109 #define DSAB1          0x4317
110 #define A2A1L          0x4318
111 #define A2A1H          0x4319
112 #define NTRL1          0x431A
113 #define DMAP2          0x4320
114 #define BBAD2          0x4321
115 #define A1T2L          0x4322
116 #define A1T2H          0x4323
117 #define A1B2           0x4324
118 #define DAS2L          0x4325
119 #define DAS2H          0x4326
120 #define DSAB2          0x4327
121 #define A2A2L          0x4328
122 #define A2A2H          0x4329
123 #define NTRL2          0x432A
124 #define DMAP3          0x4330
125 #define BBAD3          0x4331
126 #define A1T3L          0x4332
127 #define A1T3H          0x4333
128 #define A1B3           0x4334
129 #define DAS3L          0x4335
130 #define DAS3H          0x4336
131 #define DSAB3          0x4337
132 #define A2A3L          0x4338
133 #define A2A3H          0x4339
134 #define NTRL3          0x433A
135 #define DMAP4          0x4340
136 #define BBAD4          0x4341
137 #define A1T4L          0x4342
138 #define A1T4H          0x4343
139 #define A1B4           0x4344
140 #define DAS4L          0x4345
141 #define DAS4H          0x4346
142 #define DSAB4          0x4347
143 #define A2A4L          0x4348
144 #define A2A4H          0x4349
145 #define NTRL4          0x434A
146 #define DMAP5          0x4350
147 #define BBAD5          0x4351
148 #define A1T5L          0x4352
149 #define A1T5H          0x4353
150 #define A1B5           0x4354
151 #define DAS5L          0x4355
152 #define DAS5H          0x4356
153 #define DSAB5          0x4357
154 #define A2A5L          0x4358
155 #define A2A5H          0x4359
156 #define NTRL5          0x435A
157 #define DMAP6          0x4360
158 #define BBAD6          0x4361
159 #define A1T6L          0x4362
160 #define A1T6H          0x4363
161 #define A1B6           0x4364
162 #define DAS6L          0x4365
163 #define DAS6H          0x4366
164 #define DSAB6          0x4367
165 #define A2A6L          0x4368
166 #define A2A6H          0x4369
167 #define NTRL6          0x436A
168 #define DMAP7          0x4370
169 #define BBAD7          0x4371
170 #define A1T7L          0x4372
171 #define A1T7H          0x4373
172 #define A1B7           0x4374
173 #define DAS7L          0x4375
174 #define DAS7H          0x4376
175 #define DSAB7          0x4377
176 #define A2A7L          0x4378
177 #define A2A7H          0x4379
178 #define NTRL7          0x437A
179 /* Definitions for sound DSP */
180 #define DSP_V0_VOLL     0x00
181 #define DSP_V0_VOLR     0x01
182 #define DSP_V0_PITCHL   0x02
183 #define DSP_V0_PITCHH   0x03
184 #define DSP_V0_SRCN     0x04
185 #define DSP_V0_ADSR1    0x05    /* gdddaaaa = g:gain enable | d:decay | a:attack */
186 #define DSP_V0_ADSR2    0x06    /* llllrrrr = l:sustain left | r:sustain right */
187 #define DSP_V0_GAIN     0x07
188 #define DSP_V0_ENVX     0x08
189 #define DSP_V0_OUTX     0x09
190 #define DSP_V1_VOLL     0x10
191 #define DSP_V1_VOLR     0x11
192 #define DSP_V1_PITCHL   0x12
193 #define DSP_V1_PITCHH   0x13
194 #define DSP_V1_SRCN     0x14
195 #define DSP_V1_ADSR1    0x15
196 #define DSP_V1_ADSR2    0x16
197 #define DSP_V1_GAIN     0x17
198 #define DSP_V1_ENVX     0x18
199 #define DSP_V1_OUTX     0x19
200 #define DSP_V2_VOLL     0x20
201 #define DSP_V2_VOLR     0x21
202 #define DSP_V2_PITCHL   0x22
203 #define DSP_V2_PITCHH   0x23
204 #define DSP_V2_SRCN     0x24
205 #define DSP_V2_ADSR1    0x25
206 #define DSP_V2_ADSR2    0x26
207 #define DSP_V2_GAIN     0x27
208 #define DSP_V2_ENVX     0x28
209 #define DSP_V2_OUTX     0x29
210 #define DSP_V3_VOLL     0x30
211 #define DSP_V3_VOLR     0x31
212 #define DSP_V3_PITCHL   0x32
213 #define DSP_V3_PITCHH   0x33
214 #define DSP_V3_SRCN     0x34
215 #define DSP_V3_ADSR1    0x35
216 #define DSP_V3_ADSR2    0x36
217 #define DSP_V3_GAIN     0x37
218 #define DSP_V3_ENVX     0x38
219 #define DSP_V3_OUTX     0x39
220 #define DSP_V4_VOLL     0x40
221 #define DSP_V4_VOLR     0x41
222 #define DSP_V4_PITCHL   0x42
223 #define DSP_V4_PITCHH   0x43
224 #define DSP_V4_SRCN     0x44
225 #define DSP_V4_ADSR1    0x45
226 #define DSP_V4_ADSR2    0x46
227 #define DSP_V4_GAIN     0x47
228 #define DSP_V4_ENVX     0x48
229 #define DSP_V4_OUTX     0x49
230 #define DSP_V5_VOLL     0x50
231 #define DSP_V5_VOLR     0x51
232 #define DSP_V5_PITCHL   0x52
233 #define DSP_V5_PITCHH   0x53
234 #define DSP_V5_SRCN     0x54
235 #define DSP_V5_ADSR1    0x55
236 #define DSP_V5_ADSR2    0x56
237 #define DSP_V5_GAIN     0x57
238 #define DSP_V5_ENVX     0x58
239 #define DSP_V5_OUTX     0x59
240 #define DSP_V6_VOLL     0x60
241 #define DSP_V6_VOLR     0x61
242 #define DSP_V6_PITCHL   0x62
243 #define DSP_V6_PITCHH   0x63
244 #define DSP_V6_SRCN     0x64
245 #define DSP_V6_ADSR1    0x65
246 #define DSP_V6_ADSR2    0x66
247 #define DSP_V6_GAIN     0x67
248 #define DSP_V6_ENVX     0x68
249 #define DSP_V6_OUTX     0x69
250 #define DSP_V7_VOLL     0x70
251 #define DSP_V7_VOLR     0x71
252 #define DSP_V7_PITCHL   0x72
253 #define DSP_V7_PITCHH   0x73
254 #define DSP_V7_SRCN     0x74
255 #define DSP_V7_ADSR1    0x75
256 #define DSP_V7_ADSR2    0x76
257 #define DSP_V7_GAIN     0x77
258 #define DSP_V7_ENVX     0x78
259 #define DSP_V7_OUTX     0x79
260 #define DSP_MVOLL       0x0C
261 #define DSP_MVOLR       0x1C
262 #define DSP_EVOLL       0x2C
263 #define DSP_EVOLR       0x3C
264 #define DSP_KON         0x4C    /* 01234567 = Key on for voices 0-7 */
265 #define DSP_KOF         0x5C    /* 01234567 = Key off for voices 0-7 */
266 #define DSP_FLG         0x6C    /* rme--n-- = r:Soft reset | m:Mute | e:External memory through echo | n:Clock of noise generator */
267 #define DSP_ENDX        0x7C
268 #define DSP_EFB         0x0D    /* sfffffff = s: sign bit | f: feedback */
269 #define DSP_PMOD        0x2D
270 #define DSP_NON         0x3D
271 #define DSP_EON         0x4D
272 #define DSP_DIR         0x5D
273 #define DSP_ESA         0x6D
274 #define DSP_EDL         0x7D    /* ----dddd = d: echo delay */
275 #define DSP_FIR_C0      0x0F
276 #define DSP_FIR_C1      0x1F
277 #define DSP_FIR_C2      0x2F
278 #define DSP_FIR_C3      0x3F
279 #define DSP_FIR_C4      0x4F
280 #define DSP_FIR_C5      0x5F
281 #define DSP_FIR_C6      0x6F
282 #define DSP_FIR_C7      0x7F
283 
284 
285 #define SNES_CPU_REG(a) m_cpu_regs[a - 0x4200]  // regs 0x4200-0x421f
286 
287 struct snes_cart_info
288 {
289 	uint8_t *m_rom;
290 	uint32_t m_rom_size;
291 	std::unique_ptr<uint8_t[]> m_nvram;
292 	uint32_t m_nvram_size;
293 	uint8_t  mode;        /* ROM memory mode */
294 	uint32_t sram_max;    /* Maximum amount sram in cart (based on ROM mode) */
295 	int    slot_in_use; /* this is needed by Sufami Turbo slots (to check if SRAM has to be saved) */
296 	uint8_t rom_bank_map[0x100];
297 };
298 
299 class snes_state : public driver_device
300 {
301 public:
snes_state(const machine_config & mconfig,device_type type,const char * tag)302 	snes_state(const machine_config &mconfig, device_type type, const char *tag) :
303 		driver_device(mconfig, type, tag),
304 		m_maincpu(*this, "maincpu"),
305 		m_soundcpu(*this, "soundcpu"),
306 		m_s_dsp(*this, "s_dsp"),
307 		m_ppu(*this, "ppu"),
308 		m_screen(*this, "screen"),
309 		m_wram(*this, "wram")
310 	{ }
311 
312 	void init_snes();
313 	void init_snes_hirom();
314 	void init_snes_mess();
315 	void init_snesst();
316 
317 	uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
318 
319 protected:
320 	virtual void machine_start() override;
321 	virtual void machine_reset() override;
322 
323 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
324 
325 	enum
326 	{
327 		TIMER_NMI_TICK,
328 		TIMER_HIRQ_TICK,
329 		TIMER_RESET_OAM_ADDRESS,
330 		TIMER_RESET_HDMA,
331 		TIMER_UPDATE_IO,
332 		TIMER_SCANLINE_TICK,
333 		TIMER_HBLANK_TICK,
334 		TIMER_SNES_LAST
335 	};
336 
337 	/* misc */
338 	uint16_t                m_hblank_offset;
339 	uint32_t                m_wram_address;
340 	uint16_t                m_htime;
341 	uint16_t                m_vtime;
342 	bool                  m_is_pal;
343 
344 	/* non-SNES HW-specific flags / variables */
345 	uint8_t                 m_is_nss;
346 	uint8_t                 m_input_disabled;
347 	uint8_t                 m_game_over_flag;
348 	uint8_t                 m_joy_flag;
349 	uint8_t                 m_is_sfcbox;
350 
351 	/* timers */
352 	emu_timer             *m_scanline_timer;
353 	emu_timer             *m_hblank_timer;
354 	emu_timer             *m_nmi_timer;
355 	emu_timer             *m_hirq_timer;
356 //  emu_timer             *m_div_timer;
357 //  emu_timer             *m_mult_timer;
358 	emu_timer             *m_io_timer;
359 
360 	/* DMA/HDMA-related */
361 	struct
362 	{
363 		uint8_t  dmap;
364 		uint8_t  dest_addr;
365 		uint16_t src_addr;
366 		uint16_t trans_size;
367 		uint8_t  bank;
368 		uint8_t  ibank;
369 		uint16_t hdma_addr;
370 		uint16_t hdma_iaddr;
371 		uint8_t  hdma_line_counter;
372 		uint8_t  unk;
373 
374 		int    do_transfer;
375 
376 		int    dma_disabled;    // used to stop DMA if HDMA is enabled (currently not implemented, see machine/snes.c)
377 	} m_dma_channel[8];
378 	uint8_t                 m_hdmaen; /* channels enabled for HDMA */
379 	uint8_t                 m_dma_regs[0x80];
380 	uint8_t                 m_cpu_regs[0x20];
381 	uint8_t                 m_oldjoy1_latch;
382 
383 	/* input-related */
384 	uint16_t                m_data1[4];   // JOY1/JOY2 + 3rd & 4th only used by multitap (hacky support)
385 	uint16_t                m_data2[4];   // JOY3/JOY4 + 3rd & 4th only used by multitap (hacky support)
386 	uint8_t                 m_read_idx[4];    // 3rd & 4th only used by multitap (hacky support)
387 
388 	/* cart related */
389 	snes_cart_info m_cart;   // used by NSS/SFCBox only! to be moved in a derived class!
390 	void rom_map_setup(uint32_t size);
391 
392 	/* devices */
393 	required_device<_5a22_device> m_maincpu;
394 	required_device<s_smp_device> m_soundcpu;
395 	required_device<s_dsp_device> m_s_dsp;
396 	required_device<snes_ppu_device> m_ppu;
397 	required_device<screen_device> m_screen;
398 
399 	required_shared_ptr<u8> m_wram;
400 
401 	inline int dma_abus_valid(uint32_t address);
402 	inline uint8_t abus_read(address_space &space, uint32_t abus);
403 	inline void dma_transfer(address_space &space, uint8_t dma, uint32_t abus, uint16_t bbus);
404 	inline int is_last_active_channel(int dma);
405 	inline uint32_t get_hdma_addr(int dma);
406 	inline uint32_t get_hdma_iaddr(int dma);
407 	void dma(address_space &space, uint8_t channels);
408 	void hdma(address_space &space);
409 	void hdma_init(address_space &space);
410 	void hdma_update(address_space &space, int dma);
411 	void hirq_tick();
412 	virtual void write_joy_latch(uint8_t data);
413 	virtual void wrio_write(uint8_t data);
414 	inline uint8_t snes_rom_access(uint32_t offset);
415 
416 	void snes_init_ram();
417 
418 	// input related
419 	virtual void io_read();
420 	virtual uint8_t oldjoy1_read(int latched);
421 	virtual uint8_t oldjoy2_read(int latched);
422 
423 	uint8_t snes_r_io(offs_t offset);
424 	void snes_w_io(address_space &space, offs_t offset, uint8_t data);
425 	uint8_t snes_io_dma_r(offs_t offset);
426 	void snes_io_dma_w(offs_t offset, uint8_t data);
427 	uint8_t snes_r_bank1(offs_t offset);
428 	uint8_t snes_r_bank2(offs_t offset);
429 	void snes_w_bank1(address_space &space, offs_t offset, uint8_t data);
430 	void snes_w_bank2(offs_t offset, uint8_t data);
431 	uint8_t snes_open_bus_r();
432 	TIMER_CALLBACK_MEMBER(snes_nmi_tick);
433 	TIMER_CALLBACK_MEMBER(snes_hirq_tick_callback);
434 	TIMER_CALLBACK_MEMBER(snes_reset_oam_address);
435 	TIMER_CALLBACK_MEMBER(snes_reset_hdma);
436 	TIMER_CALLBACK_MEMBER(snes_update_io);
437 	TIMER_CALLBACK_MEMBER(snes_scanline_tick);
438 	TIMER_CALLBACK_MEMBER(snes_hblank_tick);
439 	DECLARE_WRITE_LINE_MEMBER(snes_extern_irq_w);
440 	DECLARE_DEVICE_IMAGE_LOAD_MEMBER(load_snes_cart);
441 	DECLARE_DEVICE_IMAGE_LOAD_MEMBER(load_sufami_cart);
442 	void snes_init_timers();
443 };
444 
445 /* Special chips, checked at init and used in memory handlers */
446 enum
447 {
448 	HAS_NONE = 0,
449 	HAS_DSP1,
450 	HAS_DSP2,
451 	HAS_DSP3,
452 	HAS_DSP4,
453 	HAS_SUPERFX,
454 	HAS_SA1,
455 	HAS_SDD1,
456 	HAS_OBC1,
457 	HAS_RTC,
458 	HAS_Z80GB,
459 	HAS_CX4,
460 	HAS_ST010,
461 	HAS_ST011,
462 	HAS_ST018,
463 	HAS_SPC7110,
464 	HAS_SPC7110_RTC,
465 	HAS_UNK
466 };
467 
468 #endif // MAME_INCLUDES_SNES_H
469