src/mame/drivers/megadriv.c
| r9282 | r9283 | |
| 2331 | 2331 | int fifo_block_a_full; |
| 2332 | 2332 | int fifo_block_b_full; |
| 2333 | 2333 | |
| 2334 | | static READ16_HANDLER( _32x_68k_a15112_r) |
| 2335 | | { |
| 2336 | | printf("read write-only FIFO register\n"); |
| 2337 | | return 0; |
| 2338 | | } |
| 2339 | 2334 | |
| 2340 | | static WRITE16_HANDLER( _32x_68k_a15112_w ) |
| 2341 | | { |
| 2342 | | //printf("write to FIFO %04x!\n", data); |
| 2343 | 2335 | |
| 2344 | | if (current_fifo_block==fifo_block_a && fifo_block_a_full) |
| 2345 | | { |
| 2346 | | printf("attempt to write to Full Fifo block a!\n"); |
| 2347 | | return; |
| 2348 | | } |
| 2349 | 2336 | |
| 2350 | | if (current_fifo_block==fifo_block_b && fifo_block_b_full) |
| 2351 | | { |
| 2352 | | printf("attempt to write to Full Fifo block b!\n"); |
| 2353 | | return; |
| 2354 | | } |
| 2355 | | |
| 2356 | | current_fifo_block[current_fifo_write_pos] = data; |
| 2357 | | current_fifo_write_pos++; |
| 2358 | | |
| 2359 | | if (current_fifo_write_pos==4) |
| 2360 | | { |
| 2361 | | if (current_fifo_block==fifo_block_a) |
| 2362 | | { |
| 2363 | | fifo_block_a_full = 1; |
| 2364 | | if (!fifo_block_b_full) |
| 2365 | | { |
| 2366 | | current_fifo_block = fifo_block_b; |
| 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 | | |
| 2372 | | } |
| 2373 | | current_fifo_write_pos = 0; |
| 2374 | | } |
| 2375 | | else |
| 2376 | | { |
| 2377 | | fifo_block_b_full = 1; |
| 2378 | | |
| 2379 | | if (!fifo_block_a_full) |
| 2380 | | { |
| 2381 | | current_fifo_block = fifo_block_a; |
| 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 | | |
| 2387 | | } |
| 2388 | | |
| 2389 | | current_fifo_write_pos = 0; |
| 2390 | | } |
| 2391 | | } |
| 2392 | | } |
| 2393 | | |
| 2394 | | |
| 2395 | | |
| 2396 | 2337 | /* |
| 2397 | 2338 | |
| 2398 | 2339 | 15106 DREQ |
| r9282 | r9283 | |
| 2460 | 2401 | |
| 2461 | 2402 | static UINT16 dreq_src_addr[2],dreq_dst_addr[2],dreq_size; |
| 2462 | 2403 | |
| 2463 | | static READ16_HANDLER( _32x_68k_a15108_r ) |
| 2404 | static READ16_HANDLER( _32x_dreq_common_r ) |
| 2464 | 2405 | { |
| 2465 | | return dreq_src_addr[offset]; |
| 2466 | | } |
| 2406 | address_space* _68kspace = cputag_get_address_space(space->machine, "maincpu", ADDRESS_SPACE_PROGRAM); |
| 2467 | 2407 | |
| 2468 | | static WRITE16_HANDLER( _32x_68k_a15108_w ) |
| 2469 | | { |
| 2470 | | dreq_src_addr[offset] = (offset == 0) ? (data & 0xff) : (data & 0xfffe); |
| 2408 | switch (offset) |
| 2409 | { |
| 2410 | case 0x00/2: // a15108 / 4008 |
| 2411 | case 0x02/2: // a1510a / 400a |
| 2412 | return dreq_src_addr[offset&1]; |
| 2471 | 2413 | |
| 2472 | | if((dreq_src_addr[0]<<16)|dreq_src_addr[1]) |
| 2473 | | printf("DREQ set SRC = %08x\n",(dreq_src_addr[0]<<16)|dreq_src_addr[1]); |
| 2474 | | } |
| 2414 | case 0x04/2: // a1510c / 400c |
| 2415 | case 0x06/2: // a1510e / 400e |
| 2416 | return dreq_dst_addr[offset&1]; |
| 2475 | 2417 | |
| 2476 | | static READ16_HANDLER( _32x_68k_a1510c_r ) |
| 2477 | | { |
| 2478 | | return dreq_dst_addr[offset]; |
| 2479 | | } |
| 2418 | case 0x08/2: // a15110 / 4010 |
| 2419 | return dreq_size; |
| 2480 | 2420 | |
| 2481 | | static WRITE16_HANDLER( _32x_68k_a1510c_w ) |
| 2482 | | { |
| 2483 | | dreq_dst_addr[offset] = (offset == 0) ? (data & 0xff) : (data & 0xffff); |
| 2421 | case 0x0a/2: // a15112 / 4012 |
| 2422 | if (space == _68kspace) |
| 2423 | { |
| 2424 | printf("attempting to READ FIFO with 68k!\n"); |
| 2425 | return 0xffff; |
| 2426 | } |
| 2484 | 2427 | |
| 2485 | | if((dreq_dst_addr[0]<<16)|dreq_dst_addr[1]) |
| 2486 | | printf("DREQ set DST = %08x\n",(dreq_dst_addr[0]<<16)|dreq_dst_addr[1]); |
| 2487 | | } |
| 2428 | UINT16 retdat = current_fifo_readblock[current_fifo_read_pos]; |
| 2488 | 2429 | |
| 2489 | | static READ16_HANDLER( _32x_68k_a15110_r ) |
| 2490 | | { |
| 2491 | | return dreq_size; |
| 2430 | current_fifo_read_pos++; |
| 2431 | |
| 2432 | // printf("reading FIFO!\n"); |
| 2433 | |
| 2434 | if (current_fifo_readblock == fifo_block_a && !fifo_block_a_full) |
| 2435 | printf("Fifo block a isn't filled!\n"); |
| 2436 | |
| 2437 | if (current_fifo_readblock == fifo_block_b && !fifo_block_b_full) |
| 2438 | printf("Fifo block b isn't filled!\n"); |
| 2439 | |
| 2440 | |
| 2441 | if (current_fifo_read_pos==4) |
| 2442 | { |
| 2443 | if (current_fifo_readblock == fifo_block_a) |
| 2444 | { |
| 2445 | fifo_block_a_full = 0; |
| 2446 | |
| 2447 | if (fifo_block_b_full) |
| 2448 | { |
| 2449 | current_fifo_readblock = fifo_block_b; |
| 2450 | current_fifo_block = fifo_block_a; |
| 2451 | } |
| 2452 | |
| 2453 | current_fifo_read_pos = 0; |
| 2454 | } |
| 2455 | else if (current_fifo_readblock == fifo_block_b) |
| 2456 | { |
| 2457 | fifo_block_b_full = 0; |
| 2458 | |
| 2459 | if (fifo_block_a_full) |
| 2460 | { |
| 2461 | current_fifo_readblock = fifo_block_a; |
| 2462 | current_fifo_block = fifo_block_b; |
| 2463 | } |
| 2464 | |
| 2465 | current_fifo_read_pos = 0; |
| 2466 | } |
| 2467 | } |
| 2468 | |
| 2469 | return retdat; |
| 2470 | } |
| 2471 | |
| 2472 | return 0x0000; |
| 2492 | 2473 | } |
| 2493 | 2474 | |
| 2494 | | static WRITE16_HANDLER( _32x_68k_a15110_w ) |
| 2475 | static WRITE16_HANDLER( _32x_dreq_common_w ) |
| 2495 | 2476 | { |
| 2496 | | dreq_size = data & 0xfffc; |
| 2477 | address_space* _68kspace = cputag_get_address_space(space->machine, "maincpu", ADDRESS_SPACE_PROGRAM); |
| 2497 | 2478 | |
| 2498 | | // if(dreq_size) |
| 2499 | | // printf("DREQ set SIZE = %04x\n",dreq_size); |
| 2500 | | } |
| 2479 | switch (offset) |
| 2480 | { |
| 2481 | case 0x00/2: // a15108 / 4008 |
| 2482 | case 0x02/2: // a1510a / 400a |
| 2483 | dreq_src_addr[offset&1] = ((offset&1) == 0) ? (data & 0xff) : (data & 0xfffe); |
| 2501 | 2484 | |
| 2502 | | /* |
| 2503 | | a1511a SEGA TV register |
| 2504 | | ---- ---x Cartridge Mode (0) ROM (1) DRAM |
| 2485 | if((dreq_src_addr[0]<<16)|dreq_src_addr[1]) |
| 2486 | printf("DREQ set SRC = %08x\n",(dreq_src_addr[0]<<16)|dreq_src_addr[1]); |
| 2505 | 2487 | |
| 2506 | | Sega disallows the use of this register |
| 2488 | break; |
| 2507 | 2489 | |
| 2508 | | */ |
| 2490 | case 0x04/2: // a1510c / 400c |
| 2491 | case 0x06/2: // a1510e / 400e |
| 2492 | dreq_dst_addr[offset&1] = ((offset&1) == 0) ? (data & 0xff) : (data & 0xffff); |
| 2509 | 2493 | |
| 2494 | if((dreq_dst_addr[0]<<16)|dreq_dst_addr[1]) |
| 2495 | printf("DREQ set DST = %08x\n",(dreq_dst_addr[0]<<16)|dreq_dst_addr[1]); |
| 2496 | |
| 2497 | break; |
| 2498 | |
| 2499 | case 0x08/2: // a15110 / 4010 |
| 2500 | dreq_size = data & 0xfffc; |
| 2501 | |
| 2502 | // if(dreq_size) |
| 2503 | // printf("DREQ set SIZE = %04x\n",dreq_size); |
| 2504 | |
| 2505 | break; |
| 2506 | |
| 2507 | case 0x0a/2: // a15112 / 4012 - FIFO Write (68k only!) |
| 2508 | if (space != _68kspace) |
| 2509 | { |
| 2510 | printf("attempting to WRITE FIFO with SH2!\n"); |
| 2511 | return; |
| 2512 | } |
| 2513 | |
| 2514 | if (current_fifo_block==fifo_block_a && fifo_block_a_full) |
| 2515 | { |
| 2516 | printf("attempt to write to Full Fifo block a!\n"); |
| 2517 | return; |
| 2518 | } |
| 2519 | |
| 2520 | if (current_fifo_block==fifo_block_b && fifo_block_b_full) |
| 2521 | { |
| 2522 | printf("attempt to write to Full Fifo block b!\n"); |
| 2523 | return; |
| 2524 | } |
| 2525 | |
| 2526 | current_fifo_block[current_fifo_write_pos] = data; |
| 2527 | current_fifo_write_pos++; |
| 2528 | |
| 2529 | if (current_fifo_write_pos==4) |
| 2530 | { |
| 2531 | if (current_fifo_block==fifo_block_a) |
| 2532 | { |
| 2533 | fifo_block_a_full = 1; |
| 2534 | if (!fifo_block_b_full) |
| 2535 | { |
| 2536 | current_fifo_block = fifo_block_b; |
| 2537 | current_fifo_readblock = fifo_block_a; |
| 2538 | // incase we have a stalled DMA in progress, let the SH2 know there is data available |
| 2539 | sh2_notify_dma_data_available(space->machine->device("32x_master_sh2")); |
| 2540 | sh2_notify_dma_data_available(space->machine->device("32x_slave_sh2")); |
| 2541 | |
| 2542 | } |
| 2543 | current_fifo_write_pos = 0; |
| 2544 | } |
| 2545 | else |
| 2546 | { |
| 2547 | fifo_block_b_full = 1; |
| 2548 | |
| 2549 | if (!fifo_block_a_full) |
| 2550 | { |
| 2551 | current_fifo_block = fifo_block_a; |
| 2552 | current_fifo_readblock = fifo_block_b; |
| 2553 | // incase we have a stalled DMA in progress, let the SH2 know there is data available |
| 2554 | sh2_notify_dma_data_available(space->machine->device("32x_master_sh2")); |
| 2555 | sh2_notify_dma_data_available(space->machine->device("32x_slave_sh2")); |
| 2556 | |
| 2557 | } |
| 2558 | |
| 2559 | current_fifo_write_pos = 0; |
| 2560 | } |
| 2561 | } |
| 2562 | |
| 2563 | break; |
| 2564 | } |
| 2565 | } |
| 2566 | |
| 2567 | |
| 2510 | 2568 | static UINT8 sega_tv; |
| 2511 | 2569 | |
| 2512 | 2570 | static READ16_HANDLER( _32x_68k_a1511a_r ) |
| r9282 | r9283 | |
| 2820 | 2878 | |
| 2821 | 2879 | if (megadrive_hblank_flag) retdata |= 0x4000; |
| 2822 | 2880 | |
| 2823 | | if (megadrive_vblank_flag && _32x_access_auth) { retdata |= 2; } // framebuffer approval (TODO: condition is unknown at current time) |
| 2881 | if (megadrive_vblank_flag) { retdata |= 2; } // framebuffer approval (TODO: condition is unknown at current time) |
| 2824 | 2882 | |
| 2825 | 2883 | if (megadrive_hblank_flag && megadrive_vblank_flag) { retdata |= 0x2000; } // palette approval (TODO: active high or low?) |
| 2826 | 2884 | |
| r9282 | r9283 | |
| 3095 | 3153 | printf("DREQ write!\n"); |
| 3096 | 3154 | } |
| 3097 | 3155 | |
| 3098 | | /**********************************************************************************************/ |
| 3099 | | // SH2 side 4008 |
| 3100 | | // 68k To SH2 DReq Source Address Register ( High Bits ) |
| 3101 | | /**********************************************************************************************/ |
| 3102 | 3156 | |
| 3103 | 3157 | /**********************************************************************************************/ |
| 3104 | | // SH2 side 400A |
| 3105 | | // 68k To SH2 DReq Source Address Register ( Low Bits ) |
| 3106 | | /**********************************************************************************************/ |
| 3107 | | |
| 3108 | | /**********************************************************************************************/ |
| 3109 | | // SH2 side 400C |
| 3110 | | // 68k To SH2 DReq Destination Address Register ( High Bits ) |
| 3111 | | /**********************************************************************************************/ |
| 3112 | | |
| 3113 | | /**********************************************************************************************/ |
| 3114 | | // SH2 side 400E |
| 3115 | | // 68k To SH2 DReq Destination Address Register ( Low Bits ) |
| 3116 | | /**********************************************************************************************/ |
| 3117 | | |
| 3118 | | /**********************************************************************************************/ |
| 3119 | | // SH2 side 4010 |
| 3120 | | // 68k To SH2 DReq Length Register |
| 3121 | | /**********************************************************************************************/ |
| 3122 | | |
| 3123 | | static READ16_HANDLER( _32x_sh2_common_4010_r ) |
| 3124 | | { |
| 3125 | | // printf("reading DReq Length!\n"); |
| 3126 | | return 0x0000; |
| 3127 | | } |
| 3128 | | |
| 3129 | | /**********************************************************************************************/ |
| 3130 | | // SH2 side 4012 |
| 3131 | | // FIFO Register (read) |
| 3132 | | /**********************************************************************************************/ |
| 3133 | | |
| 3134 | | static READ16_HANDLER( _32x_sh2_common_4012_r ) |
| 3135 | | { |
| 3136 | | UINT16 retdat = current_fifo_readblock[current_fifo_read_pos]; |
| 3137 | | |
| 3138 | | current_fifo_read_pos++; |
| 3139 | | |
| 3140 | | // printf("reading FIFO!\n"); |
| 3141 | | |
| 3142 | | if (current_fifo_readblock == fifo_block_a && !fifo_block_a_full) |
| 3143 | | printf("Fifo block a isn't filled!\n"); |
| 3144 | | |
| 3145 | | if (current_fifo_readblock == fifo_block_b && !fifo_block_b_full) |
| 3146 | | printf("Fifo block b isn't filled!\n"); |
| 3147 | | |
| 3148 | | |
| 3149 | | if (current_fifo_read_pos==4) |
| 3150 | | { |
| 3151 | | if (current_fifo_readblock == fifo_block_a) |
| 3152 | | { |
| 3153 | | fifo_block_a_full = 0; |
| 3154 | | |
| 3155 | | if (fifo_block_b_full) |
| 3156 | | { |
| 3157 | | current_fifo_readblock = fifo_block_b; |
| 3158 | | current_fifo_block = fifo_block_a; |
| 3159 | | } |
| 3160 | | |
| 3161 | | current_fifo_read_pos = 0; |
| 3162 | | } |
| 3163 | | else if (current_fifo_readblock == fifo_block_b) |
| 3164 | | { |
| 3165 | | fifo_block_b_full = 0; |
| 3166 | | |
| 3167 | | if (fifo_block_a_full) |
| 3168 | | { |
| 3169 | | current_fifo_readblock = fifo_block_a; |
| 3170 | | current_fifo_block = fifo_block_b; |
| 3171 | | } |
| 3172 | | |
| 3173 | | current_fifo_read_pos = 0; |
| 3174 | | } |
| 3175 | | } |
| 3176 | | |
| 3177 | | return retdat; |
| 3178 | | } |
| 3179 | | |
| 3180 | | |
| 3181 | | |
| 3182 | | /**********************************************************************************************/ |
| 3183 | 3158 | // SH2 side 4014 |
| 3184 | 3159 | // VRES (md reset button interrupt) clear |
| 3185 | 3160 | /**********************************************************************************************/ |
| r9282 | r9283 | |
| 3410 | 3385 | _32X_MAP_READHANDLERS(pwm_control_reg,pwm_cycle_reg) |
| 3411 | 3386 | _32X_MAP_WRITEHANDLERS(pwm_control_reg,pwm_cycle_reg) |
| 3412 | 3387 | |
| 3413 | | _32X_MAP_READHANDLERS(common_4010,common_4012) |
| 3414 | 3388 | |
| 3415 | | |
| 3416 | 3389 | _32X_MAP_RAM_READHANDLERS(framebuffer_dram) // _32x_sh2_framebuffer_dram_r |
| 3417 | 3390 | _32X_MAP_RAM_WRITEHANDLERS(framebuffer_dram) // _32x_sh2_framebuffer_dram_w |
| 3418 | 3391 | |
| r9282 | r9283 | |
| 3433 | 3406 | AM_RANGE(0x00004000, 0x00004003) AM_READWRITE( _32x_sh2_master_4000_common_4002_r, _32x_sh2_master_4000_common_4002_w ) |
| 3434 | 3407 | AM_RANGE(0x00004004, 0x00004007) AM_READWRITE( _32x_sh2_common_4004_common_4006_r, _32x_sh2_common_4004_common_4006_w) |
| 3435 | 3408 | |
| 3436 | | AM_RANGE(0x00004010, 0x00004013) AM_READ( _32x_sh2_common_4010_common_4012_r ) |
| 3409 | AM_RANGE(0x00004008, 0x00004013) AM_READWRITE16( _32x_dreq_common_r, _32x_dreq_common_w, 0xffffffff ) |
| 3437 | 3410 | |
| 3438 | 3411 | AM_RANGE(0x00004014, 0x00004017) AM_READNOP AM_WRITE( _32x_sh2_master_4014_master_4016_w ) // IRQ clear |
| 3439 | 3412 | AM_RANGE(0x00004018, 0x0000401b) AM_READNOP AM_WRITE( _32x_sh2_master_4018_master_401a_w ) // IRQ clear |
| r9282 | r9283 | |
| 3463 | 3436 | AM_RANGE(0x00004000, 0x00004003) AM_READWRITE( _32x_sh2_slave_4000_common_4002_r, _32x_sh2_slave_4000_common_4002_w ) |
| 3464 | 3437 | AM_RANGE(0x00004004, 0x00004007) AM_READWRITE( _32x_sh2_common_4004_common_4006_r, _32x_sh2_common_4004_common_4006_w) |
| 3465 | 3438 | |
| 3466 | | AM_RANGE(0x00004010, 0x00004013) AM_READ( _32x_sh2_common_4010_common_4012_r ) |
| 3439 | AM_RANGE(0x00004008, 0x00004013) AM_READWRITE16( _32x_dreq_common_r, _32x_dreq_common_w, 0xffffffff ) |
| 3467 | 3440 | |
| 3468 | 3441 | AM_RANGE(0x00004014, 0x00004017) AM_READNOP AM_WRITE( _32x_sh2_slave_4014_slave_4016_w ) // IRQ clear |
| 3469 | 3442 | AM_RANGE(0x00004018, 0x0000401b) AM_READNOP AM_WRITE( _32x_sh2_slave_4018_slave_401a_w ) // IRQ clear |
| r9282 | r9283 | |
| 6620 | 6593 | memory_install_readwrite16_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0xa15102, 0xa15103, 0, 0, _32x_68k_a15102_r, _32x_68k_a15102_w); // send irq to sh2 |
| 6621 | 6594 | memory_install_readwrite16_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0xa15104, 0xa15105, 0, 0, _32x_68k_a15104_r, _32x_68k_a15104_w); // 68k BANK rom set |
| 6622 | 6595 | memory_install_readwrite16_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0xa15106, 0xa15107, 0, 0, _32x_68k_a15106_r, _32x_68k_a15106_w); // dreq stuff |
| 6623 | | memory_install_readwrite16_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0xa15108, 0xa1510b, 0, 0, _32x_68k_a15108_r, _32x_68k_a15108_w); // dreq src address |
| 6624 | | memory_install_readwrite16_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0xa1510c, 0xa1510f, 0, 0, _32x_68k_a1510c_r, _32x_68k_a1510c_w); // dreq dst address |
| 6625 | | memory_install_readwrite16_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0xa15110, 0xa15111, 0, 0, _32x_68k_a15110_r, _32x_68k_a15110_w); // dreq length |
| 6626 | | memory_install_readwrite16_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0xa15112, 0xa15113, 0, 0, _32x_68k_a15112_r, _32x_68k_a15112_w); // fifo |
| 6596 | memory_install_readwrite16_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0xa15108, 0xa15113, 0, 0, _32x_dreq_common_r, _32x_dreq_common_w); // dreq src / dst / length /fifo |
| 6627 | 6597 | |
| 6628 | 6598 | memory_install_readwrite16_handler(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), 0xa1511a, 0xa1511b, 0, 0, _32x_68k_a1511a_r, _32x_68k_a1511a_w); // SEGA TV |
| 6629 | 6599 | |