1 /***************************************************************************
2
3 -= Seta Games =-
4
5 driver by Luca Elia (eliavit@unina.it)
6
7
8 Sound Chip:
9
10 X1-010 [Seta Custom]
11 Unsigned 16 Bit PCM [Fixed Per Game Pitch?]
12 16 Voices [There's More Data Written!]
13
14 Format:
15
16 8 registers per channel (mapped to the lower bytes of 16 words on the 68K)
17
18 Reg: Bits: Meaning:
19
20 0 7654 321-
21 ---- ---0 Key On / Off
22
23 1 7654 ---- Volume 1(L?)
24 ---- 3210 Volume 2(R?)
25
26 2 ? (high byte?)
27 3 ? (low byte?)
28
29 4 Sample Start / 0x1000 [Start/End in bytes]
30 5 0x100 - (Sample End / 0x1000) [PCM ROM is Max 1MB?]
31
32 6 ?
33 7 ?
34
35
36 Hardcoded Values (for now):
37
38 PCM ROM region: REGION_SOUND1
39 Sample Frequency: 4, 6, 8 KHz
40
41 ***************************************************************************/
42 #include "driver.h"
43
44 /* Variables and functions that driver has access to */
45 unsigned char *seta_sound_ram;
46
47 #define SETA_NUM_CHANNELS 16
48
49 /* Variables only used here */
50 static int firstchannel, frequency;
51 static int seta_reg[SETA_NUM_CHANNELS][8];
52
53
54
55
seta_sh_start(const struct MachineSound * msound)56 int seta_sh_start(const struct MachineSound *msound)
57 {
58 int i;
59 int vol[MIXER_MAX_CHANNELS];
60
61 for (i = 0;i < MIXER_MAX_CHANNELS;i++) vol[i] = 100;
62 firstchannel = mixer_allocate_channels(SETA_NUM_CHANNELS,vol);
63
64 for (i = 0; i < SETA_NUM_CHANNELS; i++)
65 {
66 char buf[40];
67 sprintf(buf,"X1-010 Channel #%d",i);
68 mixer_set_name(firstchannel + i,buf);
69 }
70 return 0;
71 }
72
seta_sh_start_4KHz(const struct MachineSound * msound)73 int seta_sh_start_4KHz(const struct MachineSound *msound)
74 {
75 frequency = 4000;
76 return seta_sh_start(msound);
77 }
78
seta_sh_start_6KHz(const struct MachineSound * msound)79 int seta_sh_start_6KHz(const struct MachineSound *msound)
80 {
81 frequency = 6000;
82 return seta_sh_start(msound);
83 }
84
seta_sh_start_8KHz(const struct MachineSound * msound)85 int seta_sh_start_8KHz(const struct MachineSound *msound)
86 {
87 frequency = 8000;
88 return seta_sh_start(msound);
89 }
90
91
92
93 /* Use these for 8 bit CPUs */
94
95
READ_HANDLER(seta_sound_r)96 READ_HANDLER( seta_sound_r )
97 {
98 int channel = offset / 8;
99 int reg = offset % 8;
100
101 if (channel < SETA_NUM_CHANNELS)
102 {
103 switch (reg)
104 {
105 case 0:
106 return ( mixer_is_sample_playing(firstchannel + channel) ? 1 : 0 );
107 default:
108 //logerror("PC: %06X - X1-010 channel %X, register %X read!\n",cpu_get_pc(),channel,reg);
109 return seta_reg[channel][reg];
110 }
111 }
112
113 return seta_sound_ram[offset];
114 }
115
116
117
118
119 #define DUMP_REGS \
120 logerror("X1-010 REGS: ch %X] %02X %02X %02X %02X - %02X %02X %02X %02X\n", \
121 channel, \
122 seta_reg[channel][0],seta_reg[channel][1], \
123 seta_reg[channel][2],seta_reg[channel][3], \
124 seta_reg[channel][4],seta_reg[channel][5], \
125 seta_reg[channel][6],seta_reg[channel][7] );
126
127
WRITE_HANDLER(seta_sound_w)128 WRITE_HANDLER( seta_sound_w )
129 {
130 int channel, reg;
131
132 seta_sound_ram[offset] = data;
133
134 if (Machine->sample_rate == 0) return;
135
136 channel = offset / 8;
137 reg = offset % 8;
138
139 if (channel >= SETA_NUM_CHANNELS) return;
140
141 seta_reg[channel][reg] = data & 0xff;
142
143 switch (reg)
144 {
145
146 case 0:
147
148 //DUMP_REGS
149
150 if (data & 1) // key on
151 {
152 int volume = seta_reg[channel][1];
153
154 int start = seta_reg[channel][4] * 0x1000;
155 int end = (0x100 - seta_reg[channel][5]) * 0x1000; // from the end of the rom
156
157 int len = end - start;
158 int maxlen = memory_region_length(REGION_SOUND1);
159
160 if (!( (start < end) && (end <= maxlen) ))
161 {
162 //logerror("PC: %06X - X1-010 OUT OF RANGE SAMPLE: %06X - %06X, channel %X\n",cpu_get_pc(),start,end,channel);
163 //DUMP_REGS
164 return;
165 }
166
167 #if 1
168 /* Print some more debug info */
169 //logerror("PC: %06X - Play 16 bit sample %06X - %06X, channel %X\n",cpu_get_pc(),start, end, channel);
170 //DUMP_REGS
171 #endif
172
173 /*
174 Twineagl continuosly writes 1 to reg 0 of the channel, so
175 the sample is restarted every time and never plays to the
176 end. It looks like the previous sample must be explicitly
177 stopped before a new one can be played
178 */
179 if ( seta_sound_r(offset) & 1 ) return; // play to the end
180
181 /* These samples are probaly looped and use the 3rd & 4th register's value */
182 if (data & 2) return;
183
184 /* left and right speaker's volume can be set indipendently.
185 We use a mean volume for now */
186 mixer_set_volume(firstchannel + channel, ((volume & 0xf)+(volume >> 4))*100/(2*0xf) );
187
188 /* I assume the pitch is fixed for a given board. It ranges
189 from 4 to 8 KHz for the games I've seen */
190
191 mixer_play_sample_16(
192 firstchannel + channel,
193 (short *) (memory_region(REGION_SOUND1) + start), // start
194 len, // len
195 frequency, // frequency
196 0); // loop
197 }
198 else
199 mixer_stop_sample(channel + firstchannel);
200
201 break;
202
203 }
204 }
205
206
207
208
209
210 /* Use these for 16 bit CPUs */
211
READ_HANDLER(seta_sound_word_r)212 READ_HANDLER( seta_sound_word_r )
213 {
214 return seta_sound_r(offset/2) & 0xff;
215 }
216
WRITE_HANDLER(seta_sound_word_w)217 WRITE_HANDLER( seta_sound_word_w )
218 {
219 if ( (data & 0x00ff0000) == 0 )
220 seta_sound_w(offset/2, data & 0xff);
221 }
222