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