src/mame/drivers/megadriv.c
| r9287 | r9288 | |
| 2761 | 2761 | // access from the SH2 via 4030 - 403f |
| 2762 | 2762 | /**********************************************************************************************/ |
| 2763 | 2763 | |
| 2764 | #define PWM_FIFO_SIZE pwm_tm_reg // guess, check this (Doom wants 3, Virtua Racing wants 1 like they sets this register?) |
| 2765 | |
| 2764 | 2766 | static UINT16 pwm_ctrl,pwm_cycle,pwm_tm_reg; |
| 2765 | | static UINT16 cur_lch,cur_rch; |
| 2767 | static UINT16 cur_lch[0x10],cur_rch[0x10]; |
| 2766 | 2768 | static UINT16 pwm_cycle_reg; //used for latching |
| 2767 | 2769 | static UINT8 pwm_timer_tick; |
| 2770 | static UINT8 lch_index_r,rch_index_r,lch_index_w,rch_index_w; |
| 2768 | 2771 | static UINT16 lch_fifo_state,rch_fifo_state; |
| 2769 | 2772 | |
| 2770 | 2773 | static emu_timer *_32x_pwm_timer; |
| 2771 | 2774 | |
| 2772 | | |
| 2773 | 2775 | static void calculate_pwm_timer(void) |
| 2774 | 2776 | { |
| 2775 | 2777 | if(pwm_tm_reg == 0) { pwm_tm_reg = 16; } // zero gives max range |
| r9287 | r9288 | |
| 2782 | 2784 | { |
| 2783 | 2785 | pwm_timer_tick = 0; |
| 2784 | 2786 | lch_fifo_state = rch_fifo_state = 0x4000; |
| 2787 | lch_index_r = rch_index_r = 0; |
| 2788 | lch_index_w = rch_index_w = 0; |
| 2785 | 2789 | timer_adjust_oneshot(_32x_pwm_timer, ATTOTIME_IN_HZ(((MASTER_CLOCK_NTSC*3 / 7) / (pwm_cycle - 1))), 0); |
| 2786 | 2790 | } |
| 2787 | 2791 | } |
| 2788 | 2792 | |
| 2789 | 2793 | static TIMER_CALLBACK( _32x_pwm_callback ) |
| 2790 | 2794 | { |
| 2791 | | if(lch_fifo_state == 0x8000) |
| 2795 | if(lch_index_r < PWM_FIFO_SIZE) |
| 2792 | 2796 | { |
| 2793 | | lch_fifo_state = 0x4000; |
| 2794 | | dac_data_16_w(machine->device("lch_pwm"), cur_lch); |
| 2797 | dac_signed_data_16_w(machine->device("lch_pwm"), cur_lch[lch_index_r++]); |
| 2798 | lch_index_w = 0; |
| 2795 | 2799 | } |
| 2796 | | if(rch_fifo_state == 0x8000) |
| 2800 | |
| 2801 | lch_fifo_state = (lch_index_r == PWM_FIFO_SIZE) ? 0x4000 : 0x0000; |
| 2802 | |
| 2803 | if(rch_index_r < PWM_FIFO_SIZE) |
| 2797 | 2804 | { |
| 2798 | | rch_fifo_state = 0x4000; |
| 2799 | | dac_data_16_w(machine->device("rch_pwm"), cur_rch); |
| 2805 | dac_signed_data_16_w(machine->device("rch_pwm"), cur_rch[rch_index_r++]); |
| 2806 | rch_index_w = 0; |
| 2800 | 2807 | } |
| 2801 | 2808 | |
| 2809 | rch_fifo_state = (rch_index_r == PWM_FIFO_SIZE) ? 0x4000 : 0x0000; |
| 2810 | |
| 2802 | 2811 | pwm_timer_tick++; |
| 2803 | 2812 | |
| 2804 | 2813 | if(pwm_timer_tick == pwm_tm_reg) |
| r9287 | r9288 | |
| 2840 | 2849 | calculate_pwm_timer(); |
| 2841 | 2850 | break; |
| 2842 | 2851 | case 0x04/2: |
| 2843 | | cur_lch = ((data & 0xfff) << 4); |
| 2844 | | lch_fifo_state = 0x8000; |
| 2852 | if(lch_index_w < PWM_FIFO_SIZE) |
| 2853 | { |
| 2854 | cur_lch[lch_index_w++] = ((data & 0xfff) << 4) | (data & 0xf); |
| 2855 | lch_index_r = 0; |
| 2856 | } |
| 2857 | |
| 2858 | lch_fifo_state = (lch_index_w == PWM_FIFO_SIZE) ? 0x8000 : 0x0000; |
| 2845 | 2859 | break; |
| 2846 | 2860 | case 0x06/2: |
| 2847 | | cur_rch = ((data & 0xfff) << 4); |
| 2848 | | rch_fifo_state = 0x8000; |
| 2861 | if(rch_index_w < PWM_FIFO_SIZE) |
| 2862 | { |
| 2863 | cur_rch[rch_index_w++] = ((data & 0xfff) << 4) | (data & 0xf); |
| 2864 | rch_index_r = 0; |
| 2865 | } |
| 2866 | |
| 2867 | rch_fifo_state = (rch_index_w == PWM_FIFO_SIZE) ? 0x8000 : 0x0000; |
| 2868 | |
| 2849 | 2869 | break; |
| 2850 | 2870 | case 0x08/2: |
| 2851 | | cur_lch = ((data & 0xfff) << 4); |
| 2852 | | cur_rch = ((data & 0xfff) << 4); |
| 2853 | | lch_fifo_state = rch_fifo_state = 0x8000; |
| 2871 | if(lch_index_w < PWM_FIFO_SIZE) |
| 2872 | { |
| 2873 | cur_lch[lch_index_w++] = ((data & 0xfff) << 4) | (data & 0xf); |
| 2874 | lch_index_r = 0; |
| 2875 | } |
| 2876 | |
| 2877 | if(rch_index_w < PWM_FIFO_SIZE) |
| 2878 | { |
| 2879 | cur_rch[rch_index_w++] = ((data & 0xfff) << 4) | (data & 0xf); |
| 2880 | rch_index_r = 0; |
| 2881 | } |
| 2882 | |
| 2883 | lch_fifo_state = (lch_index_w == PWM_FIFO_SIZE) ? 0x8000 : 0x0000; |
| 2884 | rch_fifo_state = (rch_index_w == PWM_FIFO_SIZE) ? 0x8000 : 0x0000; |
| 2885 | |
| 2854 | 2886 | break; |
| 2855 | 2887 | default: |
| 2856 | 2888 | printf("Write at undefined PWM register %02x %04x\n",offset,data); |
| r9287 | r9288 | |
| 6326 | 6358 | MDRV_QUANTUM_TIME(HZ(1800000)) |
| 6327 | 6359 | |
| 6328 | 6360 | MDRV_SOUND_ADD("lch_pwm", DAC, 0) |
| 6329 | | MDRV_SOUND_ROUTE(0, "lspeaker", 0.75) |
| 6361 | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.75) |
| 6330 | 6362 | |
| 6331 | 6363 | MDRV_SOUND_ADD("rch_pwm", DAC, 0) |
| 6332 | | MDRV_SOUND_ROUTE(0, "rspeaker", 0.75) |
| 6364 | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.75) |
| 6333 | 6365 | MACHINE_CONFIG_END |
| 6334 | 6366 | |
| 6335 | 6367 | |
| r9287 | r9288 | |
| 6349 | 6381 | // boosting the interleave here actually makes Kolibri run incorrectly however, that |
| 6350 | 6382 | // one works best just boosting the interleave on communications?! |
| 6351 | 6383 | MDRV_QUANTUM_TIME(HZ(1800000)) |
| 6384 | |
| 6385 | MDRV_SOUND_ADD("lch_pwm", DAC, 0) |
| 6386 | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.75) |
| 6387 | |
| 6388 | MDRV_SOUND_ADD("rch_pwm", DAC, 0) |
| 6389 | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.75) |
| 6352 | 6390 | MACHINE_CONFIG_END |
| 6353 | 6391 | |
| 6354 | 6392 | MACHINE_CONFIG_DERIVED( genesis_scd, megadriv ) |