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