1 /***************************************************************************
2
3 2608intf.c
4
5 The YM2608 emulator supports up to 2 chips.
6 Each chip has the following connections:
7 - Status Read / Control Write A
8 - Port Read / Data Write A
9 - Control Write B
10 - Data Write B
11
12 ***************************************************************************/
13
14 #include "driver.h"
15 #include "ay8910.h"
16 #include "2608intf.h"
17 #include "fm.h"
18
19 #ifdef BUILD_YM2608
20
21 #define YM2608_NUMBUF 2
22 /* use FM.C with stream system */
23
24 static int stream[MAX_2608];
25
26 /* Global Interface holder */
27 static const struct YM2608interface *intf;
28
29 static void *Timer[MAX_2608][2];
30
31
32 /* IRQ Handler */
IRQHandler(int n,int irq)33 static void IRQHandler(int n,int irq)
34 {
35 if(intf->handler[n]) intf->handler[n](irq);
36 }
37
38 /* Timer overflow callback from timer.c */
timer_callback_2608(int param)39 static void timer_callback_2608(int param)
40 {
41 int n=param&0x7f;
42 int c=param>>7;
43
44 YM2608TimerOver(n,c);
45 }
46
47 /* TimerHandler from fm.c */
TimerHandler(int n,int c,int count,double stepTime)48 static void TimerHandler(int n,int c,int count,double stepTime)
49 {
50 if( count == 0 )
51 { /* Reset FM Timer */
52 timer_enable(Timer[n][c], 0);
53 }
54 else
55 { /* Start FM Timer */
56 double timeSec = (double)count * stepTime;
57 if (!timer_enable(Timer[n][c], 1))
58 timer_adjust(Timer[n][c], timeSec, (c<<7)|n, 0);
59 }
60 }
61
FMTimerInit(void)62 static void FMTimerInit( void )
63 {
64 int i;
65
66 for( i = 0 ; i < MAX_2608 ; i++ )
67 {
68 Timer[i][0] = timer_alloc(timer_callback_2608);
69 Timer[i][1] = timer_alloc(timer_callback_2608);
70 }
71 }
72
73 /* update request from fm.c */
YM2608UpdateRequest(int chip)74 void YM2608UpdateRequest(int chip)
75 {
76 stream_update(stream[chip],100);
77 }
78
YM2608_sh_start(const struct MachineSound * msound)79 int YM2608_sh_start(const struct MachineSound *msound)
80 {
81 int i,j;
82 int rate = Machine->sample_rate;
83 char buf[YM2608_NUMBUF][40];
84 const char *name[YM2608_NUMBUF];
85 int mixed_vol,vol[YM2608_NUMBUF];
86 void *pcmbufa[YM2608_NUMBUF];
87 int pcmsizea[YM2608_NUMBUF];
88
89
90 intf = msound->sound_interface;
91 if( intf->num > MAX_2608 ) return 1;
92
93 if (AY8910_sh_start_ym(msound)) return 1;
94
95 /* Timer Handler set */
96 FMTimerInit();
97
98 /* stream system initialize */
99 for (i = 0;i < intf->num;i++)
100 {
101 /* stream setup */
102 mixed_vol = intf->volumeFM[i];
103 /* stream setup */
104 for (j = 0 ; j < YM2608_NUMBUF ; j++)
105 {
106 name[j]=buf[j];
107 vol[j] = mixed_vol & 0xffff;
108 mixed_vol>>=16;
109 sprintf(buf[j],"%s #%d Ch%d",sound_name(msound),i,j+1);
110 }
111 stream[i] = stream_init_multi(YM2608_NUMBUF,name,vol,rate,i,YM2608UpdateOne);
112 /* setup adpcm buffers */
113 pcmbufa[i] = (void *)(memory_region(intf->pcmrom[i]));
114 pcmsizea[i] = memory_region_length(intf->pcmrom[i]);
115 }
116
117
118 /* initialize YM2608 */
119 if (YM2608Init(intf->num,intf->baseclock,rate,
120 pcmbufa,pcmsizea,
121 TimerHandler,IRQHandler) == 0)
122 return 0;
123
124 /* error */
125 return 1;
126 }
127
128 /************************************************/
129 /* Sound Hardware Stop */
130 /************************************************/
YM2608_sh_stop(void)131 void YM2608_sh_stop(void)
132 {
133 YM2608Shutdown();
134 AY8910_sh_stop_ym();
135 }
136 /* reset */
YM2608_sh_reset(void)137 void YM2608_sh_reset(void)
138 {
139 int i;
140
141 for (i = 0;i < intf->num;i++)
142 YM2608ResetChip(i);
143 }
144
145 /************************************************/
146 /* Status Read for YM2608 - Chip 0 */
147 /************************************************/
READ_HANDLER(YM2608_status_port_0_A_r)148 READ_HANDLER( YM2608_status_port_0_A_r )
149 {
150 //logerror("PC %04x: 2608 S0A=%02X\n",activecpu_get_pc(),YM2608Read(0,0));
151 return YM2608Read(0,0);
152 }
153
READ_HANDLER(YM2608_status_port_0_B_r)154 READ_HANDLER( YM2608_status_port_0_B_r )
155 {
156 //logerror("PC %04x: 2608 S0B=%02X\n",activecpu_get_pc(),YM2608Read(0,2));
157 return YM2608Read(0,2);
158 }
159
160 /************************************************/
161 /* Status Read for YM2608 - Chip 1 */
162 /************************************************/
READ_HANDLER(YM2608_status_port_1_A_r)163 READ_HANDLER( YM2608_status_port_1_A_r ) {
164 return YM2608Read(1,0);
165 }
166
READ_HANDLER(YM2608_status_port_1_B_r)167 READ_HANDLER( YM2608_status_port_1_B_r ) {
168 return YM2608Read(1,2);
169 }
170
171 /************************************************/
172 /* Port Read for YM2608 - Chip 0 */
173 /************************************************/
READ_HANDLER(YM2608_read_port_0_r)174 READ_HANDLER( YM2608_read_port_0_r ){
175 return YM2608Read(0,1);
176 }
177
178 /************************************************/
179 /* Port Read for YM2608 - Chip 1 */
180 /************************************************/
READ_HANDLER(YM2608_read_port_1_r)181 READ_HANDLER( YM2608_read_port_1_r ){
182 return YM2608Read(1,1);
183 }
184
185 /************************************************/
186 /* Control Write for YM2608 - Chip 0 */
187 /* Consists of 2 addresses */
188 /************************************************/
WRITE_HANDLER(YM2608_control_port_0_A_w)189 WRITE_HANDLER( YM2608_control_port_0_A_w )
190 {
191 YM2608Write(0,0,data);
192 }
193
WRITE_HANDLER(YM2608_control_port_0_B_w)194 WRITE_HANDLER( YM2608_control_port_0_B_w )
195 {
196 YM2608Write(0,2,data);
197 }
198
199 /************************************************/
200 /* Control Write for YM2608 - Chip 1 */
201 /* Consists of 2 addresses */
202 /************************************************/
WRITE_HANDLER(YM2608_control_port_1_A_w)203 WRITE_HANDLER( YM2608_control_port_1_A_w ){
204 YM2608Write(1,0,data);
205 }
206
WRITE_HANDLER(YM2608_control_port_1_B_w)207 WRITE_HANDLER( YM2608_control_port_1_B_w ){
208 YM2608Write(1,2,data);
209 }
210
211 /************************************************/
212 /* Data Write for YM2608 - Chip 0 */
213 /* Consists of 2 addresses */
214 /************************************************/
WRITE_HANDLER(YM2608_data_port_0_A_w)215 WRITE_HANDLER( YM2608_data_port_0_A_w )
216 {
217 YM2608Write(0,1,data);
218 }
219
WRITE_HANDLER(YM2608_data_port_0_B_w)220 WRITE_HANDLER( YM2608_data_port_0_B_w )
221 {
222 YM2608Write(0,3,data);
223 }
224
225 /************************************************/
226 /* Data Write for YM2608 - Chip 1 */
227 /* Consists of 2 addresses */
228 /************************************************/
WRITE_HANDLER(YM2608_data_port_1_A_w)229 WRITE_HANDLER( YM2608_data_port_1_A_w ){
230 YM2608Write(1,1,data);
231 }
WRITE_HANDLER(YM2608_data_port_1_B_w)232 WRITE_HANDLER( YM2608_data_port_1_B_w ){
233 YM2608Write(1,3,data);
234 }
235
236 /**************** end of file ****************/
237
238 #endif
239