src/mame/drivers/megadriv.c
| r9263 | r9264 | |
| 75 | 75 | #include "cpu/m68000/m68000.h" |
| 76 | 76 | #include "includes/megadriv.h" |
| 77 | 77 | #include "cpu/sh2/sh2.h" |
| 78 | #include "cpu/sh2/sh2comn.h" |
| 78 | 79 | |
| 79 | 80 | #define MEGADRIV_VDP_VRAM(address) megadrive_vdp_vram[(address)&0x7fff] |
| 80 | 81 | |
| r9263 | r9264 | |
| 621 | 622 | { |
| 622 | 623 | // should we limit the valid areas here? |
| 623 | 624 | // how does this behave with the segacd etc? |
| 624 | | // with the 32x it seems to see the raw cart? - using 68k space causes the character to vanish |
| 625 | 625 | // svp uses it's own function elsewhere... |
| 626 | // note, the RV bit on 32x is important for this to work, because it causes a normal cart mapping - see tempo |
| 627 | address_space *space68k = machine->device<legacy_cpu_device>("maincpu")->space(); |
| 626 | 628 | |
| 627 | 629 | if (( source >= 0x000000 ) && ( source <= 0x3fffff )) |
| 628 | 630 | { |
| 629 | | UINT16 *rom = (UINT16*)memory_region(machine, "maincpu"); |
| 630 | | return rom[(source&0x3fffff)>>1]; |
| 631 | return space68k->read_word(source); |
| 631 | 632 | } |
| 632 | 633 | else if (( source >= 0xe00000 ) && ( source <= 0xffffff )) |
| 633 | 634 | { |
| 634 | | // mame_printf_debug("dma\n"); |
| 635 | | // return ((megadrive_ram[(source&0xffff)>>1]&0xff00)>>8)|((megadrive_ram[(source&0xffff)>>1]&0x00ff)<<8); |
| 636 | | return megadrive_ram[(source&0xffff)>>1]; |
| 635 | return space68k->read_word(source); |
| 637 | 636 | } |
| 638 | 637 | else |
| 639 | 638 | { |
| r9263 | r9264 | |
| 2366 | 2365 | { |
| 2367 | 2366 | current_fifo_block = fifo_block_b; |
| 2368 | 2367 | current_fifo_readblock = fifo_block_a; |
| 2368 | // incase we have a stalled DMA in progress, let the SH2 know there is data available |
| 2369 | sh2_notify_dma_data_available(space->machine->device("32x_master_sh2")); |
| 2370 | sh2_notify_dma_data_available(space->machine->device("32x_slave_sh2")); |
| 2371 | |
| 2369 | 2372 | } |
| 2370 | 2373 | current_fifo_write_pos = 0; |
| 2371 | 2374 | } |
| r9263 | r9264 | |
| 2377 | 2380 | { |
| 2378 | 2381 | current_fifo_block = fifo_block_a; |
| 2379 | 2382 | current_fifo_readblock = fifo_block_b; |
| 2383 | // incase we have a stalled DMA in progress, let the SH2 know there is data available |
| 2384 | sh2_notify_dma_data_available(space->machine->device("32x_master_sh2")); |
| 2385 | sh2_notify_dma_data_available(space->machine->device("32x_slave_sh2")); |
| 2386 | |
| 2380 | 2387 | } |
| 2381 | 2388 | |
| 2382 | 2389 | current_fifo_write_pos = 0; |
| r9263 | r9264 | |
| 2395 | 2402 | F = Fifo FULL |
| 2396 | 2403 | K = 68k CPU Write mode (0 = no, 1 = CPU write) |
| 2397 | 2404 | 0 = always 0? no, marsch test wants it to be latched or 1 |
| 2398 | | R = RV (0 = no operation, 1 = DMA Start allowed) |
| 2405 | R = RV (0 = no operation, 1 = DMA Start allowed) <-- RV bit actually affects memory mapping, this is misleading.. it just sets the memory up in a suitable way to use the genesis VDP DMA |
| 2399 | 2406 | |
| 2400 | 2407 | */ |
| 2401 | 2408 | |
| r9263 | r9264 | |
| 2420 | 2427 | a15106_reg = data & 0x7; |
| 2421 | 2428 | |
| 2422 | 2429 | if (a15106_reg & 0x1) /* NBA Jam TE relies on this */ |
| 2430 | { |
| 2431 | |
| 2432 | // install the game rom in the normal 0x000000-0x03fffff space used by the genesis - this allows VDP DMA operations to work as they have to be from this area or RAM |
| 2433 | // it should also UNMAP the banked rom area... |
| 2423 | 2434 | memory_install_rom(space, 0x0000100, 0x03fffff, 0, 0, memory_region(space->machine, "gamecart") + 0x100); |
| 2424 | | |
| 2435 | } |
| 2436 | else |
| 2437 | { |
| 2438 | // we should be careful and map back any rom overlay (hint) and backup ram too I think... |
| 2439 | |
| 2440 | // this is actually blank / nop area |
| 2441 | // we should also map the banked area back (we don't currently unmap it tho) |
| 2442 | memory_install_rom(space, 0x0000100, 0x03fffff, 0, 0, memory_region(space->machine, "maincpu")+0x100); |
| 2443 | } |
| 2444 | |
| 2425 | 2445 | //printf("_32x_68k_a15106_w %04x\n", data); |
| 2426 | 2446 | /* |
| 2427 | 2447 | if (a15106_reg & 0x4) |
| r9263 | r9264 | |
| 3087 | 3107 | |
| 3088 | 3108 | static READ16_HANDLER( _32x_sh2_common_4006_r ) |
| 3089 | 3109 | { |
| 3090 | | printf("DREQ read!\n"); |
| 3110 | //printf("DREQ read!\n"); // tempo reads it, shut up for now |
| 3091 | 3111 | return 0; |
| 3092 | 3112 | } |
| 3093 | 3113 | |
| r9263 | r9264 | |
| 6810 | 6830 | |
| 6811 | 6831 | ROM_REGION16_BE( 0x400000, "maincpu", ROMREGION_ERASE00 ) |
| 6812 | 6832 | // temp, rom should only be visible here when one of the regs is set, tempo needs it |
| 6813 | | ROM_COPY( "gamecart", 0x0, 0x0, 0x400000) |
| 6814 | 6833 | ROM_COPY( "32x_68k_bios", 0x0, 0x0, 0x100) |
| 6815 | 6834 | |
| 6816 | 6835 | ROM_REGION( 0x400000, "32x_master_sh2", 0 ) /* SH2 Code */ |
src/emu/cpu/sh2/sh2comn.c
| r9263 | r9264 | |
| 106 | 106 | } |
| 107 | 107 | } |
| 108 | 108 | |
| 109 | |
| 109 | 110 | static TIMER_CALLBACK( sh2_timer_callback ) |
| 110 | 111 | { |
| 111 | 112 | sh2_state *sh2 = (sh2_state *)ptr; |
| r9263 | r9264 | |
| 157 | 158 | */ |
| 158 | 159 | |
| 159 | 160 | |
| 161 | |
| 162 | void sh2_notify_dma_data_available(running_device *device) |
| 163 | { |
| 164 | sh2_state *sh2 = GET_SH2(device); |
| 165 | //printf("call notify\n"); |
| 166 | |
| 167 | for (int dma=0;dma<2;dma++) |
| 168 | { |
| 169 | //printf("sh2->dma_timer_active[dma] %04x\n",sh2->dma_timer_active[dma]); |
| 170 | |
| 171 | if (sh2->dma_timer_active[dma]==2) // 2 = stalled |
| 172 | { |
| 173 | // printf("resuming stalled dma\n"); |
| 174 | sh2->dma_timer_active[dma]=1; |
| 175 | timer_adjust_oneshot(sh2->dma_current_active_timer[dma], attotime_zero, dma); |
| 176 | } |
| 177 | } |
| 178 | |
| 179 | } |
| 180 | |
| 160 | 181 | void sh2_do_dma(sh2_state *sh2, int dma) |
| 161 | 182 | { |
| 162 | 183 | UINT32 dmadata; |
| r9263 | r9264 | |
| 165 | 186 | |
| 166 | 187 | if (sh2->active_dma_count[dma] > 0) |
| 167 | 188 | { |
| 168 | | #ifdef USE_TIMER_FOR_DMA |
| 169 | | //schedule next DMA callback |
| 170 | | timer_adjust_oneshot(sh2->dma_current_active_timer[dma], sh2->device->cycles_to_attotime(2), dma); |
| 171 | | #endif |
| 172 | 189 | |
| 190 | |
| 173 | 191 | // process current DMA |
| 174 | 192 | switch(sh2->active_dma_size[dma]) |
| 175 | 193 | { |
| r9263 | r9264 | |
| 194 | 212 | int available = sh2->dma_callback_fifo_data_available(tempsrc, tempdst, 0, sh2->active_dma_size[dma]); |
| 195 | 213 | |
| 196 | 214 | if (!available) |
| 215 | { |
| 216 | //printf("dma stalled\n"); |
| 217 | sh2->dma_timer_active[dma]=2;// mark as stalled |
| 197 | 218 | return; |
| 219 | } |
| 198 | 220 | } |
| 199 | | |
| 221 | |
| 222 | #ifdef USE_TIMER_FOR_DMA |
| 223 | //schedule next DMA callback |
| 224 | timer_adjust_oneshot(sh2->dma_current_active_timer[dma], sh2->device->cycles_to_attotime(2), dma); |
| 225 | #endif |
| 226 | |
| 200 | 227 | |
| 201 | 228 | dmadata = sh2->program->read_byte(tempsrc); |
| 202 | 229 | if (sh2->dma_callback_kludge) dmadata = sh2->dma_callback_kludge(tempsrc, tempdst, dmadata, sh2->active_dma_size[dma]); |
| r9263 | r9264 | |
| 233 | 260 | int available = sh2->dma_callback_fifo_data_available(tempsrc, tempdst, 0, sh2->active_dma_size[dma]); |
| 234 | 261 | |
| 235 | 262 | if (!available) |
| 263 | { |
| 264 | //printf("dma stalled\n"); |
| 265 | sh2->dma_timer_active[dma]=2;// mark as stalled |
| 236 | 266 | return; |
| 267 | } |
| 237 | 268 | } |
| 238 | 269 | |
| 270 | #ifdef USE_TIMER_FOR_DMA |
| 271 | //schedule next DMA callback |
| 272 | timer_adjust_oneshot(sh2->dma_current_active_timer[dma], sh2->device->cycles_to_attotime(2), dma); |
| 273 | #endif |
| 274 | |
| 239 | 275 | // check: should this really be using read_word_32 / write_word_32? |
| 240 | 276 | dmadata = sh2->program->read_word(tempsrc); |
| 241 | 277 | if (sh2->dma_callback_kludge) dmadata = sh2->dma_callback_kludge(tempsrc, tempdst, dmadata, sh2->active_dma_size[dma]); |
| r9263 | r9264 | |
| 271 | 307 | int available = sh2->dma_callback_fifo_data_available(tempsrc, tempdst, 0, sh2->active_dma_size[dma]); |
| 272 | 308 | |
| 273 | 309 | if (!available) |
| 310 | { |
| 311 | //printf("dma stalled\n"); |
| 312 | sh2->dma_timer_active[dma]=2;// mark as stalled |
| 274 | 313 | return; |
| 314 | } |
| 275 | 315 | } |
| 276 | 316 | |
| 317 | #ifdef USE_TIMER_FOR_DMA |
| 318 | //schedule next DMA callback |
| 319 | timer_adjust_oneshot(sh2->dma_current_active_timer[dma], sh2->device->cycles_to_attotime(2), dma); |
| 320 | #endif |
| 321 | |
| 277 | 322 | dmadata = sh2->program->read_dword(tempsrc); |
| 278 | 323 | if (sh2->dma_callback_kludge) dmadata = sh2->dma_callback_kludge(tempsrc, tempdst, dmadata, sh2->active_dma_size[dma]); |
| 279 | 324 | sh2->program->write_dword(tempdst, dmadata); |
| r9263 | r9264 | |
| 307 | 352 | int available = sh2->dma_callback_fifo_data_available(tempsrc, tempdst, 0, sh2->active_dma_size[dma]); |
| 308 | 353 | |
| 309 | 354 | if (!available) |
| 355 | { |
| 356 | //printf("dma stalled\n"); |
| 357 | sh2->dma_timer_active[dma]=2;// mark as stalled |
| 310 | 358 | fatalerror("SH2 dma_callback_fifo_data_available == 0 in unsupported mode"); |
| 359 | } |
| 311 | 360 | } |
| 312 | 361 | |
| 362 | #ifdef USE_TIMER_FOR_DMA |
| 363 | //schedule next DMA callback |
| 364 | timer_adjust_oneshot(sh2->dma_current_active_timer[dma], sh2->device->cycles_to_attotime(2), dma); |
| 365 | #endif |
| 366 | |
| 313 | 367 | dmadata = sh2->program->read_dword(tempsrc); |
| 314 | 368 | if (sh2->dma_callback_kludge) dmadata = sh2->dma_callback_kludge(tempsrc, tempdst, dmadata, sh2->active_dma_size[dma]); |
| 315 | 369 | sh2->program->write_dword(tempdst, dmadata); |