@@ -94,11 +94,12 @@ RetroWaveOpl::RetroWaveOpl(const char *filename)
94
94
}
95
95
cfmakeraw (&tio);
96
96
97
+ #if 0 /* setting the speed appears to not be needed, and 2000000 is not valid on all operating systems */
97
98
#ifndef __APPLE__
98
99
cfsetispeed(&tio, 2000000);
99
100
cfsetospeed(&tio, 2000000);
100
101
#endif
101
-
102
+ # endif
102
103
if (tcgetattr (fd, &tio))
103
104
{
104
105
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)
107
108
exit (EXIT_FAILURE);
108
109
}
109
110
111
+ #if 0 /* setting the speed appears to not be needed, and 2000000 is not valid on all operating systems */
110
112
#ifdef __APPLE__
111
113
int speed = 2000000;
112
114
@@ -115,17 +117,29 @@ RetroWaveOpl::RetroWaveOpl(const char *filename)
115
117
fprintf(stderr, "Failed to set baudrate on device %s: %s", filename, strerror(errno));
116
118
exit(EXIT_FAILURE);
117
119
}
120
+ #endif
118
121
#endif
119
122
120
123
cmd_buffer[0 ] = 0x00 ;
121
124
cmd_buffer_used=1 ;
122
125
io_prepare ();
123
126
flush ();
124
127
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
+
125
139
for (uint8_t i=0x20 ; i<0x28 ; i++)
126
140
{
127
141
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
129
143
io_prepare ();
130
144
flush ();
131
145
@@ -172,24 +186,24 @@ void RetroWaveOpl::cmd_prepare(uint8_t io_addr, uint8_t io_reg, const int len)
172
186
173
187
void RetroWaveOpl::queue_port0 (uint8_t reg, uint8_t val)
174
188
{
175
- cmd_prepare (RetroWave_Board_OPL3, 0x12 , 6 );
189
+ cmd_prepare (RetroWave_Board_OPL3, 0x12 , 6 ); // GPIOA register
176
190
cmd_buffer[cmd_buffer_used++] = 0xe1 ;
177
191
cmd_buffer[cmd_buffer_used++] = reg;
178
192
cmd_buffer[cmd_buffer_used++] = 0xe3 ;
179
193
cmd_buffer[cmd_buffer_used++] = val;
180
194
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
182
196
}
183
197
184
198
void RetroWaveOpl::queue_port1 (uint8_t reg, uint8_t val)
185
199
{
186
- cmd_prepare (RetroWave_Board_OPL3, 0x12 , 6 );
200
+ cmd_prepare (RetroWave_Board_OPL3, 0x12 , 6 ); // GPIOA register
187
201
cmd_buffer[cmd_buffer_used++] = 0xe5 ;
188
202
cmd_buffer[cmd_buffer_used++] = reg;
189
203
cmd_buffer[cmd_buffer_used++] = 0xe7 ;
190
204
cmd_buffer[cmd_buffer_used++] = val;
191
205
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
193
207
}
194
208
195
209
void RetroWaveOpl::reset (void )
@@ -200,62 +214,83 @@ void RetroWaveOpl::reset(void)
200
214
flush ();
201
215
}
202
216
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
204
219
cmd_buffer[cmd_buffer_used++] = 0xfe;
220
+ cmd_buffer[cmd_buffer_used++] = 0x00; // Retrowave express OPL3 seems to only like even data writes
205
221
io_prepare();
206
222
flush();
207
223
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
209
227
cmd_buffer[cmd_buffer_used++] = 0xff;
228
+ cmd_buffer[cmd_buffer_used++] = 0x00; // Retrowave express OPL3 seems to only like even data writes
210
229
io_prepare();
211
230
flush();
231
+ #else // reset by registers
232
+ queue_port1 (5 , 1 ); // Enable OPL3 mode
233
+ queue_port1 (4 , 0 ); // Disable all 4-OP connections
212
234
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++)
217
236
{
218
- queue_port0 (i, 0 );
219
- queue_port1 (i, 0 );
237
+ queue_port0 (i, 0x01 );
238
+ queue_port1 (i, 0x01 );
220
239
}
221
- for (int i=0xa0 ; i < 0xa8 ; i++)
240
+ for (int i=0x40 ; i <= 0x55 ; i++)
222
241
{
223
- queue_port0 (i, 0 );
224
- queue_port1 (i, 0 );
242
+ queue_port0 (i, 0x3f );
243
+ queue_port1 (i, 0x3f );
225
244
}
226
- for (int i=0xb0 ; i < 0xb8 ; i++)
245
+ for (int i=0x60 ; i <= 0x75 ; i++)
227
246
{
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 );
230
259
}
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++)
232
266
{
233
267
queue_port0 (i, 0 );
234
268
queue_port1 (i, 0 );
235
269
}
236
- for (int i=0xc0 ; i < 0xc8 ; i++)
270
+ for (int i=0xc0 ; i <= 0xc8 ; i++)
237
271
{
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
240
274
}
241
- for (int i=0xe0 ; i < 0xf5 ; i++)
275
+ for (int i=0xe0 ; i <= 0xf5 ; i++)
242
276
{
243
277
queue_port0 (i, 0 );
244
278
queue_port1 (i, 0 );
245
279
}
246
- for (int i=0x08 ; i < 0x08 ; i++)
280
+ for (int i=0x08 ; i <= 0x08 ; i++)
247
281
{
248
282
queue_port0 (i, 0 );
249
283
queue_port1 (i, 0 );
250
284
}
251
- for (int i=0x01 ; i < 0x01 ; i++)
285
+ for (int i=0x01 ; i <= 0x01 ; i++)
252
286
{
253
287
queue_port0 (i, 0 );
254
288
queue_port1 (i, 0 );
255
289
}
256
- queue_port1 (5 , 0 );
290
+ queue_port1 (5 , 0 ); // OPL2 mode
257
291
io_prepare ();
258
292
flush ();
293
+ #endif
259
294
}
260
295
261
296
void RetroWaveOpl::io_prepare (void )
@@ -297,7 +332,20 @@ void RetroWaveOpl::flush(void)
297
332
{
298
333
return ;
299
334
}
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
300
347
::write (fd, io_buffer, io_buffer_used);
348
+ #endif
301
349
io_buffer_used = 0 ;
302
350
}
303
351
0 commit comments