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