Skip to content

Commit 73f9ee8

Browse files
committed
* Setting Baud-Rate appears to not be needed, and does not compile correctly an multiple systems
* Reset by pin did not work due to firmware bug when only sending one byte of data, but it makes a clicking sound so we prefer to just set the OPL3 into a known state * OS X have bug in the USB serial buffering, so we must send smaller chunks at a time
1 parent 3f1f671 commit 73f9ee8

File tree

1 file changed

+76
-28
lines changed

1 file changed

+76
-28
lines changed

src/retrowave.cc

+76-28
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,12 @@ RetroWaveOpl::RetroWaveOpl(const char *filename)
9494
}
9595
cfmakeraw(&tio);
9696

97+
#if 0 /* setting the speed appears to not be needed, and 2000000 is not valid on all operating systems */
9798
#ifndef __APPLE__
9899
cfsetispeed(&tio, 2000000);
99100
cfsetospeed(&tio, 2000000);
100101
#endif
101-
102+
#endif
102103
if (tcgetattr(fd, &tio))
103104
{
104105
fprintf(stderr, "Failed to perform tcsetattr() on device %s, not a tty/serial device?: %s\n", filename, strerror(errno));
@@ -107,6 +108,7 @@ RetroWaveOpl::RetroWaveOpl(const char *filename)
107108
exit(EXIT_FAILURE);
108109
}
109110

111+
#if 0 /* setting the speed appears to not be needed, and 2000000 is not valid on all operating systems */
110112
#ifdef __APPLE__
111113
int speed = 2000000;
112114

@@ -115,17 +117,29 @@ RetroWaveOpl::RetroWaveOpl(const char *filename)
115117
fprintf(stderr, "Failed to set baudrate on device %s: %s", filename, strerror(errno));
116118
exit(EXIT_FAILURE);
117119
}
120+
#endif
118121
#endif
119122

120123
cmd_buffer[0] = 0x00;
121124
cmd_buffer_used=1;
122125
io_prepare();
123126
flush();
124127

128+
/* GPIOA.0 = /IC Initial clear (Reset)
129+
* GPIOA.1 = A0 Low=Address, High=Data
130+
* GPIOA.2 = A1 Low=Bank0, High=Bank1
131+
* GPIOA.3 = /WR Write enable
132+
* GPIOA.4 = /CS Chip Select
133+
* GPIOA.5 =
134+
* GPIOA.6 =
135+
* GPIOA.7 =
136+
* GPIOB[0:7] = D[0:7]
137+
*/
138+
125139
for (uint8_t i=0x20; i<0x28; i++)
126140
{
127141
cmd_prepare((uint8_t)(i<<1), 0x0a, 1); // IOCON register
128-
cmd_buffer[cmd_buffer_used++] = 0x28; // Enable: HAEN, SEQOP
142+
cmd_buffer[cmd_buffer_used++] = 0x28; // HAEN=1 SEQOP=1 BANK=0
129143
io_prepare();
130144
flush();
131145

@@ -172,24 +186,24 @@ void RetroWaveOpl::cmd_prepare(uint8_t io_addr, uint8_t io_reg, const int len)
172186

173187
void RetroWaveOpl::queue_port0(uint8_t reg, uint8_t val)
174188
{
175-
cmd_prepare(RetroWave_Board_OPL3, 0x12, 6);
189+
cmd_prepare(RetroWave_Board_OPL3, 0x12, 6); // GPIOA register
176190
cmd_buffer[cmd_buffer_used++] = 0xe1;
177191
cmd_buffer[cmd_buffer_used++] = reg;
178192
cmd_buffer[cmd_buffer_used++] = 0xe3;
179193
cmd_buffer[cmd_buffer_used++] = val;
180194
cmd_buffer[cmd_buffer_used++] = 0xfb;
181-
cmd_buffer[cmd_buffer_used++] = val;
195+
cmd_buffer[cmd_buffer_used++] = val; // Retrowave express OPL3 seems to only like even data writes
182196
}
183197

184198
void RetroWaveOpl::queue_port1(uint8_t reg, uint8_t val)
185199
{
186-
cmd_prepare(RetroWave_Board_OPL3, 0x12, 6);
200+
cmd_prepare(RetroWave_Board_OPL3, 0x12, 6); // GPIOA register
187201
cmd_buffer[cmd_buffer_used++] = 0xe5;
188202
cmd_buffer[cmd_buffer_used++] = reg;
189203
cmd_buffer[cmd_buffer_used++] = 0xe7;
190204
cmd_buffer[cmd_buffer_used++] = val;
191205
cmd_buffer[cmd_buffer_used++] = 0xfb;
192-
cmd_buffer[cmd_buffer_used++] = val;
206+
cmd_buffer[cmd_buffer_used++] = val; // Retrowave express OPL3 seems to only like even data writes
193207
}
194208

195209
void RetroWaveOpl::reset(void)
@@ -200,62 +214,83 @@ void RetroWaveOpl::reset(void)
200214
flush();
201215
}
202216

203-
cmd_prepare(RetroWave_Board_OPL3, 0x12, 1);
217+
#if 0 // reset by /IC, makes click sound
218+
cmd_prepare(RetroWave_Board_OPL3, 0x12, 1); // GPIOA register
204219
cmd_buffer[cmd_buffer_used++] = 0xfe;
220+
cmd_buffer[cmd_buffer_used++] = 0x00; // Retrowave express OPL3 seems to only like even data writes
205221
io_prepare();
206222
flush();
207223

208-
cmd_prepare(RetroWave_Board_OPL3, 0x12, 1);
224+
usleep (1700); /* chip needs about 1.6ms to safely reset, so delay 1.7ms */
225+
226+
cmd_prepare(RetroWave_Board_OPL3, 0x12, 1); // GPIOA register
209227
cmd_buffer[cmd_buffer_used++] = 0xff;
228+
cmd_buffer[cmd_buffer_used++] = 0x00; // Retrowave express OPL3 seems to only like even data writes
210229
io_prepare();
211230
flush();
231+
#else // reset by registers
232+
queue_port1 (5, 1); // Enable OPL3 mode
233+
queue_port1 (4, 0); // Disable all 4-OP connections
212234

213-
queue_port1 (5, 1);
214-
queue_port1 (4, 0);
215-
216-
for (int i=0x20; i < 0x35; i++)
235+
for (int i=0x20; i <= 0x35; i++)
217236
{
218-
queue_port0 (i, 0);
219-
queue_port1 (i, 0);
237+
queue_port0 (i, 0x01);
238+
queue_port1 (i, 0x01);
220239
}
221-
for (int i=0xa0; i < 0xa8; i++)
240+
for (int i=0x40; i <= 0x55; i++)
222241
{
223-
queue_port0 (i, 0);
224-
queue_port1 (i, 0);
242+
queue_port0 (i, 0x3f);
243+
queue_port1 (i, 0x3f);
225244
}
226-
for (int i=0xb0; i < 0xb8; i++)
245+
for (int i=0x60; i <= 0x75; i++)
227246
{
228-
queue_port0 (i, 0);
229-
queue_port1 (i, 0);
247+
queue_port0 (i, 0xee);
248+
queue_port1 (i, 0xee);
249+
}
250+
for (int i=0x80; i <= 0x95; i++)
251+
{
252+
queue_port0 (i, 0x0e);
253+
queue_port1 (i, 0x0e);
254+
}
255+
for (int i=0xa0; i <= 0xa8; i++)
256+
{
257+
queue_port0 (i, 0x80);
258+
queue_port1 (i, 0x80);
230259
}
231-
for (int i=0xbd; i < 0xbd; i++)
260+
for (int i=0xb0; i <= 0xb8; i++)
261+
{
262+
queue_port0 (i, 0x04);
263+
queue_port1 (i, 0x04);
264+
}
265+
for (int i=0xbd; i <= 0xbd; i++)
232266
{
233267
queue_port0 (i, 0);
234268
queue_port1 (i, 0);
235269
}
236-
for (int i=0xc0; i < 0xc8; i++)
270+
for (int i=0xc0; i <= 0xc8; i++)
237271
{
238-
queue_port0 (i, 0x30);
239-
queue_port1 (i, 0x30);
272+
queue_port0 (i, 0x30); // Enable Left and Right
273+
queue_port1 (i, 0x30); // Enable Left and Right
240274
}
241-
for (int i=0xe0; i < 0xf5; i++)
275+
for (int i=0xe0; i <= 0xf5; i++)
242276
{
243277
queue_port0 (i, 0);
244278
queue_port1 (i, 0);
245279
}
246-
for (int i=0x08; i < 0x08; i++)
280+
for (int i=0x08; i <= 0x08; i++)
247281
{
248282
queue_port0 (i, 0);
249283
queue_port1 (i, 0);
250284
}
251-
for (int i=0x01; i < 0x01; i++)
285+
for (int i=0x01; i <= 0x01; i++)
252286
{
253287
queue_port0 (i, 0);
254288
queue_port1 (i, 0);
255289
}
256-
queue_port1 (5, 0);
290+
queue_port1 (5, 0); // OPL2 mode
257291
io_prepare();
258292
flush();
293+
#endif
259294
}
260295

261296
void RetroWaveOpl::io_prepare(void)
@@ -297,7 +332,20 @@ void RetroWaveOpl::flush(void)
297332
{
298333
return;
299334
}
335+
#if defined(__APPLE__) /* Atleast OS X El Capitan has issues with buffering causing corruption*/
336+
int pos = 0;
337+
while (pos < io_buffer_used)
338+
{
339+
int target = io_buffer_used - pos;
340+
if (target > 128) target = 128;
341+
int res;
342+
::write(fd, io_buffer + pos, target);
343+
pos += target;
344+
usleep (250);
345+
}
346+
#else
300347
::write(fd, io_buffer, io_buffer_used);
348+
#endif
301349
io_buffer_used = 0;
302350
}
303351

0 commit comments

Comments
 (0)