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 0	/* QUASI88 */
89 	if (YM2203Init(intf->num,intf->baseclock,Machine->sample_rate,TimerHandler,IRQHandler) == 0)
90 #else	/* QUASI88 */
91 	if (YM2203Init(intf->num,intf->baseclock,Machine->sample_rate,0,0) == 0)
92 #endif	/* QUASI88 */
93 	{
94 		/* Ready */
95 		return 0;
96 	}
97 	/* error */
98 	/* stream close */
99 	return 1;
100 }
101 
YM2203_sh_stop(void)102 void YM2203_sh_stop(void)
103 {
104 	YM2203Shutdown();
105 	AY8910_sh_stop_ym();
106 }
107 
YM2203_sh_reset(void)108 void YM2203_sh_reset(void)
109 {
110 	int i;
111 
112 	for (i = 0;i < intf->num;i++)
113 		YM2203ResetChip(i);
114 }
115 
116 
117 
READ_HANDLER(YM2203_status_port_0_r)118 READ_HANDLER( YM2203_status_port_0_r ) { return YM2203Read(0,0); }
READ_HANDLER(YM2203_status_port_1_r)119 READ_HANDLER( YM2203_status_port_1_r ) { return YM2203Read(1,0); }
READ_HANDLER(YM2203_status_port_2_r)120 READ_HANDLER( YM2203_status_port_2_r ) { return YM2203Read(2,0); }
READ_HANDLER(YM2203_status_port_3_r)121 READ_HANDLER( YM2203_status_port_3_r ) { return YM2203Read(3,0); }
READ_HANDLER(YM2203_status_port_4_r)122 READ_HANDLER( YM2203_status_port_4_r ) { return YM2203Read(4,0); }
123 
READ_HANDLER(YM2203_read_port_0_r)124 READ_HANDLER( YM2203_read_port_0_r ) { return YM2203Read(0,1); }
READ_HANDLER(YM2203_read_port_1_r)125 READ_HANDLER( YM2203_read_port_1_r ) { return YM2203Read(1,1); }
READ_HANDLER(YM2203_read_port_2_r)126 READ_HANDLER( YM2203_read_port_2_r ) { return YM2203Read(2,1); }
READ_HANDLER(YM2203_read_port_3_r)127 READ_HANDLER( YM2203_read_port_3_r ) { return YM2203Read(3,1); }
READ_HANDLER(YM2203_read_port_4_r)128 READ_HANDLER( YM2203_read_port_4_r ) { return YM2203Read(4,1); }
129 
WRITE_HANDLER(YM2203_control_port_0_w)130 WRITE_HANDLER( YM2203_control_port_0_w )
131 {
132 	YM2203Write(0,0,data);
133 }
WRITE_HANDLER(YM2203_control_port_1_w)134 WRITE_HANDLER( YM2203_control_port_1_w )
135 {
136 	YM2203Write(1,0,data);
137 }
WRITE_HANDLER(YM2203_control_port_2_w)138 WRITE_HANDLER( YM2203_control_port_2_w )
139 {
140 	YM2203Write(2,0,data);
141 }
WRITE_HANDLER(YM2203_control_port_3_w)142 WRITE_HANDLER( YM2203_control_port_3_w )
143 {
144 	YM2203Write(3,0,data);
145 }
WRITE_HANDLER(YM2203_control_port_4_w)146 WRITE_HANDLER( YM2203_control_port_4_w )
147 {
148 	YM2203Write(4,0,data);
149 }
150 
WRITE_HANDLER(YM2203_write_port_0_w)151 WRITE_HANDLER( YM2203_write_port_0_w )
152 {
153 	YM2203Write(0,1,data);
154 }
WRITE_HANDLER(YM2203_write_port_1_w)155 WRITE_HANDLER( YM2203_write_port_1_w )
156 {
157 	YM2203Write(1,1,data);
158 }
WRITE_HANDLER(YM2203_write_port_2_w)159 WRITE_HANDLER( YM2203_write_port_2_w )
160 {
161 	YM2203Write(2,1,data);
162 }
WRITE_HANDLER(YM2203_write_port_3_w)163 WRITE_HANDLER( YM2203_write_port_3_w )
164 {
165 	YM2203Write(3,1,data);
166 }
WRITE_HANDLER(YM2203_write_port_4_w)167 WRITE_HANDLER( YM2203_write_port_4_w )
168 {
169 	YM2203Write(4,1,data);
170 }
171 
WRITE_HANDLER(YM2203_word_0_w)172 WRITE_HANDLER( YM2203_word_0_w )
173 {
174 	if (offset)
175 		YM2203_write_port_0_w(0,data);
176 	else
177 		YM2203_control_port_0_w(0,data);
178 }
179 
WRITE_HANDLER(YM2203_word_1_w)180 WRITE_HANDLER( YM2203_word_1_w )
181 {
182 	if (offset)
183 		YM2203_write_port_1_w(0,data);
184 	else
185 		YM2203_control_port_1_w(0,data);
186 }
187