1 // Time pilot, pooyan, rallyx, tutankhm, and rocnrope sound
2 // Based on MAME driver by Nicola Salmoria
3 
4 #include "burnint.h"
5 #include "z80_intf.h"
6 #include "flt_rc.h"
7 #include "ay8910.h"
8 
9 static UINT8 soundlatch;
10 static UINT8 *z80rom;
11 static UINT8 *z80ram;
12 static INT32 z80_select = 0;
13 static INT32 locomotnmode = 0;
14 
filter_write(INT32 num,UINT8 d)15 static void filter_write(INT32 num, UINT8 d)
16 {
17 	INT32 C = 0;
18 	if (d & 1) C += 220000;	/* 220000pF = 0.220uF */
19 	if (d & 2) C +=  47000;	/*  47000pF = 0.047uF */
20 	filter_rc_set_RC(num, FLT_RC_LOWPASS, 1000, 5100, 0, CAP_P(C));
21 }
22 
timeplt_sound_write(UINT16 address,UINT8 data)23 static void __fastcall timeplt_sound_write(UINT16 address, UINT8 data)
24 {
25 	//bprintf(0, _T("tpsw %X %X\n"), address, data);
26 	if (!locomotnmode && address >= 0x8000 /*&& address <= 0xffff*/) {
27 		INT32 Offset = address & 0xfff;
28 		filter_write(3, (Offset >>  0) & 3);
29 		filter_write(4, (Offset >>  2) & 3);
30 		filter_write(5, (Offset >>  4) & 3);
31 		filter_write(0, (Offset >>  6) & 3);
32 		filter_write(1, (Offset >>  8) & 3);
33 		filter_write(2, (Offset >> 10) & 3);
34 		return;
35 	}
36 
37 	if (locomotnmode && address >= 0x3000 && address <= 0x3fff) {
38 		INT32 Offset = address & 0xfff;
39 		filter_write(3, (Offset >>  0) & 3);
40 		filter_write(4, (Offset >>  2) & 3);
41 		filter_write(5, (Offset >>  4) & 3);
42 		filter_write(0, (Offset >>  6) & 3);
43 		filter_write(1, (Offset >>  8) & 3);
44 		filter_write(2, (Offset >> 10) & 3);
45 		return;
46 	}
47 
48 	switch (address & 0xf000)
49 	{
50 		case 0x4000:
51 			AY8910Write(0, 1, data);
52 		return;
53 
54 		case 0x5000:
55 			AY8910Write(0, 0, data);
56 		return;
57 
58 		case 0x6000:
59 			AY8910Write(1, 1, data);
60 		return;
61 
62 		case 0x7000:
63 			AY8910Write(1, 0, data);
64 		return;
65 	}
66 }
67 
timeplt_sound_read(UINT16 address)68 static UINT8 __fastcall timeplt_sound_read(UINT16 address)
69 {
70 	switch (address & 0xf000)
71 	{
72 		case 0x4000:
73 			return AY8910Read(0);
74 
75 		case 0x6000:
76 			return AY8910Read(1);
77 	}
78 
79 	return 0;
80 }
81 
AY8910_0_portA(UINT32)82 static UINT8 AY8910_0_portA(UINT32)
83 {
84 	ZetSetIRQLine(0, CPU_IRQSTATUS_NONE);
85 	return soundlatch;
86 }
87 
AY8910_0_portB(UINT32)88 static UINT8 AY8910_0_portB(UINT32)
89 {
90 	static const int timeplt_timer[10] = {
91 		0x00, 0x10, 0x20, 0x30, 0x40, 0x90, 0xa0, 0xb0, 0xa0, 0xd0
92 	};
93 
94 	return timeplt_timer[(ZetTotalCycles() >> 9) % 10];
95 }
96 
TimepltSndSoundlatch(UINT8 data)97 void TimepltSndSoundlatch(UINT8 data)
98 {
99 	soundlatch = data;
100 }
101 
TimepltSndReset()102 void TimepltSndReset()
103 {
104 	ZetOpen(z80_select);
105 	ZetReset();
106 	ZetClose();
107 
108 	AY8910Reset(0);
109 	AY8910Reset(1);
110 	soundlatch = 0;
111 }
112 
TimepltSndInit(UINT8 * rom,UINT8 * ram,INT32 z80number)113 void TimepltSndInit(UINT8 *rom, UINT8 *ram, INT32 z80number)
114 {
115 	z80rom = rom;
116 	z80ram = ram;
117 	z80_select = z80number;
118 
119 	ZetInit(z80_select);
120 	ZetOpen(z80_select);
121 	ZetMapMemory(z80rom,	0x0000, 0x2fff, MAP_ROM);
122 	ZetMapMemory(z80ram,	0x3000, 0x33ff, MAP_RAM);
123 	ZetMapMemory(z80ram,	0x3400, 0x37ff, MAP_RAM);
124 	ZetMapMemory(z80ram,	0x3800, 0x3bff, MAP_RAM);
125 	ZetMapMemory(z80ram,	0x3c00, 0x3fff, MAP_RAM);
126 	ZetSetWriteHandler(timeplt_sound_write);
127 	ZetSetReadHandler(timeplt_sound_read);
128 	ZetClose();
129 
130 	AY8910Init(0, 1789772, 0);
131 	AY8910Init(1, 1789772, 1);
132 	AY8910SetPorts(0, &AY8910_0_portA, &AY8910_0_portB, NULL, NULL);
133 	AY8910SetAllRoutes(0, 0.30, BURN_SND_ROUTE_BOTH);
134 	AY8910SetAllRoutes(1, 0.30, BURN_SND_ROUTE_BOTH);
135 
136 	filter_rc_init(0, FLT_RC_LOWPASS, 1000, 5100, 0, CAP_P(0), 0);
137 	filter_rc_init(1, FLT_RC_LOWPASS, 1000, 5100, 0, CAP_P(0), 1);
138 	filter_rc_init(2, FLT_RC_LOWPASS, 1000, 5100, 0, CAP_P(0), 1);
139 	filter_rc_init(3, FLT_RC_LOWPASS, 1000, 5100, 0, CAP_P(0), 1);
140 	filter_rc_init(4, FLT_RC_LOWPASS, 1000, 5100, 0, CAP_P(0), 1);
141 	filter_rc_init(5, FLT_RC_LOWPASS, 1000, 5100, 0, CAP_P(0), 1);
142 
143 	filter_rc_set_route(0, 1.00, BURN_SND_ROUTE_BOTH);
144 	filter_rc_set_route(1, 1.00, BURN_SND_ROUTE_BOTH);
145 	filter_rc_set_route(2, 1.00, BURN_SND_ROUTE_BOTH);
146 	filter_rc_set_route(3, 1.00, BURN_SND_ROUTE_BOTH);
147 	filter_rc_set_route(4, 1.00, BURN_SND_ROUTE_BOTH);
148 	filter_rc_set_route(5, 1.00, BURN_SND_ROUTE_BOTH);
149 	locomotnmode = 0;
150 }
151 
LocomotnSndInit(UINT8 * rom,UINT8 * ram,INT32 z80number)152 void LocomotnSndInit(UINT8 *rom, UINT8 *ram, INT32 z80number)
153 {
154 	z80rom = rom;
155 	z80ram = ram;
156 	z80_select = z80number;
157 
158 	ZetInit(z80_select);
159 	ZetOpen(z80_select);
160 	ZetMapMemory(z80rom,	0x0000, 0x1fff, MAP_ROM);
161 	ZetMapMemory(z80ram,	0x2000, 0x23ff, MAP_RAM);
162 	ZetMapMemory(z80ram,	0x2400, 0x27ff, MAP_RAM);
163 	ZetMapMemory(z80ram,	0x2800, 0x2bff, MAP_RAM);
164 	ZetMapMemory(z80ram,	0x2c00, 0x2fff, MAP_RAM);
165 	ZetSetWriteHandler(timeplt_sound_write);
166 	ZetSetReadHandler(timeplt_sound_read);
167 	ZetClose();
168 
169 	AY8910Init(0, 1789772, 0);
170 	AY8910Init(1, 1789772, 1);
171 	AY8910SetPorts(0, &AY8910_0_portA, &AY8910_0_portB, NULL, NULL);
172 	AY8910SetAllRoutes(0, 0.30, BURN_SND_ROUTE_BOTH);
173 	AY8910SetAllRoutes(1, 0.30, BURN_SND_ROUTE_BOTH);
174 
175 	filter_rc_init(0, FLT_RC_LOWPASS, 1000, 5100, 0, CAP_P(0), 0);
176 	filter_rc_init(1, FLT_RC_LOWPASS, 1000, 5100, 0, CAP_P(0), 1);
177 	filter_rc_init(2, FLT_RC_LOWPASS, 1000, 5100, 0, CAP_P(0), 1);
178 	filter_rc_init(3, FLT_RC_LOWPASS, 1000, 5100, 0, CAP_P(0), 1);
179 	filter_rc_init(4, FLT_RC_LOWPASS, 1000, 5100, 0, CAP_P(0), 1);
180 	filter_rc_init(5, FLT_RC_LOWPASS, 1000, 5100, 0, CAP_P(0), 1);
181 
182 	filter_rc_set_route(0, 1.00, BURN_SND_ROUTE_BOTH);
183 	filter_rc_set_route(1, 1.00, BURN_SND_ROUTE_BOTH);
184 	filter_rc_set_route(2, 1.00, BURN_SND_ROUTE_BOTH);
185 	filter_rc_set_route(3, 1.00, BURN_SND_ROUTE_BOTH);
186 	filter_rc_set_route(4, 1.00, BURN_SND_ROUTE_BOTH);
187 	filter_rc_set_route(5, 1.00, BURN_SND_ROUTE_BOTH);
188 	locomotnmode = 1;
189 }
190 
TimepltSndVol(double vol0,double vol1)191 void TimepltSndVol(double vol0, double vol1)
192 {
193 	filter_rc_set_route(0, vol0, BURN_SND_ROUTE_BOTH);
194 	filter_rc_set_route(1, vol0, BURN_SND_ROUTE_BOTH);
195 	filter_rc_set_route(2, vol0, BURN_SND_ROUTE_BOTH);
196 	filter_rc_set_route(3, vol1, BURN_SND_ROUTE_BOTH);
197 	filter_rc_set_route(4, vol1, BURN_SND_ROUTE_BOTH);
198 	filter_rc_set_route(5, vol1, BURN_SND_ROUTE_BOTH);
199 }
200 
TimepltSndSrcGain(double vol)201 void TimepltSndSrcGain(double vol)
202 {
203 	filter_rc_set_src_gain(0, vol);
204 	filter_rc_set_src_gain(1, vol);
205 	filter_rc_set_src_gain(2, vol);
206 	filter_rc_set_src_gain(3, vol);
207 	filter_rc_set_src_gain(4, vol);
208 	filter_rc_set_src_gain(5, vol);
209 }
210 
TimepltSndExit()211 void TimepltSndExit()
212 {
213 	if (z80_select == 0) ZetExit();
214 
215 	AY8910Exit(0);
216 	AY8910Exit(1);
217 	filter_rc_exit();
218 
219 	z80_select = 0;
220 	z80rom = NULL;
221 	z80ram = NULL;
222 	locomotnmode = 0;
223 }
224 
TimepltSndUpdate(INT16 * pSoundBuf,INT32 nSegmentLength)225 void TimepltSndUpdate(INT16 *pSoundBuf, INT32 nSegmentLength)
226 {
227 	if (nSegmentLength <= 0) return;
228 
229 	AY8910RenderInternal(nSegmentLength);
230 
231 	filter_rc_update(0, pAY8910Buffer[0], pSoundBuf, nSegmentLength);
232 	filter_rc_update(1, pAY8910Buffer[1], pSoundBuf, nSegmentLength);
233 	filter_rc_update(2, pAY8910Buffer[2], pSoundBuf, nSegmentLength);
234 	filter_rc_update(3, pAY8910Buffer[3], pSoundBuf, nSegmentLength);
235 	filter_rc_update(4, pAY8910Buffer[4], pSoundBuf, nSegmentLength);
236 	filter_rc_update(5, pAY8910Buffer[5], pSoundBuf, nSegmentLength);
237 }
238 
TimepltSndScan(INT32 nAction,INT32 * pnMin)239 INT32 TimepltSndScan(INT32 nAction, INT32 *pnMin)
240 {
241 	if (nAction & ACB_VOLATILE) {
242 		if (z80_select == 0) ZetScan(nAction);
243 		AY8910Scan(nAction, pnMin);
244 
245 		SCAN_VAR(soundlatch);
246 	}
247 
248 	return 0;
249 }
250