1 #include <math.h>
2 #include "driver.h"
3 #include "ay8910.h"
4 #include "fm.h"
5
6
7 static int stream[MAX_2203];
8
9 static const struct YM2203interface *intf;
10
11 static void *Timer[MAX_2203][2];
12
13 /* IRQ Handler */
IRQHandler(int n,int irq)14 static void IRQHandler(int n,int irq)
15 {
16 if(intf->handler[n]) intf->handler[n](irq);
17 }
18
19 /* Timer overflow callback from timer.c */
timer_callback_2203(int param)20 static void timer_callback_2203(int param)
21 {
22 int n=param&0x7f;
23 int c=param>>7;
24
25 YM2203TimerOver(n,c);
26 }
27
28 /* update request from fm.c */
YM2203UpdateRequest(int chip)29 void YM2203UpdateRequest(int chip)
30 {
31 stream_update(stream[chip],0);
32 }
33
34 #if 0
35 /* update callback from stream.c */
36 static void YM2203UpdateCallback(int chip,void *buffer,int length)
37 {
38 YM2203UpdateOne(chip,buffer,length);
39 }
40 #endif
41
42 /* TimerHandler from fm.c */
TimerHandler(int n,int c,int count,double stepTime)43 static void TimerHandler(int n,int c,int count,double stepTime)
44 {
45 if( count == 0 )
46 { /* Reset FM Timer */
47 timer_enable(Timer[n][c], 0);
48 }
49 else
50 { /* Start FM Timer */
51 double timeSec = (double)count * stepTime;
52 if (!timer_enable(Timer[n][c], 1))
53 timer_adjust(Timer[n][c], timeSec, (c<<7)|n, 0);
54 }
55 }
56
FMTimerInit(void)57 static void FMTimerInit( void )
58 {
59 int i;
60
61 for( i = 0 ; i < MAX_2203 ; i++ )
62 {
63 Timer[i][0] = timer_alloc(timer_callback_2203);
64 Timer[i][1] = timer_alloc(timer_callback_2203);
65 }
66 }
67
YM2203_sh_start(const struct MachineSound * msound)68 int YM2203_sh_start(const struct MachineSound *msound)
69 {
70 int i;
71
72 if (AY8910_sh_start_ym(msound)) return 1;
73
74 intf = msound->sound_interface;
75
76 /* Timer Handler set */
77 FMTimerInit();
78 /* stream system initialize */
79 for (i = 0;i < intf->num;i++)
80 {
81 int volume;
82 char name[20];
83 sprintf(name,"%s #%d FM",sound_name(msound),i);
84 volume = intf->mixing_level[i]>>16; /* high 16 bit */
85 stream[i] = stream_init(name,volume,Machine->sample_rate,i,YM2203UpdateOne/*YM2203UpdateCallback*/);
86 }
87 /* Initialize FM emurator */
88 if (YM2203Init(intf->num,intf->baseclock,Machine->sample_rate,TimerHandler,IRQHandler) == 0)
89 {
90 /* Ready */
91 return 0;
92 }
93 /* error */
94 /* stream close */
95 return 1;
96 }
97
YM2203_sh_stop(void)98 void YM2203_sh_stop(void)
99 {
100 YM2203Shutdown();
101 AY8910_sh_stop_ym();
102 }
103
YM2203_sh_reset(void)104 void YM2203_sh_reset(void)
105 {
106 int i;
107
108 for (i = 0;i < intf->num;i++)
109 YM2203ResetChip(i);
110 }
111
112
113
READ_HANDLER(YM2203_status_port_0_r)114 READ_HANDLER( YM2203_status_port_0_r ) { return YM2203Read(0,0); }
READ_HANDLER(YM2203_status_port_1_r)115 READ_HANDLER( YM2203_status_port_1_r ) { return YM2203Read(1,0); }
READ_HANDLER(YM2203_status_port_2_r)116 READ_HANDLER( YM2203_status_port_2_r ) { return YM2203Read(2,0); }
READ_HANDLER(YM2203_status_port_3_r)117 READ_HANDLER( YM2203_status_port_3_r ) { return YM2203Read(3,0); }
READ_HANDLER(YM2203_status_port_4_r)118 READ_HANDLER( YM2203_status_port_4_r ) { return YM2203Read(4,0); }
119
READ_HANDLER(YM2203_read_port_0_r)120 READ_HANDLER( YM2203_read_port_0_r ) { return YM2203Read(0,1); }
READ_HANDLER(YM2203_read_port_1_r)121 READ_HANDLER( YM2203_read_port_1_r ) { return YM2203Read(1,1); }
READ_HANDLER(YM2203_read_port_2_r)122 READ_HANDLER( YM2203_read_port_2_r ) { return YM2203Read(2,1); }
READ_HANDLER(YM2203_read_port_3_r)123 READ_HANDLER( YM2203_read_port_3_r ) { return YM2203Read(3,1); }
READ_HANDLER(YM2203_read_port_4_r)124 READ_HANDLER( YM2203_read_port_4_r ) { return YM2203Read(4,1); }
125
WRITE_HANDLER(YM2203_control_port_0_w)126 WRITE_HANDLER( YM2203_control_port_0_w )
127 {
128 YM2203Write(0,0,data);
129 }
WRITE_HANDLER(YM2203_control_port_1_w)130 WRITE_HANDLER( YM2203_control_port_1_w )
131 {
132 YM2203Write(1,0,data);
133 }
WRITE_HANDLER(YM2203_control_port_2_w)134 WRITE_HANDLER( YM2203_control_port_2_w )
135 {
136 YM2203Write(2,0,data);
137 }
WRITE_HANDLER(YM2203_control_port_3_w)138 WRITE_HANDLER( YM2203_control_port_3_w )
139 {
140 YM2203Write(3,0,data);
141 }
WRITE_HANDLER(YM2203_control_port_4_w)142 WRITE_HANDLER( YM2203_control_port_4_w )
143 {
144 YM2203Write(4,0,data);
145 }
146
WRITE_HANDLER(YM2203_write_port_0_w)147 WRITE_HANDLER( YM2203_write_port_0_w )
148 {
149 YM2203Write(0,1,data);
150 }
WRITE_HANDLER(YM2203_write_port_1_w)151 WRITE_HANDLER( YM2203_write_port_1_w )
152 {
153 YM2203Write(1,1,data);
154 }
WRITE_HANDLER(YM2203_write_port_2_w)155 WRITE_HANDLER( YM2203_write_port_2_w )
156 {
157 YM2203Write(2,1,data);
158 }
WRITE_HANDLER(YM2203_write_port_3_w)159 WRITE_HANDLER( YM2203_write_port_3_w )
160 {
161 YM2203Write(3,1,data);
162 }
WRITE_HANDLER(YM2203_write_port_4_w)163 WRITE_HANDLER( YM2203_write_port_4_w )
164 {
165 YM2203Write(4,1,data);
166 }
167
WRITE_HANDLER(YM2203_word_0_w)168 WRITE_HANDLER( YM2203_word_0_w )
169 {
170 if (offset)
171 YM2203_write_port_0_w(0,data);
172 else
173 YM2203_control_port_0_w(0,data);
174 }
175
WRITE_HANDLER(YM2203_word_1_w)176 WRITE_HANDLER( YM2203_word_1_w )
177 {
178 if (offset)
179 YM2203_write_port_1_w(0,data);
180 else
181 YM2203_control_port_1_w(0,data);
182 }
183