trunk/src/emu/machine/saturn.c
| r0 | r21331 | |
| 1 | #include "emu.h" |
| 2 | #include "includes/stv.h" |
| 3 | #include "machine/scudsp.h" |
| 4 | #include "cpu/sh2/sh2.h" |
| 5 | |
| 6 | /* TODO: do this in a verboselog style */ |
| 7 | #define LOG_CDB 0 |
| 8 | #define LOG_SCU 1 |
| 9 | #define LOG_IRQ 0 |
| 10 | #define LOG_IOGA 0 |
| 11 | |
| 12 | int saturn_state::DectoBCD(int num) |
| 13 | { |
| 14 | int i, cnt = 0, tmp, res = 0; |
| 15 | |
| 16 | while (num > 0) { |
| 17 | tmp = num; |
| 18 | while (tmp >= 10) tmp %= 10; |
| 19 | for (i=0; i<cnt; i++) |
| 20 | tmp *= 16; |
| 21 | res += tmp; |
| 22 | cnt++; |
| 23 | num /= 10; |
| 24 | } |
| 25 | |
| 26 | return res; |
| 27 | } |
| 28 | |
| 29 | /**************************************************************************************/ |
| 30 | |
| 31 | /* |
| 32 | |
| 33 | SCU Handling |
| 34 | |
| 35 | */ |
| 36 | |
| 37 | /********************************************************************************** |
| 38 | SCU Register Table |
| 39 | offset,relative address |
| 40 | Registers are in long words. |
| 41 | =================================================================================== |
| 42 | 0 0000 Level 0 DMA Set Register |
| 43 | 1 0004 |
| 44 | 2 0008 |
| 45 | 3 000c |
| 46 | 4 0010 |
| 47 | 5 0014 |
| 48 | 6 0018 |
| 49 | 7 001c |
| 50 | 8 0020 Level 1 DMA Set Register |
| 51 | 9 0024 |
| 52 | 10 0028 |
| 53 | 11 002c |
| 54 | 12 0030 |
| 55 | 13 0034 |
| 56 | 14 0038 |
| 57 | 15 003c |
| 58 | 16 0040 Level 2 DMA Set Register |
| 59 | 17 0044 |
| 60 | 18 0048 |
| 61 | 19 004c |
| 62 | 20 0050 |
| 63 | 21 0054 |
| 64 | 22 0058 |
| 65 | 23 005c |
| 66 | 24 0060 DMA Forced Stop |
| 67 | 25 0064 |
| 68 | 26 0068 |
| 69 | 27 006c |
| 70 | 28 0070 <Free> |
| 71 | 29 0074 |
| 72 | 30 0078 |
| 73 | 31 007c DMA Status Register |
| 74 | 32 0080 DSP Program Control Port |
| 75 | 33 0084 DSP Program RAM Data Port |
| 76 | 34 0088 DSP Data RAM Address Port |
| 77 | 35 008c DSP Data RAM Data Port |
| 78 | 36 0090 Timer 0 Compare Register |
| 79 | 37 0094 Timer 1 Set Data Register |
| 80 | 38 0098 Timer 1 Mode Register |
| 81 | 39 009c <Free> |
| 82 | 40 00a0 Interrupt Mask Register |
| 83 | 41 00a4 Interrupt Status Register |
| 84 | 42 00a8 A-Bus Interrupt Acknowledge |
| 85 | 43 00ac <Free> |
| 86 | 44 00b0 A-Bus Set Register |
| 87 | 45 00b4 |
| 88 | 46 00b8 A-Bus Refresh Register |
| 89 | 47 00bc <Free> |
| 90 | 48 00c0 |
| 91 | 49 00c4 SCU SDRAM Select Register |
| 92 | 50 00c8 SCU Version Register |
| 93 | 51 00cc <Free> |
| 94 | 52 00cf |
| 95 | =================================================================================== |
| 96 | DMA Status Register(32-bit): |
| 97 | xxxx xxxx x--- xx-- xx-- xx-- xx-- xx-- UNUSED |
| 98 | ---- ---- -x-- ---- ---- ---- ---- ---- DMA DSP-Bus access |
| 99 | ---- ---- --x- ---- ---- ---- ---- ---- DMA B-Bus access |
| 100 | ---- ---- ---x ---- ---- ---- ---- ---- DMA A-Bus access |
| 101 | ---- ---- ---- --x- ---- ---- ---- ---- DMA lv 1 interrupt |
| 102 | ---- ---- ---- ---x ---- ---- ---- ---- DMA lv 0 interrupt |
| 103 | ---- ---- ---- ---- --x- ---- ---- ---- DMA lv 2 in stand-by |
| 104 | ---- ---- ---- ---- ---x ---- ---- ---- DMA lv 2 in operation |
| 105 | ---- ---- ---- ---- ---- --x- ---- ---- DMA lv 1 in stand-by |
| 106 | ---- ---- ---- ---- ---- ---x ---- ---- DMA lv 1 in operation |
| 107 | ---- ---- ---- ---- ---- ---- --x- ---- DMA lv 0 in stand-by |
| 108 | ---- ---- ---- ---- ---- ---- ---x ---- DMA lv 0 in operation |
| 109 | ---- ---- ---- ---- ---- ---- ---- --x- DSP side DMA in stand-by |
| 110 | ---- ---- ---- ---- ---- ---- ---- ---x DSP side DMA in operation |
| 111 | |
| 112 | **********************************************************************************/ |
| 113 | /* |
| 114 | DMA TODO: |
| 115 | -Remove CD transfer DMA hack (tied with CD block bug(s)?) |
| 116 | -Add timings(but how fast are each DMA?). |
| 117 | -Add level priority & DMA status register. |
| 118 | */ |
| 119 | |
| 120 | #define DIRECT_MODE(_lv_) (!(m_scu_regs[5+(_lv_*8)] & 0x01000000)) |
| 121 | #define INDIRECT_MODE(_lv_) (m_scu_regs[5+(_lv_*8)] & 0x01000000) |
| 122 | #define DRUP(_lv_) (m_scu_regs[5+(_lv_*8)] & 0x00010000) |
| 123 | #define DWUP(_lv_) (m_scu_regs[5+(_lv_*8)] & 0x00000100) |
| 124 | |
| 125 | /*These macros sets the various DMA status flags.*/ |
| 126 | #define DnMV_1(_ch_) m_scu.status|=(0x10 << 4 * _ch_) |
| 127 | #define DnMV_0(_ch_) m_scu.status&=~(0x10 << 4 * _ch_) |
| 128 | |
| 129 | /*For area checking*/ |
| 130 | #define BIOS_BUS(var) (var & 0x07000000) == 0 |
| 131 | #define ABUS(_lv_) ((m_scu.src[_lv_] & 0x07000000) >= 0x02000000) && ((m_scu.src[_lv_] & 0x07000000) <= 0x04000000) |
| 132 | #define BBUS(_lv_) ((scu_##_lv_ & 0x07ffffff) >= 0x05a00000) && ((scu_##_lv_ & 0x07ffffff) <= 0x05ffffff) |
| 133 | #define VDP1_REGS(_lv_) ((scu_##_lv_ & 0x07ffffff) >= 0x05d00000) && ((scu_##_lv_ & 0x07ffffff) <= 0x05dfffff) |
| 134 | #define VDP2(_lv_) ((scu_##_lv_ & 0x07ffffff) >= 0x05e00000) && ((scu_##_lv_ & 0x07ffffff) <= 0x05fdffff) |
| 135 | #define WORK_RAM_L(_lv_) ((scu_##_lv_ & 0x07ffffff) >= 0x00200000) && ((scu_##_lv_ & 0x07ffffff) <= 0x002fffff) |
| 136 | #define WORK_RAM_H(var) (var & 0x07000000) == 0x06000000 |
| 137 | #define SOUND_RAM(_lv_) ((scu_##_lv_ & 0x07ffffff) >= 0x05a00000) && ((scu_##_lv_ & 0x07ffffff) <= 0x05afffff) |
| 138 | |
| 139 | void saturn_state::scu_do_transfer(UINT8 event) |
| 140 | { |
| 141 | address_space &space = machine().device("maincpu")->memory().space(AS_PROGRAM); |
| 142 | int i; |
| 143 | |
| 144 | for(i=0;i<3;i++) |
| 145 | { |
| 146 | if(m_scu.enable_mask[i] && m_scu.start_factor[i] == event) |
| 147 | { |
| 148 | if(DIRECT_MODE(i)) { scu_dma_direct(space,i); } |
| 149 | else { scu_dma_indirect(space,i); } |
| 150 | } |
| 151 | } |
| 152 | } |
| 153 | |
| 154 | /* test pending irqs */ |
| 155 | void saturn_state::scu_test_pending_irq() |
| 156 | { |
| 157 | int i; |
| 158 | const int irq_level[32] = { 0xf, 0xe, 0xd, 0xc, |
| 159 | 0xb, 0xa, 0x9, 0x8, |
| 160 | 0x8, 0x6, 0x6, 0x5, |
| 161 | 0x3, 0x2, -1, -1, |
| 162 | 0x7, 0x7, 0x7, 0x7, |
| 163 | 0x4, 0x4, 0x4, 0x4, |
| 164 | 0x1, 0x1, 0x1, 0x1, |
| 165 | 0x1, 0x1, 0x1, 0x1 }; |
| 166 | |
| 167 | for(i=0;i<32;i++) |
| 168 | { |
| 169 | if((!(m_scu.ism & 1 << i)) && (m_scu.ist & 1 << i)) |
| 170 | { |
| 171 | if(irq_level[i] != -1) /* TODO: cheap check for undefined irqs */ |
| 172 | { |
| 173 | m_maincpu->set_input_line_and_vector(irq_level[i], HOLD_LINE, 0x40 + i); |
| 174 | m_scu.ist &= ~(1 << i); |
| 175 | return; /* avoid spurious irqs, correct? */ |
| 176 | } |
| 177 | } |
| 178 | } |
| 179 | } |
| 180 | |
| 181 | READ32_MEMBER(saturn_state::saturn_scu_r) |
| 182 | { |
| 183 | UINT32 res; |
| 184 | |
| 185 | /*TODO: write only registers must return 0 or open bus */ |
| 186 | switch(offset) |
| 187 | { |
| 188 | case 0x5c/4: |
| 189 | // Super Major League and Shin Megami Tensei - Akuma Zensho reads from there (undocumented), DMA status mirror? |
| 190 | if(LOG_SCU && !space.debugger_access()) logerror("(PC=%08x) DMA status reg read\n",space.device().safe_pc()); |
| 191 | res = m_scu.status; |
| 192 | break; |
| 193 | case 0x7c/4: |
| 194 | if(LOG_SCU && !space.debugger_access()) logerror("(PC=%08x) DMA status reg read\n",space.device().safe_pc()); |
| 195 | res = m_scu.status; |
| 196 | break; |
| 197 | case 0x80/4: |
| 198 | res = dsp_prg_ctrl_r(space); |
| 199 | break; |
| 200 | case 0x8c/4: |
| 201 | if(LOG_SCU && !space.debugger_access()) logerror( "DSP mem read at %08X\n", m_scu_regs[34]); |
| 202 | res = dsp_ram_addr_r(); |
| 203 | break; |
| 204 | case 0xa0/4: |
| 205 | if(LOG_SCU && !space.debugger_access()) logerror("(PC=%08x) IRQ mask reg read %08x MASK=%08x\n",space.device().safe_pc(),mem_mask,m_scu_regs[0xa0/4]); |
| 206 | res = m_scu.ism; |
| 207 | break; |
| 208 | case 0xa4/4: |
| 209 | if(LOG_SCU && !space.debugger_access()) logerror("(PC=%08x) IRQ status reg read MASK=%08x IST=%08x | ISM=%08x\n",space.device().safe_pc(),mem_mask,m_scu.ist,m_scu.ism); |
| 210 | /* TODO: Bug! trips an HW fault. Basically, it tries to read the IST bit 1 with that irq enabled. |
| 211 | Densetsu no Ogre Battle doesn't like this, so it needs investigation ... |
| 212 | */ |
| 213 | // res = m_scu.ist | ~m_scu.ism; |
| 214 | res = m_scu.ist; |
| 215 | break; |
| 216 | case 0xc8/4: |
| 217 | if(LOG_SCU && !space.debugger_access()) logerror("(PC=%08x) SCU version reg read\n",space.device().safe_pc()); |
| 218 | res = 0x00000004;/*SCU Version 4, OK? */ |
| 219 | break; |
| 220 | default: |
| 221 | if(LOG_SCU && !space.debugger_access()) logerror("(PC=%08x) SCU reg read at %d = %08x\n",space.device().safe_pc(),offset,m_scu_regs[offset]); |
| 222 | res = m_scu_regs[offset]; |
| 223 | break; |
| 224 | } |
| 225 | |
| 226 | return res; |
| 227 | } |
| 228 | |
| 229 | #define DMA_CH ((offset & 0x18) / 8) |
| 230 | |
| 231 | WRITE32_MEMBER(saturn_state::saturn_scu_w) |
| 232 | { |
| 233 | COMBINE_DATA(&m_scu_regs[offset]); |
| 234 | |
| 235 | switch(offset) |
| 236 | { |
| 237 | /*LV 0 DMA*/ |
| 238 | case 0x00/4: case 0x20/4: case 0x40/4: m_scu.src[DMA_CH] = ((m_scu_regs[offset] & 0x07ffffff) >> 0); break; |
| 239 | case 0x04/4: case 0x24/4: case 0x44/4: m_scu.dst[DMA_CH] = ((m_scu_regs[offset] & 0x07ffffff) >> 0); break; |
| 240 | case 0x08/4: case 0x28/4: case 0x48/4: m_scu.size[DMA_CH] = ((m_scu_regs[offset] & ((offset == 2) ? 0x000fffff : 0xfff)) >> 0); break; |
| 241 | case 0x0c/4: case 0x2c/4: case 0x4c/4: |
| 242 | m_scu.src_add[DMA_CH] = (m_scu_regs[offset] & 0x100) ? 4 : 0; |
| 243 | m_scu.dst_add[DMA_CH] = 1 << (m_scu_regs[offset] & 7); |
| 244 | if(m_scu.dst_add[DMA_CH] == 1) { m_scu.dst_add[DMA_CH] = 0; } |
| 245 | break; |
| 246 | case 0x10/4: case 0x30/4: case 0x50/4: |
| 247 | m_scu.enable_mask[DMA_CH] = (data & 0x100) >> 8; |
| 248 | if(m_scu.enable_mask[DMA_CH] && m_scu.start_factor[DMA_CH] == 7 && m_scu_regs[offset] & 1) |
| 249 | { |
| 250 | if(DIRECT_MODE(DMA_CH)) { scu_dma_direct(space,DMA_CH); } |
| 251 | else { scu_dma_indirect(space,DMA_CH); } |
| 252 | m_scu_regs[offset]&=~1;//disable starting bit. |
| 253 | } |
| 254 | break; |
| 255 | case 0x14/4: case 0x34/4: case 0x54/4: |
| 256 | if(INDIRECT_MODE(DMA_CH)) |
| 257 | { |
| 258 | //if(LOG_SCU) logerror("Indirect Mode DMA lv %d set\n",DMA_CH); |
| 259 | if(!DWUP(DMA_CH)) m_scu.index[DMA_CH] = m_scu.dst[DMA_CH]; |
| 260 | } |
| 261 | |
| 262 | m_scu.start_factor[DMA_CH] = m_scu_regs[offset] & 7; |
| 263 | break; |
| 264 | |
| 265 | case 0x60/4: |
| 266 | if(LOG_SCU) logerror("DMA Forced Stop Register set = %02x\n",m_scu_regs[24]); |
| 267 | break; |
| 268 | case 0x7c/4: if(LOG_SCU) logerror("Warning: DMA status WRITE! Offset %02x(%d)\n",offset*4,offset); break; |
| 269 | /*DSP section*/ |
| 270 | case 0x80/4: |
| 271 | /* TODO: you can't overwrite some flags with this */ |
| 272 | dsp_prg_ctrl_w(space, m_scu_regs[offset]); |
| 273 | if(LOG_SCU) logerror("SCU DSP: Program Control Port Access %08x\n",data); |
| 274 | break; |
| 275 | case 0x84/4: |
| 276 | dsp_prg_data(m_scu_regs[offset]); |
| 277 | if(LOG_SCU) logerror("SCU DSP: Program RAM Data Port Access %08x\n",data); |
| 278 | break; |
| 279 | case 0x88/4: |
| 280 | dsp_ram_addr_ctrl(m_scu_regs[offset]); |
| 281 | if(LOG_SCU) logerror("SCU DSP: Data RAM Address Port Access %08x\n",data); |
| 282 | break; |
| 283 | case 0x8c/4: |
| 284 | dsp_ram_addr_w(m_scu_regs[offset]); |
| 285 | if(LOG_SCU) logerror("SCU DSP: Data RAM Data Port Access %08x\n",data); |
| 286 | break; |
| 287 | case 0x90/4: /*if(LOG_SCU) logerror("timer 0 compare data = %03x\n",m_scu_regs[36]);*/ break; |
| 288 | case 0x94/4: /*if(LOG_SCU) logerror("timer 1 set data = %08x\n",m_scu_regs[37]);*/ break; |
| 289 | case 0x98/4: /*if(LOG_SCU) logerror("timer 1 mode data = %08x\n",m_scu_regs[38]);*/ break; |
| 290 | case 0xa0/4: /* IRQ mask */ |
| 291 | m_scu.ism = m_scu_regs[0xa0/4]; |
| 292 | scu_test_pending_irq(); |
| 293 | break; |
| 294 | case 0xa4/4: /* IRQ control */ |
| 295 | if(LOG_SCU) logerror("PC=%08x IRQ status reg set:%08x %08x\n",space.device().safe_pc(),m_scu_regs[41],mem_mask); |
| 296 | m_scu.ist &= m_scu_regs[offset]; |
| 297 | scu_test_pending_irq(); |
| 298 | break; |
| 299 | case 0xa8/4: |
| 300 | /* This sends an irq signal to the extra devices connected to the A-Bus, not really needed for now. */ |
| 301 | //if(LOG_SCU) logerror("A-Bus IRQ ACK %08x\n",m_scu_regs[42]); |
| 302 | break; |
| 303 | case 0xc4/4: if(LOG_SCU) logerror("SCU SDRAM set: %02x\n",m_scu_regs[49]); break; |
| 304 | default: if(LOG_SCU) logerror("Warning: unused SCU reg set %d = %08x\n",offset,data); |
| 305 | } |
| 306 | } |
| 307 | |
| 308 | /*Lv 0 DMA end irq*/ |
| 309 | TIMER_CALLBACK_MEMBER(saturn_state::dma_lv0_ended ) |
| 310 | { |
| 311 | if(!(m_scu.ism & IRQ_DMALV0)) |
| 312 | m_maincpu->set_input_line_and_vector(5, HOLD_LINE, 0x4b); |
| 313 | else |
| 314 | m_scu.ist |= (IRQ_DMALV0); |
| 315 | |
| 316 | DnMV_0(0); |
| 317 | } |
| 318 | |
| 319 | /*Lv 1 DMA end irq*/ |
| 320 | TIMER_CALLBACK_MEMBER(saturn_state::dma_lv1_ended) |
| 321 | { |
| 322 | if(!(m_scu.ism & IRQ_DMALV1)) |
| 323 | m_maincpu->set_input_line_and_vector(6, HOLD_LINE, 0x4a); |
| 324 | else |
| 325 | m_scu.ist |= (IRQ_DMALV1); |
| 326 | |
| 327 | DnMV_0(1); |
| 328 | } |
| 329 | |
| 330 | /*Lv 2 DMA end irq*/ |
| 331 | TIMER_CALLBACK_MEMBER(saturn_state::dma_lv2_ended) |
| 332 | { |
| 333 | if(!(m_scu.ism & IRQ_DMALV2)) |
| 334 | m_maincpu->set_input_line_and_vector(6, HOLD_LINE, 0x49); |
| 335 | else |
| 336 | m_scu.ist |= (IRQ_DMALV2); |
| 337 | |
| 338 | DnMV_0(2); |
| 339 | } |
| 340 | |
| 341 | void saturn_state::scu_single_transfer(address_space &space, UINT32 src, UINT32 dst,UINT8 *src_shift) |
| 342 | { |
| 343 | UINT32 src_data; |
| 344 | |
| 345 | if(src & 1) |
| 346 | { |
| 347 | /* Road Blaster does a work ram h to color ram with offsetted source address, do some data rotation */ |
| 348 | src_data = ((space.read_dword(src & 0x07fffffc) & 0x00ffffff)<<8); |
| 349 | src_data |= ((space.read_dword((src & 0x07fffffc)+4) & 0xff000000) >> 24); |
| 350 | src_data >>= (*src_shift)*16; |
| 351 | } |
| 352 | else |
| 353 | src_data = space.read_dword(src & 0x07fffffc) >> (*src_shift)*16; |
| 354 | |
| 355 | space.write_word(dst,src_data); |
| 356 | |
| 357 | *src_shift ^= 1; |
| 358 | } |
| 359 | |
| 360 | void saturn_state::scu_dma_direct(address_space &space, UINT8 dma_ch) |
| 361 | { |
| 362 | UINT32 tmp_src,tmp_dst,total_size; |
| 363 | UINT8 cd_transfer_flag; |
| 364 | |
| 365 | if(m_scu.src_add[dma_ch] == 0 || (m_scu.dst_add[dma_ch] != 2 && m_scu.dst_add[dma_ch] != 4)) |
| 366 | { |
| 367 | if(LOG_SCU) printf("DMA lv %d transfer START\n" |
| 368 | "Start %08x End %08x Size %04x\n",dma_ch,m_scu.src[dma_ch],m_scu.dst[dma_ch],m_scu.size[dma_ch]); |
| 369 | if(LOG_SCU) printf("Start Add %04x Destination Add %04x\n",m_scu.src_add[dma_ch],m_scu.dst_add[dma_ch]); |
| 370 | } |
| 371 | |
| 372 | /* TODO: Game Basic and World Cup 98 trips this, according to the docs the SCU can't transfer from BIOS area (can't communicate from/to that bus) */ |
| 373 | if(BIOS_BUS(m_scu.src[dma_ch])) |
| 374 | { |
| 375 | popmessage("Warning: SCU transfer from BIOS area, contact MAMEdev"); |
| 376 | if(!(m_scu.ism & IRQ_DMAILL)) |
| 377 | m_maincpu->set_input_line_and_vector(3, HOLD_LINE, 0x4c); |
| 378 | else |
| 379 | m_scu.ist |= (IRQ_DMAILL); |
| 380 | return; |
| 381 | } |
| 382 | |
| 383 | DnMV_1(dma_ch); |
| 384 | |
| 385 | /* max size */ |
| 386 | if(m_scu.size[dma_ch] == 0) { m_scu.size[dma_ch] = (dma_ch == 0) ? 0x00100000 : 0x1000; } |
| 387 | |
| 388 | tmp_src = tmp_dst = 0; |
| 389 | |
| 390 | total_size = m_scu.size[dma_ch]; |
| 391 | if(!(DRUP(dma_ch))) tmp_src = m_scu.src[dma_ch]; |
| 392 | if(!(DWUP(dma_ch))) tmp_dst = m_scu.dst[dma_ch]; |
| 393 | |
| 394 | cd_transfer_flag = m_scu.src_add[dma_ch] == 0 && m_scu.src[dma_ch] == 0x05818000; |
| 395 | |
| 396 | /* TODO: Many games directly accesses CD-ROM register 0x05818000, it must be a dword access with current implementation otherwise it won't work */ |
| 397 | if(cd_transfer_flag) |
| 398 | { |
| 399 | int i; |
| 400 | if(WORK_RAM_H(m_scu.dst[dma_ch])) |
| 401 | m_scu.dst_add[dma_ch] = 4; |
| 402 | else |
| 403 | m_scu.dst_add[dma_ch] <<= 1; |
| 404 | |
| 405 | for (i = 0; i < m_scu.size[dma_ch];i+=m_scu.dst_add[dma_ch]) |
| 406 | { |
| 407 | space.write_dword(m_scu.dst[dma_ch],space.read_dword(m_scu.src[dma_ch])); |
| 408 | if(m_scu.dst_add[dma_ch] == 8) |
| 409 | space.write_dword(m_scu.dst[dma_ch]+4,space.read_dword(m_scu.src[dma_ch])); |
| 410 | |
| 411 | m_scu.src[dma_ch]+=m_scu.src_add[dma_ch]; |
| 412 | m_scu.dst[dma_ch]+=m_scu.dst_add[dma_ch]; |
| 413 | } |
| 414 | } |
| 415 | else |
| 416 | { |
| 417 | int i; |
| 418 | UINT8 src_shift; |
| 419 | |
| 420 | src_shift = ((m_scu.src[dma_ch] & 2) >> 1) ^ 1; |
| 421 | |
| 422 | for (i = 0; i < m_scu.size[dma_ch];i+=2) |
| 423 | { |
| 424 | scu_single_transfer(space,m_scu.src[dma_ch],m_scu.dst[dma_ch],&src_shift); |
| 425 | |
| 426 | if(src_shift) |
| 427 | m_scu.src[dma_ch]+=m_scu.src_add[dma_ch]; |
| 428 | |
| 429 | /* if target is Work RAM H, the add value is fixed, behaviour confirmed by Final Romance 2, Virtual Mahjong and Burning Rangers */ |
| 430 | m_scu.dst[dma_ch]+=(WORK_RAM_H(m_scu.dst[dma_ch])) ? 2 : m_scu.dst_add[dma_ch]; |
| 431 | } |
| 432 | } |
| 433 | |
| 434 | /* Burning Rangers doesn't agree with this. */ |
| 435 | // m_scu.size[dma_ch] = 0; |
| 436 | if(!(DRUP(dma_ch))) m_scu.src[dma_ch] = tmp_src; |
| 437 | if(!(DWUP(dma_ch))) m_scu.dst[dma_ch] = tmp_dst; |
| 438 | |
| 439 | { |
| 440 | /*TODO: change DMA into DRQ model. Timing is a guess. */ |
| 441 | switch(dma_ch) |
| 442 | { |
| 443 | case 0: machine().scheduler().timer_set(m_maincpu->cycles_to_attotime(total_size/4), timer_expired_delegate(FUNC(saturn_state::dma_lv0_ended),this)); break; |
| 444 | case 1: machine().scheduler().timer_set(m_maincpu->cycles_to_attotime(total_size/4), timer_expired_delegate(FUNC(saturn_state::dma_lv1_ended),this)); break; |
| 445 | case 2: machine().scheduler().timer_set(m_maincpu->cycles_to_attotime(total_size/4), timer_expired_delegate(FUNC(saturn_state::dma_lv2_ended),this)); break; |
| 446 | } |
| 447 | } |
| 448 | } |
| 449 | |
| 450 | void saturn_state::scu_dma_indirect(address_space &space,UINT8 dma_ch) |
| 451 | { |
| 452 | /*Helper to get out of the cycle*/ |
| 453 | UINT8 job_done = 0; |
| 454 | /*temporary storage for the transfer data*/ |
| 455 | UINT32 tmp_src; |
| 456 | UINT32 indirect_src,indirect_dst; |
| 457 | INT32 indirect_size; |
| 458 | UINT32 total_size = 0; |
| 459 | |
| 460 | DnMV_1(dma_ch); |
| 461 | |
| 462 | m_scu.index[dma_ch] = m_scu.dst[dma_ch]; |
| 463 | |
| 464 | do{ |
| 465 | tmp_src = m_scu.index[dma_ch]; |
| 466 | |
| 467 | indirect_size = space.read_dword(m_scu.index[dma_ch]); |
| 468 | indirect_src = space.read_dword(m_scu.index[dma_ch]+8); |
| 469 | indirect_dst = space.read_dword(m_scu.index[dma_ch]+4); |
| 470 | |
| 471 | /*Indirect Mode end factor*/ |
| 472 | if(indirect_src & 0x80000000) |
| 473 | job_done = 1; |
| 474 | |
| 475 | if(m_scu.src_add[dma_ch] == 0 || (m_scu.dst_add[dma_ch] != 2)) |
| 476 | { |
| 477 | if(LOG_SCU) printf("DMA lv %d indirect mode transfer START\n" |
| 478 | "Index %08x Start %08x End %08x Size %04x\n",dma_ch,tmp_src,indirect_src,indirect_dst,indirect_size); |
| 479 | if(LOG_SCU) printf("Start Add %04x Destination Add %04x\n",m_scu.src_add[dma_ch],m_scu.dst_add[dma_ch]); |
| 480 | } |
| 481 | |
| 482 | indirect_src &=0x07ffffff; |
| 483 | indirect_dst &=0x07ffffff; |
| 484 | indirect_size &= ((dma_ch == 0) ? 0xfffff : 0x3ffff); //TODO: Guardian Heroes sets up a 0x23000 transfer for the FMV? |
| 485 | |
| 486 | if(indirect_size == 0) { indirect_size = (dma_ch == 0) ? 0x00100000 : 0x2000; } |
| 487 | |
| 488 | { |
| 489 | int i; |
| 490 | UINT8 src_shift; |
| 491 | |
| 492 | src_shift = ((indirect_src & 2) >> 1) ^ 1; |
| 493 | |
| 494 | for (i = 0; i < indirect_size;i+=2) |
| 495 | { |
| 496 | scu_single_transfer(space,indirect_src,indirect_dst,&src_shift); |
| 497 | |
| 498 | if(src_shift) |
| 499 | indirect_src+=m_scu.src_add[dma_ch]; |
| 500 | |
| 501 | indirect_dst+= (WORK_RAM_H(indirect_dst)) ? 2 : m_scu.dst_add[dma_ch]; |
| 502 | } |
| 503 | } |
| 504 | |
| 505 | /* Guess: Size + data acquire (1 cycle for src/dst/size) */ |
| 506 | total_size += indirect_size + 3*4; |
| 507 | |
| 508 | //if(DRUP(0)) space.write_dword(tmp_src+8,m_scu.src[0]|job_done ? 0x80000000 : 0); |
| 509 | //if(DWUP(0)) space.write_dword(tmp_src+4,m_scu.dst[0]); |
| 510 | |
| 511 | m_scu.index[dma_ch] = tmp_src+0xc; |
| 512 | |
| 513 | }while(job_done == 0); |
| 514 | |
| 515 | { |
| 516 | /*TODO: change DMA into DRQ model. Timing is a guess. */ |
| 517 | switch(dma_ch) |
| 518 | { |
| 519 | case 0: machine().scheduler().timer_set(m_maincpu->cycles_to_attotime(total_size/4), timer_expired_delegate(FUNC(saturn_state::dma_lv0_ended),this)); break; |
| 520 | case 1: machine().scheduler().timer_set(m_maincpu->cycles_to_attotime(total_size/4), timer_expired_delegate(FUNC(saturn_state::dma_lv1_ended),this)); break; |
| 521 | case 2: machine().scheduler().timer_set(m_maincpu->cycles_to_attotime(total_size/4), timer_expired_delegate(FUNC(saturn_state::dma_lv2_ended),this)); break; |
| 522 | } |
| 523 | } |
| 524 | } |
| 525 | |
| 526 | |
| 527 | /**************************************************************************************/ |
| 528 | |
| 529 | WRITE16_MEMBER(saturn_state::saturn_soundram_w) |
| 530 | { |
| 531 | //machine().scheduler().synchronize(); // force resync |
| 532 | |
| 533 | COMBINE_DATA(&m_sound_ram[offset]); |
| 534 | } |
| 535 | |
| 536 | READ16_MEMBER(saturn_state::saturn_soundram_r) |
| 537 | { |
| 538 | //machine().scheduler().synchronize(); // force resync |
| 539 | |
| 540 | return m_sound_ram[offset]; |
| 541 | } |
| 542 | |
| 543 | /* communication,SLAVE CPU acquires data from the MASTER CPU and triggers an irq. */ |
| 544 | WRITE32_MEMBER(saturn_state::minit_w) |
| 545 | { |
| 546 | //logerror("cpu %s (PC=%08X) MINIT write = %08x\n", space.device().tag(), space.device().safe_pc(),data); |
| 547 | machine().scheduler().boost_interleave(m_minit_boost_timeslice, attotime::from_usec(m_minit_boost)); |
| 548 | machine().scheduler().trigger(1000); |
| 549 | machine().scheduler().synchronize(); // force resync |
| 550 | sh2_set_frt_input(m_slave, PULSE_LINE); |
| 551 | } |
| 552 | |
| 553 | WRITE32_MEMBER(saturn_state::sinit_w) |
| 554 | { |
| 555 | //logerror("cpu %s (PC=%08X) SINIT write = %08x\n", space.device().tag(), space.device().safe_pc(),data); |
| 556 | machine().scheduler().boost_interleave(m_sinit_boost_timeslice, attotime::from_usec(m_sinit_boost)); |
| 557 | machine().scheduler().synchronize(); // force resync |
| 558 | sh2_set_frt_input(m_maincpu, PULSE_LINE); |
| 559 | } |
| 560 | |
| 561 | /* |
| 562 | TODO: |
| 563 | Some games seems to not like either MAME's interleave system and/or SH-2 DRC, causing an hard crash. |
| 564 | Reported games are: |
| 565 | Blast Wind (before FMV) |
| 566 | Choro Q Park (car selection) |
| 567 | 060311E4: MOV.L R14,@-SP ;R14 = 0x60ffba0 / R15 = 0x60ffba0 |
| 568 | 060311E6: MOV SP,R14 ;R14 = 0x60ffba0 / R15 = 0x60ffb9c / [0x60ffb9c] <- 0x60ffba0 |
| 569 | 060311E8: MOV.L @SP+,R14 ;R14 = 0x60ffb9c / R15 = 0x60ffb9c / [0x60ffb9c] -> R14 |
| 570 | 060311EA: RTS ;R14 = 0x60ffba0 / R15 = 0x60ffba0 |
| 571 | 060311EC: NOP |
| 572 | 06031734: MULS.W R9, R8 ;R14 = 0x60ffba0 / R15 = 0x60ffba0 / EA = 0x60311E4 |
| 573 | on DRC this becomes: |
| 574 | R14 0x6031b78 (cause of the crash later on), R15 = 0x60ffba4 and EA = 0 |
| 575 | |
| 576 | Shinrei Jusatsushi Taromaru (options menu) |
| 577 | |
| 578 | */ |
| 579 | |
| 580 | WRITE32_MEMBER(saturn_state::saturn_minit_w) |
| 581 | { |
| 582 | //logerror("cpu %s (PC=%08X) MINIT write = %08x\n", space.device().tag(), space.device().safe_pc(),data); |
| 583 | if(m_fake_comms->read() & 1) |
| 584 | machine().scheduler().synchronize(); // force resync |
| 585 | else |
| 586 | { |
| 587 | machine().scheduler().boost_interleave(m_minit_boost_timeslice, attotime::from_usec(m_minit_boost)); |
| 588 | machine().scheduler().trigger(1000); |
| 589 | } |
| 590 | |
| 591 | sh2_set_frt_input(m_slave, PULSE_LINE); |
| 592 | } |
| 593 | |
| 594 | WRITE32_MEMBER(saturn_state::saturn_sinit_w) |
| 595 | { |
| 596 | //logerror("cpu %s (PC=%08X) SINIT write = %08x\n", space.device().tag(), space.device().safe_pc(),data); |
| 597 | if(m_fake_comms->read() & 1) |
| 598 | machine().scheduler().synchronize(); // force resync |
| 599 | else |
| 600 | machine().scheduler().boost_interleave(m_sinit_boost_timeslice, attotime::from_usec(m_sinit_boost)); |
| 601 | |
| 602 | sh2_set_frt_input(m_maincpu, PULSE_LINE); |
| 603 | } |
| 604 | |
| 605 | |
| 606 | READ8_MEMBER(saturn_state::saturn_backupram_r) |
| 607 | { |
| 608 | if(!(offset & 1)) |
| 609 | return 0; // yes, it makes sure the "holes" are there. |
| 610 | |
| 611 | return m_backupram[offset >> 1] & 0xff; |
| 612 | } |
| 613 | |
| 614 | WRITE8_MEMBER(saturn_state::saturn_backupram_w) |
| 615 | { |
| 616 | if(!(offset & 1)) |
| 617 | return; |
| 618 | |
| 619 | m_backupram[offset >> 1] = data; |
| 620 | } |
| 621 | |
| 622 | void saturn_state::scu_reset(void) |
| 623 | { |
| 624 | m_scu.ism = 0xbfff; |
| 625 | m_scu.ist = 0; |
| 626 | m_scu.start_factor[0] = 7; |
| 627 | m_scu.start_factor[1] = 7; |
| 628 | m_scu.start_factor[2] = 7; |
| 629 | m_scu.status = 0; |
| 630 | } |
| 631 | |
| 632 | TIMER_CALLBACK_MEMBER(saturn_state::stv_rtc_increment) |
| 633 | { |
| 634 | static const UINT8 dpm[12] = { 0x31, 0x28, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, 0x30, 0x31, 0x30, 0x31 }; |
| 635 | static int year_num, year_count; |
| 636 | |
| 637 | /* |
| 638 | m_smpc.rtc_data[0] = DectoBCD(systime.local_time.year /100); |
| 639 | m_smpc.rtc_data[1] = DectoBCD(systime.local_time.year %100); |
| 640 | m_smpc.rtc_data[2] = (systime.local_time.weekday << 4) | (systime.local_time.month+1); |
| 641 | m_smpc.rtc_data[3] = DectoBCD(systime.local_time.mday); |
| 642 | m_smpc.rtc_data[4] = DectoBCD(systime.local_time.hour); |
| 643 | m_smpc.rtc_data[5] = DectoBCD(systime.local_time.minute); |
| 644 | m_smpc.rtc_data[6] = DectoBCD(systime.local_time.second); |
| 645 | */ |
| 646 | |
| 647 | m_smpc.rtc_data[6]++; |
| 648 | |
| 649 | /* seconds from 9 -> 10*/ |
| 650 | if((m_smpc.rtc_data[6] & 0x0f) >= 0x0a) { m_smpc.rtc_data[6]+=0x10; m_smpc.rtc_data[6]&=0xf0; } |
| 651 | /* seconds from 59 -> 0 */ |
| 652 | if((m_smpc.rtc_data[6] & 0xf0) >= 0x60) { m_smpc.rtc_data[5]++; m_smpc.rtc_data[6] = 0; } |
| 653 | /* minutes from 9 -> 10 */ |
| 654 | if((m_smpc.rtc_data[5] & 0x0f) >= 0x0a) { m_smpc.rtc_data[5]+=0x10; m_smpc.rtc_data[5]&=0xf0; } |
| 655 | /* minutes from 59 -> 0 */ |
| 656 | if((m_smpc.rtc_data[5] & 0xf0) >= 0x60) { m_smpc.rtc_data[4]++; m_smpc.rtc_data[5] = 0; } |
| 657 | /* hours from 9 -> 10 */ |
| 658 | if((m_smpc.rtc_data[4] & 0x0f) >= 0x0a) { m_smpc.rtc_data[4]+=0x10; m_smpc.rtc_data[4]&=0xf0; } |
| 659 | /* hours from 23 -> 0 */ |
| 660 | if((m_smpc.rtc_data[4] & 0xff) >= 0x24) { m_smpc.rtc_data[3]++; m_smpc.rtc_data[2]+=0x10; m_smpc.rtc_data[4] = 0; } |
| 661 | /* week day name sunday -> monday */ |
| 662 | if((m_smpc.rtc_data[2] & 0xf0) >= 0x70) { m_smpc.rtc_data[2]&=0x0f; } |
| 663 | /* day number 9 -> 10 */ |
| 664 | if((m_smpc.rtc_data[3] & 0x0f) >= 0x0a) { m_smpc.rtc_data[3]+=0x10; m_smpc.rtc_data[3]&=0xf0; } |
| 665 | |
| 666 | // year BCD to dec conversion (for the leap year stuff) |
| 667 | { |
| 668 | year_num = (m_smpc.rtc_data[1] & 0xf); |
| 669 | |
| 670 | for(year_count = 0; year_count < (m_smpc.rtc_data[1] & 0xf0); year_count += 0x10) |
| 671 | year_num += 0xa; |
| 672 | |
| 673 | year_num += (m_smpc.rtc_data[0] & 0xf)*0x64; |
| 674 | |
| 675 | for(year_count = 0; year_count < (m_smpc.rtc_data[0] & 0xf0); year_count += 0x10) |
| 676 | year_num += 0x3e8; |
| 677 | } |
| 678 | |
| 679 | /* month +1 check */ |
| 680 | /* the RTC have a range of 1980 - 2100, so we don't actually need to support the leap year special conditions */ |
| 681 | if(((year_num % 4) == 0) && (m_smpc.rtc_data[2] & 0xf) == 2) |
| 682 | { |
| 683 | if((m_smpc.rtc_data[3] & 0xff) >= dpm[(m_smpc.rtc_data[2] & 0xf)-1]+1+1) |
| 684 | { m_smpc.rtc_data[2]++; m_smpc.rtc_data[3] = 0x01; } |
| 685 | } |
| 686 | else if((m_smpc.rtc_data[3] & 0xff) >= dpm[(m_smpc.rtc_data[2] & 0xf)-1]+1){ m_smpc.rtc_data[2]++; m_smpc.rtc_data[3] = 0x01; } |
| 687 | /* year +1 check */ |
| 688 | if((m_smpc.rtc_data[2] & 0x0f) > 12) { m_smpc.rtc_data[1]++; m_smpc.rtc_data[2] = (m_smpc.rtc_data[2] & 0xf0) | 0x01; } |
| 689 | /* year from 9 -> 10 */ |
| 690 | if((m_smpc.rtc_data[1] & 0x0f) >= 0x0a) { m_smpc.rtc_data[1]+=0x10; m_smpc.rtc_data[1]&=0xf0; } |
| 691 | /* year from 99 -> 100 */ |
| 692 | if((m_smpc.rtc_data[1] & 0xf0) >= 0xa0) { m_smpc.rtc_data[0]++; m_smpc.rtc_data[1] = 0; } |
| 693 | |
| 694 | // probably not SO precise, here just for reference ... |
| 695 | /* year from 999 -> 1000 */ |
| 696 | //if((m_smpc.rtc_data[0] & 0x0f) >= 0x0a) { m_smpc.rtc_data[0]+=0x10; m_smpc.rtc_data[0]&=0xf0; } |
| 697 | /* year from 9999 -> 0 */ |
| 698 | //if((m_smpc.rtc_data[0] & 0xf0) >= 0xa0) { m_smpc.rtc_data[0] = 0; } //roll over |
| 699 | } |
| 700 | |
| 701 | /* Official documentation says that the "RESET/TAS opcodes aren't supported", but Out Run definitely contradicts with it. |
| 702 | Since that m68k can't reset itself via the RESET opcode I suppose that the SMPC actually do it by reading an i/o |
| 703 | connected to this opcode. */ |
| 704 | void saturn_state::m68k_reset_callback(device_t *device) |
| 705 | { |
| 706 | saturn_state *state = device->machine().driver_data<saturn_state>(); |
| 707 | device->machine().scheduler().timer_set(attotime::from_usec(100), timer_expired_delegate(FUNC(saturn_state::smpc_audio_reset_line_pulse), state)); |
| 708 | |
| 709 | printf("m68k RESET opcode triggered\n"); |
| 710 | } |
| 711 | |
| 712 | void scsp_irq(device_t *device, int irq) |
| 713 | { |
| 714 | saturn_state *state = device->machine().driver_data<saturn_state>(); |
| 715 | |
| 716 | // don't bother the 68k if it's off |
| 717 | if (!state->m_en_68k) |
| 718 | { |
| 719 | return; |
| 720 | } |
| 721 | |
| 722 | if (irq > 0) |
| 723 | { |
| 724 | state->m_scsp_last_line = irq; |
| 725 | device->machine().device("audiocpu")->execute().set_input_line(irq, ASSERT_LINE); |
| 726 | } |
| 727 | else if (irq < 0) |
| 728 | { |
| 729 | device->machine().device("audiocpu")->execute().set_input_line(-irq, CLEAR_LINE); |
| 730 | } |
| 731 | else |
| 732 | { |
| 733 | device->machine().device("audiocpu")->execute().set_input_line(state->m_scsp_last_line, CLEAR_LINE); |
| 734 | } |
| 735 | } |
| 736 | |
| 737 | WRITE_LINE_MEMBER(saturn_state::scsp_to_main_irq) |
| 738 | { |
| 739 | if(state) |
| 740 | { |
| 741 | if(!(m_scu.ism & IRQ_SOUND_REQ)) |
| 742 | { |
| 743 | m_maincpu->set_input_line_and_vector(9, HOLD_LINE, 0x46); |
| 744 | scu_do_transfer(5); |
| 745 | } |
| 746 | else |
| 747 | m_scu.ist |= (IRQ_SOUND_REQ); |
| 748 | } |
| 749 | } |
| 750 | |
| 751 | |
| 752 | |
| 753 | /* |
| 754 | (Preliminary) explanation about this: |
| 755 | VBLANK-OUT is used at the start of the vblank period.It also sets the timer zero |
| 756 | variable to 0. |
| 757 | If the Timer Compare register is zero too,the Timer 0 irq is triggered. |
| 758 | |
| 759 | HBLANK-IN is used at the end of each scanline except when in VBLANK-IN/OUT periods. |
| 760 | |
| 761 | The timer 0 is also incremented by one at each HBLANK and checked with the value |
| 762 | of the Timer Compare register;if equal,the timer 0 irq is triggered here too. |
| 763 | Notice that the timer 0 compare register can be more than the VBLANK maximum range,in |
| 764 | this case the timer 0 irq is simply never triggered.This is a known Sega Saturn/ST-V "bug". |
| 765 | |
| 766 | VBLANK-IN is used at the end of the vblank period. |
| 767 | |
| 768 | SCU register[36] is the timer zero compare register. |
| 769 | SCU register[40] is for IRQ masking. |
| 770 | |
| 771 | TODO: |
| 772 | - VDP1 timing and CEF emulation isn't accurate at all. |
| 773 | */ |
| 774 | |
| 775 | |
| 776 | TIMER_DEVICE_CALLBACK_MEMBER(saturn_state::saturn_scanline) |
| 777 | { |
| 778 | int scanline = param; |
| 779 | int y_step,vblank_line; |
| 780 | |
| 781 | vblank_line = get_vblank_start_position(); |
| 782 | y_step = get_ystep_count(); |
| 783 | |
| 784 | //popmessage("%08x %d T0 %d T1 %d %08x",m_scu.ism ^ 0xffffffff,max_y,m_scu_regs[36],m_scu_regs[37],m_scu_regs[38]); |
| 785 | |
| 786 | if(scanline == (0)*y_step) |
| 787 | { |
| 788 | video_update_vdp1(); |
| 789 | |
| 790 | if(STV_VDP1_VBE) |
| 791 | m_vdp1.framebuffer_clear_on_next_frame = 1; |
| 792 | |
| 793 | if(!(m_scu.ism & IRQ_VDP1_END)) |
| 794 | { |
| 795 | m_maincpu->set_input_line_and_vector(0x2, HOLD_LINE, 0x4d); |
| 796 | scu_do_transfer(6); |
| 797 | } |
| 798 | else |
| 799 | m_scu.ist |= (IRQ_VDP1_END); |
| 800 | } |
| 801 | |
| 802 | if(scanline == 0*y_step) |
| 803 | { |
| 804 | if(!(m_scu.ism & IRQ_VBLANK_OUT)) |
| 805 | { |
| 806 | m_maincpu->set_input_line_and_vector(0xe, HOLD_LINE, 0x41); |
| 807 | scu_do_transfer(1); |
| 808 | } |
| 809 | else |
| 810 | m_scu.ist |= (IRQ_VBLANK_OUT); |
| 811 | |
| 812 | } |
| 813 | else if(scanline == vblank_line*y_step) |
| 814 | { |
| 815 | if(!(m_scu.ism & IRQ_VBLANK_IN)) |
| 816 | { |
| 817 | m_maincpu->set_input_line_and_vector(0xf, HOLD_LINE ,0x40); |
| 818 | scu_do_transfer(0); |
| 819 | } |
| 820 | else |
| 821 | m_scu.ist |= (IRQ_VBLANK_IN); |
| 822 | } |
| 823 | else if((scanline % y_step) == 0 && scanline < vblank_line*y_step) |
| 824 | { |
| 825 | if(!(m_scu.ism & IRQ_HBLANK_IN)) |
| 826 | { |
| 827 | m_maincpu->set_input_line_and_vector(0xd, HOLD_LINE, 0x42); |
| 828 | scu_do_transfer(2); |
| 829 | } |
| 830 | else |
| 831 | m_scu.ist |= (IRQ_HBLANK_IN); |
| 832 | } |
| 833 | |
| 834 | if(scanline == (m_scu_regs[36] & 0x3ff)*y_step) |
| 835 | { |
| 836 | if(!(m_scu.ism & IRQ_TIMER_0)) |
| 837 | { |
| 838 | m_maincpu->set_input_line_and_vector(0xc, HOLD_LINE, 0x43 ); |
| 839 | scu_do_transfer(3); |
| 840 | } |
| 841 | else |
| 842 | m_scu.ist |= (IRQ_TIMER_0); |
| 843 | } |
| 844 | |
| 845 | /* TODO: this isn't completely correct */ |
| 846 | if(m_scu_regs[38] & 0x1) |
| 847 | { |
| 848 | if((!(m_scu_regs[38] & 0x100) && (scanline % y_step) == 0) || |
| 849 | ((m_scu_regs[38] & 0x100) && (scanline == (m_scu_regs[36] & 0x3ff)*y_step))) |
| 850 | { |
| 851 | if(!(m_scu.ism & IRQ_TIMER_1)) |
| 852 | { |
| 853 | m_maincpu->set_input_line_and_vector(0xb, HOLD_LINE, 0x44 ); |
| 854 | scu_do_transfer(4); |
| 855 | } |
| 856 | else |
| 857 | m_scu.ist |= (IRQ_TIMER_1); |
| 858 | } |
| 859 | } |
| 860 | } |
| 861 | |
| 862 | TIMER_DEVICE_CALLBACK_MEMBER(saturn_state::saturn_slave_scanline ) |
| 863 | { |
| 864 | int scanline = param; |
| 865 | int y_step,vblank_line; |
| 866 | |
| 867 | vblank_line = get_vblank_start_position(); |
| 868 | y_step = get_ystep_count(); |
| 869 | |
| 870 | if(scanline == vblank_line*y_step) |
| 871 | m_slave->set_input_line_and_vector(0x6, HOLD_LINE, 0x43); |
| 872 | else if((scanline % y_step) == 0 && scanline < vblank_line*y_step) |
| 873 | m_slave->set_input_line_and_vector(0x2, HOLD_LINE, 0x41); |
| 874 | } |
| 875 | |
| 876 | static const gfx_layout tiles8x8x4_layout = |
| 877 | { |
| 878 | 8,8, |
| 879 | 0x100000/(32*8/8), |
| 880 | 4, |
| 881 | { 0, 1, 2, 3 }, |
| 882 | { 0, 4, 8, 12, 16, 20, 24, 28 }, |
| 883 | { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 }, |
| 884 | 32*8 |
| 885 | }; |
| 886 | |
| 887 | static const gfx_layout tiles16x16x4_layout = |
| 888 | { |
| 889 | 16,16, |
| 890 | 0x100000/(32*32/8), |
| 891 | 4, |
| 892 | { 0, 1, 2, 3 }, |
| 893 | { 0, 4, 8, 12, 16, 20, 24, 28, |
| 894 | 32*8+0, 32*8+4, 32*8+8, 32*8+12, 32*8+16, 32*8+20, 32*8+24, 32*8+28, |
| 895 | |
| 896 | }, |
| 897 | { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32, |
| 898 | 32*16, 32*17,32*18, 32*19,32*20,32*21,32*22,32*23 |
| 899 | |
| 900 | }, |
| 901 | 32*32 |
| 902 | }; |
| 903 | |
| 904 | static const gfx_layout tiles8x8x8_layout = |
| 905 | { |
| 906 | 8,8, |
| 907 | 0x100000/(32*8/8), |
| 908 | 8, |
| 909 | { 0, 1, 2, 3, 4, 5, 6, 7 }, |
| 910 | { 0, 8, 16, 24, 32, 40, 48, 56 }, |
| 911 | { 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64 }, |
| 912 | 32*8 /* really 64*8, but granularity is 32 bytes */ |
| 913 | }; |
| 914 | |
| 915 | static const gfx_layout tiles16x16x8_layout = |
| 916 | { |
| 917 | 16,16, |
| 918 | 0x100000/(64*16/8), |
| 919 | 8, |
| 920 | { 0, 1, 2, 3, 4, 5, 6, 7 }, |
| 921 | { 0, 8, 16, 24, 32, 40, 48, 56, |
| 922 | 64*8+0, 65*8, 66*8, 67*8, 68*8, 69*8, 70*8, 71*8 |
| 923 | |
| 924 | }, |
| 925 | { 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64, |
| 926 | 64*16, 64*17, 64*18, 64*19, 64*20, 64*21, 64*22, 64*23 |
| 927 | }, |
| 928 | 64*16 /* really 128*16, but granularity is 32 bytes */ |
| 929 | }; |
| 930 | |
| 931 | |
| 932 | |
| 933 | |
| 934 | GFXDECODE_START( stv ) |
| 935 | GFXDECODE_ENTRY( NULL, 0, tiles8x8x4_layout, 0x00, (0x80*(2+1)) ) |
| 936 | GFXDECODE_ENTRY( NULL, 0, tiles16x16x4_layout, 0x00, (0x80*(2+1)) ) |
| 937 | GFXDECODE_ENTRY( NULL, 0, tiles8x8x8_layout, 0x00, (0x08*(2+1)) ) |
| 938 | GFXDECODE_ENTRY( NULL, 0, tiles16x16x8_layout, 0x00, (0x08*(2+1)) ) |
| 939 | GFXDECODE_END |
trunk/src/mess/drivers/saturn.c
| r0 | r21331 | |
| 1 | /************************************************************************************************** |
| 2 | |
| 3 | Sega Saturn & Sega ST-V (Sega Titan Video) HW (c) 1994 Sega |
| 4 | |
| 5 | Driver by David Haywood, Angelo Salese, Olivier Galibert & Mariusz Wojcieszek |
| 6 | SCSP driver provided by R.Belmont, based on ElSemi's SCSP sound chip emulator |
| 7 | CD Block driver provided by ANY, based on sthief original emulator |
| 8 | Many thanks to Guru, Fabien, Runik and Charles MacDonald for the help given. |
| 9 | |
| 10 | =================================================================================================== |
| 11 | |
| 12 | Notes: |
| 13 | -To enter into an Advanced Test Mode,keep pressed the Test Button (F2) on the start-up. |
| 14 | -Memo: Some tests done on the original & working PCB,to be implemented: |
| 15 | -The AD-Stick returns 0x00 or a similar value. |
| 16 | -The Ports E,F & G must return 0xff |
| 17 | |
| 18 | TODO: |
| 19 | (Main issues) |
| 20 | - decap the SH-1, used for CD block (needed especially for Sega Saturn) |
| 21 | - IRQs: some games have some issues with timing accurate IRQs, check/fix all of them. |
| 22 | - The Cart-Dev mode hangs even with the -dev bios,I would like to see what it does on the real HW. |
| 23 | - IC13 games on the dev bios doesn't even load the cartridge / crashes the emulation at start-up, |
| 24 | rom rearrange needed? |
| 25 | - SCU DSP still has its fair share of issues, it also needs to be converted to CPU structure; |
| 26 | - Add the RS232c interface (serial port), needed by fhboxers (accesses some ports in the a-bus dummy range). |
| 27 | - Video emulation is nowhere near perfection. |
| 28 | - Reimplement the idle skip if possible. |
| 29 | - Properly emulate the protection chips, used by several games (check stvprot.c for more info) |
| 30 | - Move SCU device into its respective file; |
| 31 | - Split ST-V and Saturn files properly; |
| 32 | |
| 33 | (per-game issues) |
| 34 | - stress: accesses the Sound Memory Expansion Area (0x05a80000-0x05afffff), unknown purpose; |
| 35 | |
| 36 | - smleague / finlarch: it randomly hangs / crashes,it works if you use a ridiculous MCFG_INTERLEAVE number,might need strict |
| 37 | SH-2 synching or it's actually a m68k comms issue. |
| 38 | |
| 39 | - groovef: ugly back screen color, caused by incorrect usage of the Color Calculation function. |
| 40 | |
| 41 | - myfairld: Apparently this game gives a black screen (either test mode and in-game mode),but let it wait for about |
| 42 | 10 seconds and the game will load everything. This is because of a hellishly slow m68k sub-routine located at 54c2. |
| 43 | Likely to not be a bug but an in-game design issue. |
| 44 | |
| 45 | - danchih / danchiq: currently hangs randomly (regression). |
| 46 | |
| 47 | - batmanfr: Missing sound,caused by an extra ADSP chip which is on the cart.The CPU is a |
| 48 | ADSP-2181,and it's the same used by NBA Jam Extreme (ZN game). |
| 49 | |
| 50 | - vfremix: when you play as Akira, there is a problem with third match: game doesn't upload all textures |
| 51 | and tiles and doesn't enable display, although gameplay is normal - wait a while to get back |
| 52 | to title screen after losing a match |
| 53 | |
| 54 | - vfremix: various problems with SCU DSP: Jeffry causes a black screen hang. Akira's kick sometimes |
| 55 | sends the opponent out of the ring from whatever position. |
| 56 | |
| 57 | |
| 58 | ****************************************************************************************************/ |
| 59 | |
| 60 | #include "emu.h" |
| 61 | #include "cpu/m68000/m68000.h" |
| 62 | #include "machine/eeprom.h" |
| 63 | #include "cpu/sh2/sh2.h" |
| 64 | #include "machine/scudsp.h" |
| 65 | #include "sound/scsp.h" |
| 66 | #include "sound/cdda.h" |
| 67 | #include "machine/smpc.h" |
| 68 | #include "includes/stv.h" |
| 69 | #include "imagedev/chd_cd.h" |
| 70 | #include "imagedev/cartslot.h" |
| 71 | #include "coreutil.h" |
| 72 | |
| 73 | |
| 74 | |
| 75 | /* TODO: if you change the driver configuration then NVRAM contents gets screwed, needs mods in MAME framework */ |
| 76 | static NVRAM_HANDLER(saturn) |
| 77 | { |
| 78 | saturn_state *state = machine.driver_data<saturn_state>(); |
| 79 | static const UINT32 BUP_SIZE = 32*1024; |
| 80 | static const UINT32 EBUP_SIZE = 0;//0x100000; // TODO: can't support more than 8 Mbit |
| 81 | UINT8 backup_file[(BUP_SIZE)+EBUP_SIZE+4]; |
| 82 | static const UINT8 init[16] = |
| 83 | { |
| 84 | 'B', 'a', 'c', 'k', 'U', 'p', 'R', 'a', 'm', ' ', 'F', 'o', 'r', 'm', 'a', 't' |
| 85 | }; |
| 86 | UINT32 i; |
| 87 | |
| 88 | if (read_or_write) |
| 89 | { |
| 90 | for(i=0;i<BUP_SIZE;i++) |
| 91 | backup_file[i] = state->m_backupram[i]; |
| 92 | #if 0 |
| 93 | for(i=0;i<EBUP_SIZE;i++) |
| 94 | backup_file[i+BUP_SIZE] = state->m_cart_backupram[i]; |
| 95 | #endif |
| 96 | for(i=0;i<4;i++) |
| 97 | backup_file[i+(BUP_SIZE)+EBUP_SIZE] = state->m_smpc.SMEM[i]; |
| 98 | |
| 99 | file->write(backup_file, (BUP_SIZE)+EBUP_SIZE+4); |
| 100 | } |
| 101 | else |
| 102 | { |
| 103 | if (file) |
| 104 | { |
| 105 | file->read(backup_file, (BUP_SIZE)+EBUP_SIZE+4); |
| 106 | |
| 107 | for(i=0;i<BUP_SIZE;i++) |
| 108 | state->m_backupram[i] = backup_file[i]; |
| 109 | #if 0 |
| 110 | for(i=0;i<EBUP_SIZE;i++) |
| 111 | state->m_cart_backupram[i] = backup_file[i+BUP_SIZE]; |
| 112 | #endif |
| 113 | for(i=0;i<4;i++) |
| 114 | state->m_smpc.SMEM[i] = backup_file[i+BUP_SIZE+EBUP_SIZE]; |
| 115 | } |
| 116 | else |
| 117 | { |
| 118 | UINT8 j; |
| 119 | memset(state->m_backupram, 0, BUP_SIZE); |
| 120 | for (i = 0; i < 4; i++) |
| 121 | { |
| 122 | for(j=0;j<16;j++) |
| 123 | state->m_backupram[i*16+j] = init[j]; |
| 124 | } |
| 125 | #if 0 |
| 126 | memset(state->m_cart_backupram, 0, EBUP_SIZE); |
| 127 | for (i = 0; i < 32; i++) |
| 128 | { |
| 129 | for(j=0;j<16;j++) |
| 130 | state->m_cart_backupram[i*16+j] = init[j]; |
| 131 | } |
| 132 | #endif |
| 133 | memset(state->m_smpc.SMEM, 0, 4); // TODO: default for each region |
| 134 | } |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | READ8_MEMBER(saturn_state::saturn_cart_type_r) |
| 139 | { |
| 140 | const int cart_ram_header[7] = { 0xff, 0x21, 0x22, 0x23, 0x24, 0x5a, 0x5c }; |
| 141 | |
| 142 | return cart_ram_header[m_cart_type]; |
| 143 | } |
| 144 | |
| 145 | /* TODO: Bug! accesses this one, if returning 0 the SH-2 hard-crashes. Might be an actual bug with the CD block. */ |
| 146 | READ32_HANDLER( saturn_state::abus_dummy_r ) |
| 147 | { |
| 148 | logerror("A-Bus Dummy access %08x\n",offset*4); |
| 149 | return -1; |
| 150 | } |
| 151 | |
| 152 | static ADDRESS_MAP_START( saturn_mem, AS_PROGRAM, 32, saturn_state ) |
| 153 | AM_RANGE(0x00000000, 0x0007ffff) AM_ROM AM_SHARE("share6") // bios |
| 154 | AM_RANGE(0x00100000, 0x0010007f) AM_READWRITE8(saturn_SMPC_r, saturn_SMPC_w,0xffffffff) |
| 155 | AM_RANGE(0x00180000, 0x0018ffff) AM_READWRITE8(saturn_backupram_r, saturn_backupram_w,0xffffffff) AM_SHARE("share1") |
| 156 | AM_RANGE(0x00200000, 0x002fffff) AM_RAM AM_MIRROR(0x20100000) AM_SHARE("workram_l") |
| 157 | AM_RANGE(0x01000000, 0x017fffff) AM_WRITE(saturn_minit_w) |
| 158 | AM_RANGE(0x01800000, 0x01ffffff) AM_WRITE(saturn_sinit_w) |
| 159 | AM_RANGE(0x02000000, 0x023fffff) AM_ROM AM_SHARE("share7") AM_REGION("maincpu", 0x80000) // cartridge space |
| 160 | // AM_RANGE(0x02400000, 0x027fffff) AM_RAM //cart RAM area, dynamically allocated |
| 161 | // AM_RANGE(0x04000000, 0x047fffff) AM_RAM //backup RAM area, dynamically allocated |
| 162 | AM_RANGE(0x04fffffc, 0x04ffffff) AM_READ8(saturn_cart_type_r,0x000000ff) |
| 163 | AM_RANGE(0x05000000, 0x057fffff) AM_READ(abus_dummy_r) |
| 164 | AM_RANGE(0x05800000, 0x0589ffff) AM_READWRITE(stvcd_r, stvcd_w) |
| 165 | /* Sound */ |
| 166 | AM_RANGE(0x05a00000, 0x05a7ffff) AM_READWRITE16(saturn_soundram_r, saturn_soundram_w,0xffffffff) |
| 167 | AM_RANGE(0x05b00000, 0x05b00fff) AM_DEVREADWRITE16_LEGACY("scsp", scsp_r, scsp_w, 0xffffffff) |
| 168 | /* VDP1 */ |
| 169 | AM_RANGE(0x05c00000, 0x05c7ffff) AM_READWRITE(saturn_vdp1_vram_r, saturn_vdp1_vram_w) |
| 170 | AM_RANGE(0x05c80000, 0x05cbffff) AM_READWRITE(saturn_vdp1_framebuffer0_r, saturn_vdp1_framebuffer0_w) |
| 171 | AM_RANGE(0x05d00000, 0x05d0001f) AM_READWRITE16(saturn_vdp1_regs_r, saturn_vdp1_regs_w,0xffffffff) |
| 172 | AM_RANGE(0x05e00000, 0x05e7ffff) AM_MIRROR(0x80000) AM_READWRITE(saturn_vdp2_vram_r, saturn_vdp2_vram_w) |
| 173 | AM_RANGE(0x05f00000, 0x05f7ffff) AM_READWRITE(saturn_vdp2_cram_r, saturn_vdp2_cram_w) |
| 174 | AM_RANGE(0x05f80000, 0x05fbffff) AM_READWRITE16(saturn_vdp2_regs_r, saturn_vdp2_regs_w,0xffffffff) |
| 175 | AM_RANGE(0x05fe0000, 0x05fe00cf) AM_READWRITE(saturn_scu_r, saturn_scu_w) |
| 176 | AM_RANGE(0x06000000, 0x060fffff) AM_RAM AM_MIRROR(0x21f00000) AM_SHARE("workram_h") |
| 177 | AM_RANGE(0x20000000, 0x2007ffff) AM_ROM AM_SHARE("share6") // bios mirror |
| 178 | AM_RANGE(0x22000000, 0x24ffffff) AM_ROM AM_SHARE("share7") // cart mirror |
| 179 | AM_RANGE(0x45000000, 0x46ffffff) AM_WRITENOP |
| 180 | AM_RANGE(0x60000000, 0x600003ff) AM_WRITENOP // cache address array |
| 181 | AM_RANGE(0xc0000000, 0xc00007ff) AM_RAM // cache data array, Dragon Ball Z sprites relies on this |
| 182 | ADDRESS_MAP_END |
| 183 | |
| 184 | static ADDRESS_MAP_START( sound_mem, AS_PROGRAM, 16, saturn_state ) |
| 185 | AM_RANGE(0x000000, 0x0fffff) AM_RAM AM_SHARE("sound_ram") |
| 186 | AM_RANGE(0x100000, 0x100fff) AM_DEVREADWRITE_LEGACY("scsp", scsp_r, scsp_w) |
| 187 | ADDRESS_MAP_END |
| 188 | |
| 189 | |
| 190 | /* keyboard code */ |
| 191 | /* TODO: needs a proper keycode table */ |
| 192 | INPUT_CHANGED_MEMBER(saturn_state::key_stroke) |
| 193 | { |
| 194 | if(newval && !oldval) |
| 195 | { |
| 196 | m_keyb.data = ((UINT8)(FPTR)(param) & 0xff); |
| 197 | m_keyb.status |= 8; |
| 198 | } |
| 199 | |
| 200 | if(oldval && !newval) |
| 201 | { |
| 202 | //m_keyb.status &= ~8; |
| 203 | m_keyb.data = 0; |
| 204 | } |
| 205 | } |
| 206 | |
| 207 | /* Note: unused bits must stay high, Bug 2 relies on this. */ |
| 208 | #define SATURN_PAD_P1(_mask_, _val_) \ |
| 209 | PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 210 | PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 211 | PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 212 | PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 213 | PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 214 | PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P1 A") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 215 | PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("P1 C") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 216 | PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("P1 B") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 217 | PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("P1 R") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 218 | PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("P1 X") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 219 | PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("P1 Y") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 220 | PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("P1 Z") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 221 | PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("P1 L") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 222 | PORT_BIT( 0x0007, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) |
| 223 | |
| 224 | #define SATURN_PAD_P2(_mask_, _val_) \ |
| 225 | PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 226 | PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 227 | PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 228 | PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 229 | PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 230 | PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P2 A") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 231 | PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("P2 C") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 232 | PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("P2 B") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 233 | PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("P2 R") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 234 | PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("P2 X") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 235 | PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("P2 Y") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 236 | PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("P2 Z") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 237 | PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("P2 L") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 238 | PORT_BIT( 0x0007, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) |
| 239 | |
| 240 | #define MD_PAD_P1(_mask_, _val_) \ |
| 241 | PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 242 | PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 243 | PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 244 | PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 245 | PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 246 | PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P1 A") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 247 | PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("P1 C") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 248 | PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("P1 B") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 249 | PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("P1 Mode") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 250 | PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("P1 X") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 251 | PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("P1 Y") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 252 | PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("P1 Z") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 253 | PORT_BIT( 0x000f, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) //read '1' when direct mode is polled |
| 254 | |
| 255 | #define MD_PAD_P2(_mask_, _val_) \ |
| 256 | PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 257 | PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 258 | PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 259 | PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 260 | PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 261 | PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P2 A") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 262 | PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("P2 C") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 263 | PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("P2 B") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 264 | PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("P2 Mode") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 265 | PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("P2 X") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 266 | PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("P2 Y") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 267 | PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("P2 Z") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 268 | PORT_BIT( 0x000f, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) //read '1' when direct mode is polled |
| 269 | |
| 270 | #define SATURN_KEYBOARD PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x05) |
| 271 | |
| 272 | INPUT_CHANGED_MEMBER(saturn_state::nmi_reset) |
| 273 | { |
| 274 | /* TODO: correct? */ |
| 275 | if(!m_NMI_reset) |
| 276 | return; |
| 277 | |
| 278 | /* TODO: NMI doesn't stay held on SH-2 core so we can't use ASSERT_LINE/CLEAR_LINE with that yet */ |
| 279 | if(newval) |
| 280 | m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE); |
| 281 | } |
| 282 | |
| 283 | INPUT_CHANGED_MEMBER(saturn_state::tray_open) |
| 284 | { |
| 285 | if(newval) |
| 286 | stvcd_set_tray_open(); |
| 287 | } |
| 288 | |
| 289 | INPUT_CHANGED_MEMBER(saturn_state::tray_close) |
| 290 | { |
| 291 | if(newval) |
| 292 | stvcd_set_tray_close(); |
| 293 | } |
| 294 | |
| 295 | static INPUT_PORTS_START( saturn ) |
| 296 | PORT_START("RESET") /* hardwired buttons */ |
| 297 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, nmi_reset,0) PORT_NAME("Reset Button") |
| 298 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, tray_open,0) PORT_NAME("Tray Open Button") |
| 299 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, tray_close,0) PORT_NAME("Tray Close") |
| 300 | |
| 301 | PORT_START("JOY1") |
| 302 | SATURN_PAD_P1(0x0f, 0) |
| 303 | |
| 304 | PORT_START("JOY2") |
| 305 | SATURN_PAD_P2(0xf0, 0) |
| 306 | |
| 307 | /* TODO: there's no info about the keycode used on Saturn keyboard, following is trial & error with Game Basic software */ |
| 308 | PORT_START("KEY0") // 0x00 - 0x07 |
| 309 | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_UNUSED) SATURN_KEYBOARD |
| 310 | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F1") /*PORT_CODE(KEYCODE_F1)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x01) PORT_PLAYER(1) SATURN_KEYBOARD |
| 311 | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("0-3") /*PORT_CODE(KEYCODE_2) PORT_CHAR('2')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x02) PORT_PLAYER(1) SATURN_KEYBOARD |
| 312 | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F2") /*PORT_CODE(KEYCODE_F2)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x03) PORT_PLAYER(1) SATURN_KEYBOARD // RUN |
| 313 | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F3") /*PORT_CODE(KEYCODE_F3)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x04) PORT_PLAYER(1) SATURN_KEYBOARD // LIST |
| 314 | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F4") /*PORT_CODE(KEYCODE_F4)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x05) PORT_PLAYER(1) SATURN_KEYBOARD // EDIT |
| 315 | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F5") /*PORT_CODE(KEYCODE_F5)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x06) PORT_PLAYER(1) SATURN_KEYBOARD |
| 316 | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("CLR SCR") PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x07) PORT_PLAYER(1) SATURN_KEYBOARD |
| 317 | |
| 318 | PORT_START("KEY1") // 0x08 - 0x0f |
| 319 | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("1-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x08) PORT_PLAYER(1) SATURN_KEYBOARD |
| 320 | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F6") /*PORT_CODE(KEYCODE_F6)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x09) PORT_PLAYER(1) SATURN_KEYBOARD |
| 321 | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F7") /*PORT_CODE(KEYCODE_F7)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x0a) PORT_PLAYER(1) SATURN_KEYBOARD |
| 322 | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F8") /*PORT_CODE(KEYCODE_F8)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x0b) PORT_PLAYER(1) SATURN_KEYBOARD |
| 323 | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F9") /*PORT_CODE(KEYCODE_F9)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x0c) PORT_PLAYER(1) SATURN_KEYBOARD // LIST again |
| 324 | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("1-6") /*PORT_CODE(KEYCODE_5) PORT_CHAR('5')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x0d) PORT_PLAYER(1) SATURN_KEYBOARD |
| 325 | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("1-7") /*PORT_CODE(KEYCODE_6) PORT_CHAR('6')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x0e) PORT_PLAYER(1) SATURN_KEYBOARD |
| 326 | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("1-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x0f) PORT_PLAYER(1) SATURN_KEYBOARD |
| 327 | |
| 328 | PORT_START("KEY2") // 0x10 - 0x17 |
| 329 | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("2-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x10) PORT_PLAYER(1) SATURN_KEYBOARD |
| 330 | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("2-2") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x11) PORT_PLAYER(1) SATURN_KEYBOARD |
| 331 | /* TODO: break codes! */ |
| 332 | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("SHIFT") /*PORT_CODE(KEYCODE_2) PORT_CHAR('2')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x12) PORT_PLAYER(1) SATURN_KEYBOARD |
| 333 | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("KANA SHIFT") /*PORT_CODE(KEYCODE_3) PORT_CHAR('3')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x13) PORT_PLAYER(1) SATURN_KEYBOARD |
| 334 | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("(special keys)") /*PORT_CODE(KEYCODE_4) PORT_CHAR('4')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x14) PORT_PLAYER(1) SATURN_KEYBOARD |
| 335 | |
| 336 | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x15) PORT_PLAYER(1) SATURN_KEYBOARD |
| 337 | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x16) PORT_PLAYER(1) SATURN_KEYBOARD |
| 338 | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("2-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x17) PORT_PLAYER(1) SATURN_KEYBOARD |
| 339 | |
| 340 | PORT_START("KEY3") // 0x18 - 0x1f |
| 341 | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("3-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x18) PORT_PLAYER(1) SATURN_KEYBOARD |
| 342 | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("3-2") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x19) PORT_PLAYER(1) SATURN_KEYBOARD |
| 343 | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x1a) PORT_PLAYER(1) SATURN_KEYBOARD |
| 344 | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x1b) PORT_PLAYER(1) SATURN_KEYBOARD |
| 345 | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x1c) PORT_PLAYER(1) SATURN_KEYBOARD |
| 346 | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x1d) PORT_PLAYER(1) SATURN_KEYBOARD |
| 347 | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x1e) PORT_PLAYER(1) SATURN_KEYBOARD |
| 348 | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("3-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x1f) PORT_PLAYER(1) SATURN_KEYBOARD |
| 349 | |
| 350 | PORT_START("KEY4") // 0x20 - 0x27 |
| 351 | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("4-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x20) PORT_PLAYER(1) SATURN_KEYBOARD |
| 352 | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x21) PORT_PLAYER(1) SATURN_KEYBOARD |
| 353 | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x22) PORT_PLAYER(1) SATURN_KEYBOARD |
| 354 | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x23) PORT_PLAYER(1) SATURN_KEYBOARD |
| 355 | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x24) PORT_PLAYER(1) SATURN_KEYBOARD |
| 356 | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x25) PORT_PLAYER(1) SATURN_KEYBOARD |
| 357 | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x26) PORT_PLAYER(1) SATURN_KEYBOARD |
| 358 | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("4-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x27) PORT_PLAYER(1) SATURN_KEYBOARD |
| 359 | |
| 360 | PORT_START("KEY5") // 0x28 - 0x2f |
| 361 | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("5-1") /*PORT_CODE(KEYCODE_F) PORT_CHAR('F')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x28) PORT_PLAYER(1) SATURN_KEYBOARD // another F? |
| 362 | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x29) PORT_PLAYER(1) SATURN_KEYBOARD |
| 363 | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x2a) PORT_PLAYER(1) SATURN_KEYBOARD |
| 364 | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x2b) PORT_PLAYER(1) SATURN_KEYBOARD |
| 365 | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x2c) PORT_PLAYER(1) SATURN_KEYBOARD |
| 366 | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x2d) PORT_PLAYER(1) SATURN_KEYBOARD |
| 367 | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x2e) PORT_PLAYER(1) SATURN_KEYBOARD |
| 368 | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("5-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x2f) PORT_PLAYER(1) SATURN_KEYBOARD |
| 369 | |
| 370 | PORT_START("KEY6") // 0x30 - 0x37 |
| 371 | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("6-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x30) PORT_PLAYER(1) SATURN_KEYBOARD |
| 372 | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x31) PORT_PLAYER(1) SATURN_KEYBOARD |
| 373 | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x32) PORT_PLAYER(1) SATURN_KEYBOARD |
| 374 | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x33) PORT_PLAYER(1) SATURN_KEYBOARD |
| 375 | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x34) PORT_PLAYER(1) SATURN_KEYBOARD |
| 376 | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x35) PORT_PLAYER(1) SATURN_KEYBOARD |
| 377 | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x36) PORT_PLAYER(1) SATURN_KEYBOARD |
| 378 | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("6-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x37) PORT_PLAYER(1) SATURN_KEYBOARD |
| 379 | |
| 380 | PORT_START("KEY7") // 0x38 - 0x3f |
| 381 | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("7-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x38) PORT_PLAYER(1) SATURN_KEYBOARD |
| 382 | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("7-2") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x39) PORT_PLAYER(1) SATURN_KEYBOARD |
| 383 | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x3a) PORT_PLAYER(1) SATURN_KEYBOARD |
| 384 | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x3b) PORT_PLAYER(1) SATURN_KEYBOARD |
| 385 | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x3c) PORT_PLAYER(1) SATURN_KEYBOARD |
| 386 | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x3d) PORT_PLAYER(1) SATURN_KEYBOARD |
| 387 | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x3e) PORT_PLAYER(1) SATURN_KEYBOARD |
| 388 | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("7-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x3f) PORT_PLAYER(1) SATURN_KEYBOARD |
| 389 | |
| 390 | PORT_START("KEY8") // 0x40 - 0x47 |
| 391 | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("8-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x40) PORT_PLAYER(1) SATURN_KEYBOARD |
| 392 | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(",") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x41) PORT_PLAYER(1) SATURN_KEYBOARD |
| 393 | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x42) PORT_PLAYER(1) SATURN_KEYBOARD |
| 394 | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x43) PORT_PLAYER(1) SATURN_KEYBOARD |
| 395 | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x44) PORT_PLAYER(1) SATURN_KEYBOARD |
| 396 | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x45) PORT_PLAYER(1) SATURN_KEYBOARD |
| 397 | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x46) PORT_PLAYER(1) SATURN_KEYBOARD |
| 398 | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("8-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x47) PORT_PLAYER(1) SATURN_KEYBOARD |
| 399 | |
| 400 | PORT_START("KEY9") // 0x48 - 0x4f |
| 401 | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("9-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x48) PORT_PLAYER(1) SATURN_KEYBOARD |
| 402 | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(".") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x49) PORT_PLAYER(1) SATURN_KEYBOARD |
| 403 | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("/") /*PORT_CODE(KEYCODE_2) PORT_CHAR('2')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x4a) PORT_PLAYER(1) SATURN_KEYBOARD |
| 404 | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x4b) PORT_PLAYER(1) SATURN_KEYBOARD |
| 405 | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(";") /*PORT_CODE(KEYCODE_4) PORT_CHAR('4')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x4c) PORT_PLAYER(1) SATURN_KEYBOARD |
| 406 | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x4d) PORT_PLAYER(1) SATURN_KEYBOARD |
| 407 | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("- / =") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x4e) PORT_PLAYER(1) SATURN_KEYBOARD |
| 408 | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("9-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x4f) PORT_PLAYER(1) SATURN_KEYBOARD |
| 409 | |
| 410 | PORT_START("KEYA") // 0x50 - 0x57 |
| 411 | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("A-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x50) PORT_PLAYER(1) SATURN_KEYBOARD |
| 412 | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("\xC2\xA5") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x51) PORT_PLAYER(1) SATURN_KEYBOARD |
| 413 | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(":") /*PORT_CODE(KEYCODE_2) PORT_CHAR('2')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x52) PORT_PLAYER(1) SATURN_KEYBOARD |
| 414 | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("A-4") /*PORT_CODE(KEYCODE_3) PORT_CHAR('3')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x53) PORT_PLAYER(1) SATURN_KEYBOARD |
| 415 | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("@") /*PORT_CODE(KEYCODE_4) PORT_CHAR('4')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x54) PORT_PLAYER(1) SATURN_KEYBOARD |
| 416 | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("^") /*PORT_CODE(KEYCODE_5) PORT_CHAR(0xd)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x55) PORT_PLAYER(1) SATURN_KEYBOARD |
| 417 | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("A-7") /*PORT_CODE(KEYCODE_6) PORT_CHAR('6')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x56) PORT_PLAYER(1) SATURN_KEYBOARD |
| 418 | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("A-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x57) PORT_PLAYER(1) SATURN_KEYBOARD |
| 419 | |
| 420 | PORT_START("KEYB") // 0x58 - 0x5f |
| 421 | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("B-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x58) PORT_PLAYER(1) SATURN_KEYBOARD |
| 422 | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("B-2") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x59) PORT_PLAYER(1) SATURN_KEYBOARD |
| 423 | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("ENTER") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(0x0d) PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x5a) PORT_PLAYER(1) SATURN_KEYBOARD |
| 424 | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("[") /*PORT_CODE(KEYCODE_3) PORT_CHAR('3')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x5b) PORT_PLAYER(1) SATURN_KEYBOARD // { |
| 425 | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("B-5") /*PORT_CODE(KEYCODE_4) PORT_CHAR('4')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x5c) PORT_PLAYER(1) SATURN_KEYBOARD |
| 426 | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("]") /*PORT_CODE(KEYCODE_5) PORT_CHAR(0xd)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x5d) PORT_PLAYER(1) SATURN_KEYBOARD // } |
| 427 | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("B-7") /*PORT_CODE(KEYCODE_6) PORT_CHAR('6')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x5e) PORT_PLAYER(1) SATURN_KEYBOARD |
| 428 | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("B-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x5f) PORT_PLAYER(1) SATURN_KEYBOARD |
| 429 | |
| 430 | PORT_START("KEYC") // 0x60 - 0x67 |
| 431 | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x60) PORT_PLAYER(1) SATURN_KEYBOARD |
| 432 | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C-2") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x61) PORT_PLAYER(1) SATURN_KEYBOARD |
| 433 | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C-3") /*PORT_CODE(KEYCODE_2) PORT_CHAR('2')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x62) PORT_PLAYER(1) SATURN_KEYBOARD |
| 434 | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C-4") /*PORT_CODE(KEYCODE_3) PORT_CHAR('3')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x63) PORT_PLAYER(1) SATURN_KEYBOARD |
| 435 | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C-5") /*PORT_CODE(KEYCODE_4) PORT_CHAR('4')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x64) PORT_PLAYER(1) SATURN_KEYBOARD |
| 436 | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C-6") /*PORT_CODE(KEYCODE_5) PORT_CHAR(0xd)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x65) PORT_PLAYER(1) SATURN_KEYBOARD |
| 437 | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("BACKSPACE") PORT_CODE(KEYCODE_BACKSPACE) /* PORT_CHAR('6')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x66) PORT_PLAYER(1) SATURN_KEYBOARD |
| 438 | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x67) PORT_PLAYER(1) SATURN_KEYBOARD |
| 439 | |
| 440 | PORT_START("KEYD") // 0x68 - 0x6f |
| 441 | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x68) PORT_PLAYER(1) SATURN_KEYBOARD |
| 442 | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D-2") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x69) PORT_PLAYER(1) SATURN_KEYBOARD |
| 443 | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D-3") /*PORT_CODE(KEYCODE_2) PORT_CHAR('2')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x6a) PORT_PLAYER(1) SATURN_KEYBOARD |
| 444 | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D-4") /*PORT_CODE(KEYCODE_3) PORT_CHAR('3')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x6b) PORT_PLAYER(1) SATURN_KEYBOARD |
| 445 | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D-5") /*PORT_CODE(KEYCODE_4) PORT_CHAR('4')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x6c) PORT_PLAYER(1) SATURN_KEYBOARD |
| 446 | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D-6") /*PORT_CODE(KEYCODE_5) PORT_CHAR(0xd)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x6d) PORT_PLAYER(1) SATURN_KEYBOARD |
| 447 | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D-7") /*PORT_CODE(KEYCODE_6) PORT_CHAR('6')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x6e) PORT_PLAYER(1) SATURN_KEYBOARD |
| 448 | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x6f) PORT_PLAYER(1) SATURN_KEYBOARD |
| 449 | |
| 450 | PORT_START("KEYE") // 0x70 - 0x77 |
| 451 | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x70) PORT_PLAYER(1) SATURN_KEYBOARD |
| 452 | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E-2") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x71) PORT_PLAYER(1) SATURN_KEYBOARD |
| 453 | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E-3") /*PORT_CODE(KEYCODE_2) PORT_CHAR('2')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x72) PORT_PLAYER(1) SATURN_KEYBOARD |
| 454 | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E-4") /*PORT_CODE(KEYCODE_3) PORT_CHAR('3')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x73) PORT_PLAYER(1) SATURN_KEYBOARD |
| 455 | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E-5") /*PORT_CODE(KEYCODE_4) PORT_CHAR('4')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x74) PORT_PLAYER(1) SATURN_KEYBOARD |
| 456 | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E-6") /*PORT_CODE(KEYCODE_5) PORT_CHAR(0xd)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x75) PORT_PLAYER(1) SATURN_KEYBOARD |
| 457 | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E-7") /*PORT_CODE(KEYCODE_6) PORT_CHAR('6')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x76) PORT_PLAYER(1) SATURN_KEYBOARD |
| 458 | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x77) PORT_PLAYER(1) SATURN_KEYBOARD |
| 459 | |
| 460 | PORT_START("KEYF") // 0x78 - 0x7f |
| 461 | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x78) PORT_PLAYER(1) SATURN_KEYBOARD |
| 462 | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F-2") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x79) PORT_PLAYER(1) SATURN_KEYBOARD |
| 463 | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F-3") /*PORT_CODE(KEYCODE_2) PORT_CHAR('2')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x7a) PORT_PLAYER(1) SATURN_KEYBOARD |
| 464 | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F-4") /*PORT_CODE(KEYCODE_3) PORT_CHAR('3')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x7b) PORT_PLAYER(1) SATURN_KEYBOARD |
| 465 | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F-5") /*PORT_CODE(KEYCODE_4) PORT_CHAR('4')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x7c) PORT_PLAYER(1) SATURN_KEYBOARD |
| 466 | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F-6") /*PORT_CODE(KEYCODE_5) PORT_CHAR(0xd)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x7d) PORT_PLAYER(1) SATURN_KEYBOARD |
| 467 | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F-7") /*PORT_CODE(KEYCODE_6) PORT_CHAR('6')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x7e) PORT_PLAYER(1) SATURN_KEYBOARD |
| 468 | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("ESC") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x7f) PORT_PLAYER(1) SATURN_KEYBOARD //SYSTEM CONFIGURATION |
| 469 | |
| 470 | PORT_START("KEYS_1") // special keys |
| 471 | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("UP") PORT_CODE(KEYCODE_UP) /*PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x78) PORT_PLAYER(1) SATURN_KEYBOARD |
| 472 | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("DOWN") PORT_CODE(KEYCODE_DOWN) /*PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x79) PORT_PLAYER(1) SATURN_KEYBOARD |
| 473 | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("LEFT") PORT_CODE(KEYCODE_LEFT) /*PORT_CHAR('2')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x7a) PORT_PLAYER(1) SATURN_KEYBOARD |
| 474 | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("RIGHT") PORT_CODE(KEYCODE_RIGHT) /*PORT_CHAR('3')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x7b) PORT_PLAYER(1) SATURN_KEYBOARD |
| 475 | |
| 476 | PORT_START("MOUSEB1") |
| 477 | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P1 Pointer Left Button") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x04) |
| 478 | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P1 Pointer Right Button") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x04) |
| 479 | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P1 Pointer Middle Button") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x04) |
| 480 | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("P1 Pointer Start Button") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x04) |
| 481 | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P1 Mouse Left Button") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x08) |
| 482 | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P1 Mouse Right Button") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x08) |
| 483 | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P1 Mouse Middle Button") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x08) |
| 484 | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("P1 Mouse Start Button") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x08) |
| 485 | |
| 486 | PORT_START("MOUSEX1") |
| 487 | PORT_BIT(0xffff, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0xffff) PORT_KEYDELTA(2) PORT_RESET PORT_NAME("P1 Pointer X") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x04) |
| 488 | PORT_BIT(0xffff, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0xffff) PORT_KEYDELTA(2) PORT_RESET PORT_NAME("P1 Mouse X") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x08) |
| 489 | |
| 490 | PORT_START("MOUSEY1") |
| 491 | PORT_BIT(0xffff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0xffff) PORT_KEYDELTA(2) PORT_RESET PORT_REVERSE PORT_NAME("P1 Pointer Y") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x04) |
| 492 | PORT_BIT(0xffff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0xffff) PORT_KEYDELTA(2) PORT_RESET PORT_REVERSE PORT_NAME("P1 Mouse Y") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x08) |
| 493 | |
| 494 | PORT_START("MOUSEB2") |
| 495 | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P2 Pointer Left Button") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x40) |
| 496 | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P2 Pointer Right Button") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x40) |
| 497 | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P2 Pointer Middle Button") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x40) |
| 498 | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("P2 Pointer Start Button") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x40) |
| 499 | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P2 Mouse Left Button") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x80) |
| 500 | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P2 Mouse Right Button") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x80) |
| 501 | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P2 Mouse Middle Button") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x80) |
| 502 | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("P2 Mouse Start Button") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x80) |
| 503 | |
| 504 | PORT_START("MOUSEX2") |
| 505 | PORT_BIT(0xffff, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0xffff) PORT_KEYDELTA(2) PORT_RESET PORT_NAME("P2 Pointer X") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x40) |
| 506 | PORT_BIT(0xffff, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0xffff) PORT_KEYDELTA(2) PORT_RESET PORT_NAME("P2 Mouse X") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x80) |
| 507 | |
| 508 | PORT_START("MOUSEY2") |
| 509 | PORT_BIT(0xffff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0xffff) PORT_KEYDELTA(2) PORT_RESET PORT_REVERSE PORT_NAME("P2 Pointer Y") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x40) |
| 510 | PORT_BIT(0xffff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0xffff) PORT_KEYDELTA(2) PORT_RESET PORT_REVERSE PORT_NAME("P2 Mouse Y") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x80) |
| 511 | |
| 512 | PORT_START("AN_JOY1") |
| 513 | SATURN_PAD_P1(0x0f, 0x01) // racing device |
| 514 | SATURN_PAD_P1(0x0f, 0x02) // analog controller |
| 515 | |
| 516 | PORT_START("AN_JOY2") |
| 517 | SATURN_PAD_P2(0xf0, 0x10) // racing device |
| 518 | SATURN_PAD_P2(0xf0, 0x20) // analog controller |
| 519 | |
| 520 | PORT_START("AN_X1") |
| 521 | PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(1) PORT_NAME("P1 Racing Stick X") PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x01) |
| 522 | PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(1) PORT_NAME("P1 AD Stick X") PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x02) |
| 523 | |
| 524 | PORT_START("AN_Y1") |
| 525 | PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(1) PORT_NAME("P1 Racing Stick Y") PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x01) |
| 526 | PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(1) PORT_NAME("P1 AD Stick Y") PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x02) |
| 527 | |
| 528 | PORT_START("AN_Z1") |
| 529 | PORT_BIT( 0xff, 0x00, IPT_AD_STICK_Z ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(1) PORT_NAME("P1 Racing Stick Z") PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x01) |
| 530 | PORT_BIT( 0xff, 0x00, IPT_AD_STICK_Z ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(1) PORT_NAME("P1 AD Stick Z") PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x02) |
| 531 | |
| 532 | PORT_START("AN_X2") |
| 533 | PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(2) PORT_NAME("P2 Racing Stick X") PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x10) |
| 534 | PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(2) PORT_NAME("P2 AD Stick X") PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x20) |
| 535 | |
| 536 | PORT_START("AN_Y2") |
| 537 | PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(2) PORT_NAME("P2 Racing Stick Y") PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x10) |
| 538 | PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(2) PORT_NAME("P2 AD Stick Y") PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x20) |
| 539 | |
| 540 | PORT_START("AN_Z2") |
| 541 | PORT_BIT( 0xff, 0x00, IPT_AD_STICK_Z ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(2) PORT_NAME("P2 Racing Stick Z") PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x10) |
| 542 | PORT_BIT( 0xff, 0x00, IPT_AD_STICK_Z ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(2) PORT_NAME("P2 AD Stick Z") PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x20) |
| 543 | |
| 544 | PORT_START("MD_JOY1") |
| 545 | MD_PAD_P1(0x0f, 0x06) // MD 3 buttons pad |
| 546 | MD_PAD_P1(0x0f, 0x07) // MD 6 buttons pad |
| 547 | |
| 548 | PORT_START("MD_JOY2") |
| 549 | MD_PAD_P2(0xf0, 0x60) // MD 3 buttons pad |
| 550 | MD_PAD_P2(0xf0, 0x70) // MD 6 buttons pad |
| 551 | |
| 552 | PORT_START("CART_AREA") |
| 553 | PORT_CONFNAME( 0x07, 0x06, "Cart Type" ) |
| 554 | PORT_CONFSETTING( 0x00, "None" ) |
| 555 | // PORT_CONFSETTING( 0x01, "4 Mbit backup RAM" ) |
| 556 | // PORT_CONFSETTING( 0x02, "8 Mbit backup RAM" ) |
| 557 | // PORT_CONFSETTING( 0x03, "16 Mbit backup RAM" ) |
| 558 | // PORT_CONFSETTING( 0x04, "32 Mbit backup RAM" ) |
| 559 | PORT_CONFSETTING( 0x05, "8 Mbit Cart RAM" ) |
| 560 | PORT_CONFSETTING( 0x06, "32 Mbit Cart RAM" ) |
| 561 | |
| 562 | PORT_START("INPUT_TYPE") |
| 563 | PORT_CONFNAME(0x0f,0x00,"Controller Port 1") |
| 564 | PORT_CONFSETTING(0x00,"Digital Device (standard Saturn pad)") |
| 565 | PORT_CONFSETTING(0x01,"Racing Device") /* steering wheel only */ |
| 566 | PORT_CONFSETTING(0x02,"Analog Device") //Nights pad? |
| 567 | // PORT_CONFSETTING(0x03,"Lightgun Device") |
| 568 | PORT_CONFSETTING(0x04,"Trackball") // TODO: according to the docs this ID is labeled "Pointing Device" |
| 569 | PORT_CONFSETTING(0x05,"Keyboard Device") |
| 570 | PORT_CONFSETTING(0x06,"Megadrive 3B Pad") |
| 571 | PORT_CONFSETTING(0x07,"Megadrive 6B Pad") |
| 572 | PORT_CONFSETTING(0x08,"Saturn Mouse") |
| 573 | // PORT_CONFSETTING(0x09,"<unconnected>") |
| 574 | PORT_CONFNAME(0xf0,0x00,"Controller Port 2") |
| 575 | PORT_CONFSETTING(0x00,"Digital Device (standard Saturn pad)") |
| 576 | PORT_CONFSETTING(0x10,"Racing Device") |
| 577 | PORT_CONFSETTING(0x20,"Analog Device") //Nights pad? |
| 578 | // PORT_CONFSETTING(0x30,"Lightgun Device") |
| 579 | PORT_CONFSETTING(0x40,"Pointing Device") |
| 580 | // PORT_CONFSETTING(0x50,"Keyboard Device") |
| 581 | PORT_CONFSETTING(0x60,"Megadrive 3B Pad") |
| 582 | PORT_CONFSETTING(0x70,"Megadrive 6B Pad") |
| 583 | PORT_CONFSETTING(0x80,"Saturn Mouse") |
| 584 | PORT_CONFSETTING(0x90,"<unconnected>") |
| 585 | |
| 586 | PORT_START("fake") |
| 587 | PORT_CONFNAME(0x01,0x00,"Master-Slave Comms") |
| 588 | PORT_CONFSETTING(0x00,"Normal (400 cycles)") |
| 589 | PORT_CONFSETTING(0x01,"One Shot (Hack)") |
| 590 | INPUT_PORTS_END |
| 591 | |
| 592 | static const sh2_cpu_core sh2_conf_master = { 0, NULL }; |
| 593 | static const sh2_cpu_core sh2_conf_slave = { 1, NULL }; |
| 594 | |
| 595 | static const scsp_interface scsp_config = |
| 596 | { |
| 597 | 0, |
| 598 | scsp_irq, |
| 599 | DEVCB_DRIVER_LINE_MEMBER(saturn_state, scsp_to_main_irq) |
| 600 | }; |
| 601 | |
| 602 | MACHINE_START_MEMBER(saturn_state,saturn) |
| 603 | { |
| 604 | system_time systime; |
| 605 | machine().base_datetime(systime); |
| 606 | |
| 607 | m_maincpu = downcast<legacy_cpu_device*>( machine().device<cpu_device>("maincpu") ); |
| 608 | m_slave = downcast<legacy_cpu_device*>( machine().device("slave") ); |
| 609 | m_audiocpu = downcast<legacy_cpu_device*>( machine().device<cpu_device>("audiocpu") ); |
| 610 | |
| 611 | scsp_set_ram_base(machine().device("scsp"), m_sound_ram); |
| 612 | |
| 613 | // save states |
| 614 | state_save_register_global_pointer(machine(), m_scu_regs, 0x100/4); |
| 615 | state_save_register_global_pointer(machine(), m_scsp_regs, 0x1000/2); |
| 616 | state_save_register_global(machine(), m_NMI_reset); |
| 617 | state_save_register_global(machine(), m_en_68k); |
| 618 | state_save_register_global(machine(), m_smpc.IOSEL1); |
| 619 | state_save_register_global(machine(), m_smpc.IOSEL2); |
| 620 | state_save_register_global(machine(), m_smpc.EXLE1); |
| 621 | state_save_register_global(machine(), m_smpc.EXLE2); |
| 622 | state_save_register_global(machine(), m_smpc.PDR1); |
| 623 | state_save_register_global(machine(), m_smpc.PDR2); |
| 624 | // state_save_register_global(machine(), m_port_sel); |
| 625 | // state_save_register_global(machine(), mux_data); |
| 626 | state_save_register_global(machine(), m_scsp_last_line); |
| 627 | state_save_register_global(machine(), m_smpc.intback_stage); |
| 628 | state_save_register_global(machine(), m_smpc.pmode); |
| 629 | state_save_register_global(machine(), m_smpc.SR); |
| 630 | state_save_register_global_array(machine(), m_smpc.SMEM); |
| 631 | state_save_register_global_pointer(machine(), m_cart_dram, 0x400000/4); |
| 632 | |
| 633 | machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(saturn_state::stvcd_exit), this)); |
| 634 | |
| 635 | m_smpc.rtc_data[0] = DectoBCD(systime.local_time.year /100); |
| 636 | m_smpc.rtc_data[1] = DectoBCD(systime.local_time.year %100); |
| 637 | m_smpc.rtc_data[2] = (systime.local_time.weekday << 4) | (systime.local_time.month+1); |
| 638 | m_smpc.rtc_data[3] = DectoBCD(systime.local_time.mday); |
| 639 | m_smpc.rtc_data[4] = DectoBCD(systime.local_time.hour); |
| 640 | m_smpc.rtc_data[5] = DectoBCD(systime.local_time.minute); |
| 641 | m_smpc.rtc_data[6] = DectoBCD(systime.local_time.second); |
| 642 | |
| 643 | m_stv_rtc_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(saturn_state::stv_rtc_increment),this)); |
| 644 | |
| 645 | m68k_set_reset_callback(m_audiocpu, &saturn_state::m68k_reset_callback); |
| 646 | } |
| 647 | |
| 648 | /* Die Hard Trilogy tests RAM address 0x25e7ffe bit 2 with Slave during FRT minit irq, in-development tool for breaking execution of it? */ |
| 649 | READ32_MEMBER(saturn_state::saturn_null_ram_r) |
| 650 | { |
| 651 | return 0xffffffff; |
| 652 | } |
| 653 | |
| 654 | WRITE32_MEMBER(saturn_state::saturn_null_ram_w) |
| 655 | { |
| 656 | } |
| 657 | |
| 658 | READ32_MEMBER(saturn_state::saturn_cart_dram0_r) |
| 659 | { |
| 660 | return m_cart_dram[offset]; |
| 661 | } |
| 662 | |
| 663 | WRITE32_MEMBER(saturn_state::saturn_cart_dram0_w) |
| 664 | { |
| 665 | COMBINE_DATA(&m_cart_dram[offset]); |
| 666 | } |
| 667 | |
| 668 | READ32_MEMBER(saturn_state::saturn_cart_dram1_r) |
| 669 | { |
| 670 | return m_cart_dram[offset+0x200000/4]; |
| 671 | } |
| 672 | |
| 673 | WRITE32_MEMBER(saturn_state::saturn_cart_dram1_w) |
| 674 | { |
| 675 | COMBINE_DATA(&m_cart_dram[offset+0x200000/4]); |
| 676 | } |
| 677 | |
| 678 | READ32_MEMBER(saturn_state::saturn_cs1_r) |
| 679 | { |
| 680 | UINT32 res; |
| 681 | |
| 682 | res = 0; |
| 683 | //res = m_cart_backupram[offset*4+0] << 24; |
| 684 | res |= m_cart_backupram[offset*2+0] << 16; |
| 685 | //res |= m_cart_backupram[offset*4+2] << 8; |
| 686 | res |= m_cart_backupram[offset*2+1] << 0; |
| 687 | |
| 688 | return res; |
| 689 | } |
| 690 | |
| 691 | WRITE32_MEMBER(saturn_state::saturn_cs1_w) |
| 692 | { |
| 693 | if(ACCESSING_BITS_16_23) |
| 694 | m_cart_backupram[offset*2+0] = (data & 0x00ff0000) >> 16; |
| 695 | if(ACCESSING_BITS_0_7) |
| 696 | m_cart_backupram[offset*2+1] = (data & 0x000000ff) >> 0; |
| 697 | } |
| 698 | |
| 699 | MACHINE_RESET_MEMBER(saturn_state,saturn) |
| 700 | { |
| 701 | m_scsp_last_line = 0; |
| 702 | |
| 703 | // don't let the slave cpu and the 68k go anywhere |
| 704 | machine().device("slave")->execute().set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 705 | machine().device("audiocpu")->execute().set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 706 | |
| 707 | m_smpc.SR = 0x40; // this bit is always on according to docs |
| 708 | |
| 709 | scu_reset(); |
| 710 | |
| 711 | m_en_68k = 0; |
| 712 | m_NMI_reset = 0; |
| 713 | m_smpc.slave_on = 0; |
| 714 | |
| 715 | |
| 716 | //memset(stv_m_workram_l, 0, 0x100000); |
| 717 | //memset(stv_m_workram_h, 0, 0x100000); |
| 718 | |
| 719 | machine().device("maincpu")->set_unscaled_clock(MASTER_CLOCK_320/2); |
| 720 | machine().device("slave")->set_unscaled_clock(MASTER_CLOCK_320/2); |
| 721 | |
| 722 | stvcd_reset(); |
| 723 | |
| 724 | m_cart_type = ioport("CART_AREA")->read() & 7; |
| 725 | |
| 726 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x02400000, 0x027fffff, read32_delegate(FUNC(saturn_state::saturn_null_ram_r),this), write32_delegate(FUNC(saturn_state::saturn_null_ram_w),this)); |
| 727 | machine().device("slave")->memory().space(AS_PROGRAM).install_readwrite_handler(0x02400000, 0x027fffff, read32_delegate(FUNC(saturn_state::saturn_null_ram_r),this), write32_delegate(FUNC(saturn_state::saturn_null_ram_w),this)); |
| 728 | |
| 729 | if(m_cart_type == 5) |
| 730 | { |
| 731 | // AM_RANGE(0x02400000, 0x027fffff) AM_RAM //cart RAM area, dynamically allocated |
| 732 | machine().device("maincpu")->memory().space(AS_PROGRAM).nop_readwrite(0x02400000, 0x027fffff); |
| 733 | machine().device("slave")->memory().space(AS_PROGRAM).nop_readwrite(0x02400000, 0x027fffff); |
| 734 | |
| 735 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x02400000, 0x0247ffff, read32_delegate(FUNC(saturn_state::saturn_cart_dram0_r),this), write32_delegate(FUNC(saturn_state::saturn_cart_dram0_w),this)); |
| 736 | machine().device("slave")->memory().space(AS_PROGRAM).install_readwrite_handler(0x02400000, 0x0247ffff, read32_delegate(FUNC(saturn_state::saturn_cart_dram0_r),this), write32_delegate(FUNC(saturn_state::saturn_cart_dram0_w),this)); |
| 737 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x02600000, 0x0267ffff, read32_delegate(FUNC(saturn_state::saturn_cart_dram1_r),this), write32_delegate(FUNC(saturn_state::saturn_cart_dram1_w),this)); |
| 738 | machine().device("slave")->memory().space(AS_PROGRAM).install_readwrite_handler(0x02600000, 0x0267ffff, read32_delegate(FUNC(saturn_state::saturn_cart_dram1_r),this), write32_delegate(FUNC(saturn_state::saturn_cart_dram1_w),this)); |
| 739 | } |
| 740 | |
| 741 | if(m_cart_type == 6) |
| 742 | { |
| 743 | // AM_RANGE(0x02400000, 0x027fffff) AM_RAM //cart RAM area, dynamically allocated |
| 744 | machine().device("maincpu")->memory().space(AS_PROGRAM).nop_readwrite(0x02400000, 0x027fffff); |
| 745 | machine().device("slave")->memory().space(AS_PROGRAM).nop_readwrite(0x02400000, 0x027fffff); |
| 746 | |
| 747 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x02400000, 0x025fffff, read32_delegate(FUNC(saturn_state::saturn_cart_dram0_r),this), write32_delegate(FUNC(saturn_state::saturn_cart_dram0_w),this)); |
| 748 | machine().device("slave")->memory().space(AS_PROGRAM).install_readwrite_handler(0x02400000, 0x025fffff, read32_delegate(FUNC(saturn_state::saturn_cart_dram0_r),this), write32_delegate(FUNC(saturn_state::saturn_cart_dram0_w),this)); |
| 749 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x02600000, 0x027fffff, read32_delegate(FUNC(saturn_state::saturn_cart_dram1_r),this), write32_delegate(FUNC(saturn_state::saturn_cart_dram1_w),this)); |
| 750 | machine().device("slave")->memory().space(AS_PROGRAM).install_readwrite_handler(0x02600000, 0x027fffff, read32_delegate(FUNC(saturn_state::saturn_cart_dram1_r),this), write32_delegate(FUNC(saturn_state::saturn_cart_dram1_w),this)); |
| 751 | } |
| 752 | |
| 753 | machine().device("maincpu")->memory().space(AS_PROGRAM).nop_readwrite(0x04000000, 0x047fffff); |
| 754 | machine().device("slave")->memory().space(AS_PROGRAM).nop_readwrite(0x04000000, 0x047fffff); |
| 755 | |
| 756 | if(m_cart_type > 0 && m_cart_type < 5) |
| 757 | { |
| 758 | // AM_RANGE(0x04000000, 0x047fffff) AM_RAM //backup RAM area, dynamically allocated |
| 759 | UINT32 mask; |
| 760 | mask = 0x7fffff >> (4-m_cart_type); |
| 761 | //mask = 0x7fffff >> 4-4 = 0x7fffff 32mbit |
| 762 | //mask = 0x7fffff >> 4-3 = 0x3fffff 16mbit |
| 763 | //mask = 0x7fffff >> 4-2 = 0x1fffff 8mbit |
| 764 | //mask = 0x7fffff >> 4-1 = 0x0fffff 4mbit |
| 765 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x04000000, 0x04000000 | mask, read32_delegate(FUNC(saturn_state::saturn_cs1_r),this), write32_delegate(FUNC(saturn_state::saturn_cs1_w),this)); |
| 766 | machine().device("slave")->memory().space(AS_PROGRAM).install_readwrite_handler(0x04000000, 0x04000000 | mask, read32_delegate(FUNC(saturn_state::saturn_cs1_r),this), write32_delegate(FUNC(saturn_state::saturn_cs1_w),this)); |
| 767 | } |
| 768 | |
| 769 | m_vdp2.old_crmd = -1; |
| 770 | m_vdp2.old_tvmd = -1; |
| 771 | |
| 772 | m_stv_rtc_timer->adjust(attotime::zero, 0, attotime::from_seconds(1)); |
| 773 | } |
| 774 | |
| 775 | |
| 776 | struct cdrom_interface saturn_cdrom = |
| 777 | { |
| 778 | "sat_cdrom", |
| 779 | NULL |
| 780 | }; |
| 781 | |
| 782 | |
| 783 | |
| 784 | |
| 785 | DEVICE_IMAGE_LOAD_MEMBER( saturn_state, sat_cart ) |
| 786 | { |
| 787 | UINT8 *ROM = image.device().memregion("maincpu")->base()+0x080000; |
| 788 | UINT32 length; |
| 789 | |
| 790 | if (image.software_entry() != NULL) |
| 791 | { |
| 792 | length = image.get_software_region_length("cart"); |
| 793 | UINT8* imagex = image.get_software_region("cart"); |
| 794 | |
| 795 | memcpy(ROM, imagex, length); |
| 796 | } |
| 797 | else |
| 798 | { |
| 799 | length = image.fread( ROM, 0x400000); |
| 800 | } |
| 801 | |
| 802 | // fix endianness.... |
| 803 | for (int i=0;i<length;i+=4) |
| 804 | { |
| 805 | UINT8 tempa = ROM[i+0]; |
| 806 | UINT8 tempb = ROM[i+1]; |
| 807 | ROM[i+1] = ROM[i+2]; |
| 808 | ROM[i+0] = ROM[i+3]; |
| 809 | ROM[i+3] = tempa; |
| 810 | ROM[i+2] = tempb; |
| 811 | } |
| 812 | |
| 813 | return IMAGE_INIT_PASS; |
| 814 | } |
| 815 | |
| 816 | static MACHINE_CONFIG_START( saturn, saturn_state ) |
| 817 | |
| 818 | /* basic machine hardware */ |
| 819 | MCFG_CPU_ADD("maincpu", SH2, MASTER_CLOCK_352/2) // 28.6364 MHz |
| 820 | MCFG_CPU_PROGRAM_MAP(saturn_mem) |
| 821 | MCFG_CPU_CONFIG(sh2_conf_master) |
| 822 | MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", saturn_state, saturn_scanline, "screen", 0, 1) |
| 823 | |
| 824 | MCFG_CPU_ADD("slave", SH2, MASTER_CLOCK_352/2) // 28.6364 MHz |
| 825 | MCFG_CPU_PROGRAM_MAP(saturn_mem) |
| 826 | MCFG_CPU_CONFIG(sh2_conf_slave) |
| 827 | MCFG_TIMER_DRIVER_ADD_SCANLINE("slave_scantimer", saturn_state, saturn_slave_scanline, "screen", 0, 1) |
| 828 | |
| 829 | MCFG_CPU_ADD("audiocpu", M68000, 11289600) //256 x 44100 Hz = 11.2896 MHz |
| 830 | MCFG_CPU_PROGRAM_MAP(sound_mem) |
| 831 | |
| 832 | MCFG_MACHINE_START_OVERRIDE(saturn_state,saturn) |
| 833 | MCFG_MACHINE_RESET_OVERRIDE(saturn_state,saturn) |
| 834 | |
| 835 | MCFG_NVRAM_HANDLER(saturn) |
| 836 | |
| 837 | MCFG_TIMER_DRIVER_ADD("sector_timer", saturn_state, stv_sector_cb) |
| 838 | MCFG_TIMER_DRIVER_ADD("sh1_cmd", saturn_state, stv_sh1_sim) |
| 839 | |
| 840 | /* video hardware */ |
| 841 | MCFG_SCREEN_ADD("screen", RASTER) |
| 842 | MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK_320/8, 427, 0, 320, 263, 0, 224) |
| 843 | MCFG_SCREEN_UPDATE_DRIVER(saturn_state, screen_update_stv_vdp2) |
| 844 | MCFG_PALETTE_LENGTH(2048+(2048*2))//standard palette + extra memory for rgb brightness. |
| 845 | |
| 846 | MCFG_GFXDECODE(stv) |
| 847 | |
| 848 | MCFG_VIDEO_START_OVERRIDE(saturn_state,stv_vdp2) |
| 849 | |
| 850 | MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") |
| 851 | |
| 852 | MCFG_SOUND_ADD("scsp", SCSP, 0) |
| 853 | MCFG_SOUND_CONFIG(scsp_config) |
| 854 | MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) |
| 855 | MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) |
| 856 | |
| 857 | MCFG_SOUND_ADD("cdda", CDDA, 0) |
| 858 | MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) |
| 859 | MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) |
| 860 | MACHINE_CONFIG_END |
| 861 | |
| 862 | MACHINE_CONFIG_DERIVED( saturnus, saturn ) |
| 863 | MCFG_CDROM_ADD( "cdrom",saturn_cdrom ) |
| 864 | MCFG_SOFTWARE_LIST_ADD("cd_list","saturn") |
| 865 | MCFG_SOFTWARE_LIST_FILTER("cd_list","NTSC-U") |
| 866 | |
| 867 | MCFG_CARTSLOT_ADD("cart") |
| 868 | MCFG_CARTSLOT_INTERFACE("sat_cart") |
| 869 | MCFG_CARTSLOT_LOAD(saturn_state, sat_cart) |
| 870 | MCFG_SOFTWARE_LIST_ADD("cart_list","sat_cart") |
| 871 | |
| 872 | MACHINE_CONFIG_END |
| 873 | |
| 874 | MACHINE_CONFIG_DERIVED( saturneu, saturn ) |
| 875 | MCFG_CDROM_ADD( "cdrom",saturn_cdrom ) |
| 876 | MCFG_SOFTWARE_LIST_ADD("cd_list","saturn") |
| 877 | MCFG_SOFTWARE_LIST_FILTER("cd_list","PAL") |
| 878 | |
| 879 | MCFG_CARTSLOT_ADD("cart") |
| 880 | MCFG_CARTSLOT_INTERFACE("sat_cart") |
| 881 | MCFG_CARTSLOT_LOAD(saturn_state, sat_cart) |
| 882 | MCFG_SOFTWARE_LIST_ADD("cart_list","sat_cart") |
| 883 | |
| 884 | MACHINE_CONFIG_END |
| 885 | |
| 886 | MACHINE_CONFIG_DERIVED( saturnjp, saturn ) |
| 887 | MCFG_CDROM_ADD( "cdrom",saturn_cdrom ) |
| 888 | MCFG_SOFTWARE_LIST_ADD("cd_list","saturn") |
| 889 | MCFG_SOFTWARE_LIST_FILTER("cd_list","NTSC-J") |
| 890 | |
| 891 | MCFG_CARTSLOT_ADD("cart") |
| 892 | MCFG_CARTSLOT_INTERFACE("sat_cart") |
| 893 | MCFG_CARTSLOT_LOAD(saturn_state, sat_cart) |
| 894 | MCFG_SOFTWARE_LIST_ADD("cart_list","sat_cart") |
| 895 | |
| 896 | MACHINE_CONFIG_END |
| 897 | |
| 898 | |
| 899 | void saturn_state::saturn_init_driver(int rgn) |
| 900 | { |
| 901 | m_saturn_region = rgn; |
| 902 | m_vdp2.pal = (rgn == 12) ? 1 : 0; |
| 903 | |
| 904 | // set compatible options |
| 905 | sh2drc_set_options(machine().device("maincpu"), SH2DRC_STRICT_VERIFY|SH2DRC_STRICT_PCREL); |
| 906 | sh2drc_set_options(machine().device("slave"), SH2DRC_STRICT_VERIFY|SH2DRC_STRICT_PCREL); |
| 907 | |
| 908 | /* amount of time to boost interleave for on MINIT / SINIT, needed for communication to work */ |
| 909 | m_minit_boost = 400; |
| 910 | m_sinit_boost = 400; |
| 911 | m_minit_boost_timeslice = attotime::zero; |
| 912 | m_sinit_boost_timeslice = attotime::zero; |
| 913 | |
| 914 | m_scu_regs = auto_alloc_array_clear(machine(), UINT32, 0x100/4); |
| 915 | m_scsp_regs = auto_alloc_array_clear(machine(), UINT16, 0x1000/2); |
| 916 | m_cart_dram = auto_alloc_array_clear(machine(), UINT32, 0x400000/4); |
| 917 | m_backupram = auto_alloc_array_clear(machine(), UINT8, 0x8000); |
| 918 | m_cart_backupram = auto_alloc_array_clear(machine(), UINT8, 0x400000); |
| 919 | } |
| 920 | |
| 921 | DRIVER_INIT_MEMBER(saturn_state,saturnus) |
| 922 | { |
| 923 | saturn_init_driver(4); |
| 924 | } |
| 925 | |
| 926 | DRIVER_INIT_MEMBER(saturn_state,saturneu) |
| 927 | { |
| 928 | saturn_init_driver(12); |
| 929 | } |
| 930 | |
| 931 | DRIVER_INIT_MEMBER(saturn_state,saturnjp) |
| 932 | { |
| 933 | saturn_init_driver(1); |
| 934 | } |
| 935 | |
| 936 | |
| 937 | /* Japanese Saturn */ |
| 938 | ROM_START(saturnjp) |
| 939 | ROM_REGION( 0x480000, "maincpu", ROMREGION_ERASEFF ) /* SH2 code */ |
| 940 | ROM_SYSTEM_BIOS(0, "101", "Japan v1.01 (941228)") |
| 941 | ROMX_LOAD("sega_101.bin", 0x00000000, 0x00080000, CRC(224b752c) SHA1(df94c5b4d47eb3cc404d88b33a8fda237eaf4720), ROM_BIOS(1)) |
| 942 | ROM_SYSTEM_BIOS(1, "1003", "Japan v1.003 (941012)") |
| 943 | ROMX_LOAD("sega1003.bin", 0x00000000, 0x00080000, CRC(b3c63c25) SHA1(7b23b53d62de0f29a23e423d0fe751dfb469c2fa), ROM_BIOS(2)) |
| 944 | ROM_SYSTEM_BIOS(2, "100", "Japan v1.00 (940921)") |
| 945 | ROMX_LOAD("sega_100.bin", 0x00000000, 0x00080000, CRC(2aba43c2) SHA1(2b8cb4f87580683eb4d760e4ed210813d667f0a2), ROM_BIOS(3)) |
| 946 | // ROM_CART_LOAD("cart", 0x080000, 0x400000, ROM_NOMIRROR | ROM_OPTIONAL) |
| 947 | ROM_REGION( 0x080000, "slave", 0 ) /* SH2 code */ |
| 948 | ROM_COPY( "maincpu",0,0,0x080000) |
| 949 | ROM_END |
| 950 | |
| 951 | /* Overseas Saturn */ |
| 952 | ROM_START(saturn) |
| 953 | ROM_REGION( 0x480000, "maincpu", ROMREGION_ERASEFF ) /* SH2 code */ |
| 954 | ROM_SYSTEM_BIOS(0, "101a", "Overseas v1.01a (941115)") |
| 955 | /* Confirmed by ElBarto */ |
| 956 | ROMX_LOAD("mpr-17933.bin", 0x00000000, 0x00080000, CRC(4afcf0fa) SHA1(faa8ea183a6d7bbe5d4e03bb1332519800d3fbc3), ROM_BIOS(1)) |
| 957 | ROM_SYSTEM_BIOS(1, "100a", "Overseas v1.00a (941115)") |
| 958 | ROMX_LOAD("sega_100a.bin", 0x00000000, 0x00080000, CRC(f90f0089) SHA1(3bb41feb82838ab9a35601ac666de5aacfd17a58), ROM_BIOS(2)) |
| 959 | // ROM_CART_LOAD("cart", 0x080000, 0x400000, ROM_NOMIRROR | ROM_OPTIONAL) |
| 960 | ROM_REGION( 0x080000, "slave", 0 ) /* SH2 code */ |
| 961 | ROM_COPY( "maincpu",0,0,0x080000) |
| 962 | ROM_END |
| 963 | |
| 964 | ROM_START(saturneu) |
| 965 | ROM_REGION( 0x480000, "maincpu", ROMREGION_ERASEFF ) /* SH2 code */ |
| 966 | ROM_SYSTEM_BIOS(0, "101a", "Overseas v1.01a (941115)") |
| 967 | /* Confirmed by ElBarto */ |
| 968 | ROMX_LOAD("mpr-17933.bin", 0x00000000, 0x00080000, CRC(4afcf0fa) SHA1(faa8ea183a6d7bbe5d4e03bb1332519800d3fbc3), ROM_BIOS(1)) |
| 969 | ROM_SYSTEM_BIOS(1, "100a", "Overseas v1.00a (941115)") |
| 970 | ROMX_LOAD("sega_100a.bin", 0x00000000, 0x00080000, CRC(f90f0089) SHA1(3bb41feb82838ab9a35601ac666de5aacfd17a58), ROM_BIOS(2)) |
| 971 | // ROM_CART_LOAD("cart", 0x080000, 0x400000, ROM_NOMIRROR | ROM_OPTIONAL) |
| 972 | ROM_REGION( 0x080000, "slave", 0 ) /* SH2 code */ |
| 973 | ROM_COPY( "maincpu",0,0,0x080000) |
| 974 | ROM_END |
| 975 | |
| 976 | ROM_START(vsaturn) |
| 977 | ROM_REGION( 0x480000, "maincpu", ROMREGION_ERASEFF ) /* SH2 code */ |
| 978 | ROM_LOAD("vsaturn.bin", 0x00000000, 0x00080000, CRC(e4d61811) SHA1(4154e11959f3d5639b11d7902b3a393a99fb5776)) |
| 979 | // ROM_CART_LOAD("cart", 0x080000, 0x400000, ROM_NOMIRROR | ROM_OPTIONAL) |
| 980 | ROM_REGION( 0x080000, "slave", 0 ) /* SH2 code */ |
| 981 | ROM_COPY( "maincpu",0,0,0x080000) |
| 982 | ROM_END |
| 983 | |
| 984 | ROM_START(hisaturn) |
| 985 | ROM_REGION( 0x480000, "maincpu", ROMREGION_ERASEFF ) /* SH2 code */ |
| 986 | ROM_LOAD("hisaturn.bin", 0x00000000, 0x00080000, CRC(721e1b60) SHA1(49d8493008fa715ca0c94d99817a5439d6f2c796)) |
| 987 | // ROM_CART_LOAD("cart", 0x080000, 0x400000, ROM_NOMIRROR | ROM_OPTIONAL) |
| 988 | ROM_REGION( 0x080000, "slave", 0 ) /* SH2 code */ |
| 989 | ROM_COPY( "maincpu",0,0,0x080000) |
| 990 | ROM_END |
| 991 | |
| 992 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
| 993 | CONS( 1994, saturn, 0, 0, saturnus, saturn, saturn_state, saturnus, "Sega", "Saturn (USA)", GAME_NOT_WORKING ) |
| 994 | CONS( 1994, saturnjp, saturn, 0, saturnjp, saturn, saturn_state, saturnjp, "Sega", "Saturn (Japan)", GAME_NOT_WORKING ) |
| 995 | CONS( 1994, saturneu, saturn, 0, saturneu, saturn, saturn_state, saturneu, "Sega", "Saturn (PAL)", GAME_NOT_WORKING ) |
| 996 | CONS( 1995, vsaturn, saturn, 0, saturnjp, saturn, saturn_state, saturnjp, "JVC", "V-Saturn", GAME_NOT_WORKING ) |
| 997 | CONS( 1995, hisaturn, saturn, 0, saturnjp, saturn, saturn_state, saturnjp, "Hitachi", "HiSaturn", GAME_NOT_WORKING ) |
trunk/src/mame/drivers/saturn.c
| r21330 | r21331 | |
| 1 | | /************************************************************************************************** |
| 2 | | |
| 3 | | Sega Saturn & Sega ST-V (Sega Titan Video) HW (c) 1994 Sega |
| 4 | | |
| 5 | | Driver by David Haywood, Angelo Salese, Olivier Galibert & Mariusz Wojcieszek |
| 6 | | SCSP driver provided by R.Belmont, based on ElSemi's SCSP sound chip emulator |
| 7 | | CD Block driver provided by ANY, based on sthief original emulator |
| 8 | | Many thanks to Guru, Fabien, Runik and Charles MacDonald for the help given. |
| 9 | | |
| 10 | | =================================================================================================== |
| 11 | | |
| 12 | | Notes: |
| 13 | | -To enter into an Advanced Test Mode,keep pressed the Test Button (F2) on the start-up. |
| 14 | | -Memo: Some tests done on the original & working PCB,to be implemented: |
| 15 | | -The AD-Stick returns 0x00 or a similar value. |
| 16 | | -The Ports E,F & G must return 0xff |
| 17 | | |
| 18 | | TODO: |
| 19 | | (Main issues) |
| 20 | | - decap the SH-1, used for CD block (needed especially for Sega Saturn) |
| 21 | | - IRQs: some games have some issues with timing accurate IRQs, check/fix all of them. |
| 22 | | - The Cart-Dev mode hangs even with the -dev bios,I would like to see what it does on the real HW. |
| 23 | | - IC13 games on the dev bios doesn't even load the cartridge / crashes the emulation at start-up, |
| 24 | | rom rearrange needed? |
| 25 | | - SCU DSP still has its fair share of issues, it also needs to be converted to CPU structure; |
| 26 | | - Add the RS232c interface (serial port), needed by fhboxers (accesses some ports in the a-bus dummy range). |
| 27 | | - Video emulation is nowhere near perfection. |
| 28 | | - Reimplement the idle skip if possible. |
| 29 | | - Properly emulate the protection chips, used by several games (check stvprot.c for more info) |
| 30 | | - Move SCU device into its respective file; |
| 31 | | - Split ST-V and Saturn files properly; |
| 32 | | |
| 33 | | (per-game issues) |
| 34 | | - stress: accesses the Sound Memory Expansion Area (0x05a80000-0x05afffff), unknown purpose; |
| 35 | | |
| 36 | | - smleague / finlarch: it randomly hangs / crashes,it works if you use a ridiculous MCFG_INTERLEAVE number,might need strict |
| 37 | | SH-2 synching or it's actually a m68k comms issue. |
| 38 | | |
| 39 | | - groovef: ugly back screen color, caused by incorrect usage of the Color Calculation function. |
| 40 | | |
| 41 | | - myfairld: Apparently this game gives a black screen (either test mode and in-game mode),but let it wait for about |
| 42 | | 10 seconds and the game will load everything. This is because of a hellishly slow m68k sub-routine located at 54c2. |
| 43 | | Likely to not be a bug but an in-game design issue. |
| 44 | | |
| 45 | | - danchih / danchiq: currently hangs randomly (regression). |
| 46 | | |
| 47 | | - batmanfr: Missing sound,caused by an extra ADSP chip which is on the cart.The CPU is a |
| 48 | | ADSP-2181,and it's the same used by NBA Jam Extreme (ZN game). |
| 49 | | |
| 50 | | - vfremix: when you play as Akira, there is a problem with third match: game doesn't upload all textures |
| 51 | | and tiles and doesn't enable display, although gameplay is normal - wait a while to get back |
| 52 | | to title screen after losing a match |
| 53 | | |
| 54 | | - vfremix: various problems with SCU DSP: Jeffry causes a black screen hang. Akira's kick sometimes |
| 55 | | sends the opponent out of the ring from whatever position. |
| 56 | | |
| 57 | | |
| 58 | | ****************************************************************************************************/ |
| 59 | | |
| 60 | | #include "emu.h" |
| 61 | | #include "cpu/m68000/m68000.h" |
| 62 | | #include "machine/eeprom.h" |
| 63 | | #include "cpu/sh2/sh2.h" |
| 64 | | #include "machine/scudsp.h" |
| 65 | | #include "sound/scsp.h" |
| 66 | | #include "sound/cdda.h" |
| 67 | | #include "machine/smpc.h" |
| 68 | | #include "includes/stv.h" |
| 69 | | #include "imagedev/chd_cd.h" |
| 70 | | #include "imagedev/cartslot.h" |
| 71 | | #include "coreutil.h" |
| 72 | | |
| 73 | | |
| 74 | | /* TODO: do this in a verboselog style */ |
| 75 | | #define LOG_CDB 0 |
| 76 | | #define LOG_SCU 1 |
| 77 | | #define LOG_IRQ 0 |
| 78 | | #define LOG_IOGA 0 |
| 79 | | |
| 80 | | int saturn_state::DectoBCD(int num) |
| 81 | | { |
| 82 | | int i, cnt = 0, tmp, res = 0; |
| 83 | | |
| 84 | | while (num > 0) { |
| 85 | | tmp = num; |
| 86 | | while (tmp >= 10) tmp %= 10; |
| 87 | | for (i=0; i<cnt; i++) |
| 88 | | tmp *= 16; |
| 89 | | res += tmp; |
| 90 | | cnt++; |
| 91 | | num /= 10; |
| 92 | | } |
| 93 | | |
| 94 | | return res; |
| 95 | | } |
| 96 | | |
| 97 | | /**************************************************************************************/ |
| 98 | | |
| 99 | | /* |
| 100 | | |
| 101 | | SCU Handling |
| 102 | | |
| 103 | | */ |
| 104 | | |
| 105 | | /********************************************************************************** |
| 106 | | SCU Register Table |
| 107 | | offset,relative address |
| 108 | | Registers are in long words. |
| 109 | | =================================================================================== |
| 110 | | 0 0000 Level 0 DMA Set Register |
| 111 | | 1 0004 |
| 112 | | 2 0008 |
| 113 | | 3 000c |
| 114 | | 4 0010 |
| 115 | | 5 0014 |
| 116 | | 6 0018 |
| 117 | | 7 001c |
| 118 | | 8 0020 Level 1 DMA Set Register |
| 119 | | 9 0024 |
| 120 | | 10 0028 |
| 121 | | 11 002c |
| 122 | | 12 0030 |
| 123 | | 13 0034 |
| 124 | | 14 0038 |
| 125 | | 15 003c |
| 126 | | 16 0040 Level 2 DMA Set Register |
| 127 | | 17 0044 |
| 128 | | 18 0048 |
| 129 | | 19 004c |
| 130 | | 20 0050 |
| 131 | | 21 0054 |
| 132 | | 22 0058 |
| 133 | | 23 005c |
| 134 | | 24 0060 DMA Forced Stop |
| 135 | | 25 0064 |
| 136 | | 26 0068 |
| 137 | | 27 006c |
| 138 | | 28 0070 <Free> |
| 139 | | 29 0074 |
| 140 | | 30 0078 |
| 141 | | 31 007c DMA Status Register |
| 142 | | 32 0080 DSP Program Control Port |
| 143 | | 33 0084 DSP Program RAM Data Port |
| 144 | | 34 0088 DSP Data RAM Address Port |
| 145 | | 35 008c DSP Data RAM Data Port |
| 146 | | 36 0090 Timer 0 Compare Register |
| 147 | | 37 0094 Timer 1 Set Data Register |
| 148 | | 38 0098 Timer 1 Mode Register |
| 149 | | 39 009c <Free> |
| 150 | | 40 00a0 Interrupt Mask Register |
| 151 | | 41 00a4 Interrupt Status Register |
| 152 | | 42 00a8 A-Bus Interrupt Acknowledge |
| 153 | | 43 00ac <Free> |
| 154 | | 44 00b0 A-Bus Set Register |
| 155 | | 45 00b4 |
| 156 | | 46 00b8 A-Bus Refresh Register |
| 157 | | 47 00bc <Free> |
| 158 | | 48 00c0 |
| 159 | | 49 00c4 SCU SDRAM Select Register |
| 160 | | 50 00c8 SCU Version Register |
| 161 | | 51 00cc <Free> |
| 162 | | 52 00cf |
| 163 | | =================================================================================== |
| 164 | | DMA Status Register(32-bit): |
| 165 | | xxxx xxxx x--- xx-- xx-- xx-- xx-- xx-- UNUSED |
| 166 | | ---- ---- -x-- ---- ---- ---- ---- ---- DMA DSP-Bus access |
| 167 | | ---- ---- --x- ---- ---- ---- ---- ---- DMA B-Bus access |
| 168 | | ---- ---- ---x ---- ---- ---- ---- ---- DMA A-Bus access |
| 169 | | ---- ---- ---- --x- ---- ---- ---- ---- DMA lv 1 interrupt |
| 170 | | ---- ---- ---- ---x ---- ---- ---- ---- DMA lv 0 interrupt |
| 171 | | ---- ---- ---- ---- --x- ---- ---- ---- DMA lv 2 in stand-by |
| 172 | | ---- ---- ---- ---- ---x ---- ---- ---- DMA lv 2 in operation |
| 173 | | ---- ---- ---- ---- ---- --x- ---- ---- DMA lv 1 in stand-by |
| 174 | | ---- ---- ---- ---- ---- ---x ---- ---- DMA lv 1 in operation |
| 175 | | ---- ---- ---- ---- ---- ---- --x- ---- DMA lv 0 in stand-by |
| 176 | | ---- ---- ---- ---- ---- ---- ---x ---- DMA lv 0 in operation |
| 177 | | ---- ---- ---- ---- ---- ---- ---- --x- DSP side DMA in stand-by |
| 178 | | ---- ---- ---- ---- ---- ---- ---- ---x DSP side DMA in operation |
| 179 | | |
| 180 | | **********************************************************************************/ |
| 181 | | /* |
| 182 | | DMA TODO: |
| 183 | | -Remove CD transfer DMA hack (tied with CD block bug(s)?) |
| 184 | | -Add timings(but how fast are each DMA?). |
| 185 | | -Add level priority & DMA status register. |
| 186 | | */ |
| 187 | | |
| 188 | | #define DIRECT_MODE(_lv_) (!(m_scu_regs[5+(_lv_*8)] & 0x01000000)) |
| 189 | | #define INDIRECT_MODE(_lv_) (m_scu_regs[5+(_lv_*8)] & 0x01000000) |
| 190 | | #define DRUP(_lv_) (m_scu_regs[5+(_lv_*8)] & 0x00010000) |
| 191 | | #define DWUP(_lv_) (m_scu_regs[5+(_lv_*8)] & 0x00000100) |
| 192 | | |
| 193 | | /*These macros sets the various DMA status flags.*/ |
| 194 | | #define DnMV_1(_ch_) m_scu.status|=(0x10 << 4 * _ch_) |
| 195 | | #define DnMV_0(_ch_) m_scu.status&=~(0x10 << 4 * _ch_) |
| 196 | | |
| 197 | | /*For area checking*/ |
| 198 | | #define BIOS_BUS(var) (var & 0x07000000) == 0 |
| 199 | | #define ABUS(_lv_) ((m_scu.src[_lv_] & 0x07000000) >= 0x02000000) && ((m_scu.src[_lv_] & 0x07000000) <= 0x04000000) |
| 200 | | #define BBUS(_lv_) ((scu_##_lv_ & 0x07ffffff) >= 0x05a00000) && ((scu_##_lv_ & 0x07ffffff) <= 0x05ffffff) |
| 201 | | #define VDP1_REGS(_lv_) ((scu_##_lv_ & 0x07ffffff) >= 0x05d00000) && ((scu_##_lv_ & 0x07ffffff) <= 0x05dfffff) |
| 202 | | #define VDP2(_lv_) ((scu_##_lv_ & 0x07ffffff) >= 0x05e00000) && ((scu_##_lv_ & 0x07ffffff) <= 0x05fdffff) |
| 203 | | #define WORK_RAM_L(_lv_) ((scu_##_lv_ & 0x07ffffff) >= 0x00200000) && ((scu_##_lv_ & 0x07ffffff) <= 0x002fffff) |
| 204 | | #define WORK_RAM_H(var) (var & 0x07000000) == 0x06000000 |
| 205 | | #define SOUND_RAM(_lv_) ((scu_##_lv_ & 0x07ffffff) >= 0x05a00000) && ((scu_##_lv_ & 0x07ffffff) <= 0x05afffff) |
| 206 | | |
| 207 | | void saturn_state::scu_do_transfer(UINT8 event) |
| 208 | | { |
| 209 | | address_space &space = machine().device("maincpu")->memory().space(AS_PROGRAM); |
| 210 | | int i; |
| 211 | | |
| 212 | | for(i=0;i<3;i++) |
| 213 | | { |
| 214 | | if(m_scu.enable_mask[i] && m_scu.start_factor[i] == event) |
| 215 | | { |
| 216 | | if(DIRECT_MODE(i)) { scu_dma_direct(space,i); } |
| 217 | | else { scu_dma_indirect(space,i); } |
| 218 | | } |
| 219 | | } |
| 220 | | } |
| 221 | | |
| 222 | | /* test pending irqs */ |
| 223 | | void saturn_state::scu_test_pending_irq() |
| 224 | | { |
| 225 | | int i; |
| 226 | | const int irq_level[32] = { 0xf, 0xe, 0xd, 0xc, |
| 227 | | 0xb, 0xa, 0x9, 0x8, |
| 228 | | 0x8, 0x6, 0x6, 0x5, |
| 229 | | 0x3, 0x2, -1, -1, |
| 230 | | 0x7, 0x7, 0x7, 0x7, |
| 231 | | 0x4, 0x4, 0x4, 0x4, |
| 232 | | 0x1, 0x1, 0x1, 0x1, |
| 233 | | 0x1, 0x1, 0x1, 0x1 }; |
| 234 | | |
| 235 | | for(i=0;i<32;i++) |
| 236 | | { |
| 237 | | if((!(m_scu.ism & 1 << i)) && (m_scu.ist & 1 << i)) |
| 238 | | { |
| 239 | | if(irq_level[i] != -1) /* TODO: cheap check for undefined irqs */ |
| 240 | | { |
| 241 | | m_maincpu->set_input_line_and_vector(irq_level[i], HOLD_LINE, 0x40 + i); |
| 242 | | m_scu.ist &= ~(1 << i); |
| 243 | | return; /* avoid spurious irqs, correct? */ |
| 244 | | } |
| 245 | | } |
| 246 | | } |
| 247 | | } |
| 248 | | |
| 249 | | READ32_MEMBER(saturn_state::saturn_scu_r) |
| 250 | | { |
| 251 | | UINT32 res; |
| 252 | | |
| 253 | | /*TODO: write only registers must return 0 or open bus */ |
| 254 | | switch(offset) |
| 255 | | { |
| 256 | | case 0x5c/4: |
| 257 | | // Super Major League and Shin Megami Tensei - Akuma Zensho reads from there (undocumented), DMA status mirror? |
| 258 | | if(LOG_SCU && !space.debugger_access()) logerror("(PC=%08x) DMA status reg read\n",space.device().safe_pc()); |
| 259 | | res = m_scu.status; |
| 260 | | break; |
| 261 | | case 0x7c/4: |
| 262 | | if(LOG_SCU && !space.debugger_access()) logerror("(PC=%08x) DMA status reg read\n",space.device().safe_pc()); |
| 263 | | res = m_scu.status; |
| 264 | | break; |
| 265 | | case 0x80/4: |
| 266 | | res = dsp_prg_ctrl_r(space); |
| 267 | | break; |
| 268 | | case 0x8c/4: |
| 269 | | if(LOG_SCU && !space.debugger_access()) logerror( "DSP mem read at %08X\n", m_scu_regs[34]); |
| 270 | | res = dsp_ram_addr_r(); |
| 271 | | break; |
| 272 | | case 0xa0/4: |
| 273 | | if(LOG_SCU && !space.debugger_access()) logerror("(PC=%08x) IRQ mask reg read %08x MASK=%08x\n",space.device().safe_pc(),mem_mask,m_scu_regs[0xa0/4]); |
| 274 | | res = m_scu.ism; |
| 275 | | break; |
| 276 | | case 0xa4/4: |
| 277 | | if(LOG_SCU && !space.debugger_access()) logerror("(PC=%08x) IRQ status reg read MASK=%08x IST=%08x | ISM=%08x\n",space.device().safe_pc(),mem_mask,m_scu.ist,m_scu.ism); |
| 278 | | /* TODO: Bug! trips an HW fault. Basically, it tries to read the IST bit 1 with that irq enabled. |
| 279 | | Densetsu no Ogre Battle doesn't like this, so it needs investigation ... |
| 280 | | */ |
| 281 | | // res = m_scu.ist | ~m_scu.ism; |
| 282 | | res = m_scu.ist; |
| 283 | | break; |
| 284 | | case 0xc8/4: |
| 285 | | if(LOG_SCU && !space.debugger_access()) logerror("(PC=%08x) SCU version reg read\n",space.device().safe_pc()); |
| 286 | | res = 0x00000004;/*SCU Version 4, OK? */ |
| 287 | | break; |
| 288 | | default: |
| 289 | | if(LOG_SCU && !space.debugger_access()) logerror("(PC=%08x) SCU reg read at %d = %08x\n",space.device().safe_pc(),offset,m_scu_regs[offset]); |
| 290 | | res = m_scu_regs[offset]; |
| 291 | | break; |
| 292 | | } |
| 293 | | |
| 294 | | return res; |
| 295 | | } |
| 296 | | |
| 297 | | #define DMA_CH ((offset & 0x18) / 8) |
| 298 | | |
| 299 | | WRITE32_MEMBER(saturn_state::saturn_scu_w) |
| 300 | | { |
| 301 | | COMBINE_DATA(&m_scu_regs[offset]); |
| 302 | | |
| 303 | | switch(offset) |
| 304 | | { |
| 305 | | /*LV 0 DMA*/ |
| 306 | | case 0x00/4: case 0x20/4: case 0x40/4: m_scu.src[DMA_CH] = ((m_scu_regs[offset] & 0x07ffffff) >> 0); break; |
| 307 | | case 0x04/4: case 0x24/4: case 0x44/4: m_scu.dst[DMA_CH] = ((m_scu_regs[offset] & 0x07ffffff) >> 0); break; |
| 308 | | case 0x08/4: case 0x28/4: case 0x48/4: m_scu.size[DMA_CH] = ((m_scu_regs[offset] & ((offset == 2) ? 0x000fffff : 0xfff)) >> 0); break; |
| 309 | | case 0x0c/4: case 0x2c/4: case 0x4c/4: |
| 310 | | m_scu.src_add[DMA_CH] = (m_scu_regs[offset] & 0x100) ? 4 : 0; |
| 311 | | m_scu.dst_add[DMA_CH] = 1 << (m_scu_regs[offset] & 7); |
| 312 | | if(m_scu.dst_add[DMA_CH] == 1) { m_scu.dst_add[DMA_CH] = 0; } |
| 313 | | break; |
| 314 | | case 0x10/4: case 0x30/4: case 0x50/4: |
| 315 | | m_scu.enable_mask[DMA_CH] = (data & 0x100) >> 8; |
| 316 | | if(m_scu.enable_mask[DMA_CH] && m_scu.start_factor[DMA_CH] == 7 && m_scu_regs[offset] & 1) |
| 317 | | { |
| 318 | | if(DIRECT_MODE(DMA_CH)) { scu_dma_direct(space,DMA_CH); } |
| 319 | | else { scu_dma_indirect(space,DMA_CH); } |
| 320 | | m_scu_regs[offset]&=~1;//disable starting bit. |
| 321 | | } |
| 322 | | break; |
| 323 | | case 0x14/4: case 0x34/4: case 0x54/4: |
| 324 | | if(INDIRECT_MODE(DMA_CH)) |
| 325 | | { |
| 326 | | //if(LOG_SCU) logerror("Indirect Mode DMA lv %d set\n",DMA_CH); |
| 327 | | if(!DWUP(DMA_CH)) m_scu.index[DMA_CH] = m_scu.dst[DMA_CH]; |
| 328 | | } |
| 329 | | |
| 330 | | m_scu.start_factor[DMA_CH] = m_scu_regs[offset] & 7; |
| 331 | | break; |
| 332 | | |
| 333 | | case 0x60/4: |
| 334 | | if(LOG_SCU) logerror("DMA Forced Stop Register set = %02x\n",m_scu_regs[24]); |
| 335 | | break; |
| 336 | | case 0x7c/4: if(LOG_SCU) logerror("Warning: DMA status WRITE! Offset %02x(%d)\n",offset*4,offset); break; |
| 337 | | /*DSP section*/ |
| 338 | | case 0x80/4: |
| 339 | | /* TODO: you can't overwrite some flags with this */ |
| 340 | | dsp_prg_ctrl_w(space, m_scu_regs[offset]); |
| 341 | | if(LOG_SCU) logerror("SCU DSP: Program Control Port Access %08x\n",data); |
| 342 | | break; |
| 343 | | case 0x84/4: |
| 344 | | dsp_prg_data(m_scu_regs[offset]); |
| 345 | | if(LOG_SCU) logerror("SCU DSP: Program RAM Data Port Access %08x\n",data); |
| 346 | | break; |
| 347 | | case 0x88/4: |
| 348 | | dsp_ram_addr_ctrl(m_scu_regs[offset]); |
| 349 | | if(LOG_SCU) logerror("SCU DSP: Data RAM Address Port Access %08x\n",data); |
| 350 | | break; |
| 351 | | case 0x8c/4: |
| 352 | | dsp_ram_addr_w(m_scu_regs[offset]); |
| 353 | | if(LOG_SCU) logerror("SCU DSP: Data RAM Data Port Access %08x\n",data); |
| 354 | | break; |
| 355 | | case 0x90/4: /*if(LOG_SCU) logerror("timer 0 compare data = %03x\n",m_scu_regs[36]);*/ break; |
| 356 | | case 0x94/4: /*if(LOG_SCU) logerror("timer 1 set data = %08x\n",m_scu_regs[37]);*/ break; |
| 357 | | case 0x98/4: /*if(LOG_SCU) logerror("timer 1 mode data = %08x\n",m_scu_regs[38]);*/ break; |
| 358 | | case 0xa0/4: /* IRQ mask */ |
| 359 | | m_scu.ism = m_scu_regs[0xa0/4]; |
| 360 | | scu_test_pending_irq(); |
| 361 | | break; |
| 362 | | case 0xa4/4: /* IRQ control */ |
| 363 | | if(LOG_SCU) logerror("PC=%08x IRQ status reg set:%08x %08x\n",space.device().safe_pc(),m_scu_regs[41],mem_mask); |
| 364 | | m_scu.ist &= m_scu_regs[offset]; |
| 365 | | scu_test_pending_irq(); |
| 366 | | break; |
| 367 | | case 0xa8/4: |
| 368 | | /* This sends an irq signal to the extra devices connected to the A-Bus, not really needed for now. */ |
| 369 | | //if(LOG_SCU) logerror("A-Bus IRQ ACK %08x\n",m_scu_regs[42]); |
| 370 | | break; |
| 371 | | case 0xc4/4: if(LOG_SCU) logerror("SCU SDRAM set: %02x\n",m_scu_regs[49]); break; |
| 372 | | default: if(LOG_SCU) logerror("Warning: unused SCU reg set %d = %08x\n",offset,data); |
| 373 | | } |
| 374 | | } |
| 375 | | |
| 376 | | /*Lv 0 DMA end irq*/ |
| 377 | | TIMER_CALLBACK_MEMBER(saturn_state::dma_lv0_ended ) |
| 378 | | { |
| 379 | | if(!(m_scu.ism & IRQ_DMALV0)) |
| 380 | | m_maincpu->set_input_line_and_vector(5, HOLD_LINE, 0x4b); |
| 381 | | else |
| 382 | | m_scu.ist |= (IRQ_DMALV0); |
| 383 | | |
| 384 | | DnMV_0(0); |
| 385 | | } |
| 386 | | |
| 387 | | /*Lv 1 DMA end irq*/ |
| 388 | | TIMER_CALLBACK_MEMBER(saturn_state::dma_lv1_ended) |
| 389 | | { |
| 390 | | if(!(m_scu.ism & IRQ_DMALV1)) |
| 391 | | m_maincpu->set_input_line_and_vector(6, HOLD_LINE, 0x4a); |
| 392 | | else |
| 393 | | m_scu.ist |= (IRQ_DMALV1); |
| 394 | | |
| 395 | | DnMV_0(1); |
| 396 | | } |
| 397 | | |
| 398 | | /*Lv 2 DMA end irq*/ |
| 399 | | TIMER_CALLBACK_MEMBER(saturn_state::dma_lv2_ended) |
| 400 | | { |
| 401 | | if(!(m_scu.ism & IRQ_DMALV2)) |
| 402 | | m_maincpu->set_input_line_and_vector(6, HOLD_LINE, 0x49); |
| 403 | | else |
| 404 | | m_scu.ist |= (IRQ_DMALV2); |
| 405 | | |
| 406 | | DnMV_0(2); |
| 407 | | } |
| 408 | | |
| 409 | | void saturn_state::scu_single_transfer(address_space &space, UINT32 src, UINT32 dst,UINT8 *src_shift) |
| 410 | | { |
| 411 | | UINT32 src_data; |
| 412 | | |
| 413 | | if(src & 1) |
| 414 | | { |
| 415 | | /* Road Blaster does a work ram h to color ram with offsetted source address, do some data rotation */ |
| 416 | | src_data = ((space.read_dword(src & 0x07fffffc) & 0x00ffffff)<<8); |
| 417 | | src_data |= ((space.read_dword((src & 0x07fffffc)+4) & 0xff000000) >> 24); |
| 418 | | src_data >>= (*src_shift)*16; |
| 419 | | } |
| 420 | | else |
| 421 | | src_data = space.read_dword(src & 0x07fffffc) >> (*src_shift)*16; |
| 422 | | |
| 423 | | space.write_word(dst,src_data); |
| 424 | | |
| 425 | | *src_shift ^= 1; |
| 426 | | } |
| 427 | | |
| 428 | | void saturn_state::scu_dma_direct(address_space &space, UINT8 dma_ch) |
| 429 | | { |
| 430 | | UINT32 tmp_src,tmp_dst,total_size; |
| 431 | | UINT8 cd_transfer_flag; |
| 432 | | |
| 433 | | if(m_scu.src_add[dma_ch] == 0 || (m_scu.dst_add[dma_ch] != 2 && m_scu.dst_add[dma_ch] != 4)) |
| 434 | | { |
| 435 | | if(LOG_SCU) printf("DMA lv %d transfer START\n" |
| 436 | | "Start %08x End %08x Size %04x\n",dma_ch,m_scu.src[dma_ch],m_scu.dst[dma_ch],m_scu.size[dma_ch]); |
| 437 | | if(LOG_SCU) printf("Start Add %04x Destination Add %04x\n",m_scu.src_add[dma_ch],m_scu.dst_add[dma_ch]); |
| 438 | | } |
| 439 | | |
| 440 | | /* TODO: Game Basic and World Cup 98 trips this, according to the docs the SCU can't transfer from BIOS area (can't communicate from/to that bus) */ |
| 441 | | if(BIOS_BUS(m_scu.src[dma_ch])) |
| 442 | | { |
| 443 | | popmessage("Warning: SCU transfer from BIOS area, contact MAMEdev"); |
| 444 | | if(!(m_scu.ism & IRQ_DMAILL)) |
| 445 | | m_maincpu->set_input_line_and_vector(3, HOLD_LINE, 0x4c); |
| 446 | | else |
| 447 | | m_scu.ist |= (IRQ_DMAILL); |
| 448 | | return; |
| 449 | | } |
| 450 | | |
| 451 | | DnMV_1(dma_ch); |
| 452 | | |
| 453 | | /* max size */ |
| 454 | | if(m_scu.size[dma_ch] == 0) { m_scu.size[dma_ch] = (dma_ch == 0) ? 0x00100000 : 0x1000; } |
| 455 | | |
| 456 | | tmp_src = tmp_dst = 0; |
| 457 | | |
| 458 | | total_size = m_scu.size[dma_ch]; |
| 459 | | if(!(DRUP(dma_ch))) tmp_src = m_scu.src[dma_ch]; |
| 460 | | if(!(DWUP(dma_ch))) tmp_dst = m_scu.dst[dma_ch]; |
| 461 | | |
| 462 | | cd_transfer_flag = m_scu.src_add[dma_ch] == 0 && m_scu.src[dma_ch] == 0x05818000; |
| 463 | | |
| 464 | | /* TODO: Many games directly accesses CD-ROM register 0x05818000, it must be a dword access with current implementation otherwise it won't work */ |
| 465 | | if(cd_transfer_flag) |
| 466 | | { |
| 467 | | int i; |
| 468 | | if(WORK_RAM_H(m_scu.dst[dma_ch])) |
| 469 | | m_scu.dst_add[dma_ch] = 4; |
| 470 | | else |
| 471 | | m_scu.dst_add[dma_ch] <<= 1; |
| 472 | | |
| 473 | | for (i = 0; i < m_scu.size[dma_ch];i+=m_scu.dst_add[dma_ch]) |
| 474 | | { |
| 475 | | space.write_dword(m_scu.dst[dma_ch],space.read_dword(m_scu.src[dma_ch])); |
| 476 | | if(m_scu.dst_add[dma_ch] == 8) |
| 477 | | space.write_dword(m_scu.dst[dma_ch]+4,space.read_dword(m_scu.src[dma_ch])); |
| 478 | | |
| 479 | | m_scu.src[dma_ch]+=m_scu.src_add[dma_ch]; |
| 480 | | m_scu.dst[dma_ch]+=m_scu.dst_add[dma_ch]; |
| 481 | | } |
| 482 | | } |
| 483 | | else |
| 484 | | { |
| 485 | | int i; |
| 486 | | UINT8 src_shift; |
| 487 | | |
| 488 | | src_shift = ((m_scu.src[dma_ch] & 2) >> 1) ^ 1; |
| 489 | | |
| 490 | | for (i = 0; i < m_scu.size[dma_ch];i+=2) |
| 491 | | { |
| 492 | | scu_single_transfer(space,m_scu.src[dma_ch],m_scu.dst[dma_ch],&src_shift); |
| 493 | | |
| 494 | | if(src_shift) |
| 495 | | m_scu.src[dma_ch]+=m_scu.src_add[dma_ch]; |
| 496 | | |
| 497 | | /* if target is Work RAM H, the add value is fixed, behaviour confirmed by Final Romance 2, Virtual Mahjong and Burning Rangers */ |
| 498 | | m_scu.dst[dma_ch]+=(WORK_RAM_H(m_scu.dst[dma_ch])) ? 2 : m_scu.dst_add[dma_ch]; |
| 499 | | } |
| 500 | | } |
| 501 | | |
| 502 | | /* Burning Rangers doesn't agree with this. */ |
| 503 | | // m_scu.size[dma_ch] = 0; |
| 504 | | if(!(DRUP(dma_ch))) m_scu.src[dma_ch] = tmp_src; |
| 505 | | if(!(DWUP(dma_ch))) m_scu.dst[dma_ch] = tmp_dst; |
| 506 | | |
| 507 | | { |
| 508 | | /*TODO: change DMA into DRQ model. Timing is a guess. */ |
| 509 | | switch(dma_ch) |
| 510 | | { |
| 511 | | case 0: machine().scheduler().timer_set(m_maincpu->cycles_to_attotime(total_size/4), timer_expired_delegate(FUNC(saturn_state::dma_lv0_ended),this)); break; |
| 512 | | case 1: machine().scheduler().timer_set(m_maincpu->cycles_to_attotime(total_size/4), timer_expired_delegate(FUNC(saturn_state::dma_lv1_ended),this)); break; |
| 513 | | case 2: machine().scheduler().timer_set(m_maincpu->cycles_to_attotime(total_size/4), timer_expired_delegate(FUNC(saturn_state::dma_lv2_ended),this)); break; |
| 514 | | } |
| 515 | | } |
| 516 | | } |
| 517 | | |
| 518 | | void saturn_state::scu_dma_indirect(address_space &space,UINT8 dma_ch) |
| 519 | | { |
| 520 | | /*Helper to get out of the cycle*/ |
| 521 | | UINT8 job_done = 0; |
| 522 | | /*temporary storage for the transfer data*/ |
| 523 | | UINT32 tmp_src; |
| 524 | | UINT32 indirect_src,indirect_dst; |
| 525 | | INT32 indirect_size; |
| 526 | | UINT32 total_size = 0; |
| 527 | | |
| 528 | | DnMV_1(dma_ch); |
| 529 | | |
| 530 | | m_scu.index[dma_ch] = m_scu.dst[dma_ch]; |
| 531 | | |
| 532 | | do{ |
| 533 | | tmp_src = m_scu.index[dma_ch]; |
| 534 | | |
| 535 | | indirect_size = space.read_dword(m_scu.index[dma_ch]); |
| 536 | | indirect_src = space.read_dword(m_scu.index[dma_ch]+8); |
| 537 | | indirect_dst = space.read_dword(m_scu.index[dma_ch]+4); |
| 538 | | |
| 539 | | /*Indirect Mode end factor*/ |
| 540 | | if(indirect_src & 0x80000000) |
| 541 | | job_done = 1; |
| 542 | | |
| 543 | | if(m_scu.src_add[dma_ch] == 0 || (m_scu.dst_add[dma_ch] != 2)) |
| 544 | | { |
| 545 | | if(LOG_SCU) printf("DMA lv %d indirect mode transfer START\n" |
| 546 | | "Index %08x Start %08x End %08x Size %04x\n",dma_ch,tmp_src,indirect_src,indirect_dst,indirect_size); |
| 547 | | if(LOG_SCU) printf("Start Add %04x Destination Add %04x\n",m_scu.src_add[dma_ch],m_scu.dst_add[dma_ch]); |
| 548 | | } |
| 549 | | |
| 550 | | indirect_src &=0x07ffffff; |
| 551 | | indirect_dst &=0x07ffffff; |
| 552 | | indirect_size &= ((dma_ch == 0) ? 0xfffff : 0x3ffff); //TODO: Guardian Heroes sets up a 0x23000 transfer for the FMV? |
| 553 | | |
| 554 | | if(indirect_size == 0) { indirect_size = (dma_ch == 0) ? 0x00100000 : 0x2000; } |
| 555 | | |
| 556 | | { |
| 557 | | int i; |
| 558 | | UINT8 src_shift; |
| 559 | | |
| 560 | | src_shift = ((indirect_src & 2) >> 1) ^ 1; |
| 561 | | |
| 562 | | for (i = 0; i < indirect_size;i+=2) |
| 563 | | { |
| 564 | | scu_single_transfer(space,indirect_src,indirect_dst,&src_shift); |
| 565 | | |
| 566 | | if(src_shift) |
| 567 | | indirect_src+=m_scu.src_add[dma_ch]; |
| 568 | | |
| 569 | | indirect_dst+= (WORK_RAM_H(indirect_dst)) ? 2 : m_scu.dst_add[dma_ch]; |
| 570 | | } |
| 571 | | } |
| 572 | | |
| 573 | | /* Guess: Size + data acquire (1 cycle for src/dst/size) */ |
| 574 | | total_size += indirect_size + 3*4; |
| 575 | | |
| 576 | | //if(DRUP(0)) space.write_dword(tmp_src+8,m_scu.src[0]|job_done ? 0x80000000 : 0); |
| 577 | | //if(DWUP(0)) space.write_dword(tmp_src+4,m_scu.dst[0]); |
| 578 | | |
| 579 | | m_scu.index[dma_ch] = tmp_src+0xc; |
| 580 | | |
| 581 | | }while(job_done == 0); |
| 582 | | |
| 583 | | { |
| 584 | | /*TODO: change DMA into DRQ model. Timing is a guess. */ |
| 585 | | switch(dma_ch) |
| 586 | | { |
| 587 | | case 0: machine().scheduler().timer_set(m_maincpu->cycles_to_attotime(total_size/4), timer_expired_delegate(FUNC(saturn_state::dma_lv0_ended),this)); break; |
| 588 | | case 1: machine().scheduler().timer_set(m_maincpu->cycles_to_attotime(total_size/4), timer_expired_delegate(FUNC(saturn_state::dma_lv1_ended),this)); break; |
| 589 | | case 2: machine().scheduler().timer_set(m_maincpu->cycles_to_attotime(total_size/4), timer_expired_delegate(FUNC(saturn_state::dma_lv2_ended),this)); break; |
| 590 | | } |
| 591 | | } |
| 592 | | } |
| 593 | | |
| 594 | | |
| 595 | | /**************************************************************************************/ |
| 596 | | |
| 597 | | WRITE16_MEMBER(saturn_state::saturn_soundram_w) |
| 598 | | { |
| 599 | | //machine().scheduler().synchronize(); // force resync |
| 600 | | |
| 601 | | COMBINE_DATA(&m_sound_ram[offset]); |
| 602 | | } |
| 603 | | |
| 604 | | READ16_MEMBER(saturn_state::saturn_soundram_r) |
| 605 | | { |
| 606 | | //machine().scheduler().synchronize(); // force resync |
| 607 | | |
| 608 | | return m_sound_ram[offset]; |
| 609 | | } |
| 610 | | |
| 611 | | /* communication,SLAVE CPU acquires data from the MASTER CPU and triggers an irq. */ |
| 612 | | WRITE32_MEMBER(saturn_state::minit_w) |
| 613 | | { |
| 614 | | //logerror("cpu %s (PC=%08X) MINIT write = %08x\n", space.device().tag(), space.device().safe_pc(),data); |
| 615 | | machine().scheduler().boost_interleave(m_minit_boost_timeslice, attotime::from_usec(m_minit_boost)); |
| 616 | | machine().scheduler().trigger(1000); |
| 617 | | machine().scheduler().synchronize(); // force resync |
| 618 | | sh2_set_frt_input(m_slave, PULSE_LINE); |
| 619 | | } |
| 620 | | |
| 621 | | WRITE32_MEMBER(saturn_state::sinit_w) |
| 622 | | { |
| 623 | | //logerror("cpu %s (PC=%08X) SINIT write = %08x\n", space.device().tag(), space.device().safe_pc(),data); |
| 624 | | machine().scheduler().boost_interleave(m_sinit_boost_timeslice, attotime::from_usec(m_sinit_boost)); |
| 625 | | machine().scheduler().synchronize(); // force resync |
| 626 | | sh2_set_frt_input(m_maincpu, PULSE_LINE); |
| 627 | | } |
| 628 | | |
| 629 | | /* |
| 630 | | TODO: |
| 631 | | Some games seems to not like either MAME's interleave system and/or SH-2 DRC, causing an hard crash. |
| 632 | | Reported games are: |
| 633 | | Blast Wind (before FMV) |
| 634 | | Choro Q Park (car selection) |
| 635 | | 060311E4: MOV.L R14,@-SP ;R14 = 0x60ffba0 / R15 = 0x60ffba0 |
| 636 | | 060311E6: MOV SP,R14 ;R14 = 0x60ffba0 / R15 = 0x60ffb9c / [0x60ffb9c] <- 0x60ffba0 |
| 637 | | 060311E8: MOV.L @SP+,R14 ;R14 = 0x60ffb9c / R15 = 0x60ffb9c / [0x60ffb9c] -> R14 |
| 638 | | 060311EA: RTS ;R14 = 0x60ffba0 / R15 = 0x60ffba0 |
| 639 | | 060311EC: NOP |
| 640 | | 06031734: MULS.W R9, R8 ;R14 = 0x60ffba0 / R15 = 0x60ffba0 / EA = 0x60311E4 |
| 641 | | on DRC this becomes: |
| 642 | | R14 0x6031b78 (cause of the crash later on), R15 = 0x60ffba4 and EA = 0 |
| 643 | | |
| 644 | | Shinrei Jusatsushi Taromaru (options menu) |
| 645 | | |
| 646 | | */ |
| 647 | | |
| 648 | | WRITE32_MEMBER(saturn_state::saturn_minit_w) |
| 649 | | { |
| 650 | | //logerror("cpu %s (PC=%08X) MINIT write = %08x\n", space.device().tag(), space.device().safe_pc(),data); |
| 651 | | if(m_fake_comms->read() & 1) |
| 652 | | machine().scheduler().synchronize(); // force resync |
| 653 | | else |
| 654 | | { |
| 655 | | machine().scheduler().boost_interleave(m_minit_boost_timeslice, attotime::from_usec(m_minit_boost)); |
| 656 | | machine().scheduler().trigger(1000); |
| 657 | | } |
| 658 | | |
| 659 | | sh2_set_frt_input(m_slave, PULSE_LINE); |
| 660 | | } |
| 661 | | |
| 662 | | WRITE32_MEMBER(saturn_state::saturn_sinit_w) |
| 663 | | { |
| 664 | | //logerror("cpu %s (PC=%08X) SINIT write = %08x\n", space.device().tag(), space.device().safe_pc(),data); |
| 665 | | if(m_fake_comms->read() & 1) |
| 666 | | machine().scheduler().synchronize(); // force resync |
| 667 | | else |
| 668 | | machine().scheduler().boost_interleave(m_sinit_boost_timeslice, attotime::from_usec(m_sinit_boost)); |
| 669 | | |
| 670 | | sh2_set_frt_input(m_maincpu, PULSE_LINE); |
| 671 | | } |
| 672 | | |
| 673 | | |
| 674 | | READ8_MEMBER(saturn_state::saturn_backupram_r) |
| 675 | | { |
| 676 | | if(!(offset & 1)) |
| 677 | | return 0; // yes, it makes sure the "holes" are there. |
| 678 | | |
| 679 | | return m_backupram[offset >> 1] & 0xff; |
| 680 | | } |
| 681 | | |
| 682 | | WRITE8_MEMBER(saturn_state::saturn_backupram_w) |
| 683 | | { |
| 684 | | if(!(offset & 1)) |
| 685 | | return; |
| 686 | | |
| 687 | | m_backupram[offset >> 1] = data; |
| 688 | | } |
| 689 | | |
| 690 | | /* TODO: if you change the driver configuration then NVRAM contents gets screwed, needs mods in MAME framework */ |
| 691 | | static NVRAM_HANDLER(saturn) |
| 692 | | { |
| 693 | | saturn_state *state = machine.driver_data<saturn_state>(); |
| 694 | | static const UINT32 BUP_SIZE = 32*1024; |
| 695 | | static const UINT32 EBUP_SIZE = 0;//0x100000; // TODO: can't support more than 8 Mbit |
| 696 | | UINT8 backup_file[(BUP_SIZE)+EBUP_SIZE+4]; |
| 697 | | static const UINT8 init[16] = |
| 698 | | { |
| 699 | | 'B', 'a', 'c', 'k', 'U', 'p', 'R', 'a', 'm', ' ', 'F', 'o', 'r', 'm', 'a', 't' |
| 700 | | }; |
| 701 | | UINT32 i; |
| 702 | | |
| 703 | | if (read_or_write) |
| 704 | | { |
| 705 | | for(i=0;i<BUP_SIZE;i++) |
| 706 | | backup_file[i] = state->m_backupram[i]; |
| 707 | | #if 0 |
| 708 | | for(i=0;i<EBUP_SIZE;i++) |
| 709 | | backup_file[i+BUP_SIZE] = state->m_cart_backupram[i]; |
| 710 | | #endif |
| 711 | | for(i=0;i<4;i++) |
| 712 | | backup_file[i+(BUP_SIZE)+EBUP_SIZE] = state->m_smpc.SMEM[i]; |
| 713 | | |
| 714 | | file->write(backup_file, (BUP_SIZE)+EBUP_SIZE+4); |
| 715 | | } |
| 716 | | else |
| 717 | | { |
| 718 | | if (file) |
| 719 | | { |
| 720 | | file->read(backup_file, (BUP_SIZE)+EBUP_SIZE+4); |
| 721 | | |
| 722 | | for(i=0;i<BUP_SIZE;i++) |
| 723 | | state->m_backupram[i] = backup_file[i]; |
| 724 | | #if 0 |
| 725 | | for(i=0;i<EBUP_SIZE;i++) |
| 726 | | state->m_cart_backupram[i] = backup_file[i+BUP_SIZE]; |
| 727 | | #endif |
| 728 | | for(i=0;i<4;i++) |
| 729 | | state->m_smpc.SMEM[i] = backup_file[i+BUP_SIZE+EBUP_SIZE]; |
| 730 | | } |
| 731 | | else |
| 732 | | { |
| 733 | | UINT8 j; |
| 734 | | memset(state->m_backupram, 0, BUP_SIZE); |
| 735 | | for (i = 0; i < 4; i++) |
| 736 | | { |
| 737 | | for(j=0;j<16;j++) |
| 738 | | state->m_backupram[i*16+j] = init[j]; |
| 739 | | } |
| 740 | | #if 0 |
| 741 | | memset(state->m_cart_backupram, 0, EBUP_SIZE); |
| 742 | | for (i = 0; i < 32; i++) |
| 743 | | { |
| 744 | | for(j=0;j<16;j++) |
| 745 | | state->m_cart_backupram[i*16+j] = init[j]; |
| 746 | | } |
| 747 | | #endif |
| 748 | | memset(state->m_smpc.SMEM, 0, 4); // TODO: default for each region |
| 749 | | } |
| 750 | | } |
| 751 | | } |
| 752 | | |
| 753 | | READ8_MEMBER(saturn_state::saturn_cart_type_r) |
| 754 | | { |
| 755 | | const int cart_ram_header[7] = { 0xff, 0x21, 0x22, 0x23, 0x24, 0x5a, 0x5c }; |
| 756 | | |
| 757 | | return cart_ram_header[m_cart_type]; |
| 758 | | } |
| 759 | | |
| 760 | | /* TODO: Bug! accesses this one, if returning 0 the SH-2 hard-crashes. Might be an actual bug with the CD block. */ |
| 761 | | READ32_HANDLER( saturn_state::abus_dummy_r ) |
| 762 | | { |
| 763 | | logerror("A-Bus Dummy access %08x\n",offset*4); |
| 764 | | return -1; |
| 765 | | } |
| 766 | | |
| 767 | | static ADDRESS_MAP_START( saturn_mem, AS_PROGRAM, 32, saturn_state ) |
| 768 | | AM_RANGE(0x00000000, 0x0007ffff) AM_ROM AM_SHARE("share6") // bios |
| 769 | | AM_RANGE(0x00100000, 0x0010007f) AM_READWRITE8(saturn_SMPC_r, saturn_SMPC_w,0xffffffff) |
| 770 | | AM_RANGE(0x00180000, 0x0018ffff) AM_READWRITE8(saturn_backupram_r, saturn_backupram_w,0xffffffff) AM_SHARE("share1") |
| 771 | | AM_RANGE(0x00200000, 0x002fffff) AM_RAM AM_MIRROR(0x20100000) AM_SHARE("workram_l") |
| 772 | | AM_RANGE(0x01000000, 0x017fffff) AM_WRITE(saturn_minit_w) |
| 773 | | AM_RANGE(0x01800000, 0x01ffffff) AM_WRITE(saturn_sinit_w) |
| 774 | | AM_RANGE(0x02000000, 0x023fffff) AM_ROM AM_SHARE("share7") AM_REGION("maincpu", 0x80000) // cartridge space |
| 775 | | // AM_RANGE(0x02400000, 0x027fffff) AM_RAM //cart RAM area, dynamically allocated |
| 776 | | // AM_RANGE(0x04000000, 0x047fffff) AM_RAM //backup RAM area, dynamically allocated |
| 777 | | AM_RANGE(0x04fffffc, 0x04ffffff) AM_READ8(saturn_cart_type_r,0x000000ff) |
| 778 | | AM_RANGE(0x05000000, 0x057fffff) AM_READ(abus_dummy_r) |
| 779 | | AM_RANGE(0x05800000, 0x0589ffff) AM_READWRITE(stvcd_r, stvcd_w) |
| 780 | | /* Sound */ |
| 781 | | AM_RANGE(0x05a00000, 0x05a7ffff) AM_READWRITE16(saturn_soundram_r, saturn_soundram_w,0xffffffff) |
| 782 | | AM_RANGE(0x05b00000, 0x05b00fff) AM_DEVREADWRITE16_LEGACY("scsp", scsp_r, scsp_w, 0xffffffff) |
| 783 | | /* VDP1 */ |
| 784 | | AM_RANGE(0x05c00000, 0x05c7ffff) AM_READWRITE(saturn_vdp1_vram_r, saturn_vdp1_vram_w) |
| 785 | | AM_RANGE(0x05c80000, 0x05cbffff) AM_READWRITE(saturn_vdp1_framebuffer0_r, saturn_vdp1_framebuffer0_w) |
| 786 | | AM_RANGE(0x05d00000, 0x05d0001f) AM_READWRITE16(saturn_vdp1_regs_r, saturn_vdp1_regs_w,0xffffffff) |
| 787 | | AM_RANGE(0x05e00000, 0x05e7ffff) AM_MIRROR(0x80000) AM_READWRITE(saturn_vdp2_vram_r, saturn_vdp2_vram_w) |
| 788 | | AM_RANGE(0x05f00000, 0x05f7ffff) AM_READWRITE(saturn_vdp2_cram_r, saturn_vdp2_cram_w) |
| 789 | | AM_RANGE(0x05f80000, 0x05fbffff) AM_READWRITE16(saturn_vdp2_regs_r, saturn_vdp2_regs_w,0xffffffff) |
| 790 | | AM_RANGE(0x05fe0000, 0x05fe00cf) AM_READWRITE(saturn_scu_r, saturn_scu_w) |
| 791 | | AM_RANGE(0x06000000, 0x060fffff) AM_RAM AM_MIRROR(0x21f00000) AM_SHARE("workram_h") |
| 792 | | AM_RANGE(0x20000000, 0x2007ffff) AM_ROM AM_SHARE("share6") // bios mirror |
| 793 | | AM_RANGE(0x22000000, 0x24ffffff) AM_ROM AM_SHARE("share7") // cart mirror |
| 794 | | AM_RANGE(0x45000000, 0x46ffffff) AM_WRITENOP |
| 795 | | AM_RANGE(0x60000000, 0x600003ff) AM_WRITENOP // cache address array |
| 796 | | AM_RANGE(0xc0000000, 0xc00007ff) AM_RAM // cache data array, Dragon Ball Z sprites relies on this |
| 797 | | ADDRESS_MAP_END |
| 798 | | |
| 799 | | static ADDRESS_MAP_START( sound_mem, AS_PROGRAM, 16, saturn_state ) |
| 800 | | AM_RANGE(0x000000, 0x0fffff) AM_RAM AM_SHARE("sound_ram") |
| 801 | | AM_RANGE(0x100000, 0x100fff) AM_DEVREADWRITE_LEGACY("scsp", scsp_r, scsp_w) |
| 802 | | ADDRESS_MAP_END |
| 803 | | |
| 804 | | |
| 805 | | /* keyboard code */ |
| 806 | | /* TODO: needs a proper keycode table */ |
| 807 | | INPUT_CHANGED_MEMBER(saturn_state::key_stroke) |
| 808 | | { |
| 809 | | if(newval && !oldval) |
| 810 | | { |
| 811 | | m_keyb.data = ((UINT8)(FPTR)(param) & 0xff); |
| 812 | | m_keyb.status |= 8; |
| 813 | | } |
| 814 | | |
| 815 | | if(oldval && !newval) |
| 816 | | { |
| 817 | | //m_keyb.status &= ~8; |
| 818 | | m_keyb.data = 0; |
| 819 | | } |
| 820 | | } |
| 821 | | |
| 822 | | /* Note: unused bits must stay high, Bug 2 relies on this. */ |
| 823 | | #define SATURN_PAD_P1(_mask_, _val_) \ |
| 824 | | PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 825 | | PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 826 | | PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 827 | | PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 828 | | PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 829 | | PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P1 A") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 830 | | PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("P1 C") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 831 | | PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("P1 B") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 832 | | PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("P1 R") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 833 | | PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("P1 X") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 834 | | PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("P1 Y") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 835 | | PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("P1 Z") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 836 | | PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("P1 L") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 837 | | PORT_BIT( 0x0007, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) |
| 838 | | |
| 839 | | #define SATURN_PAD_P2(_mask_, _val_) \ |
| 840 | | PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 841 | | PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 842 | | PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 843 | | PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 844 | | PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 845 | | PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P2 A") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 846 | | PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("P2 C") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 847 | | PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("P2 B") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 848 | | PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("P2 R") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 849 | | PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("P2 X") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 850 | | PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("P2 Y") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 851 | | PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("P2 Z") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 852 | | PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("P2 L") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 853 | | PORT_BIT( 0x0007, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) |
| 854 | | |
| 855 | | #define MD_PAD_P1(_mask_, _val_) \ |
| 856 | | PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 857 | | PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 858 | | PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 859 | | PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 860 | | PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 861 | | PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P1 A") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 862 | | PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("P1 C") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 863 | | PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("P1 B") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 864 | | PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("P1 Mode") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 865 | | PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("P1 X") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 866 | | PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("P1 Y") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 867 | | PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("P1 Z") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 868 | | PORT_BIT( 0x000f, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) //read '1' when direct mode is polled |
| 869 | | |
| 870 | | #define MD_PAD_P2(_mask_, _val_) \ |
| 871 | | PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 872 | | PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 873 | | PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 874 | | PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 875 | | PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 876 | | PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P2 A") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 877 | | PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("P2 C") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 878 | | PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("P2 B") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 879 | | PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("P2 Mode") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 880 | | PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("P2 X") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 881 | | PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("P2 Y") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 882 | | PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("P2 Z") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) \ |
| 883 | | PORT_BIT( 0x000f, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("INPUT_TYPE", _mask_, EQUALS, _val_) //read '1' when direct mode is polled |
| 884 | | |
| 885 | | #define SATURN_KEYBOARD PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x05) |
| 886 | | |
| 887 | | INPUT_CHANGED_MEMBER(saturn_state::nmi_reset) |
| 888 | | { |
| 889 | | /* TODO: correct? */ |
| 890 | | if(!m_NMI_reset) |
| 891 | | return; |
| 892 | | |
| 893 | | /* TODO: NMI doesn't stay held on SH-2 core so we can't use ASSERT_LINE/CLEAR_LINE with that yet */ |
| 894 | | if(newval) |
| 895 | | m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE); |
| 896 | | } |
| 897 | | |
| 898 | | INPUT_CHANGED_MEMBER(saturn_state::tray_open) |
| 899 | | { |
| 900 | | if(newval) |
| 901 | | stvcd_set_tray_open(); |
| 902 | | } |
| 903 | | |
| 904 | | INPUT_CHANGED_MEMBER(saturn_state::tray_close) |
| 905 | | { |
| 906 | | if(newval) |
| 907 | | stvcd_set_tray_close(); |
| 908 | | } |
| 909 | | |
| 910 | | static INPUT_PORTS_START( saturn ) |
| 911 | | PORT_START("RESET") /* hardwired buttons */ |
| 912 | | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, nmi_reset,0) PORT_NAME("Reset Button") |
| 913 | | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, tray_open,0) PORT_NAME("Tray Open Button") |
| 914 | | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, tray_close,0) PORT_NAME("Tray Close") |
| 915 | | |
| 916 | | PORT_START("JOY1") |
| 917 | | SATURN_PAD_P1(0x0f, 0) |
| 918 | | |
| 919 | | PORT_START("JOY2") |
| 920 | | SATURN_PAD_P2(0xf0, 0) |
| 921 | | |
| 922 | | /* TODO: there's no info about the keycode used on Saturn keyboard, following is trial & error with Game Basic software */ |
| 923 | | PORT_START("KEY0") // 0x00 - 0x07 |
| 924 | | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_UNUSED) SATURN_KEYBOARD |
| 925 | | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F1") /*PORT_CODE(KEYCODE_F1)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x01) PORT_PLAYER(1) SATURN_KEYBOARD |
| 926 | | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("0-3") /*PORT_CODE(KEYCODE_2) PORT_CHAR('2')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x02) PORT_PLAYER(1) SATURN_KEYBOARD |
| 927 | | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F2") /*PORT_CODE(KEYCODE_F2)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x03) PORT_PLAYER(1) SATURN_KEYBOARD // RUN |
| 928 | | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F3") /*PORT_CODE(KEYCODE_F3)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x04) PORT_PLAYER(1) SATURN_KEYBOARD // LIST |
| 929 | | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F4") /*PORT_CODE(KEYCODE_F4)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x05) PORT_PLAYER(1) SATURN_KEYBOARD // EDIT |
| 930 | | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F5") /*PORT_CODE(KEYCODE_F5)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x06) PORT_PLAYER(1) SATURN_KEYBOARD |
| 931 | | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("CLR SCR") PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x07) PORT_PLAYER(1) SATURN_KEYBOARD |
| 932 | | |
| 933 | | PORT_START("KEY1") // 0x08 - 0x0f |
| 934 | | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("1-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x08) PORT_PLAYER(1) SATURN_KEYBOARD |
| 935 | | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F6") /*PORT_CODE(KEYCODE_F6)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x09) PORT_PLAYER(1) SATURN_KEYBOARD |
| 936 | | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F7") /*PORT_CODE(KEYCODE_F7)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x0a) PORT_PLAYER(1) SATURN_KEYBOARD |
| 937 | | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F8") /*PORT_CODE(KEYCODE_F8)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x0b) PORT_PLAYER(1) SATURN_KEYBOARD |
| 938 | | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F9") /*PORT_CODE(KEYCODE_F9)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x0c) PORT_PLAYER(1) SATURN_KEYBOARD // LIST again |
| 939 | | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("1-6") /*PORT_CODE(KEYCODE_5) PORT_CHAR('5')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x0d) PORT_PLAYER(1) SATURN_KEYBOARD |
| 940 | | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("1-7") /*PORT_CODE(KEYCODE_6) PORT_CHAR('6')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x0e) PORT_PLAYER(1) SATURN_KEYBOARD |
| 941 | | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("1-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x0f) PORT_PLAYER(1) SATURN_KEYBOARD |
| 942 | | |
| 943 | | PORT_START("KEY2") // 0x10 - 0x17 |
| 944 | | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("2-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x10) PORT_PLAYER(1) SATURN_KEYBOARD |
| 945 | | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("2-2") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x11) PORT_PLAYER(1) SATURN_KEYBOARD |
| 946 | | /* TODO: break codes! */ |
| 947 | | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("SHIFT") /*PORT_CODE(KEYCODE_2) PORT_CHAR('2')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x12) PORT_PLAYER(1) SATURN_KEYBOARD |
| 948 | | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("KANA SHIFT") /*PORT_CODE(KEYCODE_3) PORT_CHAR('3')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x13) PORT_PLAYER(1) SATURN_KEYBOARD |
| 949 | | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("(special keys)") /*PORT_CODE(KEYCODE_4) PORT_CHAR('4')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x14) PORT_PLAYER(1) SATURN_KEYBOARD |
| 950 | | |
| 951 | | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x15) PORT_PLAYER(1) SATURN_KEYBOARD |
| 952 | | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x16) PORT_PLAYER(1) SATURN_KEYBOARD |
| 953 | | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("2-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x17) PORT_PLAYER(1) SATURN_KEYBOARD |
| 954 | | |
| 955 | | PORT_START("KEY3") // 0x18 - 0x1f |
| 956 | | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("3-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x18) PORT_PLAYER(1) SATURN_KEYBOARD |
| 957 | | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("3-2") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x19) PORT_PLAYER(1) SATURN_KEYBOARD |
| 958 | | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x1a) PORT_PLAYER(1) SATURN_KEYBOARD |
| 959 | | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x1b) PORT_PLAYER(1) SATURN_KEYBOARD |
| 960 | | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x1c) PORT_PLAYER(1) SATURN_KEYBOARD |
| 961 | | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x1d) PORT_PLAYER(1) SATURN_KEYBOARD |
| 962 | | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x1e) PORT_PLAYER(1) SATURN_KEYBOARD |
| 963 | | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("3-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x1f) PORT_PLAYER(1) SATURN_KEYBOARD |
| 964 | | |
| 965 | | PORT_START("KEY4") // 0x20 - 0x27 |
| 966 | | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("4-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x20) PORT_PLAYER(1) SATURN_KEYBOARD |
| 967 | | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x21) PORT_PLAYER(1) SATURN_KEYBOARD |
| 968 | | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x22) PORT_PLAYER(1) SATURN_KEYBOARD |
| 969 | | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x23) PORT_PLAYER(1) SATURN_KEYBOARD |
| 970 | | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x24) PORT_PLAYER(1) SATURN_KEYBOARD |
| 971 | | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x25) PORT_PLAYER(1) SATURN_KEYBOARD |
| 972 | | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x26) PORT_PLAYER(1) SATURN_KEYBOARD |
| 973 | | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("4-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x27) PORT_PLAYER(1) SATURN_KEYBOARD |
| 974 | | |
| 975 | | PORT_START("KEY5") // 0x28 - 0x2f |
| 976 | | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("5-1") /*PORT_CODE(KEYCODE_F) PORT_CHAR('F')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x28) PORT_PLAYER(1) SATURN_KEYBOARD // another F? |
| 977 | | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x29) PORT_PLAYER(1) SATURN_KEYBOARD |
| 978 | | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x2a) PORT_PLAYER(1) SATURN_KEYBOARD |
| 979 | | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x2b) PORT_PLAYER(1) SATURN_KEYBOARD |
| 980 | | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x2c) PORT_PLAYER(1) SATURN_KEYBOARD |
| 981 | | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x2d) PORT_PLAYER(1) SATURN_KEYBOARD |
| 982 | | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x2e) PORT_PLAYER(1) SATURN_KEYBOARD |
| 983 | | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("5-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x2f) PORT_PLAYER(1) SATURN_KEYBOARD |
| 984 | | |
| 985 | | PORT_START("KEY6") // 0x30 - 0x37 |
| 986 | | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("6-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x30) PORT_PLAYER(1) SATURN_KEYBOARD |
| 987 | | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x31) PORT_PLAYER(1) SATURN_KEYBOARD |
| 988 | | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x32) PORT_PLAYER(1) SATURN_KEYBOARD |
| 989 | | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x33) PORT_PLAYER(1) SATURN_KEYBOARD |
| 990 | | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x34) PORT_PLAYER(1) SATURN_KEYBOARD |
| 991 | | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x35) PORT_PLAYER(1) SATURN_KEYBOARD |
| 992 | | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x36) PORT_PLAYER(1) SATURN_KEYBOARD |
| 993 | | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("6-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x37) PORT_PLAYER(1) SATURN_KEYBOARD |
| 994 | | |
| 995 | | PORT_START("KEY7") // 0x38 - 0x3f |
| 996 | | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("7-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x38) PORT_PLAYER(1) SATURN_KEYBOARD |
| 997 | | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("7-2") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x39) PORT_PLAYER(1) SATURN_KEYBOARD |
| 998 | | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x3a) PORT_PLAYER(1) SATURN_KEYBOARD |
| 999 | | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x3b) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1000 | | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x3c) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1001 | | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x3d) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1002 | | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x3e) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1003 | | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("7-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x3f) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1004 | | |
| 1005 | | PORT_START("KEY8") // 0x40 - 0x47 |
| 1006 | | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("8-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x40) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1007 | | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(",") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x41) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1008 | | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x42) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1009 | | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x43) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1010 | | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x44) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1011 | | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x45) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1012 | | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x46) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1013 | | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("8-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x47) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1014 | | |
| 1015 | | PORT_START("KEY9") // 0x48 - 0x4f |
| 1016 | | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("9-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x48) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1017 | | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(".") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x49) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1018 | | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("/") /*PORT_CODE(KEYCODE_2) PORT_CHAR('2')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x4a) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1019 | | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x4b) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1020 | | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(";") /*PORT_CODE(KEYCODE_4) PORT_CHAR('4')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x4c) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1021 | | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x4d) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1022 | | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("- / =") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x4e) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1023 | | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("9-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x4f) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1024 | | |
| 1025 | | PORT_START("KEYA") // 0x50 - 0x57 |
| 1026 | | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("A-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x50) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1027 | | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("\xC2\xA5") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x51) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1028 | | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(":") /*PORT_CODE(KEYCODE_2) PORT_CHAR('2')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x52) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1029 | | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("A-4") /*PORT_CODE(KEYCODE_3) PORT_CHAR('3')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x53) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1030 | | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("@") /*PORT_CODE(KEYCODE_4) PORT_CHAR('4')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x54) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1031 | | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("^") /*PORT_CODE(KEYCODE_5) PORT_CHAR(0xd)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x55) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1032 | | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("A-7") /*PORT_CODE(KEYCODE_6) PORT_CHAR('6')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x56) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1033 | | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("A-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x57) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1034 | | |
| 1035 | | PORT_START("KEYB") // 0x58 - 0x5f |
| 1036 | | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("B-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x58) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1037 | | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("B-2") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x59) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1038 | | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("ENTER") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(0x0d) PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x5a) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1039 | | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("[") /*PORT_CODE(KEYCODE_3) PORT_CHAR('3')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x5b) PORT_PLAYER(1) SATURN_KEYBOARD // { |
| 1040 | | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("B-5") /*PORT_CODE(KEYCODE_4) PORT_CHAR('4')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x5c) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1041 | | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("]") /*PORT_CODE(KEYCODE_5) PORT_CHAR(0xd)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x5d) PORT_PLAYER(1) SATURN_KEYBOARD // } |
| 1042 | | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("B-7") /*PORT_CODE(KEYCODE_6) PORT_CHAR('6')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x5e) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1043 | | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("B-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x5f) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1044 | | |
| 1045 | | PORT_START("KEYC") // 0x60 - 0x67 |
| 1046 | | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x60) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1047 | | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C-2") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x61) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1048 | | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C-3") /*PORT_CODE(KEYCODE_2) PORT_CHAR('2')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x62) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1049 | | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C-4") /*PORT_CODE(KEYCODE_3) PORT_CHAR('3')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x63) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1050 | | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C-5") /*PORT_CODE(KEYCODE_4) PORT_CHAR('4')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x64) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1051 | | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C-6") /*PORT_CODE(KEYCODE_5) PORT_CHAR(0xd)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x65) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1052 | | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("BACKSPACE") PORT_CODE(KEYCODE_BACKSPACE) /* PORT_CHAR('6')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x66) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1053 | | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x67) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1054 | | |
| 1055 | | PORT_START("KEYD") // 0x68 - 0x6f |
| 1056 | | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x68) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1057 | | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D-2") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x69) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1058 | | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D-3") /*PORT_CODE(KEYCODE_2) PORT_CHAR('2')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x6a) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1059 | | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D-4") /*PORT_CODE(KEYCODE_3) PORT_CHAR('3')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x6b) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1060 | | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D-5") /*PORT_CODE(KEYCODE_4) PORT_CHAR('4')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x6c) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1061 | | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D-6") /*PORT_CODE(KEYCODE_5) PORT_CHAR(0xd)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x6d) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1062 | | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D-7") /*PORT_CODE(KEYCODE_6) PORT_CHAR('6')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x6e) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1063 | | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x6f) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1064 | | |
| 1065 | | PORT_START("KEYE") // 0x70 - 0x77 |
| 1066 | | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x70) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1067 | | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E-2") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x71) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1068 | | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E-3") /*PORT_CODE(KEYCODE_2) PORT_CHAR('2')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x72) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1069 | | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E-4") /*PORT_CODE(KEYCODE_3) PORT_CHAR('3')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x73) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1070 | | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E-5") /*PORT_CODE(KEYCODE_4) PORT_CHAR('4')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x74) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1071 | | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E-6") /*PORT_CODE(KEYCODE_5) PORT_CHAR(0xd)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x75) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1072 | | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E-7") /*PORT_CODE(KEYCODE_6) PORT_CHAR('6')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x76) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1073 | | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x77) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1074 | | |
| 1075 | | PORT_START("KEYF") // 0x78 - 0x7f |
| 1076 | | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x78) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1077 | | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F-2") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x79) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1078 | | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F-3") /*PORT_CODE(KEYCODE_2) PORT_CHAR('2')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x7a) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1079 | | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F-4") /*PORT_CODE(KEYCODE_3) PORT_CHAR('3')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x7b) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1080 | | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F-5") /*PORT_CODE(KEYCODE_4) PORT_CHAR('4')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x7c) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1081 | | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F-6") /*PORT_CODE(KEYCODE_5) PORT_CHAR(0xd)*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x7d) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1082 | | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F-7") /*PORT_CODE(KEYCODE_6) PORT_CHAR('6')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x7e) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1083 | | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("ESC") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x7f) PORT_PLAYER(1) SATURN_KEYBOARD //SYSTEM CONFIGURATION |
| 1084 | | |
| 1085 | | PORT_START("KEYS_1") // special keys |
| 1086 | | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("UP") PORT_CODE(KEYCODE_UP) /*PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x78) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1087 | | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("DOWN") PORT_CODE(KEYCODE_DOWN) /*PORT_CHAR('1')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x79) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1088 | | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("LEFT") PORT_CODE(KEYCODE_LEFT) /*PORT_CHAR('2')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x7a) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1089 | | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("RIGHT") PORT_CODE(KEYCODE_RIGHT) /*PORT_CHAR('3')*/ PORT_CHANGED_MEMBER(DEVICE_SELF, saturn_state, key_stroke, 0x7b) PORT_PLAYER(1) SATURN_KEYBOARD |
| 1090 | | |
| 1091 | | PORT_START("MOUSEB1") |
| 1092 | | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P1 Pointer Left Button") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x04) |
| 1093 | | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P1 Pointer Right Button") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x04) |
| 1094 | | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P1 Pointer Middle Button") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x04) |
| 1095 | | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("P1 Pointer Start Button") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x04) |
| 1096 | | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P1 Mouse Left Button") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x08) |
| 1097 | | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P1 Mouse Right Button") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x08) |
| 1098 | | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P1 Mouse Middle Button") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x08) |
| 1099 | | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("P1 Mouse Start Button") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x08) |
| 1100 | | |
| 1101 | | PORT_START("MOUSEX1") |
| 1102 | | PORT_BIT(0xffff, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0xffff) PORT_KEYDELTA(2) PORT_RESET PORT_NAME("P1 Pointer X") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x04) |
| 1103 | | PORT_BIT(0xffff, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0xffff) PORT_KEYDELTA(2) PORT_RESET PORT_NAME("P1 Mouse X") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x08) |
| 1104 | | |
| 1105 | | PORT_START("MOUSEY1") |
| 1106 | | PORT_BIT(0xffff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0xffff) PORT_KEYDELTA(2) PORT_RESET PORT_REVERSE PORT_NAME("P1 Pointer Y") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x04) |
| 1107 | | PORT_BIT(0xffff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0xffff) PORT_KEYDELTA(2) PORT_RESET PORT_REVERSE PORT_NAME("P1 Mouse Y") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x08) |
| 1108 | | |
| 1109 | | PORT_START("MOUSEB2") |
| 1110 | | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P2 Pointer Left Button") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x40) |
| 1111 | | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P2 Pointer Right Button") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x40) |
| 1112 | | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P2 Pointer Middle Button") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x40) |
| 1113 | | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("P2 Pointer Start Button") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x40) |
| 1114 | | PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P2 Mouse Left Button") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x80) |
| 1115 | | PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P2 Mouse Right Button") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x80) |
| 1116 | | PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P2 Mouse Middle Button") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x80) |
| 1117 | | PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("P2 Mouse Start Button") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x80) |
| 1118 | | |
| 1119 | | PORT_START("MOUSEX2") |
| 1120 | | PORT_BIT(0xffff, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0xffff) PORT_KEYDELTA(2) PORT_RESET PORT_NAME("P2 Pointer X") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x40) |
| 1121 | | PORT_BIT(0xffff, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0xffff) PORT_KEYDELTA(2) PORT_RESET PORT_NAME("P2 Mouse X") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x80) |
| 1122 | | |
| 1123 | | PORT_START("MOUSEY2") |
| 1124 | | PORT_BIT(0xffff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0xffff) PORT_KEYDELTA(2) PORT_RESET PORT_REVERSE PORT_NAME("P2 Pointer Y") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x40) |
| 1125 | | PORT_BIT(0xffff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0xffff) PORT_KEYDELTA(2) PORT_RESET PORT_REVERSE PORT_NAME("P2 Mouse Y") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x80) |
| 1126 | | |
| 1127 | | PORT_START("AN_JOY1") |
| 1128 | | SATURN_PAD_P1(0x0f, 0x01) // racing device |
| 1129 | | SATURN_PAD_P1(0x0f, 0x02) // analog controller |
| 1130 | | |
| 1131 | | PORT_START("AN_JOY2") |
| 1132 | | SATURN_PAD_P2(0xf0, 0x10) // racing device |
| 1133 | | SATURN_PAD_P2(0xf0, 0x20) // analog controller |
| 1134 | | |
| 1135 | | PORT_START("AN_X1") |
| 1136 | | PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(1) PORT_NAME("P1 Racing Stick X") PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x01) |
| 1137 | | PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(1) PORT_NAME("P1 AD Stick X") PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x02) |
| 1138 | | |
| 1139 | | PORT_START("AN_Y1") |
| 1140 | | PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(1) PORT_NAME("P1 Racing Stick Y") PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x01) |
| 1141 | | PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(1) PORT_NAME("P1 AD Stick Y") PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x02) |
| 1142 | | |
| 1143 | | PORT_START("AN_Z1") |
| 1144 | | PORT_BIT( 0xff, 0x00, IPT_AD_STICK_Z ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(1) PORT_NAME("P1 Racing Stick Z") PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x01) |
| 1145 | | PORT_BIT( 0xff, 0x00, IPT_AD_STICK_Z ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(1) PORT_NAME("P1 AD Stick Z") PORT_CONDITION("INPUT_TYPE", 0x0f, EQUALS, 0x02) |
| 1146 | | |
| 1147 | | PORT_START("AN_X2") |
| 1148 | | PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(2) PORT_NAME("P2 Racing Stick X") PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x10) |
| 1149 | | PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(2) PORT_NAME("P2 AD Stick X") PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x20) |
| 1150 | | |
| 1151 | | PORT_START("AN_Y2") |
| 1152 | | PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(2) PORT_NAME("P2 Racing Stick Y") PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x10) |
| 1153 | | PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(2) PORT_NAME("P2 AD Stick Y") PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x20) |
| 1154 | | |
| 1155 | | PORT_START("AN_Z2") |
| 1156 | | PORT_BIT( 0xff, 0x00, IPT_AD_STICK_Z ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(2) PORT_NAME("P2 Racing Stick Z") PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x10) |
| 1157 | | PORT_BIT( 0xff, 0x00, IPT_AD_STICK_Z ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(2) PORT_NAME("P2 AD Stick Z") PORT_CONDITION("INPUT_TYPE", 0xf0, EQUALS, 0x20) |
| 1158 | | |
| 1159 | | PORT_START("MD_JOY1") |
| 1160 | | MD_PAD_P1(0x0f, 0x06) // MD 3 buttons pad |
| 1161 | | MD_PAD_P1(0x0f, 0x07) // MD 6 buttons pad |
| 1162 | | |
| 1163 | | PORT_START("MD_JOY2") |
| 1164 | | MD_PAD_P2(0xf0, 0x60) // MD 3 buttons pad |
| 1165 | | MD_PAD_P2(0xf0, 0x70) // MD 6 buttons pad |
| 1166 | | |
| 1167 | | PORT_START("CART_AREA") |
| 1168 | | PORT_CONFNAME( 0x07, 0x06, "Cart Type" ) |
| 1169 | | PORT_CONFSETTING( 0x00, "None" ) |
| 1170 | | // PORT_CONFSETTING( 0x01, "4 Mbit backup RAM" ) |
| 1171 | | // PORT_CONFSETTING( 0x02, "8 Mbit backup RAM" ) |
| 1172 | | // PORT_CONFSETTING( 0x03, "16 Mbit backup RAM" ) |
| 1173 | | // PORT_CONFSETTING( 0x04, "32 Mbit backup RAM" ) |
| 1174 | | PORT_CONFSETTING( 0x05, "8 Mbit Cart RAM" ) |
| 1175 | | PORT_CONFSETTING( 0x06, "32 Mbit Cart RAM" ) |
| 1176 | | |
| 1177 | | PORT_START("INPUT_TYPE") |
| 1178 | | PORT_CONFNAME(0x0f,0x00,"Controller Port 1") |
| 1179 | | PORT_CONFSETTING(0x00,"Digital Device (standard Saturn pad)") |
| 1180 | | PORT_CONFSETTING(0x01,"Racing Device") /* steering wheel only */ |
| 1181 | | PORT_CONFSETTING(0x02,"Analog Device") //Nights pad? |
| 1182 | | // PORT_CONFSETTING(0x03,"Lightgun Device") |
| 1183 | | PORT_CONFSETTING(0x04,"Trackball") // TODO: according to the docs this ID is labeled "Pointing Device" |
| 1184 | | PORT_CONFSETTING(0x05,"Keyboard Device") |
| 1185 | | PORT_CONFSETTING(0x06,"Megadrive 3B Pad") |
| 1186 | | PORT_CONFSETTING(0x07,"Megadrive 6B Pad") |
| 1187 | | PORT_CONFSETTING(0x08,"Saturn Mouse") |
| 1188 | | // PORT_CONFSETTING(0x09,"<unconnected>") |
| 1189 | | PORT_CONFNAME(0xf0,0x00,"Controller Port 2") |
| 1190 | | PORT_CONFSETTING(0x00,"Digital Device (standard Saturn pad)") |
| 1191 | | PORT_CONFSETTING(0x10,"Racing Device") |
| 1192 | | PORT_CONFSETTING(0x20,"Analog Device") //Nights pad? |
| 1193 | | // PORT_CONFSETTING(0x30,"Lightgun Device") |
| 1194 | | PORT_CONFSETTING(0x40,"Pointing Device") |
| 1195 | | // PORT_CONFSETTING(0x50,"Keyboard Device") |
| 1196 | | PORT_CONFSETTING(0x60,"Megadrive 3B Pad") |
| 1197 | | PORT_CONFSETTING(0x70,"Megadrive 6B Pad") |
| 1198 | | PORT_CONFSETTING(0x80,"Saturn Mouse") |
| 1199 | | PORT_CONFSETTING(0x90,"<unconnected>") |
| 1200 | | |
| 1201 | | PORT_START("fake") |
| 1202 | | PORT_CONFNAME(0x01,0x00,"Master-Slave Comms") |
| 1203 | | PORT_CONFSETTING(0x00,"Normal (400 cycles)") |
| 1204 | | PORT_CONFSETTING(0x01,"One Shot (Hack)") |
| 1205 | | INPUT_PORTS_END |
| 1206 | | |
| 1207 | | static const gfx_layout tiles8x8x4_layout = |
| 1208 | | { |
| 1209 | | 8,8, |
| 1210 | | 0x100000/(32*8/8), |
| 1211 | | 4, |
| 1212 | | { 0, 1, 2, 3 }, |
| 1213 | | { 0, 4, 8, 12, 16, 20, 24, 28 }, |
| 1214 | | { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 }, |
| 1215 | | 32*8 |
| 1216 | | }; |
| 1217 | | |
| 1218 | | static const gfx_layout tiles16x16x4_layout = |
| 1219 | | { |
| 1220 | | 16,16, |
| 1221 | | 0x100000/(32*32/8), |
| 1222 | | 4, |
| 1223 | | { 0, 1, 2, 3 }, |
| 1224 | | { 0, 4, 8, 12, 16, 20, 24, 28, |
| 1225 | | 32*8+0, 32*8+4, 32*8+8, 32*8+12, 32*8+16, 32*8+20, 32*8+24, 32*8+28, |
| 1226 | | |
| 1227 | | }, |
| 1228 | | { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32, |
| 1229 | | 32*16, 32*17,32*18, 32*19,32*20,32*21,32*22,32*23 |
| 1230 | | |
| 1231 | | }, |
| 1232 | | 32*32 |
| 1233 | | }; |
| 1234 | | |
| 1235 | | static const gfx_layout tiles8x8x8_layout = |
| 1236 | | { |
| 1237 | | 8,8, |
| 1238 | | 0x100000/(32*8/8), |
| 1239 | | 8, |
| 1240 | | { 0, 1, 2, 3, 4, 5, 6, 7 }, |
| 1241 | | { 0, 8, 16, 24, 32, 40, 48, 56 }, |
| 1242 | | { 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64 }, |
| 1243 | | 32*8 /* really 64*8, but granularity is 32 bytes */ |
| 1244 | | }; |
| 1245 | | |
| 1246 | | static const gfx_layout tiles16x16x8_layout = |
| 1247 | | { |
| 1248 | | 16,16, |
| 1249 | | 0x100000/(64*16/8), |
| 1250 | | 8, |
| 1251 | | { 0, 1, 2, 3, 4, 5, 6, 7 }, |
| 1252 | | { 0, 8, 16, 24, 32, 40, 48, 56, |
| 1253 | | 64*8+0, 65*8, 66*8, 67*8, 68*8, 69*8, 70*8, 71*8 |
| 1254 | | |
| 1255 | | }, |
| 1256 | | { 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64, |
| 1257 | | 64*16, 64*17, 64*18, 64*19, 64*20, 64*21, 64*22, 64*23 |
| 1258 | | }, |
| 1259 | | 64*16 /* really 128*16, but granularity is 32 bytes */ |
| 1260 | | }; |
| 1261 | | |
| 1262 | | |
| 1263 | | |
| 1264 | | |
| 1265 | | GFXDECODE_START( stv ) |
| 1266 | | GFXDECODE_ENTRY( NULL, 0, tiles8x8x4_layout, 0x00, (0x80*(2+1)) ) |
| 1267 | | GFXDECODE_ENTRY( NULL, 0, tiles16x16x4_layout, 0x00, (0x80*(2+1)) ) |
| 1268 | | GFXDECODE_ENTRY( NULL, 0, tiles8x8x8_layout, 0x00, (0x08*(2+1)) ) |
| 1269 | | GFXDECODE_ENTRY( NULL, 0, tiles16x16x8_layout, 0x00, (0x08*(2+1)) ) |
| 1270 | | GFXDECODE_END |
| 1271 | | |
| 1272 | | static const sh2_cpu_core sh2_conf_master = { 0, NULL }; |
| 1273 | | static const sh2_cpu_core sh2_conf_slave = { 1, NULL }; |
| 1274 | | |
| 1275 | | void scsp_irq(device_t *device, int irq) |
| 1276 | | { |
| 1277 | | saturn_state *state = device->machine().driver_data<saturn_state>(); |
| 1278 | | |
| 1279 | | // don't bother the 68k if it's off |
| 1280 | | if (!state->m_en_68k) |
| 1281 | | { |
| 1282 | | return; |
| 1283 | | } |
| 1284 | | |
| 1285 | | if (irq > 0) |
| 1286 | | { |
| 1287 | | state->m_scsp_last_line = irq; |
| 1288 | | device->machine().device("audiocpu")->execute().set_input_line(irq, ASSERT_LINE); |
| 1289 | | } |
| 1290 | | else if (irq < 0) |
| 1291 | | { |
| 1292 | | device->machine().device("audiocpu")->execute().set_input_line(-irq, CLEAR_LINE); |
| 1293 | | } |
| 1294 | | else |
| 1295 | | { |
| 1296 | | device->machine().device("audiocpu")->execute().set_input_line(state->m_scsp_last_line, CLEAR_LINE); |
| 1297 | | } |
| 1298 | | } |
| 1299 | | |
| 1300 | | WRITE_LINE_MEMBER(saturn_state::scsp_to_main_irq) |
| 1301 | | { |
| 1302 | | if(state) |
| 1303 | | { |
| 1304 | | if(!(m_scu.ism & IRQ_SOUND_REQ)) |
| 1305 | | { |
| 1306 | | m_maincpu->set_input_line_and_vector(9, HOLD_LINE, 0x46); |
| 1307 | | scu_do_transfer(5); |
| 1308 | | } |
| 1309 | | else |
| 1310 | | m_scu.ist |= (IRQ_SOUND_REQ); |
| 1311 | | } |
| 1312 | | } |
| 1313 | | |
| 1314 | | static const scsp_interface scsp_config = |
| 1315 | | { |
| 1316 | | 0, |
| 1317 | | scsp_irq, |
| 1318 | | DEVCB_DRIVER_LINE_MEMBER(saturn_state, scsp_to_main_irq) |
| 1319 | | }; |
| 1320 | | |
| 1321 | | TIMER_CALLBACK_MEMBER(saturn_state::stv_rtc_increment) |
| 1322 | | { |
| 1323 | | static const UINT8 dpm[12] = { 0x31, 0x28, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, 0x30, 0x31, 0x30, 0x31 }; |
| 1324 | | static int year_num, year_count; |
| 1325 | | |
| 1326 | | /* |
| 1327 | | m_smpc.rtc_data[0] = DectoBCD(systime.local_time.year /100); |
| 1328 | | m_smpc.rtc_data[1] = DectoBCD(systime.local_time.year %100); |
| 1329 | | m_smpc.rtc_data[2] = (systime.local_time.weekday << 4) | (systime.local_time.month+1); |
| 1330 | | m_smpc.rtc_data[3] = DectoBCD(systime.local_time.mday); |
| 1331 | | m_smpc.rtc_data[4] = DectoBCD(systime.local_time.hour); |
| 1332 | | m_smpc.rtc_data[5] = DectoBCD(systime.local_time.minute); |
| 1333 | | m_smpc.rtc_data[6] = DectoBCD(systime.local_time.second); |
| 1334 | | */ |
| 1335 | | |
| 1336 | | m_smpc.rtc_data[6]++; |
| 1337 | | |
| 1338 | | /* seconds from 9 -> 10*/ |
| 1339 | | if((m_smpc.rtc_data[6] & 0x0f) >= 0x0a) { m_smpc.rtc_data[6]+=0x10; m_smpc.rtc_data[6]&=0xf0; } |
| 1340 | | /* seconds from 59 -> 0 */ |
| 1341 | | if((m_smpc.rtc_data[6] & 0xf0) >= 0x60) { m_smpc.rtc_data[5]++; m_smpc.rtc_data[6] = 0; } |
| 1342 | | /* minutes from 9 -> 10 */ |
| 1343 | | if((m_smpc.rtc_data[5] & 0x0f) >= 0x0a) { m_smpc.rtc_data[5]+=0x10; m_smpc.rtc_data[5]&=0xf0; } |
| 1344 | | /* minutes from 59 -> 0 */ |
| 1345 | | if((m_smpc.rtc_data[5] & 0xf0) >= 0x60) { m_smpc.rtc_data[4]++; m_smpc.rtc_data[5] = 0; } |
| 1346 | | /* hours from 9 -> 10 */ |
| 1347 | | if((m_smpc.rtc_data[4] & 0x0f) >= 0x0a) { m_smpc.rtc_data[4]+=0x10; m_smpc.rtc_data[4]&=0xf0; } |
| 1348 | | /* hours from 23 -> 0 */ |
| 1349 | | if((m_smpc.rtc_data[4] & 0xff) >= 0x24) { m_smpc.rtc_data[3]++; m_smpc.rtc_data[2]+=0x10; m_smpc.rtc_data[4] = 0; } |
| 1350 | | /* week day name sunday -> monday */ |
| 1351 | | if((m_smpc.rtc_data[2] & 0xf0) >= 0x70) { m_smpc.rtc_data[2]&=0x0f; } |
| 1352 | | /* day number 9 -> 10 */ |
| 1353 | | if((m_smpc.rtc_data[3] & 0x0f) >= 0x0a) { m_smpc.rtc_data[3]+=0x10; m_smpc.rtc_data[3]&=0xf0; } |
| 1354 | | |
| 1355 | | // year BCD to dec conversion (for the leap year stuff) |
| 1356 | | { |
| 1357 | | year_num = (m_smpc.rtc_data[1] & 0xf); |
| 1358 | | |
| 1359 | | for(year_count = 0; year_count < (m_smpc.rtc_data[1] & 0xf0); year_count += 0x10) |
| 1360 | | year_num += 0xa; |
| 1361 | | |
| 1362 | | year_num += (m_smpc.rtc_data[0] & 0xf)*0x64; |
| 1363 | | |
| 1364 | | for(year_count = 0; year_count < (m_smpc.rtc_data[0] & 0xf0); year_count += 0x10) |
| 1365 | | year_num += 0x3e8; |
| 1366 | | } |
| 1367 | | |
| 1368 | | /* month +1 check */ |
| 1369 | | /* the RTC have a range of 1980 - 2100, so we don't actually need to support the leap year special conditions */ |
| 1370 | | if(((year_num % 4) == 0) && (m_smpc.rtc_data[2] & 0xf) == 2) |
| 1371 | | { |
| 1372 | | if((m_smpc.rtc_data[3] & 0xff) >= dpm[(m_smpc.rtc_data[2] & 0xf)-1]+1+1) |
| 1373 | | { m_smpc.rtc_data[2]++; m_smpc.rtc_data[3] = 0x01; } |
| 1374 | | } |
| 1375 | | else if((m_smpc.rtc_data[3] & 0xff) >= dpm[(m_smpc.rtc_data[2] & 0xf)-1]+1){ m_smpc.rtc_data[2]++; m_smpc.rtc_data[3] = 0x01; } |
| 1376 | | /* year +1 check */ |
| 1377 | | if((m_smpc.rtc_data[2] & 0x0f) > 12) { m_smpc.rtc_data[1]++; m_smpc.rtc_data[2] = (m_smpc.rtc_data[2] & 0xf0) | 0x01; } |
| 1378 | | /* year from 9 -> 10 */ |
| 1379 | | if((m_smpc.rtc_data[1] & 0x0f) >= 0x0a) { m_smpc.rtc_data[1]+=0x10; m_smpc.rtc_data[1]&=0xf0; } |
| 1380 | | /* year from 99 -> 100 */ |
| 1381 | | if((m_smpc.rtc_data[1] & 0xf0) >= 0xa0) { m_smpc.rtc_data[0]++; m_smpc.rtc_data[1] = 0; } |
| 1382 | | |
| 1383 | | // probably not SO precise, here just for reference ... |
| 1384 | | /* year from 999 -> 1000 */ |
| 1385 | | //if((m_smpc.rtc_data[0] & 0x0f) >= 0x0a) { m_smpc.rtc_data[0]+=0x10; m_smpc.rtc_data[0]&=0xf0; } |
| 1386 | | /* year from 9999 -> 0 */ |
| 1387 | | //if((m_smpc.rtc_data[0] & 0xf0) >= 0xa0) { m_smpc.rtc_data[0] = 0; } //roll over |
| 1388 | | } |
| 1389 | | |
| 1390 | | /* Official documentation says that the "RESET/TAS opcodes aren't supported", but Out Run definitely contradicts with it. |
| 1391 | | Since that m68k can't reset itself via the RESET opcode I suppose that the SMPC actually do it by reading an i/o |
| 1392 | | connected to this opcode. */ |
| 1393 | | void saturn_state::m68k_reset_callback(device_t *device) |
| 1394 | | { |
| 1395 | | saturn_state *state = device->machine().driver_data<saturn_state>(); |
| 1396 | | device->machine().scheduler().timer_set(attotime::from_usec(100), timer_expired_delegate(FUNC(saturn_state::smpc_audio_reset_line_pulse), state)); |
| 1397 | | |
| 1398 | | printf("m68k RESET opcode triggered\n"); |
| 1399 | | } |
| 1400 | | |
| 1401 | | MACHINE_START_MEMBER(saturn_state,saturn) |
| 1402 | | { |
| 1403 | | system_time systime; |
| 1404 | | machine().base_datetime(systime); |
| 1405 | | |
| 1406 | | m_maincpu = downcast<legacy_cpu_device*>( machine().device<cpu_device>("maincpu") ); |
| 1407 | | m_slave = downcast<legacy_cpu_device*>( machine().device("slave") ); |
| 1408 | | m_audiocpu = downcast<legacy_cpu_device*>( machine().device<cpu_device>("audiocpu") ); |
| 1409 | | |
| 1410 | | scsp_set_ram_base(machine().device("scsp"), m_sound_ram); |
| 1411 | | |
| 1412 | | // save states |
| 1413 | | state_save_register_global_pointer(machine(), m_scu_regs, 0x100/4); |
| 1414 | | state_save_register_global_pointer(machine(), m_scsp_regs, 0x1000/2); |
| 1415 | | state_save_register_global(machine(), m_NMI_reset); |
| 1416 | | state_save_register_global(machine(), m_en_68k); |
| 1417 | | state_save_register_global(machine(), m_smpc.IOSEL1); |
| 1418 | | state_save_register_global(machine(), m_smpc.IOSEL2); |
| 1419 | | state_save_register_global(machine(), m_smpc.EXLE1); |
| 1420 | | state_save_register_global(machine(), m_smpc.EXLE2); |
| 1421 | | state_save_register_global(machine(), m_smpc.PDR1); |
| 1422 | | state_save_register_global(machine(), m_smpc.PDR2); |
| 1423 | | // state_save_register_global(machine(), m_port_sel); |
| 1424 | | // state_save_register_global(machine(), mux_data); |
| 1425 | | state_save_register_global(machine(), m_scsp_last_line); |
| 1426 | | state_save_register_global(machine(), m_smpc.intback_stage); |
| 1427 | | state_save_register_global(machine(), m_smpc.pmode); |
| 1428 | | state_save_register_global(machine(), m_smpc.SR); |
| 1429 | | state_save_register_global_array(machine(), m_smpc.SMEM); |
| 1430 | | state_save_register_global_pointer(machine(), m_cart_dram, 0x400000/4); |
| 1431 | | |
| 1432 | | machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(saturn_state::stvcd_exit), this)); |
| 1433 | | |
| 1434 | | m_smpc.rtc_data[0] = DectoBCD(systime.local_time.year /100); |
| 1435 | | m_smpc.rtc_data[1] = DectoBCD(systime.local_time.year %100); |
| 1436 | | m_smpc.rtc_data[2] = (systime.local_time.weekday << 4) | (systime.local_time.month+1); |
| 1437 | | m_smpc.rtc_data[3] = DectoBCD(systime.local_time.mday); |
| 1438 | | m_smpc.rtc_data[4] = DectoBCD(systime.local_time.hour); |
| 1439 | | m_smpc.rtc_data[5] = DectoBCD(systime.local_time.minute); |
| 1440 | | m_smpc.rtc_data[6] = DectoBCD(systime.local_time.second); |
| 1441 | | |
| 1442 | | m_stv_rtc_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(saturn_state::stv_rtc_increment),this)); |
| 1443 | | |
| 1444 | | m68k_set_reset_callback(m_audiocpu, &saturn_state::m68k_reset_callback); |
| 1445 | | } |
| 1446 | | |
| 1447 | | |
| 1448 | | /* |
| 1449 | | (Preliminary) explanation about this: |
| 1450 | | VBLANK-OUT is used at the start of the vblank period.It also sets the timer zero |
| 1451 | | variable to 0. |
| 1452 | | If the Timer Compare register is zero too,the Timer 0 irq is triggered. |
| 1453 | | |
| 1454 | | HBLANK-IN is used at the end of each scanline except when in VBLANK-IN/OUT periods. |
| 1455 | | |
| 1456 | | The timer 0 is also incremented by one at each HBLANK and checked with the value |
| 1457 | | of the Timer Compare register;if equal,the timer 0 irq is triggered here too. |
| 1458 | | Notice that the timer 0 compare register can be more than the VBLANK maximum range,in |
| 1459 | | this case the timer 0 irq is simply never triggered.This is a known Sega Saturn/ST-V "bug". |
| 1460 | | |
| 1461 | | VBLANK-IN is used at the end of the vblank period. |
| 1462 | | |
| 1463 | | SCU register[36] is the timer zero compare register. |
| 1464 | | SCU register[40] is for IRQ masking. |
| 1465 | | |
| 1466 | | TODO: |
| 1467 | | - VDP1 timing and CEF emulation isn't accurate at all. |
| 1468 | | */ |
| 1469 | | |
| 1470 | | |
| 1471 | | TIMER_DEVICE_CALLBACK_MEMBER(saturn_state::saturn_scanline) |
| 1472 | | { |
| 1473 | | int scanline = param; |
| 1474 | | int y_step,vblank_line; |
| 1475 | | |
| 1476 | | vblank_line = get_vblank_start_position(); |
| 1477 | | y_step = get_ystep_count(); |
| 1478 | | |
| 1479 | | //popmessage("%08x %d T0 %d T1 %d %08x",m_scu.ism ^ 0xffffffff,max_y,m_scu_regs[36],m_scu_regs[37],m_scu_regs[38]); |
| 1480 | | |
| 1481 | | if(scanline == (0)*y_step) |
| 1482 | | { |
| 1483 | | video_update_vdp1(); |
| 1484 | | |
| 1485 | | if(STV_VDP1_VBE) |
| 1486 | | m_vdp1.framebuffer_clear_on_next_frame = 1; |
| 1487 | | |
| 1488 | | if(!(m_scu.ism & IRQ_VDP1_END)) |
| 1489 | | { |
| 1490 | | m_maincpu->set_input_line_and_vector(0x2, HOLD_LINE, 0x4d); |
| 1491 | | scu_do_transfer(6); |
| 1492 | | } |
| 1493 | | else |
| 1494 | | m_scu.ist |= (IRQ_VDP1_END); |
| 1495 | | } |
| 1496 | | |
| 1497 | | if(scanline == 0*y_step) |
| 1498 | | { |
| 1499 | | if(!(m_scu.ism & IRQ_VBLANK_OUT)) |
| 1500 | | { |
| 1501 | | m_maincpu->set_input_line_and_vector(0xe, HOLD_LINE, 0x41); |
| 1502 | | scu_do_transfer(1); |
| 1503 | | } |
| 1504 | | else |
| 1505 | | m_scu.ist |= (IRQ_VBLANK_OUT); |
| 1506 | | |
| 1507 | | } |
| 1508 | | else if(scanline == vblank_line*y_step) |
| 1509 | | { |
| 1510 | | if(!(m_scu.ism & IRQ_VBLANK_IN)) |
| 1511 | | { |
| 1512 | | m_maincpu->set_input_line_and_vector(0xf, HOLD_LINE ,0x40); |
| 1513 | | scu_do_transfer(0); |
| 1514 | | } |
| 1515 | | else |
| 1516 | | m_scu.ist |= (IRQ_VBLANK_IN); |
| 1517 | | } |
| 1518 | | else if((scanline % y_step) == 0 && scanline < vblank_line*y_step) |
| 1519 | | { |
| 1520 | | if(!(m_scu.ism & IRQ_HBLANK_IN)) |
| 1521 | | { |
| 1522 | | m_maincpu->set_input_line_and_vector(0xd, HOLD_LINE, 0x42); |
| 1523 | | scu_do_transfer(2); |
| 1524 | | } |
| 1525 | | else |
| 1526 | | m_scu.ist |= (IRQ_HBLANK_IN); |
| 1527 | | } |
| 1528 | | |
| 1529 | | if(scanline == (m_scu_regs[36] & 0x3ff)*y_step) |
| 1530 | | { |
| 1531 | | if(!(m_scu.ism & IRQ_TIMER_0)) |
| 1532 | | { |
| 1533 | | m_maincpu->set_input_line_and_vector(0xc, HOLD_LINE, 0x43 ); |
| 1534 | | scu_do_transfer(3); |
| 1535 | | } |
| 1536 | | else |
| 1537 | | m_scu.ist |= (IRQ_TIMER_0); |
| 1538 | | } |
| 1539 | | |
| 1540 | | /* TODO: this isn't completely correct */ |
| 1541 | | if(m_scu_regs[38] & 0x1) |
| 1542 | | { |
| 1543 | | if((!(m_scu_regs[38] & 0x100) && (scanline % y_step) == 0) || |
| 1544 | | ((m_scu_regs[38] & 0x100) && (scanline == (m_scu_regs[36] & 0x3ff)*y_step))) |
| 1545 | | { |
| 1546 | | if(!(m_scu.ism & IRQ_TIMER_1)) |
| 1547 | | { |
| 1548 | | m_maincpu->set_input_line_and_vector(0xb, HOLD_LINE, 0x44 ); |
| 1549 | | scu_do_transfer(4); |
| 1550 | | } |
| 1551 | | else |
| 1552 | | m_scu.ist |= (IRQ_TIMER_1); |
| 1553 | | } |
| 1554 | | } |
| 1555 | | } |
| 1556 | | |
| 1557 | | TIMER_DEVICE_CALLBACK_MEMBER(saturn_state::saturn_slave_scanline ) |
| 1558 | | { |
| 1559 | | int scanline = param; |
| 1560 | | int y_step,vblank_line; |
| 1561 | | |
| 1562 | | vblank_line = get_vblank_start_position(); |
| 1563 | | y_step = get_ystep_count(); |
| 1564 | | |
| 1565 | | if(scanline == vblank_line*y_step) |
| 1566 | | m_slave->set_input_line_and_vector(0x6, HOLD_LINE, 0x43); |
| 1567 | | else if((scanline % y_step) == 0 && scanline < vblank_line*y_step) |
| 1568 | | m_slave->set_input_line_and_vector(0x2, HOLD_LINE, 0x41); |
| 1569 | | } |
| 1570 | | |
| 1571 | | /* Die Hard Trilogy tests RAM address 0x25e7ffe bit 2 with Slave during FRT minit irq, in-development tool for breaking execution of it? */ |
| 1572 | | READ32_MEMBER(saturn_state::saturn_null_ram_r) |
| 1573 | | { |
| 1574 | | return 0xffffffff; |
| 1575 | | } |
| 1576 | | |
| 1577 | | WRITE32_MEMBER(saturn_state::saturn_null_ram_w) |
| 1578 | | { |
| 1579 | | } |
| 1580 | | |
| 1581 | | READ32_MEMBER(saturn_state::saturn_cart_dram0_r) |
| 1582 | | { |
| 1583 | | return m_cart_dram[offset]; |
| 1584 | | } |
| 1585 | | |
| 1586 | | WRITE32_MEMBER(saturn_state::saturn_cart_dram0_w) |
| 1587 | | { |
| 1588 | | COMBINE_DATA(&m_cart_dram[offset]); |
| 1589 | | } |
| 1590 | | |
| 1591 | | READ32_MEMBER(saturn_state::saturn_cart_dram1_r) |
| 1592 | | { |
| 1593 | | return m_cart_dram[offset+0x200000/4]; |
| 1594 | | } |
| 1595 | | |
| 1596 | | WRITE32_MEMBER(saturn_state::saturn_cart_dram1_w) |
| 1597 | | { |
| 1598 | | COMBINE_DATA(&m_cart_dram[offset+0x200000/4]); |
| 1599 | | } |
| 1600 | | |
| 1601 | | READ32_MEMBER(saturn_state::saturn_cs1_r) |
| 1602 | | { |
| 1603 | | UINT32 res; |
| 1604 | | |
| 1605 | | res = 0; |
| 1606 | | //res = m_cart_backupram[offset*4+0] << 24; |
| 1607 | | res |= m_cart_backupram[offset*2+0] << 16; |
| 1608 | | //res |= m_cart_backupram[offset*4+2] << 8; |
| 1609 | | res |= m_cart_backupram[offset*2+1] << 0; |
| 1610 | | |
| 1611 | | return res; |
| 1612 | | } |
| 1613 | | |
| 1614 | | WRITE32_MEMBER(saturn_state::saturn_cs1_w) |
| 1615 | | { |
| 1616 | | if(ACCESSING_BITS_16_23) |
| 1617 | | m_cart_backupram[offset*2+0] = (data & 0x00ff0000) >> 16; |
| 1618 | | if(ACCESSING_BITS_0_7) |
| 1619 | | m_cart_backupram[offset*2+1] = (data & 0x000000ff) >> 0; |
| 1620 | | } |
| 1621 | | |
| 1622 | | void saturn_state::scu_reset(void) |
| 1623 | | { |
| 1624 | | m_scu.ism = 0xbfff; |
| 1625 | | m_scu.ist = 0; |
| 1626 | | m_scu.start_factor[0] = 7; |
| 1627 | | m_scu.start_factor[1] = 7; |
| 1628 | | m_scu.start_factor[2] = 7; |
| 1629 | | m_scu.status = 0; |
| 1630 | | } |
| 1631 | | |
| 1632 | | MACHINE_RESET_MEMBER(saturn_state,saturn) |
| 1633 | | { |
| 1634 | | m_scsp_last_line = 0; |
| 1635 | | |
| 1636 | | // don't let the slave cpu and the 68k go anywhere |
| 1637 | | machine().device("slave")->execute().set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 1638 | | machine().device("audiocpu")->execute().set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 1639 | | |
| 1640 | | m_smpc.SR = 0x40; // this bit is always on according to docs |
| 1641 | | |
| 1642 | | scu_reset(); |
| 1643 | | |
| 1644 | | m_en_68k = 0; |
| 1645 | | m_NMI_reset = 0; |
| 1646 | | m_smpc.slave_on = 0; |
| 1647 | | |
| 1648 | | |
| 1649 | | //memset(stv_m_workram_l, 0, 0x100000); |
| 1650 | | //memset(stv_m_workram_h, 0, 0x100000); |
| 1651 | | |
| 1652 | | machine().device("maincpu")->set_unscaled_clock(MASTER_CLOCK_320/2); |
| 1653 | | machine().device("slave")->set_unscaled_clock(MASTER_CLOCK_320/2); |
| 1654 | | |
| 1655 | | stvcd_reset(); |
| 1656 | | |
| 1657 | | m_cart_type = ioport("CART_AREA")->read() & 7; |
| 1658 | | |
| 1659 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x02400000, 0x027fffff, read32_delegate(FUNC(saturn_state::saturn_null_ram_r),this), write32_delegate(FUNC(saturn_state::saturn_null_ram_w),this)); |
| 1660 | | machine().device("slave")->memory().space(AS_PROGRAM).install_readwrite_handler(0x02400000, 0x027fffff, read32_delegate(FUNC(saturn_state::saturn_null_ram_r),this), write32_delegate(FUNC(saturn_state::saturn_null_ram_w),this)); |
| 1661 | | |
| 1662 | | if(m_cart_type == 5) |
| 1663 | | { |
| 1664 | | // AM_RANGE(0x02400000, 0x027fffff) AM_RAM //cart RAM area, dynamically allocated |
| 1665 | | machine().device("maincpu")->memory().space(AS_PROGRAM).nop_readwrite(0x02400000, 0x027fffff); |
| 1666 | | machine().device("slave")->memory().space(AS_PROGRAM).nop_readwrite(0x02400000, 0x027fffff); |
| 1667 | | |
| 1668 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x02400000, 0x0247ffff, read32_delegate(FUNC(saturn_state::saturn_cart_dram0_r),this), write32_delegate(FUNC(saturn_state::saturn_cart_dram0_w),this)); |
| 1669 | | machine().device("slave")->memory().space(AS_PROGRAM).install_readwrite_handler(0x02400000, 0x0247ffff, read32_delegate(FUNC(saturn_state::saturn_cart_dram0_r),this), write32_delegate(FUNC(saturn_state::saturn_cart_dram0_w),this)); |
| 1670 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x02600000, 0x0267ffff, read32_delegate(FUNC(saturn_state::saturn_cart_dram1_r),this), write32_delegate(FUNC(saturn_state::saturn_cart_dram1_w),this)); |
| 1671 | | machine().device("slave")->memory().space(AS_PROGRAM).install_readwrite_handler(0x02600000, 0x0267ffff, read32_delegate(FUNC(saturn_state::saturn_cart_dram1_r),this), write32_delegate(FUNC(saturn_state::saturn_cart_dram1_w),this)); |
| 1672 | | } |
| 1673 | | |
| 1674 | | if(m_cart_type == 6) |
| 1675 | | { |
| 1676 | | // AM_RANGE(0x02400000, 0x027fffff) AM_RAM //cart RAM area, dynamically allocated |
| 1677 | | machine().device("maincpu")->memory().space(AS_PROGRAM).nop_readwrite(0x02400000, 0x027fffff); |
| 1678 | | machine().device("slave")->memory().space(AS_PROGRAM).nop_readwrite(0x02400000, 0x027fffff); |
| 1679 | | |
| 1680 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x02400000, 0x025fffff, read32_delegate(FUNC(saturn_state::saturn_cart_dram0_r),this), write32_delegate(FUNC(saturn_state::saturn_cart_dram0_w),this)); |
| 1681 | | machine().device("slave")->memory().space(AS_PROGRAM).install_readwrite_handler(0x02400000, 0x025fffff, read32_delegate(FUNC(saturn_state::saturn_cart_dram0_r),this), write32_delegate(FUNC(saturn_state::saturn_cart_dram0_w),this)); |
| 1682 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x02600000, 0x027fffff, read32_delegate(FUNC(saturn_state::saturn_cart_dram1_r),this), write32_delegate(FUNC(saturn_state::saturn_cart_dram1_w),this)); |
| 1683 | | machine().device("slave")->memory().space(AS_PROGRAM).install_readwrite_handler(0x02600000, 0x027fffff, read32_delegate(FUNC(saturn_state::saturn_cart_dram1_r),this), write32_delegate(FUNC(saturn_state::saturn_cart_dram1_w),this)); |
| 1684 | | } |
| 1685 | | |
| 1686 | | machine().device("maincpu")->memory().space(AS_PROGRAM).nop_readwrite(0x04000000, 0x047fffff); |
| 1687 | | machine().device("slave")->memory().space(AS_PROGRAM).nop_readwrite(0x04000000, 0x047fffff); |
| 1688 | | |
| 1689 | | if(m_cart_type > 0 && m_cart_type < 5) |
| 1690 | | { |
| 1691 | | // AM_RANGE(0x04000000, 0x047fffff) AM_RAM //backup RAM area, dynamically allocated |
| 1692 | | UINT32 mask; |
| 1693 | | mask = 0x7fffff >> (4-m_cart_type); |
| 1694 | | //mask = 0x7fffff >> 4-4 = 0x7fffff 32mbit |
| 1695 | | //mask = 0x7fffff >> 4-3 = 0x3fffff 16mbit |
| 1696 | | //mask = 0x7fffff >> 4-2 = 0x1fffff 8mbit |
| 1697 | | //mask = 0x7fffff >> 4-1 = 0x0fffff 4mbit |
| 1698 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(0x04000000, 0x04000000 | mask, read32_delegate(FUNC(saturn_state::saturn_cs1_r),this), write32_delegate(FUNC(saturn_state::saturn_cs1_w),this)); |
| 1699 | | machine().device("slave")->memory().space(AS_PROGRAM).install_readwrite_handler(0x04000000, 0x04000000 | mask, read32_delegate(FUNC(saturn_state::saturn_cs1_r),this), write32_delegate(FUNC(saturn_state::saturn_cs1_w),this)); |
| 1700 | | } |
| 1701 | | |
| 1702 | | m_vdp2.old_crmd = -1; |
| 1703 | | m_vdp2.old_tvmd = -1; |
| 1704 | | |
| 1705 | | m_stv_rtc_timer->adjust(attotime::zero, 0, attotime::from_seconds(1)); |
| 1706 | | } |
| 1707 | | |
| 1708 | | |
| 1709 | | struct cdrom_interface saturn_cdrom = |
| 1710 | | { |
| 1711 | | "sat_cdrom", |
| 1712 | | NULL |
| 1713 | | }; |
| 1714 | | |
| 1715 | | |
| 1716 | | |
| 1717 | | |
| 1718 | | DEVICE_IMAGE_LOAD_MEMBER( saturn_state, sat_cart ) |
| 1719 | | { |
| 1720 | | UINT8 *ROM = image.device().memregion("maincpu")->base()+0x080000; |
| 1721 | | UINT32 length; |
| 1722 | | |
| 1723 | | if (image.software_entry() != NULL) |
| 1724 | | { |
| 1725 | | length = image.get_software_region_length("cart"); |
| 1726 | | UINT8* imagex = image.get_software_region("cart"); |
| 1727 | | |
| 1728 | | memcpy(ROM, imagex, length); |
| 1729 | | } |
| 1730 | | else |
| 1731 | | { |
| 1732 | | length = image.fread( ROM, 0x400000); |
| 1733 | | } |
| 1734 | | |
| 1735 | | // fix endianness.... |
| 1736 | | for (int i=0;i<length;i+=4) |
| 1737 | | { |
| 1738 | | UINT8 tempa = ROM[i+0]; |
| 1739 | | UINT8 tempb = ROM[i+1]; |
| 1740 | | ROM[i+1] = ROM[i+2]; |
| 1741 | | ROM[i+0] = ROM[i+3]; |
| 1742 | | ROM[i+3] = tempa; |
| 1743 | | ROM[i+2] = tempb; |
| 1744 | | } |
| 1745 | | |
| 1746 | | return IMAGE_INIT_PASS; |
| 1747 | | } |
| 1748 | | |
| 1749 | | static MACHINE_CONFIG_START( saturn, saturn_state ) |
| 1750 | | |
| 1751 | | /* basic machine hardware */ |
| 1752 | | MCFG_CPU_ADD("maincpu", SH2, MASTER_CLOCK_352/2) // 28.6364 MHz |
| 1753 | | MCFG_CPU_PROGRAM_MAP(saturn_mem) |
| 1754 | | MCFG_CPU_CONFIG(sh2_conf_master) |
| 1755 | | MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", saturn_state, saturn_scanline, "screen", 0, 1) |
| 1756 | | |
| 1757 | | MCFG_CPU_ADD("slave", SH2, MASTER_CLOCK_352/2) // 28.6364 MHz |
| 1758 | | MCFG_CPU_PROGRAM_MAP(saturn_mem) |
| 1759 | | MCFG_CPU_CONFIG(sh2_conf_slave) |
| 1760 | | MCFG_TIMER_DRIVER_ADD_SCANLINE("slave_scantimer", saturn_state, saturn_slave_scanline, "screen", 0, 1) |
| 1761 | | |
| 1762 | | MCFG_CPU_ADD("audiocpu", M68000, 11289600) //256 x 44100 Hz = 11.2896 MHz |
| 1763 | | MCFG_CPU_PROGRAM_MAP(sound_mem) |
| 1764 | | |
| 1765 | | MCFG_MACHINE_START_OVERRIDE(saturn_state,saturn) |
| 1766 | | MCFG_MACHINE_RESET_OVERRIDE(saturn_state,saturn) |
| 1767 | | |
| 1768 | | MCFG_NVRAM_HANDLER(saturn) |
| 1769 | | |
| 1770 | | MCFG_TIMER_DRIVER_ADD("sector_timer", saturn_state, stv_sector_cb) |
| 1771 | | MCFG_TIMER_DRIVER_ADD("sh1_cmd", saturn_state, stv_sh1_sim) |
| 1772 | | |
| 1773 | | /* video hardware */ |
| 1774 | | MCFG_SCREEN_ADD("screen", RASTER) |
| 1775 | | MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK_320/8, 427, 0, 320, 263, 0, 224) |
| 1776 | | MCFG_SCREEN_UPDATE_DRIVER(saturn_state, screen_update_stv_vdp2) |
| 1777 | | MCFG_PALETTE_LENGTH(2048+(2048*2))//standard palette + extra memory for rgb brightness. |
| 1778 | | |
| 1779 | | MCFG_GFXDECODE(stv) |
| 1780 | | |
| 1781 | | MCFG_VIDEO_START_OVERRIDE(saturn_state,stv_vdp2) |
| 1782 | | |
| 1783 | | MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") |
| 1784 | | |
| 1785 | | MCFG_SOUND_ADD("scsp", SCSP, 0) |
| 1786 | | MCFG_SOUND_CONFIG(scsp_config) |
| 1787 | | MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) |
| 1788 | | MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) |
| 1789 | | |
| 1790 | | MCFG_SOUND_ADD("cdda", CDDA, 0) |
| 1791 | | MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) |
| 1792 | | MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) |
| 1793 | | MACHINE_CONFIG_END |
| 1794 | | |
| 1795 | | MACHINE_CONFIG_DERIVED( saturnus, saturn ) |
| 1796 | | MCFG_CDROM_ADD( "cdrom",saturn_cdrom ) |
| 1797 | | MCFG_SOFTWARE_LIST_ADD("cd_list","saturn") |
| 1798 | | MCFG_SOFTWARE_LIST_FILTER("cd_list","NTSC-U") |
| 1799 | | |
| 1800 | | MCFG_CARTSLOT_ADD("cart") |
| 1801 | | MCFG_CARTSLOT_INTERFACE("sat_cart") |
| 1802 | | MCFG_CARTSLOT_LOAD(saturn_state, sat_cart) |
| 1803 | | MCFG_SOFTWARE_LIST_ADD("cart_list","sat_cart") |
| 1804 | | |
| 1805 | | MACHINE_CONFIG_END |
| 1806 | | |
| 1807 | | MACHINE_CONFIG_DERIVED( saturneu, saturn ) |
| 1808 | | MCFG_CDROM_ADD( "cdrom",saturn_cdrom ) |
| 1809 | | MCFG_SOFTWARE_LIST_ADD("cd_list","saturn") |
| 1810 | | MCFG_SOFTWARE_LIST_FILTER("cd_list","PAL") |
| 1811 | | |
| 1812 | | MCFG_CARTSLOT_ADD("cart") |
| 1813 | | MCFG_CARTSLOT_INTERFACE("sat_cart") |
| 1814 | | MCFG_CARTSLOT_LOAD(saturn_state, sat_cart) |
| 1815 | | MCFG_SOFTWARE_LIST_ADD("cart_list","sat_cart") |
| 1816 | | |
| 1817 | | MACHINE_CONFIG_END |
| 1818 | | |
| 1819 | | MACHINE_CONFIG_DERIVED( saturnjp, saturn ) |
| 1820 | | MCFG_CDROM_ADD( "cdrom",saturn_cdrom ) |
| 1821 | | MCFG_SOFTWARE_LIST_ADD("cd_list","saturn") |
| 1822 | | MCFG_SOFTWARE_LIST_FILTER("cd_list","NTSC-J") |
| 1823 | | |
| 1824 | | MCFG_CARTSLOT_ADD("cart") |
| 1825 | | MCFG_CARTSLOT_INTERFACE("sat_cart") |
| 1826 | | MCFG_CARTSLOT_LOAD(saturn_state, sat_cart) |
| 1827 | | MCFG_SOFTWARE_LIST_ADD("cart_list","sat_cart") |
| 1828 | | |
| 1829 | | MACHINE_CONFIG_END |
| 1830 | | |
| 1831 | | |
| 1832 | | void saturn_state::saturn_init_driver(int rgn) |
| 1833 | | { |
| 1834 | | m_saturn_region = rgn; |
| 1835 | | m_vdp2.pal = (rgn == 12) ? 1 : 0; |
| 1836 | | |
| 1837 | | // set compatible options |
| 1838 | | sh2drc_set_options(machine().device("maincpu"), SH2DRC_STRICT_VERIFY|SH2DRC_STRICT_PCREL); |
| 1839 | | sh2drc_set_options(machine().device("slave"), SH2DRC_STRICT_VERIFY|SH2DRC_STRICT_PCREL); |
| 1840 | | |
| 1841 | | /* amount of time to boost interleave for on MINIT / SINIT, needed for communication to work */ |
| 1842 | | m_minit_boost = 400; |
| 1843 | | m_sinit_boost = 400; |
| 1844 | | m_minit_boost_timeslice = attotime::zero; |
| 1845 | | m_sinit_boost_timeslice = attotime::zero; |
| 1846 | | |
| 1847 | | m_scu_regs = auto_alloc_array_clear(machine(), UINT32, 0x100/4); |
| 1848 | | m_scsp_regs = auto_alloc_array_clear(machine(), UINT16, 0x1000/2); |
| 1849 | | m_cart_dram = auto_alloc_array_clear(machine(), UINT32, 0x400000/4); |
| 1850 | | m_backupram = auto_alloc_array_clear(machine(), UINT8, 0x8000); |
| 1851 | | m_cart_backupram = auto_alloc_array_clear(machine(), UINT8, 0x400000); |
| 1852 | | } |
| 1853 | | |
| 1854 | | DRIVER_INIT_MEMBER(saturn_state,saturnus) |
| 1855 | | { |
| 1856 | | saturn_init_driver(4); |
| 1857 | | } |
| 1858 | | |
| 1859 | | DRIVER_INIT_MEMBER(saturn_state,saturneu) |
| 1860 | | { |
| 1861 | | saturn_init_driver(12); |
| 1862 | | } |
| 1863 | | |
| 1864 | | DRIVER_INIT_MEMBER(saturn_state,saturnjp) |
| 1865 | | { |
| 1866 | | saturn_init_driver(1); |
| 1867 | | } |
| 1868 | | |
| 1869 | | |
| 1870 | | /* Japanese Saturn */ |
| 1871 | | ROM_START(saturnjp) |
| 1872 | | ROM_REGION( 0x480000, "maincpu", ROMREGION_ERASEFF ) /* SH2 code */ |
| 1873 | | ROM_SYSTEM_BIOS(0, "101", "Japan v1.01 (941228)") |
| 1874 | | ROMX_LOAD("sega_101.bin", 0x00000000, 0x00080000, CRC(224b752c) SHA1(df94c5b4d47eb3cc404d88b33a8fda237eaf4720), ROM_BIOS(1)) |
| 1875 | | ROM_SYSTEM_BIOS(1, "1003", "Japan v1.003 (941012)") |
| 1876 | | ROMX_LOAD("sega1003.bin", 0x00000000, 0x00080000, CRC(b3c63c25) SHA1(7b23b53d62de0f29a23e423d0fe751dfb469c2fa), ROM_BIOS(2)) |
| 1877 | | ROM_SYSTEM_BIOS(2, "100", "Japan v1.00 (940921)") |
| 1878 | | ROMX_LOAD("sega_100.bin", 0x00000000, 0x00080000, CRC(2aba43c2) SHA1(2b8cb4f87580683eb4d760e4ed210813d667f0a2), ROM_BIOS(3)) |
| 1879 | | // ROM_CART_LOAD("cart", 0x080000, 0x400000, ROM_NOMIRROR | ROM_OPTIONAL) |
| 1880 | | ROM_REGION( 0x080000, "slave", 0 ) /* SH2 code */ |
| 1881 | | ROM_COPY( "maincpu",0,0,0x080000) |
| 1882 | | ROM_END |
| 1883 | | |
| 1884 | | /* Overseas Saturn */ |
| 1885 | | ROM_START(saturn) |
| 1886 | | ROM_REGION( 0x480000, "maincpu", ROMREGION_ERASEFF ) /* SH2 code */ |
| 1887 | | ROM_SYSTEM_BIOS(0, "101a", "Overseas v1.01a (941115)") |
| 1888 | | /* Confirmed by ElBarto */ |
| 1889 | | ROMX_LOAD("mpr-17933.bin", 0x00000000, 0x00080000, CRC(4afcf0fa) SHA1(faa8ea183a6d7bbe5d4e03bb1332519800d3fbc3), ROM_BIOS(1)) |
| 1890 | | ROM_SYSTEM_BIOS(1, "100a", "Overseas v1.00a (941115)") |
| 1891 | | ROMX_LOAD("sega_100a.bin", 0x00000000, 0x00080000, CRC(f90f0089) SHA1(3bb41feb82838ab9a35601ac666de5aacfd17a58), ROM_BIOS(2)) |
| 1892 | | // ROM_CART_LOAD("cart", 0x080000, 0x400000, ROM_NOMIRROR | ROM_OPTIONAL) |
| 1893 | | ROM_REGION( 0x080000, "slave", 0 ) /* SH2 code */ |
| 1894 | | ROM_COPY( "maincpu",0,0,0x080000) |
| 1895 | | ROM_END |
| 1896 | | |
| 1897 | | ROM_START(saturneu) |
| 1898 | | ROM_REGION( 0x480000, "maincpu", ROMREGION_ERASEFF ) /* SH2 code */ |
| 1899 | | ROM_SYSTEM_BIOS(0, "101a", "Overseas v1.01a (941115)") |
| 1900 | | /* Confirmed by ElBarto */ |
| 1901 | | ROMX_LOAD("mpr-17933.bin", 0x00000000, 0x00080000, CRC(4afcf0fa) SHA1(faa8ea183a6d7bbe5d4e03bb1332519800d3fbc3), ROM_BIOS(1)) |
| 1902 | | ROM_SYSTEM_BIOS(1, "100a", "Overseas v1.00a (941115)") |
| 1903 | | ROMX_LOAD("sega_100a.bin", 0x00000000, 0x00080000, CRC(f90f0089) SHA1(3bb41feb82838ab9a35601ac666de5aacfd17a58), ROM_BIOS(2)) |
| 1904 | | // ROM_CART_LOAD("cart", 0x080000, 0x400000, ROM_NOMIRROR | ROM_OPTIONAL) |
| 1905 | | ROM_REGION( 0x080000, "slave", 0 ) /* SH2 code */ |
| 1906 | | ROM_COPY( "maincpu",0,0,0x080000) |
| 1907 | | ROM_END |
| 1908 | | |
| 1909 | | ROM_START(vsaturn) |
| 1910 | | ROM_REGION( 0x480000, "maincpu", ROMREGION_ERASEFF ) /* SH2 code */ |
| 1911 | | ROM_LOAD("vsaturn.bin", 0x00000000, 0x00080000, CRC(e4d61811) SHA1(4154e11959f3d5639b11d7902b3a393a99fb5776)) |
| 1912 | | // ROM_CART_LOAD("cart", 0x080000, 0x400000, ROM_NOMIRROR | ROM_OPTIONAL) |
| 1913 | | ROM_REGION( 0x080000, "slave", 0 ) /* SH2 code */ |
| 1914 | | ROM_COPY( "maincpu",0,0,0x080000) |
| 1915 | | ROM_END |
| 1916 | | |
| 1917 | | ROM_START(hisaturn) |
| 1918 | | ROM_REGION( 0x480000, "maincpu", ROMREGION_ERASEFF ) /* SH2 code */ |
| 1919 | | ROM_LOAD("hisaturn.bin", 0x00000000, 0x00080000, CRC(721e1b60) SHA1(49d8493008fa715ca0c94d99817a5439d6f2c796)) |
| 1920 | | // ROM_CART_LOAD("cart", 0x080000, 0x400000, ROM_NOMIRROR | ROM_OPTIONAL) |
| 1921 | | ROM_REGION( 0x080000, "slave", 0 ) /* SH2 code */ |
| 1922 | | ROM_COPY( "maincpu",0,0,0x080000) |
| 1923 | | ROM_END |
| 1924 | | |
| 1925 | | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ |
| 1926 | | CONS( 1994, saturn, 0, 0, saturnus, saturn, saturn_state, saturnus, "Sega", "Saturn (USA)", GAME_NOT_WORKING ) |
| 1927 | | CONS( 1994, saturnjp, saturn, 0, saturnjp, saturn, saturn_state, saturnjp, "Sega", "Saturn (Japan)", GAME_NOT_WORKING ) |
| 1928 | | CONS( 1994, saturneu, saturn, 0, saturneu, saturn, saturn_state, saturneu, "Sega", "Saturn (PAL)", GAME_NOT_WORKING ) |
| 1929 | | CONS( 1995, vsaturn, saturn, 0, saturnjp, saturn, saturn_state, saturnjp, "JVC", "V-Saturn", GAME_NOT_WORKING ) |
| 1930 | | CONS( 1995, hisaturn, saturn, 0, saturnjp, saturn, saturn_state, saturnjp, "Hitachi", "HiSaturn", GAME_NOT_WORKING ) |